aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.mailmap4
-rw-r--r--Documentation/ABI/testing/sysfs-bus-media6
-rw-r--r--Documentation/DocBook/Makefile5
-rw-r--r--Documentation/DocBook/media-entities.tmpl59
-rw-r--r--Documentation/DocBook/media.tmpl3
-rw-r--r--Documentation/DocBook/v4l/bayer.pdfbin0 -> 12116 bytes
-rw-r--r--Documentation/DocBook/v4l/bayer.pngbin0 -> 9725 bytes
-rw-r--r--Documentation/DocBook/v4l/common.xml2
-rw-r--r--Documentation/DocBook/v4l/compat.xml26
-rw-r--r--Documentation/DocBook/v4l/dev-capture.xml13
-rw-r--r--Documentation/DocBook/v4l/dev-output.xml13
-rw-r--r--Documentation/DocBook/v4l/dev-subdev.xml313
-rw-r--r--Documentation/DocBook/v4l/func-mmap.xml10
-rw-r--r--Documentation/DocBook/v4l/func-munmap.xml3
-rw-r--r--Documentation/DocBook/v4l/io.xml283
-rw-r--r--Documentation/DocBook/v4l/lirc_device_interface.xml2
-rw-r--r--Documentation/DocBook/v4l/media-controller.xml89
-rw-r--r--Documentation/DocBook/v4l/media-func-close.xml59
-rw-r--r--Documentation/DocBook/v4l/media-func-ioctl.xml116
-rw-r--r--Documentation/DocBook/v4l/media-func-open.xml94
-rw-r--r--Documentation/DocBook/v4l/media-ioc-device-info.xml133
-rw-r--r--Documentation/DocBook/v4l/media-ioc-enum-entities.xml308
-rw-r--r--Documentation/DocBook/v4l/media-ioc-enum-links.xml207
-rw-r--r--Documentation/DocBook/v4l/media-ioc-setup-link.xml93
-rw-r--r--Documentation/DocBook/v4l/nv12mt.gifbin0 -> 2108 bytes
-rw-r--r--Documentation/DocBook/v4l/nv12mt_example.gifbin0 -> 6858 bytes
-rw-r--r--Documentation/DocBook/v4l/pipeline.pdfbin0 -> 20276 bytes
-rw-r--r--Documentation/DocBook/v4l/pipeline.pngbin0 -> 12130 bytes
-rw-r--r--Documentation/DocBook/v4l/pixfmt-nv12m.xml154
-rw-r--r--Documentation/DocBook/v4l/pixfmt-nv12mt.xml74
-rw-r--r--Documentation/DocBook/v4l/pixfmt-srggb12.xml90
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yuv420m.xml162
-rw-r--r--Documentation/DocBook/v4l/pixfmt.xml119
-rw-r--r--Documentation/DocBook/v4l/planar-apis.xml62
-rw-r--r--Documentation/DocBook/v4l/subdev-formats.xml2467
-rw-r--r--Documentation/DocBook/v4l/v4l2.xml30
-rw-r--r--Documentation/DocBook/v4l/videodev2.h.xml141
-rw-r--r--Documentation/DocBook/v4l/vidioc-enum-fmt.xml2
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-fmt.xml15
-rw-r--r--Documentation/DocBook/v4l/vidioc-qbuf.xml24
-rw-r--r--Documentation/DocBook/v4l/vidioc-querybuf.xml14
-rw-r--r--Documentation/DocBook/v4l/vidioc-querycap.xml18
-rw-r--r--Documentation/DocBook/v4l/vidioc-streamon.xml9
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml152
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml154
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml119
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml155
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml180
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml141
-rw-r--r--Documentation/acpi/apei/output_format.txt25
-rw-r--r--Documentation/block/biodoc.txt5
-rw-r--r--Documentation/cgroups/blkio-controller.txt30
-rw-r--r--Documentation/devicetree/bindings/fb/sm501fb.txt34
-rw-r--r--Documentation/dvb/get_dvb_firmware8
-rw-r--r--Documentation/dvb/lmedm04.txt16
-rw-r--r--Documentation/fb/sm501.txt10
-rw-r--r--Documentation/feature-removal-schedule.txt44
-rw-r--r--Documentation/filesystems/exofs.txt10
-rw-r--r--Documentation/filesystems/squashfs.txt28
-rw-r--r--Documentation/hwmon/twl4030-madc-hwmon45
-rw-r--r--Documentation/ioctl/ioctl-number.txt1
-rw-r--r--Documentation/iostats.txt17
-rw-r--r--Documentation/media-framework.txt353
-rw-r--r--Documentation/video4linux/README.ivtv3
-rw-r--r--Documentation/video4linux/gspca.txt10
-rw-r--r--Documentation/video4linux/omap3isp.txt278
-rw-r--r--Documentation/video4linux/v4l2-framework.txt267
-rw-r--r--MAINTAINERS14
-rw-r--r--arch/arm/boot/compressed/mmcif-sh7372.c13
-rw-r--r--arch/arm/configs/omap2plus_defconfig11
-rw-r--r--arch/arm/configs/tegra_defconfig29
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c11
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c10
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c10
-rw-r--r--arch/arm/mach-mx3/mach-mx31moboard.c6
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c6
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c82
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c2
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c12
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c10
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c12
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c12
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c3
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c12
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c210
-rw-r--r--arch/arm/mach-omap2/board-overo.c357
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c12
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c8
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c8
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c14
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c15
-rw-r--r--arch/arm/mach-omap2/devices.c62
-rw-r--r--arch/arm/mach-omap2/devices.h19
-rw-r--r--arch/arm/mach-omap2/display.c80
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c13
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c12
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c23
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c3
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c25
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h (renamed from arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h)10
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmc-mackerel.h (renamed from arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h)11
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmc.h (renamed from arch/arm/mach-shmobile/include/mach/mmcif.h)10
-rw-r--r--arch/arm/mach-tegra/Kconfig5
-rw-r--r--arch/arm/mach-tegra/Makefile4
-rw-r--r--arch/arm/mach-tegra/board-harmony-pcie.c24
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c28
-rw-r--r--arch/arm/mach-tegra/board-harmony-power.c117
-rw-r--r--arch/arm/mach-tegra/board-harmony.c95
-rw-r--r--arch/arm/mach-tegra/board-harmony.h15
-rw-r--r--arch/arm/mach-tegra/board-paz00-pinmux.c157
-rw-r--r--arch/arm/mach-tegra/board-paz00.c128
-rw-r--r--arch/arm/mach-tegra/board-paz00.h29
-rw-r--r--arch/arm/mach-tegra/board-seaboard-pinmux.c11
-rw-r--r--arch/arm/mach-tegra/board-seaboard.c68
-rw-r--r--arch/arm/mach-tegra/board-seaboard.h3
-rw-r--r--arch/arm/mach-tegra/board-trimslice-pinmux.c9
-rw-r--r--arch/arm/mach-tegra/board-trimslice.c19
-rw-r--r--arch/arm/mach-tegra/board-trimslice.h3
-rw-r--r--arch/arm/mach-tegra/devices.c70
-rw-r--r--arch/arm/mach-tegra/devices.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h3
-rw-r--r--arch/arm/mm/init.c2
-rw-r--r--arch/arm/plat-omap/include/plat/display.h15
-rw-r--r--arch/arm/plat-omap/include/plat/omap34xx.h16
-rw-r--r--arch/blackfin/Kconfig1
-rw-r--r--arch/blackfin/include/asm/atomic.h2
-rw-r--r--arch/blackfin/include/asm/unistd.h3
-rw-r--r--arch/blackfin/mach-bf548/include/mach/anomaly.h6
-rw-r--r--arch/blackfin/mach-bf561/hotplug.c9
-rw-r--r--arch/blackfin/mach-common/entry.S1
-rw-r--r--arch/ia64/include/asm/acpi.h6
-rw-r--r--arch/ia64/include/asm/unistd.h6
-rw-r--r--arch/ia64/kernel/acpi.c23
-rw-r--r--arch/ia64/kernel/entry.S4
-rw-r--r--arch/ia64/mm/contig.c2
-rw-r--r--arch/ia64/mm/discontig.c2
-rw-r--r--arch/mn10300/Kconfig10
-rw-r--r--arch/mn10300/Kconfig.debug17
-rw-r--r--arch/mn10300/include/asm/debugger.h43
-rw-r--r--arch/mn10300/include/asm/div64.h21
-rw-r--r--arch/mn10300/include/asm/fpu.h2
-rw-r--r--arch/mn10300/include/asm/irqflags.h2
-rw-r--r--arch/mn10300/include/asm/kgdb.h81
-rw-r--r--arch/mn10300/include/asm/smp.h6
-rw-r--r--arch/mn10300/include/asm/thread_info.h4
-rw-r--r--arch/mn10300/kernel/Makefile5
-rw-r--r--arch/mn10300/kernel/entry.S67
-rw-r--r--arch/mn10300/kernel/fpu.c18
-rw-r--r--arch/mn10300/kernel/gdb-cache.S105
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c8
-rw-r--r--arch/mn10300/kernel/gdb-stub.c41
-rw-r--r--arch/mn10300/kernel/internal.h7
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/kgdb.c502
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c75
-rw-r--r--arch/mn10300/kernel/process.c6
-rw-r--r--arch/mn10300/kernel/smp.c26
-rw-r--r--arch/mn10300/kernel/switch_to.S111
-rw-r--r--arch/mn10300/kernel/traps.c406
-rw-r--r--arch/mn10300/mm/Kconfig.cache46
-rw-r--r--arch/mn10300/mm/Makefile9
-rw-r--r--arch/mn10300/mm/cache-dbg-flush-by-reg.S160
-rw-r--r--arch/mn10300/mm/cache-dbg-flush-by-tag.S114
-rw-r--r--arch/mn10300/mm/cache-dbg-inv-by-reg.S69
-rw-r--r--arch/mn10300/mm/cache-dbg-inv-by-tag.S120
-rw-r--r--arch/mn10300/mm/cache-dbg-inv.S47
-rw-r--r--arch/mn10300/mm/cache-flush-by-tag.S13
-rw-r--r--arch/mn10300/mm/cache-inv-by-reg.S22
-rw-r--r--arch/mn10300/mm/cache-inv-by-tag.S86
-rw-r--r--arch/mn10300/mm/cache.inc133
-rw-r--r--arch/mn10300/mm/fault.c9
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/cache.h1
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/cache.h1
-rw-r--r--arch/parisc/mm/init.c2
-rw-r--r--arch/powerpc/xmon/xmon.c2
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/boards/board-edosk7760.c2
-rw-r--r--arch/sh/boot/romimage/mmcif-sh7724.c9
-rw-r--r--arch/sh/include/asm/sizes.h63
-rw-r--r--arch/sh/include/asm/unistd_32.h3
-rw-r--r--arch/sh/include/asm/unistd_64.h3
-rw-r--r--arch/sh/kernel/process.c4
-rw-r--r--arch/sh/kernel/ptrace_32.c8
-rw-r--r--arch/sh/kernel/ptrace_64.c6
-rw-r--r--arch/sh/kernel/syscalls_32.S1
-rw-r--r--arch/sh/kernel/syscalls_64.S1
-rw-r--r--arch/sh/mm/pmb.c43
-rw-r--r--arch/sparc/mm/init_32.c2
-rw-r--r--arch/tile/mm/pgtable.c2
-rw-r--r--arch/unicore32/mm/init.c2
-rw-r--r--arch/x86/include/asm/acpi.h5
-rw-r--r--arch/x86/kernel/acpi/sleep.c12
-rw-r--r--arch/x86/kernel/acpi/sleep.h2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-apei.c42
-rw-r--r--arch/x86/platform/olpc/olpc-xo1.c42
-rw-r--r--block/blk-cgroup.c16
-rw-r--r--block/blk-cgroup.h14
-rw-r--r--block/blk-core.c646
-rw-r--r--block/blk-exec.c4
-rw-r--r--block/blk-flush.c439
-rw-r--r--block/blk-lib.c2
-rw-r--r--block/blk-merge.c6
-rw-r--r--block/blk-settings.c15
-rw-r--r--block/blk-sysfs.c2
-rw-r--r--block/blk-throttle.c139
-rw-r--r--block/blk.h16
-rw-r--r--block/cfq-iosched.c163
-rw-r--r--block/cfq.h6
-rw-r--r--block/deadline-iosched.c9
-rw-r--r--block/elevator.c108
-rw-r--r--block/genhd.c18
-rw-r--r--block/noop-iosched.c8
-rw-r--r--drivers/acpi/acpi_pad.c13
-rw-r--r--drivers/acpi/acpica/Makefile4
-rw-r--r--drivers/acpi/acpica/acdispat.h38
-rw-r--r--drivers/acpi/acpica/acglobal.h4
-rw-r--r--drivers/acpi/acpica/aclocal.h19
-rw-r--r--drivers/acpi/acpica/dsargs.c391
-rw-r--r--drivers/acpi/acpica/dscontrol.c410
-rw-r--r--drivers/acpi/acpica/dsopcode.c725
-rw-r--r--drivers/acpi/acpica/dswload.c670
-rw-r--r--drivers/acpi/acpica/dswload2.c720
-rw-r--r--drivers/acpi/acpica/evgpe.c9
-rw-r--r--drivers/acpi/acpica/evregion.c2
-rw-r--r--drivers/acpi/acpica/evxfregn.c34
-rw-r--r--drivers/acpi/acpica/exfldio.c4
-rw-r--r--drivers/acpi/acpica/hwxface.c10
-rw-r--r--drivers/acpi/acpica/tbfadt.c5
-rw-r--r--drivers/acpi/acpica/utdecode.c548
-rw-r--r--drivers/acpi/acpica/utglobal.c484
-rw-r--r--drivers/acpi/apei/Kconfig7
-rw-r--r--drivers/acpi/apei/cper.c18
-rw-r--r--drivers/acpi/apei/erst-dbg.c24
-rw-r--r--drivers/acpi/apei/erst.c235
-rw-r--r--drivers/acpi/battery.c22
-rw-r--r--drivers/acpi/button.c174
-rw-r--r--drivers/acpi/ec_sys.c4
-rw-r--r--drivers/acpi/internal.h3
-rw-r--r--drivers/acpi/nvs.c22
-rw-r--r--drivers/acpi/osl.c139
-rw-r--r--drivers/acpi/pci_link.c30
-rw-r--r--drivers/acpi/processor_core.c17
-rw-r--r--drivers/acpi/processor_driver.c4
-rw-r--r--drivers/acpi/reboot.c14
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/acpi/sleep.c28
-rw-r--r--drivers/block/DAC960.c8
-rw-r--r--drivers/block/amiflop.c9
-rw-r--r--drivers/block/ataflop.c14
-rw-r--r--drivers/block/cciss.c6
-rw-r--r--drivers/block/cpqarray.c3
-rw-r--r--drivers/block/drbd/drbd_actlog.c4
-rw-r--r--drivers/block/drbd/drbd_bitmap.c1
-rw-r--r--drivers/block/drbd/drbd_int.h16
-rw-r--r--drivers/block/drbd/drbd_main.c36
-rw-r--r--drivers/block/drbd/drbd_receiver.c29
-rw-r--r--drivers/block/drbd/drbd_req.c4
-rw-r--r--drivers/block/drbd/drbd_worker.c1
-rw-r--r--drivers/block/drbd/drbd_wrappers.h18
-rw-r--r--drivers/block/floppy.c11
-rw-r--r--drivers/block/loop.c16
-rw-r--r--drivers/block/paride/pcd.c18
-rw-r--r--drivers/block/paride/pd.c7
-rw-r--r--drivers/block/paride/pf.c10
-rw-r--r--drivers/block/pktcdvd.c15
-rw-r--r--drivers/block/swim.c8
-rw-r--r--drivers/block/swim3.c11
-rw-r--r--drivers/block/ub.c10
-rw-r--r--drivers/block/umem.c26
-rw-r--r--drivers/block/xsysace.c9
-rw-r--r--drivers/cdrom/gdrom.c16
-rw-r--r--drivers/cdrom/viocd.c17
-rw-r--r--drivers/dma/timb_dma.c3
-rw-r--r--drivers/gpio/Kconfig7
-rw-r--r--drivers/gpio/janz-ttl.c3
-rw-r--r--drivers/gpio/rdc321x-gpio.c3
-rw-r--r--drivers/gpio/sch_gpio.c57
-rw-r--r--drivers/gpio/timbgpio.c6
-rw-r--r--drivers/gpu/drm/drm_crtc.c51
-rw-r--r--drivers/gpu/drm/drm_gem.c5
-rw-r--r--drivers/gpu/drm/drm_ioctl.c3
-rw-r--r--drivers/gpu/drm/drm_irq.c15
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c8
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c70
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c21
-rw-r--r--drivers/gpu/drm/i915/intel_display.c39
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c4
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c109
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c21
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c30
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c8
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/jz4740-hwmon.c4
-rw-r--r--drivers/hwmon/twl4030-madc-hwmon.c157
-rw-r--r--drivers/i2c/busses/i2c-ocores.c3
-rw-r--r--drivers/i2c/busses/i2c-xiic.c3
-rw-r--r--drivers/ide/ide-atapi.c3
-rw-r--r--drivers/ide/ide-cd.c23
-rw-r--r--drivers/ide/ide-cd.h3
-rw-r--r--drivers/ide/ide-cd_ioctl.c8
-rw-r--r--drivers/ide/ide-gd.c14
-rw-r--r--drivers/ide/ide-io.c4
-rw-r--r--drivers/ide/ide-park.c2
-rw-r--r--drivers/idle/intel_idle.c22
-rw-r--r--drivers/infiniband/core/addr.c2
-rw-r--r--drivers/infiniband/core/agent.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c3
-rw-r--r--drivers/infiniband/hw/nes/nes.c2
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c725
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h38
-rw-r--r--drivers/input/misc/88pm860x_onkey.c2
-rw-r--r--drivers/input/misc/twl4030-vibra.c3
-rw-r--r--drivers/leds/leds-88pm860x.c60
-rw-r--r--drivers/leds/leds-mc13783.c7
-rw-r--r--drivers/md/bitmap.c5
-rw-r--r--drivers/md/dm-crypt.c9
-rw-r--r--drivers/md/dm-io.c2
-rw-r--r--drivers/md/dm-kcopyd.c55
-rw-r--r--drivers/md/dm-raid.c2
-rw-r--r--drivers/md/dm-raid1.c2
-rw-r--r--drivers/md/dm-table.c31
-rw-r--r--drivers/md/dm.c52
-rw-r--r--drivers/md/dm.h2
-rw-r--r--drivers/md/linear.c20
-rw-r--r--drivers/md/md.c20
-rw-r--r--drivers/md/multipath.c38
-rw-r--r--drivers/md/raid0.c19
-rw-r--r--drivers/md/raid1.c91
-rw-r--r--drivers/md/raid10.c97
-rw-r--r--drivers/md/raid5.c63
-rw-r--r--drivers/md/raid5.h2
-rw-r--r--drivers/media/Kconfig22
-rw-r--r--drivers/media/Makefile6
-rw-r--r--drivers/media/common/tuners/tda9887.c9
-rw-r--r--drivers/media/common/tuners/tea5761.c33
-rw-r--r--drivers/media/common/tuners/tuner-types.c21
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c16
-rw-r--r--drivers/media/common/tuners/xc5000.c56
-rw-r--r--drivers/media/common/tuners/xc5000.h1
-rw-r--r--drivers/media/dvb/Kconfig2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h1
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c8
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c67
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c47
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c1381
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c590
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c235
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c33
-rw-r--r--drivers/media/dvb/dvb-usb/technisat-usb2.c807
-rw-r--r--drivers/media/dvb/firewire/Kconfig8
-rw-r--r--drivers/media/dvb/firewire/Makefile5
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c300
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c15
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c135
-rw-r--r--drivers/media/dvb/firewire/firedtv-fe.c8
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c146
-rw-r--r--drivers/media/dvb/firewire/firedtv.h45
-rw-r--r--drivers/media/dvb/frontends/Kconfig15
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/af9013.c55
-rw-r--r--drivers/media/dvb/frontends/dib0090.c1583
-rw-r--r--drivers/media/dvb/frontends/dib0090.h31
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c1945
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h96
-rw-r--r--drivers/media/dvb/frontends/dib8000.c821
-rw-r--r--drivers/media/dvb/frontends/dib8000.h20
-rw-r--r--drivers/media/dvb/frontends/dib9000.c2351
-rw-r--r--drivers/media/dvb/frontends/dib9000.h131
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c279
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h152
-rw-r--r--drivers/media/dvb/frontends/ds3000.c645
-rw-r--r--drivers/media/dvb/frontends/ds3000.h3
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c79
-rw-r--r--drivers/media/dvb/frontends/stv0288.c7
-rw-r--r--drivers/media/dvb/frontends/stv0367.c3459
-rw-r--r--drivers/media/dvb/frontends/stv0367.h66
-rw-r--r--drivers/media/dvb/frontends/stv0367_priv.h212
-rw-r--r--drivers/media/dvb/frontends/stv0367_regs.h3614
-rw-r--r--drivers/media/dvb/frontends/stv0900.h2
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c27
-rw-r--r--drivers/media/dvb/frontends/stv090x.c295
-rw-r--r--drivers/media/dvb/frontends/stv090x.h16
-rw-r--r--drivers/media/dvb/frontends/stv090x_reg.h16
-rw-r--r--drivers/media/dvb/frontends/zl10036.c10
-rw-r--r--drivers/media/dvb/ngene/Makefile3
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c179
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c236
-rw-r--r--drivers/media/dvb/ngene/ngene-dvb.c71
-rw-r--r--drivers/media/dvb/ngene/ngene.h24
-rw-r--r--drivers/media/dvb/siano/sms-cards.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c15
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c1
-rw-r--r--drivers/media/media-device.c382
-rw-r--r--drivers/media/media-devnode.c320
-rw-r--r--drivers/media/media-entity.c536
-rw-r--r--drivers/media/radio/Kconfig4
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/dsbr100.c128
-rw-r--r--drivers/media/radio/radio-si4713.c3
-rw-r--r--drivers/media/radio/radio-timb.c3
-rw-r--r--drivers/media/radio/radio-wl1273.c367
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c1
-rw-r--r--drivers/media/radio/wl128x/Kconfig17
-rw-r--r--drivers/media/radio/wl128x/Makefile6
-rw-r--r--drivers/media/radio/wl128x/fmdrv.h244
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c1677
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.h402
-rw-r--r--drivers/media/radio/wl128x/fmdrv_rx.c847
-rw-r--r--drivers/media/radio/wl128x/fmdrv_rx.h59
-rw-r--r--drivers/media/radio/wl128x/fmdrv_tx.c425
-rw-r--r--drivers/media/radio/wl128x/fmdrv_tx.h37
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.c580
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.h33
-rw-r--r--drivers/media/rc/Kconfig35
-rw-r--r--drivers/media/rc/Makefile1
-rw-r--r--drivers/media/rc/imon.c11
-rw-r--r--drivers/media/rc/ir-nec-decoder.c10
-rw-r--r--drivers/media/rc/ite-cir.c1736
-rw-r--r--drivers/media/rc/ite-cir.h481
-rw-r--r--drivers/media/rc/keymaps/Makefile6
-rw-r--r--drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c6
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-dvbt.c4
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m135a.c2
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c2
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-rm-ks.c2
-rw-r--r--drivers/media/rc/keymaps/rc-behold-columbus.c2
-rw-r--r--drivers/media/rc/keymaps/rc-behold.c2
-rw-r--r--drivers/media/rc/keymaps/rc-budget-ci-old.c3
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy.c2
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c2
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv.c4
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv2.c2
-rw-r--r--drivers/media/rc/keymaps/rc-flydvb.c4
-rw-r--r--drivers/media/rc/keymaps/rc-hauppauge-new.c100
-rw-r--r--drivers/media/rc/keymaps/rc-hauppauge.c (renamed from drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c)190
-rw-r--r--drivers/media/rc/keymaps/rc-imon-mce.c2
-rw-r--r--drivers/media/rc/keymaps/rc-imon-pad.c2
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-315u.c2
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c2
-rw-r--r--drivers/media/rc/keymaps/rc-lme2510.c96
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c2
-rw-r--r--drivers/media/rc/keymaps/rc-nebula.c2
-rw-r--r--drivers/media/rc/keymaps/rc-norwood.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pctv-sedna.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-mk12.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-new.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pv951.c4
-rw-r--r--drivers/media/rc/keymaps/rc-rc5-tv.c81
-rw-r--r--drivers/media/rc/keymaps/rc-rc6-mce.c2
-rw-r--r--drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c2
-rw-r--r--drivers/media/rc/keymaps/rc-technisat-usb2.c93
-rw-r--r--drivers/media/rc/keymaps/rc-terratec-slim-2.c72
-rw-r--r--drivers/media/rc/keymaps/rc-winfast.c22
-rw-r--r--drivers/media/rc/mceusb.c4
-rw-r--r--drivers/media/video/Kconfig58
-rw-r--r--drivers/media/video/Makefile12
-rw-r--r--drivers/media/video/adv7343.c167
-rw-r--r--drivers/media/video/adv7343_regs.h8
-rw-r--r--drivers/media/video/au0828/au0828-cards.c3
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c3
-rw-r--r--drivers/media/video/au0828/au0828-video.c4
-rw-r--r--drivers/media/video/bt819.c129
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c34
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c374
-rw-r--r--drivers/media/video/cs5345.c87
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c92
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c175
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h12
-rw-r--r--drivers/media/video/cx18/cx18-controls.c285
-rw-r--r--drivers/media/video/cx18/cx18-controls.h7
-rw-r--r--drivers/media/video/cx18/cx18-driver.c31
-rw-r--r--drivers/media/video/cx18/cx18-driver.h16
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c52
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c152
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c5
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h5
-rw-r--r--drivers/media/video/cx18/cx18-streams.c17
-rw-r--r--drivers/media/video/cx18/cx23418.h2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-417.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c14
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c246
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c16
-rw-r--r--drivers/media/video/cx231xx/cx231xx-i2c.c31
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c20
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h7
-rw-r--r--drivers/media/video/cx23885/Kconfig12
-rw-r--r--drivers/media/video/cx23885/Makefile1
-rw-r--r--drivers/media/video/cx23885/altera-ci.c838
-rw-r--r--drivers/media/video/cx23885/altera-ci.h100
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c110
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c37
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c175
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h1
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c7
-rw-r--r--drivers/media/video/cx23885/cx23885.h7
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c118
-rw-r--r--drivers/media/video/cx88/cx88-cards.c24
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c23
-rw-r--r--drivers/media/video/cx88/cx88-input.c5
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c8
-rw-r--r--drivers/media/video/cx88/cx88-video.c78
-rw-r--r--drivers/media/video/cx88/cx88.h14
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c10
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c33
-rw-r--r--drivers/media/video/gspca/Kconfig19
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/autogain_functions.h179
-rw-r--r--drivers/media/video/gspca/cpia1.c37
-rw-r--r--drivers/media/video/gspca/gspca.c16
-rw-r--r--drivers/media/video/gspca/jeilinj.c2
-rw-r--r--drivers/media/video/gspca/nw80x.c2145
-rw-r--r--drivers/media/video/gspca/ov519.c208
-rw-r--r--drivers/media/video/gspca/ov534.c980
-rw-r--r--drivers/media/video/gspca/sn9c20x.c40
-rw-r--r--drivers/media/video/gspca/sonixb.c306
-rw-r--r--drivers/media/video/gspca/sonixj.c353
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c2
-rw-r--r--drivers/media/video/gspca/vicam.c381
-rw-r--r--drivers/media/video/gspca/zc3xx-reg.h2
-rw-r--r--drivers/media/video/gspca/zc3xx.c128
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c72
-rw-r--r--drivers/media/video/ir-kbd-i2c.c18
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c3
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c159
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c7
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c52
-rw-r--r--drivers/media/video/mem2mem_testdev.c231
-rw-r--r--drivers/media/video/meye.c3
-rw-r--r--drivers/media/video/mt9m001.c2
-rw-r--r--drivers/media/video/mt9v022.c4
-rw-r--r--drivers/media/video/mx3_camera.c415
-rw-r--r--drivers/media/video/mxb.c3
-rw-r--r--drivers/media/video/noon010pc30.c792
-rw-r--r--drivers/media/video/omap1_camera.c66
-rw-r--r--drivers/media/video/omap24xxcam.c1
-rw-r--r--drivers/media/video/omap3isp/Makefile13
-rw-r--r--drivers/media/video/omap3isp/cfa_coef_table.h61
-rw-r--r--drivers/media/video/omap3isp/gamma_table.h90
-rw-r--r--drivers/media/video/omap3isp/isp.c2220
-rw-r--r--drivers/media/video/omap3isp/isp.h431
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c2268
-rw-r--r--drivers/media/video/omap3isp/ispccdc.h219
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c1173
-rw-r--r--drivers/media/video/omap3isp/ispccp2.h98
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c1317
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.h166
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.c247
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.h74
-rw-r--r--drivers/media/video/omap3isp/isph3a.h117
-rw-r--r--drivers/media/video/omap3isp/isph3a_aewb.c374
-rw-r--r--drivers/media/video/omap3isp/isph3a_af.c429
-rw-r--r--drivers/media/video/omap3isp/isphist.c520
-rw-r--r--drivers/media/video/omap3isp/isphist.h40
-rw-r--r--drivers/media/video/omap3isp/isppreview.c2113
-rw-r--r--drivers/media/video/omap3isp/isppreview.h214
-rw-r--r--drivers/media/video/omap3isp/ispqueue.c1153
-rw-r--r--drivers/media/video/omap3isp/ispqueue.h187
-rw-r--r--drivers/media/video/omap3isp/ispreg.h1589
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c1693
-rw-r--r--drivers/media/video/omap3isp/ispresizer.h147
-rw-r--r--drivers/media/video/omap3isp/ispstat.c1092
-rw-r--r--drivers/media/video/omap3isp/ispstat.h169
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c1255
-rw-r--r--drivers/media/video/omap3isp/ispvideo.h202
-rw-r--r--drivers/media/video/omap3isp/luma_enhance_table.h42
-rw-r--r--drivers/media/video/omap3isp/noise_filter_table.h30
-rw-r--r--drivers/media/video/ov6650.c10
-rw-r--r--drivers/media/video/ov9740.c1009
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c24
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c84
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c2
-rw-r--r--drivers/media/video/pwc/pwc-if.c38
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1033
-rw-r--r--drivers/media/video/pwc/pwc.h3
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c602
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c1019
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h180
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c205
-rw-r--r--drivers/media/video/s5p-fimc/regs-fimc.h29
-rw-r--r--drivers/media/video/saa7110.c115
-rw-r--r--drivers/media/video/saa7134/Kconfig1
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c43
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c35
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c52
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c10
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c16
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c8
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c10
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c8
-rw-r--r--drivers/media/video/saa7164/saa7164-dvb.c4
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c8
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c2
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c8
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c274
-rw-r--r--drivers/media/video/sh_mobile_csi2.c6
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c6
-rw-r--r--drivers/media/video/soc_camera.c156
-rw-r--r--drivers/media/video/soc_mediabus.c16
-rw-r--r--drivers/media/video/timblogiw.c3
-rw-r--r--drivers/media/video/tlg2300/pd-video.c4
-rw-r--r--drivers/media/video/tlv320aic23b.c74
-rw-r--r--drivers/media/video/tuner-core.c1205
-rw-r--r--drivers/media/video/tvp514x.c236
-rw-r--r--drivers/media/video/tvp5150.c199
-rw-r--r--drivers/media/video/tvp7002.c117
-rw-r--r--drivers/media/video/uvc/uvc_driver.c8
-rw-r--r--drivers/media/video/uvc/uvc_video.c14
-rw-r--r--drivers/media/video/v4l2-common.c64
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c244
-rw-r--r--drivers/media/video/v4l2-ctrls.c2
-rw-r--r--drivers/media/video/v4l2-dev.c152
-rw-r--r--drivers/media/video/v4l2-device.c101
-rw-r--r--drivers/media/video/v4l2-fh.c47
-rw-r--r--drivers/media/video/v4l2-ioctl.c669
-rw-r--r--drivers/media/video/v4l2-mem2mem.c236
-rw-r--r--drivers/media/video/v4l2-subdev.c332
-rw-r--r--drivers/media/video/via-camera.c147
-rw-r--r--drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--drivers/media/video/videobuf2-core.c1819
-rw-r--r--drivers/media/video/videobuf2-dma-contig.c185
-rw-r--r--drivers/media/video/videobuf2-dma-sg.c294
-rw-r--r--drivers/media/video/videobuf2-memops.c235
-rw-r--r--drivers/media/video/videobuf2-vmalloc.c132
-rw-r--r--drivers/media/video/vivi.c579
-rw-r--r--drivers/media/video/vpx3220.c137
-rw-r--r--drivers/media/video/wm8775.c126
-rw-r--r--drivers/message/i2o/i2o_block.c17
-rw-r--r--drivers/mfd/88pm860x-core.c567
-rw-r--r--drivers/mfd/88pm860x-i2c.c103
-rw-r--r--drivers/mfd/Kconfig42
-rw-r--r--drivers/mfd/Makefile6
-rw-r--r--drivers/mfd/ab3100-core.c10
-rw-r--r--drivers/mfd/ab3550-core.c12
-rw-r--r--drivers/mfd/ab8500-core.c56
-rw-r--r--drivers/mfd/ab8500-debugfs.c6
-rw-r--r--drivers/mfd/ab8500-gpadc.c614
-rw-r--r--drivers/mfd/ab8500-sysctrl.c80
-rw-r--r--drivers/mfd/adp5520.c15
-rw-r--r--drivers/mfd/asic3.c10
-rw-r--r--drivers/mfd/cs5535-mfd.c37
-rw-r--r--drivers/mfd/davinci_voicecodec.c4
-rw-r--r--drivers/mfd/htc-pasic3.c7
-rw-r--r--drivers/mfd/janz-cmodio.c3
-rw-r--r--drivers/mfd/jz4740-adc.c4
-rw-r--r--drivers/mfd/lpc_sch.c7
-rw-r--r--drivers/mfd/max8997.c427
-rw-r--r--drivers/mfd/max8998.c4
-rw-r--r--drivers/mfd/mc13xxx-core.c21
-rw-r--r--drivers/mfd/mfd-core.c135
-rw-r--r--drivers/mfd/pcf50633-core.c24
-rw-r--r--drivers/mfd/rdc321x-southbridge.c4
-rw-r--r--drivers/mfd/sh_mobile_sdhi.c4
-rw-r--r--drivers/mfd/sm501.c134
-rw-r--r--drivers/mfd/t7l66xb.c13
-rw-r--r--drivers/mfd/tc6387xb.c7
-rw-r--r--drivers/mfd/tc6393xb.c25
-rw-r--r--drivers/mfd/timberdale.c81
-rw-r--r--drivers/mfd/tps6105x.c246
-rw-r--r--drivers/mfd/tps6586x.c26
-rw-r--r--drivers/mfd/twl-core.c8
-rw-r--r--drivers/mfd/twl4030-codec.c6
-rw-r--r--drivers/mfd/twl4030-madc.c802
-rw-r--r--drivers/mfd/ucb1x00-ts.c5
-rw-r--r--drivers/mfd/vx855.c1
-rw-r--r--drivers/mfd/wl1273-core.c155
-rw-r--r--drivers/mfd/wm831x-i2c.c18
-rw-r--r--drivers/mfd/wm831x-irq.c44
-rw-r--r--drivers/mfd/wm831x-spi.c24
-rw-r--r--drivers/mfd/wm8400-core.c2
-rw-r--r--drivers/mfd/wm8994-core.c77
-rw-r--r--drivers/mfd/wm8994-irq.c14
-rw-r--r--drivers/mmc/card/queue.c3
-rw-r--r--drivers/mmc/host/tmio_mmc.c34
-rw-r--r--drivers/mtd/nand/tmio_nand.c11
-rw-r--r--drivers/mtd/ubi/io.c4
-rw-r--r--drivers/net/can/janz-ican3.c3
-rw-r--r--drivers/net/ks8842.c3
-rw-r--r--drivers/net/mlx4/main.c3
-rw-r--r--drivers/of/base.c3
-rw-r--r--drivers/of/fdt.c6
-rw-r--r--drivers/of/platform.c72
-rw-r--r--drivers/pci/pci-acpi.c16
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h9
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c182
-rw-r--r--drivers/power/jz4740-battery.c4
-rw-r--r--drivers/regulator/88pm8607.c46
-rw-r--r--drivers/regulator/Kconfig18
-rw-r--r--drivers/regulator/Makefile3
-rw-r--r--drivers/regulator/ab3100.c3
-rw-r--r--drivers/regulator/max8997.c1213
-rw-r--r--drivers/regulator/mc13783-regulator.c7
-rw-r--r--drivers/regulator/mc13892-regulator.c7
-rw-r--r--drivers/regulator/tps6105x-regulator.c196
-rw-r--r--drivers/regulator/twl-regulator.c24
-rw-r--r--drivers/s390/block/dasd.c2
-rw-r--r--drivers/s390/char/tape_block.c12
-rw-r--r--drivers/scsi/scsi_lib.c44
-rw-r--r--drivers/scsi/scsi_transport_fc.c2
-rw-r--r--drivers/scsi/scsi_transport_sas.c6
-rw-r--r--drivers/sh/clk/core.c68
-rw-r--r--drivers/sh/intc/core.c95
-rw-r--r--drivers/sh/intc/internals.h1
-rw-r--r--drivers/spi/amba-pl022.c20
-rw-r--r--drivers/spi/omap2_mcspi.c6
-rw-r--r--drivers/spi/xilinx_spi.c3
-rw-r--r--drivers/staging/Kconfig8
-rw-r--r--drivers/staging/Makefile5
-rw-r--r--drivers/staging/altera-stapl/Kconfig8
-rw-r--r--drivers/staging/altera-stapl/Makefile3
-rw-r--r--drivers/staging/altera-stapl/altera-comp.c142
-rw-r--r--drivers/staging/altera-stapl/altera-exprt.h33
-rw-r--r--drivers/staging/altera-stapl/altera-jtag.c1020
-rw-r--r--drivers/staging/altera-stapl/altera-jtag.h113
-rw-r--r--drivers/staging/altera-stapl/altera-lpt.c70
-rw-r--r--drivers/staging/altera-stapl/altera.c2527
-rw-r--r--drivers/staging/cx25821/Kconfig1
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c2
-rw-r--r--drivers/staging/cx25821/cx25821-core.c16
-rw-r--r--drivers/staging/cx25821/cx25821-video.c9
-rw-r--r--drivers/staging/cx25821/cx25821.h3
-rw-r--r--drivers/staging/cxd2099/Kconfig11
-rw-r--r--drivers/staging/cxd2099/Makefile5
-rw-r--r--drivers/staging/cxd2099/TODO12
-rw-r--r--drivers/staging/cxd2099/cxd2099.c574
-rw-r--r--drivers/staging/cxd2099/cxd2099.h41
-rw-r--r--drivers/staging/dabusb/Kconfig14
-rw-r--r--drivers/staging/dabusb/Makefile2
-rw-r--r--drivers/staging/dabusb/TODO5
-rw-r--r--drivers/staging/dabusb/dabusb.c926
-rw-r--r--drivers/staging/dabusb/dabusb.h80
-rw-r--r--drivers/staging/easycap/easycap_ioctl.c3
-rw-r--r--drivers/staging/hv/blkvsc_drv.c11
-rw-r--r--drivers/staging/lirc/Kconfig12
-rw-r--r--drivers/staging/lirc/Makefile2
-rw-r--r--drivers/staging/lirc/TODO.lirc_zilog51
-rw-r--r--drivers/staging/lirc/lirc_imon.c2
-rw-r--r--drivers/staging/lirc/lirc_it87.c1027
-rw-r--r--drivers/staging/lirc/lirc_it87.h116
-rw-r--r--drivers/staging/lirc/lirc_ite8709.c542
-rw-r--r--drivers/staging/lirc/lirc_sasem.c2
-rw-r--r--drivers/staging/lirc/lirc_zilog.c814
-rw-r--r--drivers/staging/se401/Kconfig13
-rw-r--r--drivers/staging/se401/Makefile1
-rw-r--r--drivers/staging/se401/TODO5
-rw-r--r--drivers/staging/se401/se401.c1492
-rw-r--r--drivers/staging/se401/se401.h236
-rw-r--r--drivers/staging/se401/videodev.h318
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c13
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c102
-rw-r--r--drivers/staging/tm6000/tm6000-core.c298
-rw-r--r--drivers/staging/tm6000/tm6000-regs.h63
-rw-r--r--drivers/staging/tm6000/tm6000-stds.c35
-rw-r--r--drivers/staging/tm6000/tm6000-video.c344
-rw-r--r--drivers/staging/tm6000/tm6000.h25
-rw-r--r--drivers/staging/usbvideo/Kconfig15
-rw-r--r--drivers/staging/usbvideo/Makefile2
-rw-r--r--drivers/staging/usbvideo/TODO5
-rw-r--r--drivers/staging/usbvideo/usbvideo.c2222
-rw-r--r--drivers/staging/usbvideo/usbvideo.h395
-rw-r--r--drivers/staging/usbvideo/vicam.c946
-rw-r--r--drivers/staging/usbvideo/videodev.h318
-rw-r--r--drivers/staging/westbridge/astoria/block/cyasblkdev_block.c11
-rw-r--r--drivers/target/target_core_iblock.c7
-rw-r--r--drivers/thermal/thermal_sys.c3
-rw-r--r--drivers/tty/sysrq.c2
-rw-r--r--drivers/tty/vt/keyboard.c2
-rw-r--r--drivers/usb/class/cdc-acm.c7
-rw-r--r--drivers/usb/class/cdc-wdm.c2
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/host/ehci-q.c12
-rw-r--r--drivers/usb/host/ohci-tmio.c8
-rw-r--r--drivers/usb/misc/uss720.c7
-rw-r--r--drivers/usb/musb/blackfin.c6
-rw-r--r--drivers/usb/musb/musb_gadget.c8
-rw-r--r--drivers/usb/serial/usb_wwan.c3
-rw-r--r--drivers/video/arkfb.c160
-rw-r--r--drivers/video/atmel_lcdfb.c31
-rw-r--r--drivers/video/aty/radeon_base.c2
-rw-r--r--drivers/video/aty/radeon_i2c.c3
-rw-r--r--drivers/video/backlight/88pm860x_bl.c34
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/cg6.c1
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/console/tileblit.c2
-rw-r--r--drivers/video/edid.h4
-rw-r--r--drivers/video/ffb.c2
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/hpfb.c6
-rw-r--r--drivers/video/matrox/matroxfb_base.c3
-rw-r--r--drivers/video/metronomefb.c2
-rw-r--r--drivers/video/omap/Kconfig7
-rw-r--r--drivers/video/omap/blizzard.c3
-rw-r--r--drivers/video/omap/hwa742.c3
-rw-r--r--drivers/video/omap2/displays/Kconfig6
-rw-r--r--drivers/video/omap2/displays/Makefile1
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c25
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c279
-rw-r--r--drivers/video/omap2/displays/panel-taal.c123
-rw-r--r--drivers/video/omap2/dss/Kconfig14
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/core.c480
-rw-r--r--drivers/video/omap2/dss/dispc.c335
-rw-r--r--drivers/video/omap2/dss/display.c35
-rw-r--r--drivers/video/omap2/dss/dpi.c45
-rw-r--r--drivers/video/omap2/dss/dsi.c967
-rw-r--r--drivers/video/omap2/dss/dss.c763
-rw-r--r--drivers/video/omap2/dss/dss.h153
-rw-r--r--drivers/video/omap2/dss/dss_features.c163
-rw-r--r--drivers/video/omap2/dss/dss_features.h27
-rw-r--r--drivers/video/omap2/dss/hdmi.c1332
-rw-r--r--drivers/video/omap2/dss/hdmi.h415
-rw-r--r--drivers/video/omap2/dss/hdmi_omap4_panel.c222
-rw-r--r--drivers/video/omap2/dss/manager.c13
-rw-r--r--drivers/video/omap2/dss/overlay.c10
-rw-r--r--drivers/video/omap2/dss/rfbi.c128
-rw-r--r--drivers/video/omap2/dss/sdi.c62
-rw-r--r--drivers/video/omap2/dss/venc.c128
-rw-r--r--drivers/video/omap2/omapfb/Kconfig6
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c23
-rw-r--r--drivers/video/s3c-fb.c1
-rw-r--r--drivers/video/s3fb.c341
-rw-r--r--drivers/video/sh7760fb.c4
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c5
-rw-r--r--drivers/video/sis/sis.h1
-rw-r--r--drivers/video/sis/sis_main.c315
-rw-r--r--drivers/video/sis/vgatypes.h1
-rw-r--r--drivers/video/sm501fb.c275
-rw-r--r--drivers/video/svgalib.c175
-rw-r--r--drivers/video/tcx.c1
-rw-r--r--drivers/video/tmiofb.c28
-rw-r--r--drivers/video/uvesafb.c49
-rw-r--r--drivers/video/vermilion/vermilion.c3
-rw-r--r--drivers/video/vesafb.c44
-rw-r--r--drivers/video/vt8623fb.c157
-rw-r--r--drivers/w1/masters/ds1wm.c13
-rw-r--r--drivers/watchdog/rdc321x_wdt.c3
-rw-r--r--fs/adfs/inode.c1
-rw-r--r--fs/affs/file.c2
-rw-r--r--fs/aio.c77
-rw-r--r--fs/befs/linuxvfs.c1
-rw-r--r--fs/bfs/file.c1
-rw-r--r--fs/bio-integrity.c3
-rw-r--r--fs/bio.c10
-rw-r--r--fs/block_dev.c27
-rw-r--r--fs/btrfs/disk-io.c79
-rw-r--r--fs/btrfs/extent_io.c2
-rw-r--r--fs/btrfs/inode.c1
-rw-r--r--fs/btrfs/volumes.c91
-rw-r--r--fs/buffer.c51
-rw-r--r--fs/cifs/file.c30
-rw-r--r--fs/direct-io.c7
-rw-r--r--fs/efs/inode.c1
-rw-r--r--fs/exofs/common.h18
-rw-r--r--fs/exofs/dir.c33
-rw-r--r--fs/exofs/exofs.h6
-rw-r--r--fs/exofs/file.c16
-rw-r--r--fs/exofs/inode.c52
-rw-r--r--fs/exofs/super.c190
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext3/inode.c3
-rw-r--r--fs/ext4/inode.c4
-rw-r--r--fs/ext4/page-io.c3
-rw-r--r--fs/fat/inode.c1
-rw-r--r--fs/freevxfs/vxfs_subr.c1
-rw-r--r--fs/fuse/inode.c1
-rw-r--r--fs/gfs2/aops.c3
-rw-r--r--fs/gfs2/log.c4
-rw-r--r--fs/gfs2/lops.c12
-rw-r--r--fs/gfs2/meta_io.c3
-rw-r--r--fs/hfs/inode.c2
-rw-r--r--fs/hfsplus/inode.c2
-rw-r--r--fs/hpfs/file.c1
-rw-r--r--fs/isofs/inode.c1
-rw-r--r--fs/jbd/commit.c22
-rw-r--r--fs/jbd2/commit.c22
-rw-r--r--fs/jfs/inode.c1
-rw-r--r--fs/jfs/jfs_metapage.c1
-rw-r--r--fs/locks.c12
-rw-r--r--fs/logfs/dev_bdev.c2
-rw-r--r--fs/minix/inode.c1
-rw-r--r--fs/mpage.c8
-rw-r--r--fs/nfsd/export.c1
-rw-r--r--fs/nfsd/nfs4idmap.c1
-rw-r--r--fs/nfsd/nfs4proc.c4
-rw-r--r--fs/nfsd/nfs4state.c160
-rw-r--r--fs/nfsd/nfs4xdr.c5
-rw-r--r--fs/nfsd/nfsctl.c35
-rw-r--r--fs/nfsd/state.h12
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/nilfs2/btnode.c7
-rw-r--r--fs/nilfs2/gcinode.c1
-rw-r--r--fs/nilfs2/inode.c1
-rw-r--r--fs/nilfs2/mdt.c9
-rw-r--r--fs/nilfs2/page.c5
-rw-r--r--fs/nilfs2/page.h3
-rw-r--r--fs/nilfs2/segbuf.c2
-rw-r--r--fs/ntfs/aops.c4
-rw-r--r--fs/ntfs/compress.c3
-rw-r--r--fs/ocfs2/aops.c1
-rw-r--r--fs/ocfs2/cluster/heartbeat.c4
-rw-r--r--fs/omfs/file.c1
-rw-r--r--fs/partitions/check.c3
-rw-r--r--fs/pstore/platform.c15
-rw-r--r--fs/qnx4/inode.c1
-rw-r--r--fs/reiserfs/inode.c1
-rw-r--r--fs/squashfs/Kconfig12
-rw-r--r--fs/squashfs/decompressor.c34
-rw-r--r--fs/squashfs/decompressor.h7
-rw-r--r--fs/squashfs/dir.c9
-rw-r--r--fs/squashfs/lzo_wrapper.c4
-rw-r--r--fs/squashfs/namei.c12
-rw-r--r--fs/squashfs/squashfs.h1
-rw-r--r--fs/squashfs/squashfs_fs.h4
-rw-r--r--fs/squashfs/super.c15
-rw-r--r--fs/squashfs/xz_wrapper.c53
-rw-r--r--fs/squashfs/zlib_wrapper.c10
-rw-r--r--fs/super.c2
-rw-r--r--fs/sync.c4
-rw-r--r--fs/sysv/itree.c1
-rw-r--r--fs/ubifs/Kconfig9
-rw-r--r--fs/ubifs/debug.c2
-rw-r--r--fs/ubifs/file.c11
-rw-r--r--fs/ubifs/lprops.c2
-rw-r--r--fs/ubifs/lpt_commit.c4
-rw-r--r--fs/ubifs/orphan.c2
-rw-r--r--fs/ubifs/super.c1
-rw-r--r--fs/udf/file.c1
-rw-r--r--fs/udf/inode.c1
-rw-r--r--fs/ufs/inode.c1
-rw-r--r--fs/ufs/truncate.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c13
-rw-r--r--include/acpi/acoutput.h12
-rw-r--r--include/acpi/acpi_bus.h1
-rw-r--r--include/acpi/acpixf.h2
-rw-r--r--include/acpi/actbl.h16
-rw-r--r--include/acpi/actbl2.h64
-rw-r--r--include/acpi/apei.h5
-rw-r--r--include/drm/drm.h4
-rw-r--r--include/linux/Kbuild4
-rw-r--r--include/linux/acpi_io.h3
-rw-r--r--include/linux/aer.h24
-rw-r--r--include/linux/backing-dev.h16
-rw-r--r--include/linux/bio.h1
-rw-r--r--include/linux/blk_types.h6
-rw-r--r--include/linux/blkdev.h101
-rw-r--r--include/linux/buffer_head.h1
-rw-r--r--include/linux/cper.h2
-rw-r--r--include/linux/device-mapper.h5
-rw-r--r--include/linux/elevator.h10
-rw-r--r--include/linux/fs.h29
-rw-r--r--include/linux/genhd.h12
-rw-r--r--include/linux/i2c/twl.h2
-rw-r--r--include/linux/i2c/twl4030-madc.h141
-rw-r--r--include/linux/kgdb.h1
-rw-r--r--include/linux/media.h132
-rw-r--r--include/linux/mfd/88pm860x.h20
-rw-r--r--include/linux/mfd/ab8500.h4
-rw-r--r--include/linux/mfd/ab8500/gpadc.h32
-rw-r--r--include/linux/mfd/ab8500/sysctrl.h254
-rw-r--r--include/linux/mfd/abx500.h1
-rw-r--r--include/linux/mfd/core.h54
-rw-r--r--include/linux/mfd/max8997-private.h347
-rw-r--r--include/linux/mfd/max8997.h114
-rw-r--r--include/linux/mfd/mc13xxx.h3
-rw-r--r--include/linux/mfd/tps6105x.h101
-rw-r--r--include/linux/mfd/wl1273-core.h2
-rw-r--r--include/linux/mfd/wm831x/pdata.h6
-rw-r--r--include/linux/mfd/wm8994/core.h4
-rw-r--r--include/linux/mm.h5
-rw-r--r--include/linux/mmc/boot.h7
-rw-r--r--include/linux/mmc/sh_mmcif.h3
-rw-r--r--include/linux/of_platform.h3
-rw-r--r--include/linux/omap3isp.h646
-rw-r--r--include/linux/pagemap.h12
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/sched.h6
-rw-r--r--include/linux/sm501.h8
-rw-r--r--include/linux/svga.h34
-rw-r--r--include/linux/swap.h2
-rw-r--r--include/linux/v4l2-mediabus.h108
-rw-r--r--include/linux/v4l2-subdev.h141
-rw-r--r--include/linux/videodev2.h146
-rw-r--r--include/media/media-device.h95
-rw-r--r--include/media/media-devnode.h97
-rw-r--r--include/media/media-entity.h151
-rw-r--r--include/media/noon010pc30.h28
-rw-r--r--include/media/rc-map.h6
-rw-r--r--include/media/s5p_fimc.h (renamed from include/media/s3c_fimc.h)27
-rw-r--r--include/media/soc_camera.h24
-rw-r--r--include/media/soc_mediabus.h4
-rw-r--r--include/media/tuner.h16
-rw-r--r--include/media/v4l2-chip-ident.h4
-rw-r--r--include/media/v4l2-common.h15
-rw-r--r--include/media/v4l2-dev.h46
-rw-r--r--include/media/v4l2-device.h24
-rw-r--r--include/media/v4l2-fh.h29
-rw-r--r--include/media/v4l2-ioctl.h18
-rw-r--r--include/media/v4l2-mediabus.h61
-rw-r--r--include/media/v4l2-mem2mem.h58
-rw-r--r--include/media/v4l2-subdev.h113
-rw-r--r--include/media/videobuf2-core.h380
-rw-r--r--include/media/videobuf2-dma-contig.h32
-rw-r--r--include/media/videobuf2-dma-sg.h32
-rw-r--r--include/media/videobuf2-memops.h45
-rw-r--r--include/media/videobuf2-vmalloc.h20
-rw-r--r--include/media/wm8775.h9
-rw-r--r--include/staging/altera.h49
-rw-r--r--include/video/atmel_lcdc.h1
-rw-r--r--kernel/debug/gdbstub.c30
-rw-r--r--kernel/exit.c1
-rw-r--r--kernel/fork.c3
-rw-r--r--kernel/power/block_io.c2
-rw-r--r--kernel/sched.c12
-rw-r--r--kernel/trace/blktrace.c15
-rw-r--r--lib/show_mem.c7
-rw-r--r--mm/backing-dev.c8
-rw-r--r--mm/filemap.c74
-rw-r--r--mm/memory-failure.c8
-rw-r--r--mm/nommu.c4
-rw-r--r--mm/oom_kill.c2
-rw-r--r--mm/page-writeback.c10
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/page_io.c2
-rw-r--r--mm/readahead.c18
-rw-r--r--mm/shmem.c1
-rw-r--r--mm/slub.c6
-rw-r--r--mm/swap_state.c5
-rw-r--r--mm/swapfile.c37
-rw-r--r--mm/vmscan.c2
-rw-r--r--net/sunrpc/svcauth_unix.c18
-rw-r--r--sound/soc/codecs/Kconfig2
-rw-r--r--sound/soc/codecs/cq93vc.c3
-rw-r--r--sound/soc/codecs/twl4030.c6
-rw-r--r--sound/soc/codecs/wl1273.c14
-rw-r--r--sound/soc/codecs/wm8400.c3
-rw-r--r--sound/soc/davinci/davinci-vcif.c2
1065 files changed, 99084 insertions, 28078 deletions
diff --git a/.mailmap b/.mailmap
index 1eba28acab64..5a6dd592eedc 100644
--- a/.mailmap
+++ b/.mailmap
@@ -20,6 +20,7 @@ Andreas Herrmann <aherrman@de.ibm.com>
20Andrew Morton <akpm@osdl.org> 20Andrew Morton <akpm@osdl.org>
21Andrew Vasquez <andrew.vasquez@qlogic.com> 21Andrew Vasquez <andrew.vasquez@qlogic.com>
22Andy Adamson <andros@citi.umich.edu> 22Andy Adamson <andros@citi.umich.edu>
23Archit Taneja <archit@ti.com>
23Arnaud Patard <arnaud.patard@rtp-net.org> 24Arnaud Patard <arnaud.patard@rtp-net.org>
24Arnd Bergmann <arnd@arndb.de> 25Arnd Bergmann <arnd@arndb.de>
25Axel Dyks <xl@xlsigned.net> 26Axel Dyks <xl@xlsigned.net>
@@ -70,6 +71,7 @@ Leonid I Ananiev <leonid.i.ananiev@intel.com>
70Linas Vepstas <linas@austin.ibm.com> 71Linas Vepstas <linas@austin.ibm.com>
71Mark Brown <broonie@sirena.org.uk> 72Mark Brown <broonie@sirena.org.uk>
72Matthieu CASTET <castet.matthieu@free.fr> 73Matthieu CASTET <castet.matthieu@free.fr>
74Mayuresh Janorkar <mayur@ti.com>
73Michael Buesch <mb@bu3sch.de> 75Michael Buesch <mb@bu3sch.de>
74Michael Buesch <mbuesch@freenet.de> 76Michael Buesch <mbuesch@freenet.de>
75Michel Dänzer <michel@tungstengraphics.com> 77Michel Dänzer <michel@tungstengraphics.com>
@@ -78,6 +80,7 @@ Morten Welinder <terra@gnome.org>
78Morten Welinder <welinder@anemone.rentec.com> 80Morten Welinder <welinder@anemone.rentec.com>
79Morten Welinder <welinder@darter.rentec.com> 81Morten Welinder <welinder@darter.rentec.com>
80Morten Welinder <welinder@troll.com> 82Morten Welinder <welinder@troll.com>
83Mythri P K <mythripk@ti.com>
81Nguyen Anh Quynh <aquynh@gmail.com> 84Nguyen Anh Quynh <aquynh@gmail.com>
82Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> 85Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
83Patrick Mochel <mochel@digitalimplant.org> 86Patrick Mochel <mochel@digitalimplant.org>
@@ -98,6 +101,7 @@ S.Çağlar Onur <caglar@pardus.org.tr>
98Simon Kelley <simon@thekelleys.org.uk> 101Simon Kelley <simon@thekelleys.org.uk>
99Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr> 102Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
100Stephen Hemminger <shemminger@osdl.org> 103Stephen Hemminger <shemminger@osdl.org>
104Sumit Semwal <sumit.semwal@ti.com>
101Tejun Heo <htejun@gmail.com> 105Tejun Heo <htejun@gmail.com>
102Thomas Graf <tgraf@suug.ch> 106Thomas Graf <tgraf@suug.ch>
103Tony Luck <tony.luck@intel.com> 107Tony Luck <tony.luck@intel.com>
diff --git a/Documentation/ABI/testing/sysfs-bus-media b/Documentation/ABI/testing/sysfs-bus-media
new file mode 100644
index 000000000000..7057e574154a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-media
@@ -0,0 +1,6 @@
1What: /sys/bus/media/devices/.../model
2Date: January 2011
3Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
4 linux-media@vger.kernel.org
5Description: Contains the device model name in UTF-8. The device version is
6 is not be appended to the model name.
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 8b6e00a71034..2deb069aedf1 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -53,7 +53,10 @@ MAN := $(patsubst %.xml, %.9, $(BOOKS))
53mandocs: $(MAN) 53mandocs: $(MAN)
54 54
55build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \ 55build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
56 cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/ 56 cp $(srctree)/Documentation/DocBook/dvb/*.png \
57 $(srctree)/Documentation/DocBook/v4l/*.gif \
58 $(srctree)/Documentation/DocBook/v4l/*.png \
59 $(objtree)/Documentation/DocBook/media/
57 60
58xmldoclinks: 61xmldoclinks:
59ifneq ($(objtree),$(srctree)) 62ifneq ($(objtree),$(srctree))
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
index be34dcbe0d90..5d259c632cdf 100644
--- a/Documentation/DocBook/media-entities.tmpl
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -11,6 +11,10 @@
11<!ENTITY func-select "<link linkend='func-select'><function>select()</function></link>"> 11<!ENTITY func-select "<link linkend='func-select'><function>select()</function></link>">
12<!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>"> 12<!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>">
13 13
14<!ENTITY media-func-close "<link linkend='media-func-close'><function>close()</function></link>">
15<!ENTITY media-func-ioctl "<link linkend='media-func-ioctl'><function>ioctl()</function></link>">
16<!ENTITY media-func-open "<link linkend='media-func-open'><function>open()</function></link>">
17
14<!-- Ioctls --> 18<!-- Ioctls -->
15<!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>"> 19<!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>">
16<!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</constant></link>"> 20<!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</constant></link>">
@@ -82,11 +86,24 @@
82<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>"> 86<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>">
83<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>"> 87<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>">
84<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>"> 88<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
89<!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>">
90<!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>">
91<!ENTITY VIDIOC-SUBDEV-G-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_G_CROP</constant></link>">
92<!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>">
93<!ENTITY VIDIOC-SUBDEV-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>">
94<!ENTITY VIDIOC-SUBDEV-S-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_S_CROP</constant></link>">
95<!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>">
96<!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></link>">
85<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>"> 97<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
86<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>"> 98<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
87<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>"> 99<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
88<!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>"> 100<!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>">
89 101
102<!ENTITY MEDIA-IOC-DEVICE-INFO "<link linkend='media-ioc-device-info'><constant>MEDIA_IOC_DEVICE_INFO</constant></link>">
103<!ENTITY MEDIA-IOC-ENUM-ENTITIES "<link linkend='media-ioc-enum-entities'><constant>MEDIA_IOC_ENUM_ENTITIES</constant></link>">
104<!ENTITY MEDIA-IOC-ENUM-LINKS "<link linkend='media-ioc-enum-links'><constant>MEDIA_IOC_ENUM_LINKS</constant></link>">
105<!ENTITY MEDIA-IOC-SETUP-LINK "<link linkend='media-ioc-setup-link'><constant>MEDIA_IOC_SETUP_LINK</constant></link>">
106
90<!-- Types --> 107<!-- Types -->
91<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>"> 108<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
92 109
@@ -98,6 +115,7 @@
98<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>"> 115<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>">
99<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>"> 116<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>">
100<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>"> 117<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>">
118<!ENTITY v4l2-mbus-pixelcode "enum&nbsp;<link linkend='v4l2-mbus-pixelcode'>v4l2_mbus_pixelcode</link>">
101<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>"> 119<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>">
102<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>"> 120<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>">
103<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>"> 121<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>">
@@ -121,6 +139,7 @@
121<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>"> 139<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>">
122<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>"> 140<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>">
123<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>"> 141<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>">
142<!ENTITY v4l2-subdev-format-whence "enum&nbsp;<link linkend='v4l2-subdev-format-whence'>v4l2_subdev_format_whence</link>">
124<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>"> 143<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>">
125<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>"> 144<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>">
126 145
@@ -129,6 +148,7 @@
129<!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>"> 148<!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
130<!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>"> 149<!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>">
131<!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>"> 150<!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
151<!ENTITY v4l2-plane "struct&nbsp;<link linkend='v4l2-plane'>v4l2_plane</link>">
132<!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>"> 152<!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
133<!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>"> 153<!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
134<!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>"> 154<!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>">
@@ -162,11 +182,14 @@
162<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>"> 182<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>">
163<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>"> 183<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>">
164<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>"> 184<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>">
185<!ENTITY v4l2-mbus-framefmt "struct&nbsp;<link linkend='v4l2-mbus-framefmt'>v4l2_mbus_framefmt</link>">
165<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>"> 186<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>">
166<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>"> 187<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>">
167<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>"> 188<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>">
168<!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>"> 189<!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>">
169<!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>"> 190<!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>">
191<!ENTITY v4l2-pix-format-mplane "struct&nbsp;<link linkend='v4l2-pix-format-mplane'>v4l2_pix_format_mplane</link>">
192<!ENTITY v4l2-plane-pix-format "struct&nbsp;<link linkend='v4l2-plane-pix-format'>v4l2_plane_pix_format</link>">
170<!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>"> 193<!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>">
171<!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>"> 194<!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>">
172<!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>"> 195<!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>">
@@ -174,6 +197,12 @@
174<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>"> 197<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>">
175<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>"> 198<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>">
176<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>"> 199<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
200<!ENTITY v4l2-subdev-frame-interval "struct&nbsp;<link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>">
201<!ENTITY v4l2-subdev-frame-interval-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</link>">
202<!ENTITY v4l2-subdev-frame-size-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>">
203<!ENTITY v4l2-subdev-crop "struct&nbsp;<link linkend='v4l2-subdev-crop'>v4l2_subdev_crop</link>">
204<!ENTITY v4l2-subdev-format "struct&nbsp;<link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>">
205<!ENTITY v4l2-subdev-mbus-code-enum "struct&nbsp;<link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>">
177<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>"> 206<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
178<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>"> 207<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>">
179<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>"> 208<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>">
@@ -181,6 +210,12 @@
181<!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>"> 210<!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>">
182<!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>"> 211<!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>">
183 212
213<!ENTITY media-device-info "struct&nbsp;<link linkend='media-device-info'>media_device_info</link>">
214<!ENTITY media-entity-desc "struct&nbsp;<link linkend='media-entity-desc'>media_entity_desc</link>">
215<!ENTITY media-links-enum "struct&nbsp;<link linkend='media-links-enum'>media_links_enum</link>">
216<!ENTITY media-pad-desc "struct&nbsp;<link linkend='media-pad-desc'>media_pad_desc</link>">
217<!ENTITY media-link-desc "struct&nbsp;<link linkend='media-link-desc'>media_link_desc</link>">
218
184<!-- Error Codes --> 219<!-- Error Codes -->
185<!ENTITY EACCES "<errorcode>EACCES</errorcode> error code"> 220<!ENTITY EACCES "<errorcode>EACCES</errorcode> error code">
186<!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code"> 221<!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code">
@@ -197,11 +232,13 @@
197<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code"> 232<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code">
198<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code"> 233<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code">
199<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code"> 234<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code">
235<!ENTITY EPIPE "<errorcode>EPIPE</errorcode> error code">
200<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code"> 236<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code">
201 237
202<!-- Subsections --> 238<!-- Subsections -->
203<!ENTITY sub-biblio SYSTEM "v4l/biblio.xml"> 239<!ENTITY sub-biblio SYSTEM "v4l/biblio.xml">
204<!ENTITY sub-common SYSTEM "v4l/common.xml"> 240<!ENTITY sub-common SYSTEM "v4l/common.xml">
241<!ENTITY sub-planar-apis SYSTEM "v4l/planar-apis.xml">
205<!ENTITY sub-compat SYSTEM "v4l/compat.xml"> 242<!ENTITY sub-compat SYSTEM "v4l/compat.xml">
206<!ENTITY sub-controls SYSTEM "v4l/controls.xml"> 243<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
207<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml"> 244<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
@@ -215,6 +252,7 @@
215<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml"> 252<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml">
216<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml"> 253<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml">
217<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml"> 254<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml">
255<!ENTITY sub-dev-subdev SYSTEM "v4l/dev-subdev.xml">
218<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml"> 256<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
219<!ENTITY sub-driver SYSTEM "v4l/driver.xml"> 257<!ENTITY sub-driver SYSTEM "v4l/driver.xml">
220<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml"> 258<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
@@ -233,6 +271,8 @@
233<!ENTITY sub-io SYSTEM "v4l/io.xml"> 271<!ENTITY sub-io SYSTEM "v4l/io.xml">
234<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml"> 272<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
235<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml"> 273<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
274<!ENTITY sub-nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
275<!ENTITY sub-nv12mt SYSTEM "v4l/pixfmt-nv12mt.xml">
236<!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml"> 276<!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml">
237<!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml"> 277<!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
238<!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml"> 278<!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
@@ -247,6 +287,7 @@
247<!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml"> 287<!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
248<!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml"> 288<!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
249<!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml"> 289<!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
290<!ENTITY sub-yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml">
250<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> 291<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
251<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> 292<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
252<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> 293<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
@@ -298,6 +339,13 @@
298<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml"> 339<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
299<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml"> 340<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
300<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml"> 341<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml">
342<!ENTITY sub-subdev-enum-frame-interval SYSTEM "v4l/vidioc-subdev-enum-frame-interval.xml">
343<!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml">
344<!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml">
345<!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml">
346<!ENTITY sub-subdev-g-crop SYSTEM "v4l/vidioc-subdev-g-crop.xml">
347<!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml">
348<!ENTITY sub-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml">
301<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml"> 349<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
302<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml"> 350<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
303<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml"> 351<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
@@ -321,6 +369,15 @@
321<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl"> 369<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
322<!ENTITY sub-media-indices SYSTEM "media-indices.tmpl"> 370<!ENTITY sub-media-indices SYSTEM "media-indices.tmpl">
323 371
372<!ENTITY sub-media-controller SYSTEM "v4l/media-controller.xml">
373<!ENTITY sub-media-open SYSTEM "v4l/media-func-open.xml">
374<!ENTITY sub-media-close SYSTEM "v4l/media-func-close.xml">
375<!ENTITY sub-media-ioctl SYSTEM "v4l/media-func-ioctl.xml">
376<!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml">
377<!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml">
378<!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml">
379<!ENTITY sub-media-ioc-setup-link SYSTEM "v4l/media-ioc-setup-link.xml">
380
324<!-- Function Reference --> 381<!-- Function Reference -->
325<!ENTITY close SYSTEM "v4l/func-close.xml"> 382<!ENTITY close SYSTEM "v4l/func-close.xml">
326<!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml"> 383<!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml">
@@ -333,6 +390,7 @@
333<!ENTITY write SYSTEM "v4l/func-write.xml"> 390<!ENTITY write SYSTEM "v4l/func-write.xml">
334<!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml"> 391<!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml">
335<!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml"> 392<!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml">
393<!ENTITY nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
336<!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml"> 394<!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml">
337<!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml"> 395<!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
338<!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml"> 396<!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
@@ -347,6 +405,7 @@
347<!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml"> 405<!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
348<!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml"> 406<!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
349<!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml"> 407<!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
408<!ENTITY yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml">
350<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> 409<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
351<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> 410<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
352<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> 411<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl
index a99088aae1aa..88f2cc680cc2 100644
--- a/Documentation/DocBook/media.tmpl
+++ b/Documentation/DocBook/media.tmpl
@@ -106,6 +106,9 @@ Foundation. A copy of the license is included in the chapter entitled
106&sub-remote_controllers; 106&sub-remote_controllers;
107</chapter> 107</chapter>
108</part> 108</part>
109<part id="media_common">
110&sub-media-controller;
111</part>
109 112
110&sub-fdl-appendix; 113&sub-fdl-appendix;
111 114
diff --git a/Documentation/DocBook/v4l/bayer.pdf b/Documentation/DocBook/v4l/bayer.pdf
new file mode 100644
index 000000000000..905e60e6cd42
--- /dev/null
+++ b/Documentation/DocBook/v4l/bayer.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/bayer.png b/Documentation/DocBook/v4l/bayer.png
new file mode 100644
index 000000000000..9b15fb22e817
--- /dev/null
+++ b/Documentation/DocBook/v4l/bayer.png
Binary files differ
diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml
index cea23e1c4fc6..dbab79c215c1 100644
--- a/Documentation/DocBook/v4l/common.xml
+++ b/Documentation/DocBook/v4l/common.xml
@@ -846,6 +846,8 @@ conversion routine or library for integration into applications.</para>
846 </section> 846 </section>
847 </section> 847 </section>
848 848
849 &sub-planar-apis;
850
849 <section id="crop"> 851 <section id="crop">
850 <title>Image Cropping, Insertion and Scaling</title> 852 <title>Image Cropping, Insertion and Scaling</title>
851 853
diff --git a/Documentation/DocBook/v4l/compat.xml b/Documentation/DocBook/v4l/compat.xml
index c9ce61d981f5..9f7cd4f25792 100644
--- a/Documentation/DocBook/v4l/compat.xml
+++ b/Documentation/DocBook/v4l/compat.xml
@@ -1711,8 +1711,8 @@ ioctl would enumerate the available audio inputs. An ioctl to
1711determine the current audio input, if more than one combines with the 1711determine the current audio input, if more than one combines with the
1712current video input, did not exist. So 1712current video input, did not exist. So
1713<constant>VIDIOC_G_AUDIO</constant> was renamed to 1713<constant>VIDIOC_G_AUDIO</constant> was renamed to
1714<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl will be removed in 1714<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl was removed on
1715the future. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate 1715Kernel 2.6.39. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate
1716audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio 1716audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio
1717input.</para> 1717input.</para>
1718 <para>The same changes were made to &VIDIOC-G-AUDOUT; and 1718 <para>The same changes were made to &VIDIOC-G-AUDOUT; and
@@ -1726,7 +1726,7 @@ must be updated to successfully compile again.</para>
1726 <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with 1726 <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with
1727write-read parameter. It was changed to write-only, while the write-read 1727write-read parameter. It was changed to write-only, while the write-read
1728version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old 1728version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old
1729ioctl will be removed in the future. Until further the "videodev" 1729ioctl was removed on Kernel 2.6.39. Until further the "videodev"
1730kernel module will automatically translate to the new version, so drivers 1730kernel module will automatically translate to the new version, so drivers
1731must be recompiled, but not applications.</para> 1731must be recompiled, but not applications.</para>
1732 </listitem> 1732 </listitem>
@@ -1744,7 +1744,7 @@ surface can be seen.</para>
1744defined with write-only parameter, inconsistent with other ioctls 1744defined with write-only parameter, inconsistent with other ioctls
1745modifying their argument. They were changed to write-read, while a 1745modifying their argument. They were changed to write-read, while a
1746<constant>_OLD</constant> suffix was added to the write-only versions. 1746<constant>_OLD</constant> suffix was added to the write-only versions.
1747The old ioctls will be removed in the future. Drivers and 1747The old ioctls were removed on Kernel 2.6.39. Drivers and
1748applications assuming a constant parameter need an update.</para> 1748applications assuming a constant parameter need an update.</para>
1749 </listitem> 1749 </listitem>
1750 </orderedlist> 1750 </orderedlist>
@@ -1815,8 +1815,8 @@ yet to be addressed, for details see <xref
1815 <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined 1815 <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined
1816with read-only parameter. It is now defined as write-read ioctl, while 1816with read-only parameter. It is now defined as write-read ioctl, while
1817the read-only version was renamed to 1817the read-only version was renamed to
1818<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl will be removed 1818<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl was removed
1819in the future.</para> 1819on Kernel 2.6.39.</para>
1820 </listitem> 1820 </listitem>
1821 </orderedlist> 1821 </orderedlist>
1822 </section> 1822 </section>
@@ -2353,6 +2353,20 @@ that used it. It was originally scheduled for removal in 2.6.35.
2353 </listitem> 2353 </listitem>
2354 </orderedlist> 2354 </orderedlist>
2355 </section> 2355 </section>
2356 <section>
2357 <title>V4L2 in Linux 2.6.39</title>
2358 <orderedlist>
2359 <listitem>
2360 <para>The old VIDIOC_*_OLD symbols and V4L1 support were removed.</para>
2361 </listitem>
2362 <listitem>
2363 <para>Multi-planar API added. Does not affect the compatibility of
2364 current drivers and applications. See
2365 <link linkend="planar-apis">multi-planar API</link>
2366 for details.</para>
2367 </listitem>
2368 </orderedlist>
2369 </section>
2356 2370
2357 <section id="other"> 2371 <section id="other">
2358 <title>Relation of V4L2 to other Linux multimedia APIs</title> 2372 <title>Relation of V4L2 to other Linux multimedia APIs</title>
diff --git a/Documentation/DocBook/v4l/dev-capture.xml b/Documentation/DocBook/v4l/dev-capture.xml
index 32807e43f170..2237c661f26a 100644
--- a/Documentation/DocBook/v4l/dev-capture.xml
+++ b/Documentation/DocBook/v4l/dev-capture.xml
@@ -18,7 +18,8 @@ files are used for video output devices.</para>
18 <title>Querying Capabilities</title> 18 <title>Querying Capabilities</title>
19 19
20 <para>Devices supporting the video capture interface set the 20 <para>Devices supporting the video capture interface set the
21<constant>V4L2_CAP_VIDEO_CAPTURE</constant> flag in the 21<constant>V4L2_CAP_VIDEO_CAPTURE</constant> or
22<constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant> flag in the
22<structfield>capabilities</structfield> field of &v4l2-capability; 23<structfield>capabilities</structfield> field of &v4l2-capability;
23returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions 24returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
24they may also support the <link linkend="overlay">video overlay</link> 25they may also support the <link linkend="overlay">video overlay</link>
@@ -64,9 +65,11 @@ linkend="crop" />.</para>
64 65
65 <para>To query the current image format applications set the 66 <para>To query the current image format applications set the
66<structfield>type</structfield> field of a &v4l2-format; to 67<structfield>type</structfield> field of a &v4l2-format; to
67<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and call the 68<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or
69<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant> and call the
68&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill 70&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
69the &v4l2-pix-format; <structfield>pix</structfield> member of the 71the &v4l2-pix-format; <structfield>pix</structfield> or the
72&v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the
70<structfield>fmt</structfield> union.</para> 73<structfield>fmt</structfield> union.</para>
71 74
72 <para>To request different parameters applications set the 75 <para>To request different parameters applications set the
@@ -84,8 +87,8 @@ adjust the parameters and finally return the actual parameters as
84without disabling I/O or possibly time consuming hardware 87without disabling I/O or possibly time consuming hardware
85preparations.</para> 88preparations.</para>
86 89
87 <para>The contents of &v4l2-pix-format; are discussed in <xref 90 <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane;
88linkend="pixfmt" />. See also the specification of the 91are discussed in <xref linkend="pixfmt" />. See also the specification of the
89<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant> 92<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
90and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video 93and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
91capture devices must implement both the 94capture devices must implement both the
diff --git a/Documentation/DocBook/v4l/dev-output.xml b/Documentation/DocBook/v4l/dev-output.xml
index 63c3c20e5a72..919e22c53854 100644
--- a/Documentation/DocBook/v4l/dev-output.xml
+++ b/Documentation/DocBook/v4l/dev-output.xml
@@ -17,7 +17,8 @@ files are used for video capture devices.</para>
17 <title>Querying Capabilities</title> 17 <title>Querying Capabilities</title>
18 18
19 <para>Devices supporting the video output interface set the 19 <para>Devices supporting the video output interface set the
20<constant>V4L2_CAP_VIDEO_OUTPUT</constant> flag in the 20<constant>V4L2_CAP_VIDEO_OUTPUT</constant> or
21<constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant> flag in the
21<structfield>capabilities</structfield> field of &v4l2-capability; 22<structfield>capabilities</structfield> field of &v4l2-capability;
22returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions 23returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
23they may also support the <link linkend="raw-vbi">raw VBI 24they may also support the <link linkend="raw-vbi">raw VBI
@@ -60,9 +61,11 @@ linkend="crop" />.</para>
60 61
61 <para>To query the current image format applications set the 62 <para>To query the current image format applications set the
62<structfield>type</structfield> field of a &v4l2-format; to 63<structfield>type</structfield> field of a &v4l2-format; to
63<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and call the 64<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or
65<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and call the
64&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill 66&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
65the &v4l2-pix-format; <structfield>pix</structfield> member of the 67the &v4l2-pix-format; <structfield>pix</structfield> or the
68&v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the
66<structfield>fmt</structfield> union.</para> 69<structfield>fmt</structfield> union.</para>
67 70
68 <para>To request different parameters applications set the 71 <para>To request different parameters applications set the
@@ -80,8 +83,8 @@ adjust the parameters and finally return the actual parameters as
80without disabling I/O or possibly time consuming hardware 83without disabling I/O or possibly time consuming hardware
81preparations.</para> 84preparations.</para>
82 85
83 <para>The contents of &v4l2-pix-format; are discussed in <xref 86 <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane;
84linkend="pixfmt" />. See also the specification of the 87are discussed in <xref linkend="pixfmt" />. See also the specification of the
85<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant> 88<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
86and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video 89and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
87output devices must implement both the 90output devices must implement both the
diff --git a/Documentation/DocBook/v4l/dev-subdev.xml b/Documentation/DocBook/v4l/dev-subdev.xml
new file mode 100644
index 000000000000..21caff6d159b
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-subdev.xml
@@ -0,0 +1,313 @@
1 <title>Sub-device Interface</title>
2
3 <note>
4 <title>Experimental</title>
5 <para>This is an <link linkend="experimental">experimental</link>
6 interface and may change in the future.</para>
7 </note>
8
9 <para>The complex nature of V4L2 devices, where hardware is often made of
10 several integrated circuits that need to interact with each other in a
11 controlled way, leads to complex V4L2 drivers. The drivers usually reflect
12 the hardware model in software, and model the different hardware components
13 as software blocks called sub-devices.</para>
14
15 <para>V4L2 sub-devices are usually kernel-only objects. If the V4L2 driver
16 implements the media device API, they will automatically inherit from media
17 entities. Applications will be able to enumerate the sub-devices and discover
18 the hardware topology using the media entities, pads and links enumeration
19 API.</para>
20
21 <para>In addition to make sub-devices discoverable, drivers can also choose
22 to make them directly configurable by applications. When both the sub-device
23 driver and the V4L2 device driver support this, sub-devices will feature a
24 character device node on which ioctls can be called to
25 <itemizedlist>
26 <listitem><para>query, read and write sub-devices controls</para></listitem>
27 <listitem><para>subscribe and unsubscribe to events and retrieve them</para></listitem>
28 <listitem><para>negotiate image formats on individual pads</para></listitem>
29 </itemizedlist>
30 </para>
31
32 <para>Sub-device character device nodes, conventionally named
33 <filename>/dev/v4l-subdev*</filename>, use major number 81.</para>
34
35 <section>
36 <title>Controls</title>
37 <para>Most V4L2 controls are implemented by sub-device hardware. Drivers
38 usually merge all controls and expose them through video device nodes.
39 Applications can control all sub-devices through a single interface.</para>
40
41 <para>Complex devices sometimes implement the same control in different
42 pieces of hardware. This situation is common in embedded platforms, where
43 both sensors and image processing hardware implement identical functions,
44 such as contrast adjustment, white balance or faulty pixels correction. As
45 the V4L2 controls API doesn't support several identical controls in a single
46 device, all but one of the identical controls are hidden.</para>
47
48 <para>Applications can access those hidden controls through the sub-device
49 node with the V4L2 control API described in <xref linkend="control" />. The
50 ioctls behave identically as when issued on V4L2 device nodes, with the
51 exception that they deal only with controls implemented in the sub-device.
52 </para>
53
54 <para>Depending on the driver, those controls might also be exposed through
55 one (or several) V4L2 device nodes.</para>
56 </section>
57
58 <section>
59 <title>Events</title>
60 <para>V4L2 sub-devices can notify applications of events as described in
61 <xref linkend="event" />. The API behaves identically as when used on V4L2
62 device nodes, with the exception that it only deals with events generated by
63 the sub-device. Depending on the driver, those events might also be reported
64 on one (or several) V4L2 device nodes.</para>
65 </section>
66
67 <section id="pad-level-formats">
68 <title>Pad-level Formats</title>
69
70 <warning><para>Pad-level formats are only applicable to very complex device that
71 need to expose low-level format configuration to user space. Generic V4L2
72 applications do <emphasis>not</emphasis> need to use the API described in
73 this section.</para></warning>
74
75 <note><para>For the purpose of this section, the term
76 <wordasword>format</wordasword> means the combination of media bus data
77 format, frame width and frame height.</para></note>
78
79 <para>Image formats are typically negotiated on video capture and output
80 devices using the <link linkend="crop">cropping and scaling</link> ioctls.
81 The driver is responsible for configuring every block in the video pipeline
82 according to the requested format at the pipeline input and/or
83 output.</para>
84
85 <para>For complex devices, such as often found in embedded systems,
86 identical image sizes at the output of a pipeline can be achieved using
87 different hardware configurations. One such example is shown on
88 <xref linkend="pipeline-scaling" />, where
89 image scaling can be performed on both the video sensor and the host image
90 processing hardware.</para>
91
92 <figure id="pipeline-scaling">
93 <title>Image Format Negotation on Pipelines</title>
94 <mediaobject>
95 <imageobject>
96 <imagedata fileref="pipeline.pdf" format="PS" />
97 </imageobject>
98 <imageobject>
99 <imagedata fileref="pipeline.png" format="PNG" />
100 </imageobject>
101 <textobject>
102 <phrase>High quality and high speed pipeline configuration</phrase>
103 </textobject>
104 </mediaobject>
105 </figure>
106
107 <para>The sensor scaler is usually of less quality than the host scaler, but
108 scaling on the sensor is required to achieve higher frame rates. Depending
109 on the use case (quality vs. speed), the pipeline must be configured
110 differently. Applications need to configure the formats at every point in
111 the pipeline explicitly.</para>
112
113 <para>Drivers that implement the <link linkend="media-controller-intro">media
114 API</link> can expose pad-level image format configuration to applications.
115 When they do, applications can use the &VIDIOC-SUBDEV-G-FMT; and
116 &VIDIOC-SUBDEV-S-FMT; ioctls. to negotiate formats on a per-pad basis.</para>
117
118 <para>Applications are responsible for configuring coherent parameters on
119 the whole pipeline and making sure that connected pads have compatible
120 formats. The pipeline is checked for formats mismatch at &VIDIOC-STREAMON;
121 time, and an &EPIPE; is then returned if the configuration is
122 invalid.</para>
123
124 <para>Pad-level image format configuration support can be tested by calling
125 the &VIDIOC-SUBDEV-G-FMT; ioctl on pad 0. If the driver returns an &EINVAL;
126 pad-level format configuration is not supported by the sub-device.</para>
127
128 <section>
129 <title>Format Negotiation</title>
130
131 <para>Acceptable formats on pads can (and usually do) depend on a number
132 of external parameters, such as formats on other pads, active links, or
133 even controls. Finding a combination of formats on all pads in a video
134 pipeline, acceptable to both application and driver, can't rely on formats
135 enumeration only. A format negotiation mechanism is required.</para>
136
137 <para>Central to the format negotiation mechanism are the get/set format
138 operations. When called with the <structfield>which</structfield> argument
139 set to <constant>V4L2_SUBDEV_FORMAT_TRY</constant>, the
140 &VIDIOC-SUBDEV-G-FMT; and &VIDIOC-SUBDEV-S-FMT; ioctls operate on a set of
141 formats parameters that are not connected to the hardware configuration.
142 Modifying those 'try' formats leaves the device state untouched (this
143 applies to both the software state stored in the driver and the hardware
144 state stored in the device itself).</para>
145
146 <para>While not kept as part of the device state, try formats are stored
147 in the sub-device file handles. A &VIDIOC-SUBDEV-G-FMT; call will return
148 the last try format set <emphasis>on the same sub-device file
149 handle</emphasis>. Several applications querying the same sub-device at
150 the same time will thus not interact with each other.</para>
151
152 <para>To find out whether a particular format is supported by the device,
153 applications use the &VIDIOC-SUBDEV-S-FMT; ioctl. Drivers verify and, if
154 needed, change the requested <structfield>format</structfield> based on
155 device requirements and return the possibly modified value. Applications
156 can then choose to try a different format or accept the returned value and
157 continue.</para>
158
159 <para>Formats returned by the driver during a negotiation iteration are
160 guaranteed to be supported by the device. In particular, drivers guarantee
161 that a returned format will not be further changed if passed to an
162 &VIDIOC-SUBDEV-S-FMT; call as-is (as long as external parameters, such as
163 formats on other pads or links' configuration are not changed).</para>
164
165 <para>Drivers automatically propagate formats inside sub-devices. When a
166 try or active format is set on a pad, corresponding formats on other pads
167 of the same sub-device can be modified by the driver. Drivers are free to
168 modify formats as required by the device. However, they should comply with
169 the following rules when possible:
170 <itemizedlist>
171 <listitem><para>Formats should be propagated from sink pads to source pads.
172 Modifying a format on a source pad should not modify the format on any
173 sink pad.</para></listitem>
174 <listitem><para>Sub-devices that scale frames using variable scaling factors
175 should reset the scale factors to default values when sink pads formats
176 are modified. If the 1:1 scaling ratio is supported, this means that
177 source pads formats should be reset to the sink pads formats.</para></listitem>
178 </itemizedlist>
179 </para>
180
181 <para>Formats are not propagated across links, as that would involve
182 propagating them from one sub-device file handle to another. Applications
183 must then take care to configure both ends of every link explicitly with
184 compatible formats. Identical formats on the two ends of a link are
185 guaranteed to be compatible. Drivers are free to accept different formats
186 matching device requirements as being compatible.</para>
187
188 <para><xref linkend="sample-pipeline-config" />
189 shows a sample configuration sequence for the pipeline described in
190 <xref linkend="pipeline-scaling" /> (table
191 columns list entity names and pad numbers).</para>
192
193 <table pgwide="0" frame="none" id="sample-pipeline-config">
194 <title>Sample Pipeline Configuration</title>
195 <tgroup cols="3">
196 <colspec colname="what"/>
197 <colspec colname="sensor-0" />
198 <colspec colname="frontend-0" />
199 <colspec colname="frontend-1" />
200 <colspec colname="scaler-0" />
201 <colspec colname="scaler-1" />
202 <thead>
203 <row>
204 <entry></entry>
205 <entry>Sensor/0</entry>
206 <entry>Frontend/0</entry>
207 <entry>Frontend/1</entry>
208 <entry>Scaler/0</entry>
209 <entry>Scaler/1</entry>
210 </row>
211 </thead>
212 <tbody valign="top">
213 <row>
214 <entry>Initial state</entry>
215 <entry>2048x1536</entry>
216 <entry>-</entry>
217 <entry>-</entry>
218 <entry>-</entry>
219 <entry>-</entry>
220 </row>
221 <row>
222 <entry>Configure frontend input</entry>
223 <entry>2048x1536</entry>
224 <entry><emphasis>2048x1536</emphasis></entry>
225 <entry><emphasis>2046x1534</emphasis></entry>
226 <entry>-</entry>
227 <entry>-</entry>
228 </row>
229 <row>
230 <entry>Configure scaler input</entry>
231 <entry>2048x1536</entry>
232 <entry>2048x1536</entry>
233 <entry>2046x1534</entry>
234 <entry><emphasis>2046x1534</emphasis></entry>
235 <entry><emphasis>2046x1534</emphasis></entry>
236 </row>
237 <row>
238 <entry>Configure scaler output</entry>
239 <entry>2048x1536</entry>
240 <entry>2048x1536</entry>
241 <entry>2046x1534</entry>
242 <entry>2046x1534</entry>
243 <entry><emphasis>1280x960</emphasis></entry>
244 </row>
245 </tbody>
246 </tgroup>
247 </table>
248
249 <para>
250 <orderedlist>
251 <listitem><para>Initial state. The sensor output is set to its native 3MP
252 resolution. Resolutions on the host frontend and scaler input and output
253 pads are undefined.</para></listitem>
254 <listitem><para>The application configures the frontend input pad resolution to
255 2048x1536. The driver propagates the format to the frontend output pad.
256 Note that the propagated output format can be different, as in this case,
257 than the input format, as the hardware might need to crop pixels (for
258 instance when converting a Bayer filter pattern to RGB or YUV).</para></listitem>
259 <listitem><para>The application configures the scaler input pad resolution to
260 2046x1534 to match the frontend output resolution. The driver propagates
261 the format to the scaler output pad.</para></listitem>
262 <listitem><para>The application configures the scaler output pad resolution to
263 1280x960.</para></listitem>
264 </orderedlist>
265 </para>
266
267 <para>When satisfied with the try results, applications can set the active
268 formats by setting the <structfield>which</structfield> argument to
269 <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. Active formats are changed
270 exactly as try formats by drivers. To avoid modifying the hardware state
271 during format negotiation, applications should negotiate try formats first
272 and then modify the active settings using the try formats returned during
273 the last negotiation iteration. This guarantees that the active format
274 will be applied as-is by the driver without being modified.
275 </para>
276 </section>
277
278 <section>
279 <title>Cropping and scaling</title>
280
281 <para>Many sub-devices support cropping frames on their input or output
282 pads (or possible even on both). Cropping is used to select the area of
283 interest in an image, typically on a video sensor or video decoder. It can
284 also be used as part of digital zoom implementations to select the area of
285 the image that will be scaled up.</para>
286
287 <para>Crop settings are defined by a crop rectangle and represented in a
288 &v4l2-rect; by the coordinates of the top left corner and the rectangle
289 size. Both the coordinates and sizes are expressed in pixels.</para>
290
291 <para>The crop rectangle is retrieved and set using the
292 &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad
293 formats, drivers store try and active crop rectangles. The format
294 negotiation mechanism applies to crop settings as well.</para>
295
296 <para>On input pads, cropping is applied relatively to the current pad
297 format. The pad format represents the image size as received by the
298 sub-device from the previous block in the pipeline, and the crop rectangle
299 represents the sub-image that will be transmitted further inside the
300 sub-device for processing. The crop rectangle be entirely containted
301 inside the input image size.</para>
302
303 <para>Input crop rectangle are reset to their default value when the input
304 image format is modified. Drivers should use the input image size as the
305 crop rectangle default value, but hardware requirements may prevent this.
306 </para>
307
308 <para>Cropping behaviour on output pads is not defined.</para>
309
310 </section>
311 </section>
312
313 &sub-subdev-formats;
diff --git a/Documentation/DocBook/v4l/func-mmap.xml b/Documentation/DocBook/v4l/func-mmap.xml
index 2e2fc3933aea..786732b64bbd 100644
--- a/Documentation/DocBook/v4l/func-mmap.xml
+++ b/Documentation/DocBook/v4l/func-mmap.xml
@@ -45,7 +45,10 @@ just specify a <constant>NULL</constant> pointer here.</para>
45 <listitem> 45 <listitem>
46 <para>Length of the memory area to map. This must be the 46 <para>Length of the memory area to map. This must be the
47same value as returned by the driver in the &v4l2-buffer; 47same value as returned by the driver in the &v4l2-buffer;
48<structfield>length</structfield> field.</para> 48<structfield>length</structfield> field for the
49single-planar API, and the same value as returned by the driver
50in the &v4l2-plane; <structfield>length</structfield> field for the
51multi-planar API.</para>
49 </listitem> 52 </listitem>
50 </varlistentry> 53 </varlistentry>
51 <varlistentry> 54 <varlistentry>
@@ -106,7 +109,10 @@ flag.</para>
106 <listitem> 109 <listitem>
107 <para>Offset of the buffer in device memory. This must be the 110 <para>Offset of the buffer in device memory. This must be the
108same value as returned by the driver in the &v4l2-buffer; 111same value as returned by the driver in the &v4l2-buffer;
109<structfield>m</structfield> union <structfield>offset</structfield> field.</para> 112<structfield>m</structfield> union <structfield>offset</structfield> field for
113the single-planar API, and the same value as returned by the driver
114in the &v4l2-plane; <structfield>m</structfield> union
115<structfield>mem_offset</structfield> field for the multi-planar API.</para>
110 </listitem> 116 </listitem>
111 </varlistentry> 117 </varlistentry>
112 </variablelist> 118 </variablelist>
diff --git a/Documentation/DocBook/v4l/func-munmap.xml b/Documentation/DocBook/v4l/func-munmap.xml
index 502ed49323b0..e2c4190f9bb6 100644
--- a/Documentation/DocBook/v4l/func-munmap.xml
+++ b/Documentation/DocBook/v4l/func-munmap.xml
@@ -37,7 +37,8 @@
37 <para>Length of the mapped buffer. This must be the same 37 <para>Length of the mapped buffer. This must be the same
38value as given to <function>mmap()</function> and returned by the 38value as given to <function>mmap()</function> and returned by the
39driver in the &v4l2-buffer; <structfield>length</structfield> 39driver in the &v4l2-buffer; <structfield>length</structfield>
40field.</para> 40field for the single-planar API and in the &v4l2-plane;
41<structfield>length</structfield> field for the multi-planar API.</para>
41 </listitem> 42 </listitem>
42 </varlistentry> 43 </varlistentry>
43 </variablelist> 44 </variablelist>
diff --git a/Documentation/DocBook/v4l/io.xml b/Documentation/DocBook/v4l/io.xml
index d424886beda0..227e7ac45a06 100644
--- a/Documentation/DocBook/v4l/io.xml
+++ b/Documentation/DocBook/v4l/io.xml
@@ -121,18 +121,22 @@ mapped.</para>
121 <para>Before applications can access the buffers they must map 121 <para>Before applications can access the buffers they must map
122them into their address space with the &func-mmap; function. The 122them into their address space with the &func-mmap; function. The
123location of the buffers in device memory can be determined with the 123location of the buffers in device memory can be determined with the
124&VIDIOC-QUERYBUF; ioctl. The <structfield>m.offset</structfield> and 124&VIDIOC-QUERYBUF; ioctl. In the single-planar API case, the
125<structfield>length</structfield> returned in a &v4l2-buffer; are 125<structfield>m.offset</structfield> and <structfield>length</structfield>
126passed as sixth and second parameter to the 126returned in a &v4l2-buffer; are passed as sixth and second parameter to the
127<function>mmap()</function> function. The offset and length values 127<function>mmap()</function> function. When using the multi-planar API,
128must not be modified. Remember the buffers are allocated in physical 128struct &v4l2-buffer; contains an array of &v4l2-plane; structures, each
129memory, as opposed to virtual memory which can be swapped out to disk. 129containing its own <structfield>m.offset</structfield> and
130Applications should free the buffers as soon as possible with the 130<structfield>length</structfield>. When using the multi-planar API, every
131&func-munmap; function.</para> 131plane of every buffer has to be mapped separately, so the number of
132calls to &func-mmap; should be equal to number of buffers times number of
133planes in each buffer. The offset and length values must not be modified.
134Remember, the buffers are allocated in physical memory, as opposed to virtual
135memory, which can be swapped out to disk. Applications should free the buffers
136as soon as possible with the &func-munmap; function.</para>
132 137
133 <example> 138 <example>
134 <title>Mapping buffers</title> 139 <title>Mapping buffers in the single-planar API</title>
135
136 <programlisting> 140 <programlisting>
137&v4l2-requestbuffers; reqbuf; 141&v4l2-requestbuffers; reqbuf;
138struct { 142struct {
@@ -141,63 +145,145 @@ struct {
141} *buffers; 145} *buffers;
142unsigned int i; 146unsigned int i;
143 147
144memset (&amp;reqbuf, 0, sizeof (reqbuf)); 148memset(&amp;reqbuf, 0, sizeof(reqbuf));
145reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 149reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
146reqbuf.memory = V4L2_MEMORY_MMAP; 150reqbuf.memory = V4L2_MEMORY_MMAP;
147reqbuf.count = 20; 151reqbuf.count = 20;
148 152
149if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf)) { 153if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf)) {
150 if (errno == EINVAL) 154 if (errno == EINVAL)
151 printf ("Video capturing or mmap-streaming is not supported\n"); 155 printf("Video capturing or mmap-streaming is not supported\n");
152 else 156 else
153 perror ("VIDIOC_REQBUFS"); 157 perror("VIDIOC_REQBUFS");
154 158
155 exit (EXIT_FAILURE); 159 exit(EXIT_FAILURE);
156} 160}
157 161
158/* We want at least five buffers. */ 162/* We want at least five buffers. */
159 163
160if (reqbuf.count &lt; 5) { 164if (reqbuf.count &lt; 5) {
161 /* You may need to free the buffers here. */ 165 /* You may need to free the buffers here. */
162 printf ("Not enough buffer memory\n"); 166 printf("Not enough buffer memory\n");
163 exit (EXIT_FAILURE); 167 exit(EXIT_FAILURE);
164} 168}
165 169
166buffers = calloc (reqbuf.count, sizeof (*buffers)); 170buffers = calloc(reqbuf.count, sizeof(*buffers));
167assert (buffers != NULL); 171assert(buffers != NULL);
168 172
169for (i = 0; i &lt; reqbuf.count; i++) { 173for (i = 0; i &lt; reqbuf.count; i++) {
170 &v4l2-buffer; buffer; 174 &v4l2-buffer; buffer;
171 175
172 memset (&amp;buffer, 0, sizeof (buffer)); 176 memset(&amp;buffer, 0, sizeof(buffer));
173 buffer.type = reqbuf.type; 177 buffer.type = reqbuf.type;
174 buffer.memory = V4L2_MEMORY_MMAP; 178 buffer.memory = V4L2_MEMORY_MMAP;
175 buffer.index = i; 179 buffer.index = i;
176 180
177 if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &amp;buffer)) { 181 if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &amp;buffer)) {
178 perror ("VIDIOC_QUERYBUF"); 182 perror("VIDIOC_QUERYBUF");
179 exit (EXIT_FAILURE); 183 exit(EXIT_FAILURE);
180 } 184 }
181 185
182 buffers[i].length = buffer.length; /* remember for munmap() */ 186 buffers[i].length = buffer.length; /* remember for munmap() */
183 187
184 buffers[i].start = mmap (NULL, buffer.length, 188 buffers[i].start = mmap(NULL, buffer.length,
185 PROT_READ | PROT_WRITE, /* recommended */ 189 PROT_READ | PROT_WRITE, /* recommended */
186 MAP_SHARED, /* recommended */ 190 MAP_SHARED, /* recommended */
187 fd, buffer.m.offset); 191 fd, buffer.m.offset);
188 192
189 if (MAP_FAILED == buffers[i].start) { 193 if (MAP_FAILED == buffers[i].start) {
190 /* If you do not exit here you should unmap() and free() 194 /* If you do not exit here you should unmap() and free()
191 the buffers mapped so far. */ 195 the buffers mapped so far. */
192 perror ("mmap"); 196 perror("mmap");
193 exit (EXIT_FAILURE); 197 exit(EXIT_FAILURE);
198 }
199}
200
201/* Cleanup. */
202
203for (i = 0; i &lt; reqbuf.count; i++)
204 munmap(buffers[i].start, buffers[i].length);
205 </programlisting>
206 </example>
207
208 <example>
209 <title>Mapping buffers in the multi-planar API</title>
210 <programlisting>
211&v4l2-requestbuffers; reqbuf;
212/* Our current format uses 3 planes per buffer */
213#define FMT_NUM_PLANES = 3;
214
215struct {
216 void *start[FMT_NUM_PLANES];
217 size_t length[FMT_NUM_PLANES];
218} *buffers;
219unsigned int i, j;
220
221memset(&amp;reqbuf, 0, sizeof(reqbuf));
222reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
223reqbuf.memory = V4L2_MEMORY_MMAP;
224reqbuf.count = 20;
225
226if (ioctl(fd, &VIDIOC-REQBUFS;, &amp;reqbuf) &lt; 0) {
227 if (errno == EINVAL)
228 printf("Video capturing or mmap-streaming is not supported\n");
229 else
230 perror("VIDIOC_REQBUFS");
231
232 exit(EXIT_FAILURE);
233}
234
235/* We want at least five buffers. */
236
237if (reqbuf.count &lt; 5) {
238 /* You may need to free the buffers here. */
239 printf("Not enough buffer memory\n");
240 exit(EXIT_FAILURE);
241}
242
243buffers = calloc(reqbuf.count, sizeof(*buffers));
244assert(buffers != NULL);
245
246for (i = 0; i &lt; reqbuf.count; i++) {
247 &v4l2-buffer; buffer;
248 &v4l2-plane; planes[FMT_NUM_PLANES];
249
250 memset(&amp;buffer, 0, sizeof(buffer));
251 buffer.type = reqbuf.type;
252 buffer.memory = V4L2_MEMORY_MMAP;
253 buffer.index = i;
254 /* length in struct v4l2_buffer in multi-planar API stores the size
255 * of planes array. */
256 buffer.length = FMT_NUM_PLANES;
257 buffer.m.planes = planes;
258
259 if (ioctl(fd, &VIDIOC-QUERYBUF;, &amp;buffer) &lt; 0) {
260 perror("VIDIOC_QUERYBUF");
261 exit(EXIT_FAILURE);
262 }
263
264 /* Every plane has to be mapped separately */
265 for (j = 0; j &lt; FMT_NUM_PLANES; j++) {
266 buffers[i].length[j] = buffer.m.planes[j].length; /* remember for munmap() */
267
268 buffers[i].start[j] = mmap(NULL, buffer.m.planes[j].length,
269 PROT_READ | PROT_WRITE, /* recommended */
270 MAP_SHARED, /* recommended */
271 fd, buffer.m.planes[j].m.offset);
272
273 if (MAP_FAILED == buffers[i].start[j]) {
274 /* If you do not exit here you should unmap() and free()
275 the buffers and planes mapped so far. */
276 perror("mmap");
277 exit(EXIT_FAILURE);
278 }
194 } 279 }
195} 280}
196 281
197/* Cleanup. */ 282/* Cleanup. */
198 283
199for (i = 0; i &lt; reqbuf.count; i++) 284for (i = 0; i &lt; reqbuf.count; i++)
200 munmap (buffers[i].start, buffers[i].length); 285 for (j = 0; j &lt; FMT_NUM_PLANES; j++)
286 munmap(buffers[i].start[j], buffers[i].length[j]);
201 </programlisting> 287 </programlisting>
202 </example> 288 </example>
203 289
@@ -286,13 +372,13 @@ pointer method (not only memory mapping) is supported must be
286determined by calling the &VIDIOC-REQBUFS; ioctl.</para> 372determined by calling the &VIDIOC-REQBUFS; ioctl.</para>
287 373
288 <para>This I/O method combines advantages of the read/write and 374 <para>This I/O method combines advantages of the read/write and
289memory mapping methods. Buffers are allocated by the application 375memory mapping methods. Buffers (planes) are allocated by the application
290itself, and can reside for example in virtual or shared memory. Only 376itself, and can reside for example in virtual or shared memory. Only
291pointers to data are exchanged, these pointers and meta-information 377pointers to data are exchanged, these pointers and meta-information
292are passed in &v4l2-buffer;. The driver must be switched 378are passed in &v4l2-buffer; (or in &v4l2-plane; in the multi-planar API case).
293into user pointer I/O mode by calling the &VIDIOC-REQBUFS; with the 379The driver must be switched into user pointer I/O mode by calling the
294desired buffer type. No buffers are allocated beforehands, 380&VIDIOC-REQBUFS; with the desired buffer type. No buffers (planes) are allocated
295consequently they are not indexed and cannot be queried like mapped 381beforehand, consequently they are not indexed and cannot be queried like mapped
296buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para> 382buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para>
297 383
298 <example> 384 <example>
@@ -316,7 +402,7 @@ if (ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf) == -1) {
316 </programlisting> 402 </programlisting>
317 </example> 403 </example>
318 404
319 <para>Buffer addresses and sizes are passed on the fly with the 405 <para>Buffer (plane) addresses and sizes are passed on the fly with the
320&VIDIOC-QBUF; ioctl. Although buffers are commonly cycled, 406&VIDIOC-QBUF; ioctl. Although buffers are commonly cycled,
321applications can pass different addresses and sizes at each 407applications can pass different addresses and sizes at each
322<constant>VIDIOC_QBUF</constant> call. If required by the hardware the 408<constant>VIDIOC_QBUF</constant> call. If required by the hardware the
@@ -396,11 +482,18 @@ rest should be evident.</para>
396 <title>Buffers</title> 482 <title>Buffers</title>
397 483
398 <para>A buffer contains data exchanged by application and 484 <para>A buffer contains data exchanged by application and
399driver using one of the Streaming I/O methods. Only pointers to 485driver using one of the Streaming I/O methods. In the multi-planar API, the
400buffers are exchanged, the data itself is not copied. These pointers, 486data is held in planes, while the buffer structure acts as a container
401together with meta-information like timestamps or field parity, are 487for the planes. Only pointers to buffers (planes) are exchanged, the data
402stored in a struct <structname>v4l2_buffer</structname>, argument to 488itself is not copied. These pointers, together with meta-information like
403the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.</para> 489timestamps or field parity, are stored in a struct
490<structname>v4l2_buffer</structname>, argument to
491the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.
492In the multi-planar API, some plane-specific members of struct
493<structname>v4l2_buffer</structname>, such as pointers and sizes for each
494plane, are stored in struct <structname>v4l2_plane</structname> instead.
495In that case, struct <structname>v4l2_buffer</structname> contains an array of
496plane structures.</para>
404 497
405 <para>Nominally timestamps refer to the first data byte transmitted. 498 <para>Nominally timestamps refer to the first data byte transmitted.
406In practice however the wide range of hardware covered by the V4L2 API 499In practice however the wide range of hardware covered by the V4L2 API
@@ -551,26 +644,40 @@ in accordance with the selected I/O method.</entry>
551 <entry></entry> 644 <entry></entry>
552 <entry>__u32</entry> 645 <entry>__u32</entry>
553 <entry><structfield>offset</structfield></entry> 646 <entry><structfield>offset</structfield></entry>
554 <entry>When <structfield>memory</structfield> is 647 <entry>For the single-planar API and when
555<constant>V4L2_MEMORY_MMAP</constant> this is the offset of the buffer 648<structfield>memory</structfield> is <constant>V4L2_MEMORY_MMAP</constant> this
556from the start of the device memory. The value is returned by the 649is the offset of the buffer from the start of the device memory. The value is
557driver and apart of serving as parameter to the &func-mmap; function 650returned by the driver and apart of serving as parameter to the &func-mmap;
558not useful for applications. See <xref linkend="mmap" /> for details.</entry> 651function not useful for applications. See <xref linkend="mmap" /> for details
652 </entry>
559 </row> 653 </row>
560 <row> 654 <row>
561 <entry></entry> 655 <entry></entry>
562 <entry>unsigned long</entry> 656 <entry>unsigned long</entry>
563 <entry><structfield>userptr</structfield></entry> 657 <entry><structfield>userptr</structfield></entry>
564 <entry>When <structfield>memory</structfield> is 658 <entry>For the single-planar API and when
565<constant>V4L2_MEMORY_USERPTR</constant> this is a pointer to the 659<structfield>memory</structfield> is <constant>V4L2_MEMORY_USERPTR</constant>
566buffer (casted to unsigned long type) in virtual memory, set by the 660this is a pointer to the buffer (casted to unsigned long type) in virtual
567application. See <xref linkend="userp" /> for details.</entry> 661memory, set by the application. See <xref linkend="userp" /> for details.
662 </entry>
663 </row>
664 <row>
665 <entry></entry>
666 <entry>struct v4l2_plane</entry>
667 <entry><structfield>*planes</structfield></entry>
668 <entry>When using the multi-planar API, contains a userspace pointer
669 to an array of &v4l2-plane;. The size of the array should be put
670 in the <structfield>length</structfield> field of this
671 <structname>v4l2_buffer</structname> structure.</entry>
568 </row> 672 </row>
569 <row> 673 <row>
570 <entry>__u32</entry> 674 <entry>__u32</entry>
571 <entry><structfield>length</structfield></entry> 675 <entry><structfield>length</structfield></entry>
572 <entry></entry> 676 <entry></entry>
573 <entry>Size of the buffer (not the payload) in bytes.</entry> 677 <entry>Size of the buffer (not the payload) in bytes for the
678 single-planar API. For the multi-planar API should contain the
679 number of elements in the <structfield>planes</structfield> array.
680 </entry>
574 </row> 681 </row>
575 <row> 682 <row>
576 <entry>__u32</entry> 683 <entry>__u32</entry>
@@ -596,6 +703,66 @@ should set this to 0.</entry>
596 </tgroup> 703 </tgroup>
597 </table> 704 </table>
598 705
706 <table frame="none" pgwide="1" id="v4l2-plane">
707 <title>struct <structname>v4l2_plane</structname></title>
708 <tgroup cols="4">
709 &cs-ustr;
710 <tbody valign="top">
711 <row>
712 <entry>__u32</entry>
713 <entry><structfield>bytesused</structfield></entry>
714 <entry></entry>
715 <entry>The number of bytes occupied by data in the plane
716 (its payload).</entry>
717 </row>
718 <row>
719 <entry>__u32</entry>
720 <entry><structfield>length</structfield></entry>
721 <entry></entry>
722 <entry>Size in bytes of the plane (not its payload).</entry>
723 </row>
724 <row>
725 <entry>union</entry>
726 <entry><structfield>m</structfield></entry>
727 <entry></entry>
728 <entry></entry>
729 </row>
730 <row>
731 <entry></entry>
732 <entry>__u32</entry>
733 <entry><structfield>mem_offset</structfield></entry>
734 <entry>When the memory type in the containing &v4l2-buffer; is
735 <constant>V4L2_MEMORY_MMAP</constant>, this is the value that
736 should be passed to &func-mmap;, similar to the
737 <structfield>offset</structfield> field in &v4l2-buffer;.</entry>
738 </row>
739 <row>
740 <entry></entry>
741 <entry>__unsigned long</entry>
742 <entry><structfield>userptr</structfield></entry>
743 <entry>When the memory type in the containing &v4l2-buffer; is
744 <constant>V4L2_MEMORY_USERPTR</constant>, this is a userspace
745 pointer to the memory allocated for this plane by an application.
746 </entry>
747 </row>
748 <row>
749 <entry>__u32</entry>
750 <entry><structfield>data_offset</structfield></entry>
751 <entry></entry>
752 <entry>Offset in bytes to video data in the plane, if applicable.
753 </entry>
754 </row>
755 <row>
756 <entry>__u32</entry>
757 <entry><structfield>reserved[11]</structfield></entry>
758 <entry></entry>
759 <entry>Reserved for future use. Should be zeroed by an
760 application.</entry>
761 </row>
762 </tbody>
763 </tgroup>
764 </table>
765
599 <table frame="none" pgwide="1" id="v4l2-buf-type"> 766 <table frame="none" pgwide="1" id="v4l2-buf-type">
600 <title>enum v4l2_buf_type</title> 767 <title>enum v4l2_buf_type</title>
601 <tgroup cols="3"> 768 <tgroup cols="3">
@@ -604,13 +771,27 @@ should set this to 0.</entry>
604 <row> 771 <row>
605 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry> 772 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
606 <entry>1</entry> 773 <entry>1</entry>
607 <entry>Buffer of a video capture stream, see <xref 774 <entry>Buffer of a single-planar video capture stream, see <xref
775 linkend="capture" />.</entry>
776 </row>
777 <row>
778 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>
779 </entry>
780 <entry>9</entry>
781 <entry>Buffer of a multi-planar video capture stream, see <xref
608 linkend="capture" />.</entry> 782 linkend="capture" />.</entry>
609 </row> 783 </row>
610 <row> 784 <row>
611 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry> 785 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
612 <entry>2</entry> 786 <entry>2</entry>
613 <entry>Buffer of a video output stream, see <xref 787 <entry>Buffer of a single-planar video output stream, see <xref
788 linkend="output" />.</entry>
789 </row>
790 <row>
791 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>
792 </entry>
793 <entry>10</entry>
794 <entry>Buffer of a multi-planar video output stream, see <xref
614 linkend="output" />.</entry> 795 linkend="output" />.</entry>
615 </row> 796 </row>
616 <row> 797 <row>
diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml b/Documentation/DocBook/v4l/lirc_device_interface.xml
index 68134c0ab4d1..0e0453f39e73 100644
--- a/Documentation/DocBook/v4l/lirc_device_interface.xml
+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml
@@ -45,7 +45,7 @@ describing an IR signal are read from the chardev.</para>
45<para>The data written to the chardev is a pulse/space sequence of integer 45<para>The data written to the chardev is a pulse/space sequence of integer
46values. Pulses and spaces are only marked implicitly by their position. The 46values. Pulses and spaces are only marked implicitly by their position. The
47data must start and end with a pulse, therefore, the data must always include 47data must start and end with a pulse, therefore, the data must always include
48an unevent number of samples. The write function must block until the data has 48an uneven number of samples. The write function must block until the data has
49been transmitted by the hardware.</para> 49been transmitted by the hardware.</para>
50</section> 50</section>
51 51
diff --git a/Documentation/DocBook/v4l/media-controller.xml b/Documentation/DocBook/v4l/media-controller.xml
new file mode 100644
index 000000000000..2dc25e1d4089
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-controller.xml
@@ -0,0 +1,89 @@
1<partinfo>
2 <authorgroup>
3 <author>
4 <firstname>Laurent</firstname>
5 <surname>Pinchart</surname>
6 <affiliation><address><email>laurent.pinchart@ideasonboard.com</email></address></affiliation>
7 <contrib>Initial version.</contrib>
8 </author>
9 </authorgroup>
10 <copyright>
11 <year>2010</year>
12 <holder>Laurent Pinchart</holder>
13 </copyright>
14
15 <revhistory>
16 <!-- Put document revisions here, newest first. -->
17 <revision>
18 <revnumber>1.0.0</revnumber>
19 <date>2010-11-10</date>
20 <authorinitials>lp</authorinitials>
21 <revremark>Initial revision</revremark>
22 </revision>
23 </revhistory>
24</partinfo>
25
26<title>Media Controller API</title>
27
28<chapter id="media_controller">
29 <title>Media Controller</title>
30
31 <section id="media-controller-intro">
32 <title>Introduction</title>
33 <para>Media devices increasingly handle multiple related functions. Many USB
34 cameras include microphones, video capture hardware can also output video,
35 or SoC camera interfaces also perform memory-to-memory operations similar to
36 video codecs.</para>
37 <para>Independent functions, even when implemented in the same hardware, can
38 be modelled as separate devices. A USB camera with a microphone will be
39 presented to userspace applications as V4L2 and ALSA capture devices. The
40 devices' relationships (when using a webcam, end-users shouldn't have to
41 manually select the associated USB microphone), while not made available
42 directly to applications by the drivers, can usually be retrieved from
43 sysfs.</para>
44 <para>With more and more advanced SoC devices being introduced, the current
45 approach will not scale. Device topologies are getting increasingly complex
46 and can't always be represented by a tree structure. Hardware blocks are
47 shared between different functions, creating dependencies between seemingly
48 unrelated devices.</para>
49 <para>Kernel abstraction APIs such as V4L2 and ALSA provide means for
50 applications to access hardware parameters. As newer hardware expose an
51 increasingly high number of those parameters, drivers need to guess what
52 applications really require based on limited information, thereby
53 implementing policies that belong to userspace.</para>
54 <para>The media controller API aims at solving those problems.</para>
55 </section>
56
57 <section id="media-controller-model">
58 <title>Media device model</title>
59 <para>Discovering a device internal topology, and configuring it at runtime,
60 is one of the goals of the media controller API. To achieve this, hardware
61 devices are modelled as an oriented graph of building blocks called entities
62 connected through pads.</para>
63 <para>An entity is a basic media hardware or software building block. It can
64 correspond to a large variety of logical blocks such as physical hardware
65 devices (CMOS sensor for instance), logical hardware devices (a building
66 block in a System-on-Chip image processing pipeline), DMA channels or
67 physical connectors.</para>
68 <para>A pad is a connection endpoint through which an entity can interact
69 with other entities. Data (not restricted to video) produced by an entity
70 flows from the entity's output to one or more entity inputs. Pads should not
71 be confused with physical pins at chip boundaries.</para>
72 <para>A link is a point-to-point oriented connection between two pads,
73 either on the same entity or on different entities. Data flows from a source
74 pad to a sink pad.</para>
75 </section>
76</chapter>
77
78<appendix id="media-user-func">
79 <title>Function Reference</title>
80 <!-- Keep this alphabetically sorted. -->
81 &sub-media-open;
82 &sub-media-close;
83 &sub-media-ioctl;
84 <!-- All ioctls go here. -->
85 &sub-media-ioc-device-info;
86 &sub-media-ioc-enum-entities;
87 &sub-media-ioc-enum-links;
88 &sub-media-ioc-setup-link;
89</appendix>
diff --git a/Documentation/DocBook/v4l/media-func-close.xml b/Documentation/DocBook/v4l/media-func-close.xml
new file mode 100644
index 000000000000..be149c802aeb
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-func-close.xml
@@ -0,0 +1,59 @@
1<refentry id="media-func-close">
2 <refmeta>
3 <refentrytitle>media close()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>media-close</refname>
9 <refpurpose>Close a media device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>int <function>close</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 </funcprototype>
19 </funcsynopsis>
20 </refsynopsisdiv>
21
22 <refsect1>
23 <title>Arguments</title>
24
25 <variablelist>
26 <varlistentry>
27 <term><parameter>fd</parameter></term>
28 <listitem>
29 <para>&fd;</para>
30 </listitem>
31 </varlistentry>
32 </variablelist>
33 </refsect1>
34
35 <refsect1>
36 <title>Description</title>
37
38 <para>Closes the media device. Resources associated with the file descriptor
39 are freed. The device configuration remain unchanged.</para>
40 </refsect1>
41
42 <refsect1>
43 <title>Return Value</title>
44
45 <para><function>close</function> returns 0 on success. On error, -1 is
46 returned, and <varname>errno</varname> is set appropriately. Possible error
47 codes are:</para>
48
49 <variablelist>
50 <varlistentry>
51 <term><errorcode>EBADF</errorcode></term>
52 <listitem>
53 <para><parameter>fd</parameter> is not a valid open file descriptor.
54 </para>
55 </listitem>
56 </varlistentry>
57 </variablelist>
58 </refsect1>
59</refentry>
diff --git a/Documentation/DocBook/v4l/media-func-ioctl.xml b/Documentation/DocBook/v4l/media-func-ioctl.xml
new file mode 100644
index 000000000000..bda8604de15c
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-func-ioctl.xml
@@ -0,0 +1,116 @@
1<refentry id="media-func-ioctl">
2 <refmeta>
3 <refentrytitle>media ioctl()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>media-ioctl</refname>
9 <refpurpose>Control a media device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;sys/ioctl.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>void *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>Media ioctl request code as defined in the media.h header file,
38 for example MEDIA_IOC_SETUP_LINK.</para>
39 </listitem>
40 </varlistentry>
41 <varlistentry>
42 <term><parameter>argp</parameter></term>
43 <listitem>
44 <para>Pointer to a request-specific structure.</para>
45 </listitem>
46 </varlistentry>
47 </variablelist>
48 </refsect1>
49
50 <refsect1>
51 <title>Description</title>
52 <para>The <function>ioctl()</function> function manipulates media device
53 parameters. The argument <parameter>fd</parameter> must be an open file
54 descriptor.</para>
55 <para>The ioctl <parameter>request</parameter> code specifies the media
56 function to be called. It has encoded in it whether the argument is an
57 input, output or read/write parameter, and the size of the argument
58 <parameter>argp</parameter> in bytes.</para>
59 <para>Macros and structures definitions specifying media ioctl requests and
60 their parameters are located in the media.h header file. All media ioctl
61 requests, their respective function and parameters are specified in
62 <xref linkend="media-user-func" />.</para>
63 </refsect1>
64
65 <refsect1>
66 <title>Return Value</title>
67
68 <para><function>ioctl()</function> returns <returnvalue>0</returnvalue> on
69 success. On failure, <returnvalue>-1</returnvalue> is returned, and the
70 <varname>errno</varname> variable is set appropriately. Generic error codes
71 are listed below, and request-specific error codes are listed in the
72 individual requests descriptions.</para>
73 <para>When an ioctl that takes an output or read/write parameter fails,
74 the parameter remains unmodified.</para>
75
76 <variablelist>
77 <varlistentry>
78 <term><errorcode>EBADF</errorcode></term>
79 <listitem>
80 <para><parameter>fd</parameter> is not a valid open file descriptor.
81 </para>
82 </listitem>
83 </varlistentry>
84 <varlistentry>
85 <term><errorcode>EFAULT</errorcode></term>
86 <listitem>
87 <para><parameter>argp</parameter> references an inaccessible memory
88 area.</para>
89 </listitem>
90 </varlistentry>
91 <varlistentry>
92 <term><errorcode>EINVAL</errorcode></term>
93 <listitem>
94 <para>The <parameter>request</parameter> or the data pointed to by
95 <parameter>argp</parameter> is not valid. This is a very common error
96 code, see the individual ioctl requests listed in
97 <xref linkend="media-user-func" /> for actual causes.</para>
98 </listitem>
99 </varlistentry>
100 <varlistentry>
101 <term><errorcode>ENOMEM</errorcode></term>
102 <listitem>
103 <para>Insufficient kernel memory was available to complete the
104 request.</para>
105 </listitem>
106 </varlistentry>
107 <varlistentry>
108 <term><errorcode>ENOTTY</errorcode></term>
109 <listitem>
110 <para><parameter>fd</parameter> is not associated with a character
111 special device.</para>
112 </listitem>
113 </varlistentry>
114 </variablelist>
115 </refsect1>
116</refentry>
diff --git a/Documentation/DocBook/v4l/media-func-open.xml b/Documentation/DocBook/v4l/media-func-open.xml
new file mode 100644
index 000000000000..f7df034dc9ed
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-func-open.xml
@@ -0,0 +1,94 @@
1<refentry id="media-func-open">
2 <refmeta>
3 <refentrytitle>media open()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>media-open</refname>
9 <refpurpose>Open a media device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;fcntl.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>int <function>open</function></funcdef>
17 <paramdef>const char *<parameter>device_name</parameter></paramdef>
18 <paramdef>int <parameter>flags</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>device_name</parameter></term>
29 <listitem>
30 <para>Device to be opened.</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>flags</parameter></term>
35 <listitem>
36 <para>Open flags. Access mode must be either <constant>O_RDONLY</constant>
37 or <constant>O_RDWR</constant>. Other flags have no effect.</para>
38 </listitem>
39 </varlistentry>
40 </variablelist>
41 </refsect1>
42 <refsect1>
43 <title>Description</title>
44 <para>To open a media device applications call <function>open()</function>
45 with the desired device name. The function has no side effects; the device
46 configuration remain unchanged.</para>
47 <para>When the device is opened in read-only mode, attemps to modify its
48 configuration will result in an error, and <varname>errno</varname> will be
49 set to <errorcode>EBADF</errorcode>.</para>
50 </refsect1>
51 <refsect1>
52 <title>Return Value</title>
53
54 <para><function>open</function> returns the new file descriptor on success.
55 On error, -1 is returned, and <varname>errno</varname> is set appropriately.
56 Possible error codes are:</para>
57
58 <variablelist>
59 <varlistentry>
60 <term><errorcode>EACCES</errorcode></term>
61 <listitem>
62 <para>The requested access to the file is not allowed.</para>
63 </listitem>
64 </varlistentry>
65 <varlistentry>
66 <term><errorcode>EMFILE</errorcode></term>
67 <listitem>
68 <para>The process already has the maximum number of files open.
69 </para>
70 </listitem>
71 </varlistentry>
72 <varlistentry>
73 <term><errorcode>ENFILE</errorcode></term>
74 <listitem>
75 <para>The system limit on the total number of open files has been
76 reached.</para>
77 </listitem>
78 </varlistentry>
79 <varlistentry>
80 <term><errorcode>ENOMEM</errorcode></term>
81 <listitem>
82 <para>Insufficient kernel memory was available.</para>
83 </listitem>
84 </varlistentry>
85 <varlistentry>
86 <term><errorcode>ENXIO</errorcode></term>
87 <listitem>
88 <para>No device corresponding to this device special file exists.
89 </para>
90 </listitem>
91 </varlistentry>
92 </variablelist>
93 </refsect1>
94</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-device-info.xml b/Documentation/DocBook/v4l/media-ioc-device-info.xml
new file mode 100644
index 000000000000..1f3237351bba
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-device-info.xml
@@ -0,0 +1,133 @@
1<refentry id="media-ioc-device-info">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_DEVICE_INFO</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_DEVICE_INFO</refname>
9 <refpurpose>Query device information</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct media_device_info *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_DEVICE_INFO</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>All media devices must support the <constant>MEDIA_IOC_DEVICE_INFO</constant>
53 ioctl. To query device information, applications call the ioctl with a
54 pointer to a &media-device-info;. The driver fills the structure and returns
55 the information to the application.
56 The ioctl never fails.</para>
57
58 <table pgwide="1" frame="none" id="media-device-info">
59 <title>struct <structname>media_device_info</structname></title>
60 <tgroup cols="3">
61 &cs-str;
62 <tbody valign="top">
63 <row>
64 <entry>char</entry>
65 <entry><structfield>driver</structfield>[16]</entry>
66 <entry><para>Name of the driver implementing the media API as a
67 NUL-terminated ASCII string. The driver version is stored in the
68 <structfield>driver_version</structfield> field.</para>
69 <para>Driver specific applications can use this information to
70 verify the driver identity. It is also useful to work around
71 known bugs, or to identify drivers in error reports.</para></entry>
72 </row>
73 <row>
74 <entry>char</entry>
75 <entry><structfield>model</structfield>[32]</entry>
76 <entry>Device model name as a NUL-terminated UTF-8 string. The
77 device version is stored in the <structfield>device_version</structfield>
78 field and is not be appended to the model name.</entry>
79 </row>
80 <row>
81 <entry>char</entry>
82 <entry><structfield>serial</structfield>[40]</entry>
83 <entry>Serial number as a NUL-terminated ASCII string.</entry>
84 </row>
85 <row>
86 <entry>char</entry>
87 <entry><structfield>bus_info</structfield>[32]</entry>
88 <entry>Location of the device in the system as a NUL-terminated
89 ASCII string. This includes the bus type name (PCI, USB, ...) and a
90 bus-specific identifier.</entry>
91 </row>
92 <row>
93 <entry>__u32</entry>
94 <entry><structfield>media_version</structfield></entry>
95 <entry>Media API version, formatted with the
96 <constant>KERNEL_VERSION()</constant> macro.</entry>
97 </row>
98 <row>
99 <entry>__u32</entry>
100 <entry><structfield>hw_revision</structfield></entry>
101 <entry>Hardware device revision in a driver-specific format.</entry>
102 </row>
103 <row>
104 <entry>__u32</entry>
105 <entry><structfield>media_version</structfield></entry>
106 <entry>Media device driver version, formatted with the
107 <constant>KERNEL_VERSION()</constant> macro. Together with the
108 <structfield>driver</structfield> field this identifies a particular
109 driver.</entry>
110 </row>
111 <row>
112 <entry>__u32</entry>
113 <entry><structfield>reserved</structfield>[31]</entry>
114 <entry>Reserved for future extensions. Drivers and applications must
115 set this array to zero.</entry>
116 </row>
117 </tbody>
118 </tgroup>
119 </table>
120 <para>The <structfield>serial</structfield> and <structfield>bus_info</structfield>
121 fields can be used to distinguish between multiple instances of otherwise
122 identical hardware. The serial number takes precedence when provided and can
123 be assumed to be unique. If the serial number is an empty string, the
124 <structfield>bus_info</structfield> field can be used instead. The
125 <structfield>bus_info</structfield> field is guaranteed to be unique, but
126 can vary across reboots or device unplug/replug.</para>
127 </refsect1>
128
129 <refsect1>
130 <title>Return value</title>
131 <para>This function doesn't return specific error codes.</para>
132 </refsect1>
133</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/v4l/media-ioc-enum-entities.xml
new file mode 100644
index 000000000000..576b68b33f2c
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-enum-entities.xml
@@ -0,0 +1,308 @@
1<refentry id="media-ioc-enum-entities">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_ENUM_ENTITIES</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_ENUM_ENTITIES</refname>
9 <refpurpose>Enumerate entities and their properties</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct media_entity_desc *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_ENUM_ENTITIES</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51 <para>To query the attributes of an entity, applications set the id field
52 of a &media-entity-desc; structure and call the MEDIA_IOC_ENUM_ENTITIES
53 ioctl with a pointer to this structure. The driver fills the rest of the
54 structure or returns an &EINVAL; when the id is invalid.</para>
55 <para>Entities can be enumerated by or'ing the id with the
56 <constant>MEDIA_ENT_ID_FLAG_NEXT</constant> flag. The driver will return
57 information about the entity with the smallest id strictly larger than the
58 requested one ('next entity'), or the &EINVAL; if there is none.</para>
59 <para>Entity IDs can be non-contiguous. Applications must
60 <emphasis>not</emphasis> try to enumerate entities by calling
61 MEDIA_IOC_ENUM_ENTITIES with increasing id's until they get an error.</para>
62 <para>Two or more entities that share a common non-zero
63 <structfield>group_id</structfield> value are considered as logically
64 grouped. Groups are used to report
65 <itemizedlist>
66 <listitem><para>ALSA, VBI and video nodes that carry the same media
67 stream</para></listitem>
68 <listitem><para>lens and flash controllers associated with a sensor</para></listitem>
69 </itemizedlist>
70 </para>
71
72 <table pgwide="1" frame="none" id="media-entity-desc">
73 <title>struct <structname>media_entity_desc</structname></title>
74 <tgroup cols="5">
75 <colspec colname="c1" />
76 <colspec colname="c2" />
77 <colspec colname="c3" />
78 <colspec colname="c4" />
79 <colspec colname="c5" />
80 <tbody valign="top">
81 <row>
82 <entry>__u32</entry>
83 <entry><structfield>id</structfield></entry>
84 <entry></entry>
85 <entry></entry>
86 <entry>Entity id, set by the application. When the id is or'ed with
87 <constant>MEDIA_ENT_ID_FLAG_NEXT</constant>, the driver clears the
88 flag and returns the first entity with a larger id.</entry>
89 </row>
90 <row>
91 <entry>char</entry>
92 <entry><structfield>name</structfield>[32]</entry>
93 <entry></entry>
94 <entry></entry>
95 <entry>Entity name as an UTF-8 NULL-terminated string.</entry>
96 </row>
97 <row>
98 <entry>__u32</entry>
99 <entry><structfield>type</structfield></entry>
100 <entry></entry>
101 <entry></entry>
102 <entry>Entity type, see <xref linkend="media-entity-type" /> for details.</entry>
103 </row>
104 <row>
105 <entry>__u32</entry>
106 <entry><structfield>revision</structfield></entry>
107 <entry></entry>
108 <entry></entry>
109 <entry>Entity revision in a driver/hardware specific format.</entry>
110 </row>
111 <row>
112 <entry>__u32</entry>
113 <entry><structfield>flags</structfield></entry>
114 <entry></entry>
115 <entry></entry>
116 <entry>Entity flags, see <xref linkend="media-entity-flag" /> for details.</entry>
117 </row>
118 <row>
119 <entry>__u32</entry>
120 <entry><structfield>group_id</structfield></entry>
121 <entry></entry>
122 <entry></entry>
123 <entry>Entity group ID</entry>
124 </row>
125 <row>
126 <entry>__u16</entry>
127 <entry><structfield>pads</structfield></entry>
128 <entry></entry>
129 <entry></entry>
130 <entry>Number of pads</entry>
131 </row>
132 <row>
133 <entry>__u16</entry>
134 <entry><structfield>links</structfield></entry>
135 <entry></entry>
136 <entry></entry>
137 <entry>Total number of outbound links. Inbound links are not counted
138 in this field.</entry>
139 </row>
140 <row>
141 <entry>union</entry>
142 </row>
143 <row>
144 <entry></entry>
145 <entry>struct</entry>
146 <entry><structfield>v4l</structfield></entry>
147 <entry></entry>
148 <entry>Valid for V4L sub-devices and nodes only.</entry>
149 </row>
150 <row>
151 <entry></entry>
152 <entry></entry>
153 <entry>__u32</entry>
154 <entry><structfield>major</structfield></entry>
155 <entry>V4L device node major number. For V4L sub-devices with no
156 device node, set by the driver to 0.</entry>
157 </row>
158 <row>
159 <entry></entry>
160 <entry></entry>
161 <entry>__u32</entry>
162 <entry><structfield>minor</structfield></entry>
163 <entry>V4L device node minor number. For V4L sub-devices with no
164 device node, set by the driver to 0.</entry>
165 </row>
166 <row>
167 <entry></entry>
168 <entry>struct</entry>
169 <entry><structfield>fb</structfield></entry>
170 <entry></entry>
171 <entry>Valid for frame buffer nodes only.</entry>
172 </row>
173 <row>
174 <entry></entry>
175 <entry></entry>
176 <entry>__u32</entry>
177 <entry><structfield>major</structfield></entry>
178 <entry>Frame buffer device node major number.</entry>
179 </row>
180 <row>
181 <entry></entry>
182 <entry></entry>
183 <entry>__u32</entry>
184 <entry><structfield>minor</structfield></entry>
185 <entry>Frame buffer device node minor number.</entry>
186 </row>
187 <row>
188 <entry></entry>
189 <entry>struct</entry>
190 <entry><structfield>alsa</structfield></entry>
191 <entry></entry>
192 <entry>Valid for ALSA devices only.</entry>
193 </row>
194 <row>
195 <entry></entry>
196 <entry></entry>
197 <entry>__u32</entry>
198 <entry><structfield>card</structfield></entry>
199 <entry>ALSA card number</entry>
200 </row>
201 <row>
202 <entry></entry>
203 <entry></entry>
204 <entry>__u32</entry>
205 <entry><structfield>device</structfield></entry>
206 <entry>ALSA device number</entry>
207 </row>
208 <row>
209 <entry></entry>
210 <entry></entry>
211 <entry>__u32</entry>
212 <entry><structfield>subdevice</structfield></entry>
213 <entry>ALSA sub-device number</entry>
214 </row>
215 <row>
216 <entry></entry>
217 <entry>int</entry>
218 <entry><structfield>dvb</structfield></entry>
219 <entry></entry>
220 <entry>DVB card number</entry>
221 </row>
222 <row>
223 <entry></entry>
224 <entry>__u8</entry>
225 <entry><structfield>raw</structfield>[180]</entry>
226 <entry></entry>
227 <entry></entry>
228 </row>
229 </tbody>
230 </tgroup>
231 </table>
232
233 <table frame="none" pgwide="1" id="media-entity-type">
234 <title>Media entity types</title>
235 <tgroup cols="2">
236 <colspec colname="c1"/>
237 <colspec colname="c2"/>
238 <tbody valign="top">
239 <row>
240 <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry>
241 <entry>Unknown device node</entry>
242 </row>
243 <row>
244 <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
245 <entry>V4L video, radio or vbi device node</entry>
246 </row>
247 <row>
248 <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry>
249 <entry>Frame buffer device node</entry>
250 </row>
251 <row>
252 <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry>
253 <entry>ALSA card</entry>
254 </row>
255 <row>
256 <entry><constant>MEDIA_ENT_T_DEVNODE_DVB</constant></entry>
257 <entry>DVB card</entry>
258 </row>
259 <row>
260 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
261 <entry>Unknown V4L sub-device</entry>
262 </row>
263 <row>
264 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry>
265 <entry>Video sensor</entry>
266 </row>
267 <row>
268 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry>
269 <entry>Flash controller</entry>
270 </row>
271 <row>
272 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry>
273 <entry>Lens controller</entry>
274 </row>
275 </tbody>
276 </tgroup>
277 </table>
278
279 <table frame="none" pgwide="1" id="media-entity-flag">
280 <title>Media entity flags</title>
281 <tgroup cols="2">
282 <colspec colname="c1"/>
283 <colspec colname="c2"/>
284 <tbody valign="top">
285 <row>
286 <entry><constant>MEDIA_ENT_FL_DEFAULT</constant></entry>
287 <entry>Default entity for its type. Used to discover the default
288 audio, VBI and video devices, the default camera sensor, ...</entry>
289 </row>
290 </tbody>
291 </tgroup>
292 </table>
293 </refsect1>
294
295 <refsect1>
296 &return-value;
297
298 <variablelist>
299 <varlistentry>
300 <term><errorcode>EINVAL</errorcode></term>
301 <listitem>
302 <para>The &media-entity-desc; <structfield>id</structfield> references
303 a non-existing entity.</para>
304 </listitem>
305 </varlistentry>
306 </variablelist>
307 </refsect1>
308</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/v4l/media-ioc-enum-links.xml
new file mode 100644
index 000000000000..d2fc73ef8d56
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-enum-links.xml
@@ -0,0 +1,207 @@
1<refentry id="media-ioc-enum-links">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_ENUM_LINKS</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_ENUM_LINKS</refname>
9 <refpurpose>Enumerate all pads and links for a given entity</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct media_links_enum *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_ENUM_LINKS</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>To enumerate pads and/or links for a given entity, applications set
53 the entity field of a &media-links-enum; structure and initialize the
54 &media-pad-desc; and &media-link-desc; structure arrays pointed by the
55 <structfield>pads</structfield> and <structfield>links</structfield> fields.
56 They then call the MEDIA_IOC_ENUM_LINKS ioctl with a pointer to this
57 structure.</para>
58 <para>If the <structfield>pads</structfield> field is not NULL, the driver
59 fills the <structfield>pads</structfield> array with information about the
60 entity's pads. The array must have enough room to store all the entity's
61 pads. The number of pads can be retrieved with the &MEDIA-IOC-ENUM-ENTITIES;
62 ioctl.</para>
63 <para>If the <structfield>links</structfield> field is not NULL, the driver
64 fills the <structfield>links</structfield> array with information about the
65 entity's outbound links. The array must have enough room to store all the
66 entity's outbound links. The number of outbound links can be retrieved with
67 the &MEDIA-IOC-ENUM-ENTITIES; ioctl.</para>
68 <para>Only forward links that originate at one of the entity's source pads
69 are returned during the enumeration process.</para>
70
71 <table pgwide="1" frame="none" id="media-links-enum">
72 <title>struct <structname>media_links_enum</structname></title>
73 <tgroup cols="3">
74 &cs-str;
75 <tbody valign="top">
76 <row>
77 <entry>__u32</entry>
78 <entry><structfield>entity</structfield></entry>
79 <entry>Entity id, set by the application.</entry>
80 </row>
81 <row>
82 <entry>struct &media-pad-desc;</entry>
83 <entry>*<structfield>pads</structfield></entry>
84 <entry>Pointer to a pads array allocated by the application. Ignored
85 if NULL.</entry>
86 </row>
87 <row>
88 <entry>struct &media-link-desc;</entry>
89 <entry>*<structfield>links</structfield></entry>
90 <entry>Pointer to a links array allocated by the application. Ignored
91 if NULL.</entry>
92 </row>
93 </tbody>
94 </tgroup>
95 </table>
96
97 <table pgwide="1" frame="none" id="media-pad-desc">
98 <title>struct <structname>media_pad_desc</structname></title>
99 <tgroup cols="3">
100 &cs-str;
101 <tbody valign="top">
102 <row>
103 <entry>__u32</entry>
104 <entry><structfield>entity</structfield></entry>
105 <entry>ID of the entity this pad belongs to.</entry>
106 </row>
107 <row>
108 <entry>__u16</entry>
109 <entry><structfield>index</structfield></entry>
110 <entry>0-based pad index.</entry>
111 </row>
112 <row>
113 <entry>__u32</entry>
114 <entry><structfield>flags</structfield></entry>
115 <entry>Pad flags, see <xref linkend="media-pad-flag" /> for more details.</entry>
116 </row>
117 </tbody>
118 </tgroup>
119 </table>
120
121 <table frame="none" pgwide="1" id="media-pad-flag">
122 <title>Media pad flags</title>
123 <tgroup cols="2">
124 <colspec colname="c1"/>
125 <colspec colname="c2"/>
126 <tbody valign="top">
127 <row>
128 <entry><constant>MEDIA_PAD_FL_SINK</constant></entry>
129 <entry>Input pad, relative to the entity. Input pads sink data and
130 are targets of links.</entry>
131 </row>
132 <row>
133 <entry><constant>MEDIA_PAD_FL_SOURCE</constant></entry>
134 <entry>Output pad, relative to the entity. Output pads source data
135 and are origins of links.</entry>
136 </row>
137 </tbody>
138 </tgroup>
139 </table>
140
141 <table pgwide="1" frame="none" id="media-link-desc">
142 <title>struct <structname>media_links_desc</structname></title>
143 <tgroup cols="3">
144 &cs-str;
145 <tbody valign="top">
146 <row>
147 <entry>struct &media-pad-desc;</entry>
148 <entry><structfield>source</structfield></entry>
149 <entry>Pad at the origin of this link.</entry>
150 </row>
151 <row>
152 <entry>struct &media-pad-desc;</entry>
153 <entry><structfield>sink</structfield></entry>
154 <entry>Pad at the target of this link.</entry>
155 </row>
156 <row>
157 <entry>__u32</entry>
158 <entry><structfield>flags</structfield></entry>
159 <entry>Link flags, see <xref linkend="media-link-flag" /> for more details.</entry>
160 </row>
161 </tbody>
162 </tgroup>
163 </table>
164
165 <table frame="none" pgwide="1" id="media-link-flag">
166 <title>Media link flags</title>
167 <tgroup cols="2">
168 <colspec colname="c1"/>
169 <colspec colname="c2"/>
170 <tbody valign="top">
171 <row>
172 <entry><constant>MEDIA_LNK_FL_ENABLED</constant></entry>
173 <entry>The link is enabled and can be used to transfer media data.
174 When two or more links target a sink pad, only one of them can be
175 enabled at a time.</entry>
176 </row>
177 <row>
178 <entry><constant>MEDIA_LNK_FL_IMMUTABLE</constant></entry>
179 <entry>The link enabled state can't be modified at runtime. An
180 immutable link is always enabled.</entry>
181 </row>
182 <row>
183 <entry><constant>MEDIA_LNK_FL_DYNAMIC</constant></entry>
184 <entry>The link enabled state can be modified during streaming. This
185 flag is set by drivers and is read-only for applications.</entry>
186 </row>
187 </tbody>
188 </tgroup>
189 </table>
190 <para>One and only one of <constant>MEDIA_PAD_FL_SINK</constant> and
191 <constant>MEDIA_PAD_FL_SOURCE</constant> must be set for every pad.</para>
192 </refsect1>
193
194 <refsect1>
195 &return-value;
196
197 <variablelist>
198 <varlistentry>
199 <term><errorcode>EINVAL</errorcode></term>
200 <listitem>
201 <para>The &media-links-enum; <structfield>id</structfield> references
202 a non-existing entity.</para>
203 </listitem>
204 </varlistentry>
205 </variablelist>
206 </refsect1>
207</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/Documentation/DocBook/v4l/media-ioc-setup-link.xml
new file mode 100644
index 000000000000..2331e76ded17
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-setup-link.xml
@@ -0,0 +1,93 @@
1<refentry id="media-ioc-setup-link">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_SETUP_LINK</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_SETUP_LINK</refname>
9 <refpurpose>Modify the properties of a link</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct media_link_desc *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_ENUM_LINKS</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>To change link properties applications fill a &media-link-desc; with
53 link identification information (source and sink pad) and the new requested
54 link flags. They then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to
55 that structure.</para>
56 <para>The only configurable property is the <constant>ENABLED</constant>
57 link flag to enable/disable a link. Links marked with the
58 <constant>IMMUTABLE</constant> link flag can not be enabled or disabled.
59 </para>
60 <para>Link configuration has no side effect on other links. If an enabled
61 link at the sink pad prevents the link from being enabled, the driver
62 returns with an &EBUSY;.</para>
63 <para>Only links marked with the <constant>DYNAMIC</constant> link flag can
64 be enabled/disabled while streaming media data. Attempting to enable or
65 disable a streaming non-dynamic link will return an &EBUSY;.</para>
66 <para>If the specified link can't be found the driver returns with an
67 &EINVAL;.</para>
68 </refsect1>
69
70 <refsect1>
71 &return-value;
72
73 <variablelist>
74 <varlistentry>
75 <term><errorcode>EBUSY</errorcode></term>
76 <listitem>
77 <para>The link properties can't be changed because the link is
78 currently busy. This can be caused, for instance, by an active media
79 stream (audio or video) on the link. The ioctl shouldn't be retried if
80 no other action is performed before to fix the problem.</para>
81 </listitem>
82 </varlistentry>
83 <varlistentry>
84 <term><errorcode>EINVAL</errorcode></term>
85 <listitem>
86 <para>The &media-link-desc; references a non-existing link, or the
87 link is immutable and an attempt to modify its configuration was made.
88 </para>
89 </listitem>
90 </varlistentry>
91 </variablelist>
92 </refsect1>
93</refentry>
diff --git a/Documentation/DocBook/v4l/nv12mt.gif b/Documentation/DocBook/v4l/nv12mt.gif
new file mode 100644
index 000000000000..ef2d4cf8367b
--- /dev/null
+++ b/Documentation/DocBook/v4l/nv12mt.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/nv12mt_example.gif b/Documentation/DocBook/v4l/nv12mt_example.gif
new file mode 100644
index 000000000000..df81d68108ee
--- /dev/null
+++ b/Documentation/DocBook/v4l/nv12mt_example.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/pipeline.pdf b/Documentation/DocBook/v4l/pipeline.pdf
new file mode 100644
index 000000000000..ee3e37f04b6a
--- /dev/null
+++ b/Documentation/DocBook/v4l/pipeline.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/pipeline.png b/Documentation/DocBook/v4l/pipeline.png
new file mode 100644
index 000000000000..f19b86c2c24d
--- /dev/null
+++ b/Documentation/DocBook/v4l/pipeline.png
Binary files differ
diff --git a/Documentation/DocBook/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/v4l/pixfmt-nv12m.xml
new file mode 100644
index 000000000000..c9e166d9ded8
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv12m.xml
@@ -0,0 +1,154 @@
1 <refentry id="V4L2-PIX-FMT-NV12M">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname> <constant>V4L2_PIX_FMT_NV12M</constant></refname>
8 <refpurpose>Variation of <constant>V4L2_PIX_FMT_NV12</constant> with planes
9 non contiguous in memory. </refpurpose>
10 </refnamediv>
11 <refsect1>
12 <title>Description</title>
13
14 <para>This is a multi-planar, two-plane version of the YUV 4:2:0 format.
15The three components are separated into two sub-images or planes.
16<constant>V4L2_PIX_FMT_NV12M</constant> differs from <constant>V4L2_PIX_FMT_NV12
17</constant> in that the two planes are non-contiguous in memory, i.e. the chroma
18plane do not necessarily immediately follows the luma plane.
19The luminance data occupies the first plane. The Y plane has one byte per pixel.
20In the second plane there is a chrominance data with alternating chroma samples.
21The CbCr plane is the same width, in bytes, as the Y plane (and of the image),
22but is half as tall in pixels. Each CbCr pair belongs to four pixels. For example,
23Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
24Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
25Y'<subscript>10</subscript>, Y'<subscript>11</subscript>. </para>
26
27 <para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
28used only in drivers and applications that support the multi-planar API,
29described in <xref linkend="planar-apis"/>. </para>
30
31 <para>If the Y plane has pad bytes after each row, then the
32CbCr plane has as many pad bytes after its rows.</para>
33
34 <example>
35 <title><constant>V4L2_PIX_FMT_NV12M</constant> 4 &times; 4 pixel image</title>
36
37 <formalpara>
38 <title>Byte Order.</title>
39 <para>Each cell is one byte.
40 <informaltable frame="none">
41 <tgroup cols="5" align="center">
42 <colspec align="left" colwidth="2*" />
43 <tbody valign="top">
44 <row>
45 <entry>start0&nbsp;+&nbsp;0:</entry>
46 <entry>Y'<subscript>00</subscript></entry>
47 <entry>Y'<subscript>01</subscript></entry>
48 <entry>Y'<subscript>02</subscript></entry>
49 <entry>Y'<subscript>03</subscript></entry>
50 </row>
51 <row>
52 <entry>start0&nbsp;+&nbsp;4:</entry>
53 <entry>Y'<subscript>10</subscript></entry>
54 <entry>Y'<subscript>11</subscript></entry>
55 <entry>Y'<subscript>12</subscript></entry>
56 <entry>Y'<subscript>13</subscript></entry>
57 </row>
58 <row>
59 <entry>start0&nbsp;+&nbsp;8:</entry>
60 <entry>Y'<subscript>20</subscript></entry>
61 <entry>Y'<subscript>21</subscript></entry>
62 <entry>Y'<subscript>22</subscript></entry>
63 <entry>Y'<subscript>23</subscript></entry>
64 </row>
65 <row>
66 <entry>start0&nbsp;+&nbsp;12:</entry>
67 <entry>Y'<subscript>30</subscript></entry>
68 <entry>Y'<subscript>31</subscript></entry>
69 <entry>Y'<subscript>32</subscript></entry>
70 <entry>Y'<subscript>33</subscript></entry>
71 </row>
72 <row>
73 <entry></entry>
74 </row>
75 <row>
76 <entry>start1&nbsp;+&nbsp;0:</entry>
77 <entry>Cb<subscript>00</subscript></entry>
78 <entry>Cr<subscript>00</subscript></entry>
79 <entry>Cb<subscript>01</subscript></entry>
80 <entry>Cr<subscript>01</subscript></entry>
81 </row>
82 <row>
83 <entry>start1&nbsp;+&nbsp;4:</entry>
84 <entry>Cb<subscript>10</subscript></entry>
85 <entry>Cr<subscript>10</subscript></entry>
86 <entry>Cb<subscript>11</subscript></entry>
87 <entry>Cr<subscript>11</subscript></entry>
88 </row>
89 </tbody>
90 </tgroup>
91 </informaltable>
92 </para>
93 </formalpara>
94
95 <formalpara>
96 <title>Color Sample Location.</title>
97 <para>
98 <informaltable frame="none">
99 <tgroup cols="7" align="center">
100 <tbody valign="top">
101 <row>
102 <entry></entry>
103 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
104 <entry>2</entry><entry></entry><entry>3</entry>
105 </row>
106 <row>
107 <entry>0</entry>
108 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
109 <entry>Y</entry><entry></entry><entry>Y</entry>
110 </row>
111 <row>
112 <entry></entry>
113 <entry></entry><entry>C</entry><entry></entry><entry></entry>
114 <entry></entry><entry>C</entry><entry></entry>
115 </row>
116 <row>
117 <entry>1</entry>
118 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
119 <entry>Y</entry><entry></entry><entry>Y</entry>
120 </row>
121 <row>
122 <entry></entry>
123 </row>
124 <row>
125 <entry>2</entry>
126 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
127 <entry>Y</entry><entry></entry><entry>Y</entry>
128 </row>
129 <row>
130 <entry></entry>
131 <entry></entry><entry>C</entry><entry></entry><entry></entry>
132 <entry></entry><entry>C</entry><entry></entry>
133 </row>
134 <row>
135 <entry>3</entry>
136 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
137 <entry>Y</entry><entry></entry><entry>Y</entry>
138 </row>
139 </tbody>
140 </tgroup>
141 </informaltable>
142 </para>
143 </formalpara>
144 </example>
145 </refsect1>
146 </refentry>
147
148 <!--
149Local Variables:
150mode: sgml
151sgml-parent-document: "pixfmt.sgml"
152indent-tabs-mode: nil
153End:
154 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-nv12mt.xml b/Documentation/DocBook/v4l/pixfmt-nv12mt.xml
new file mode 100644
index 000000000000..7a2855a526c1
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv12mt.xml
@@ -0,0 +1,74 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_NV12MT ('TM12')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname id="V4L2-PIX-FMT-NV12MT"><constant>V4L2_PIX_FMT_NV12MT
8</constant></refname>
9 <refpurpose>Formats with &frac12; horizontal and vertical
10chroma resolution. This format has two planes - one for luminance and one for
11chrominance. Chroma samples are interleaved. The difference to
12<constant>V4L2_PIX_FMT_NV12</constant> is the memory layout. Pixels are
13grouped in macroblocks of 64x32 size. The order of macroblocks in memory is
14also not standard.
15 </refpurpose>
16 </refnamediv>
17 <refsect1>
18 <title>Description</title>
19
20 <para>This is the two-plane versions of the YUV 4:2:0 format where data
21is grouped into 64x32 macroblocks. The three components are separated into two
22sub-images or planes. The Y plane has one byte per pixel and pixels are grouped
23into 64x32 macroblocks. The CbCr plane has the same width, in bytes, as the Y
24plane (and the image), but is half as tall in pixels. The chroma plane is also
25grouped into 64x32 macroblocks.</para>
26 <para>Width of the buffer has to be aligned to the multiple of 128, and
27height alignment is 32. Every four adjactent buffers - two horizontally and two
28vertically are grouped together and are located in memory in Z or flipped Z
29order. </para>
30 <para>Layout of macroblocks in memory is presented in the following
31figure.</para>
32 <para><figure id="nv12mt">
33 <title><constant>V4L2_PIX_FMT_NV12MT</constant> macroblock Z shape
34memory layout</title>
35 <mediaobject>
36 <imageobject>
37 <imagedata fileref="nv12mt.gif" format="GIF" />
38 </imageobject>
39 </mediaobject>
40 </figure>
41 The requirement that width is multiple of 128 is implemented because,
42the Z shape cannot be cut in half horizontally. In case the vertical resolution
43of macroblocks is odd then the last row of macroblocks is arranged in a linear
44order. </para>
45 <para>In case of chroma the layout is identical. Cb and Cr samples are
46interleaved. Height of the buffer is aligned to 32.
47 </para>
48 <example>
49 <title>Memory layout of macroblocks in <constant>V4L2_PIX_FMT_NV12
50</constant> format pixel image - extreme case</title>
51 <para>
52 <figure id="nv12mt_ex">
53 <title>Example <constant>V4L2_PIX_FMT_NV12MT</constant> memory
54layout of macroblocks</title>
55 <mediaobject>
56 <imageobject>
57 <imagedata fileref="nv12mt_example.gif" format="GIF" />
58 </imageobject>
59 </mediaobject>
60 </figure>
61 Memory layout of macroblocks of <constant>V4L2_PIX_FMT_NV12MT
62</constant> format in most extreme case.
63 </para>
64 </example>
65 </refsect1>
66 </refentry>
67
68 <!--
69Local Variables:
70mode: sgml
71sgml-parent-document: "pixfmt.sgml"
72indent-tabs-mode: nil
73End:
74 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-srggb12.xml b/Documentation/DocBook/v4l/pixfmt-srggb12.xml
new file mode 100644
index 000000000000..9ba4fb690bc0
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-srggb12.xml
@@ -0,0 +1,90 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_SRGGB12 ('RG12'),
4 V4L2_PIX_FMT_SGRBG12 ('BA12'),
5 V4L2_PIX_FMT_SGBRG12 ('GB12'),
6 V4L2_PIX_FMT_SBGGR12 ('BG12'),
7 </refentrytitle>
8 &manvol;
9 </refmeta>
10 <refnamediv>
11 <refname id="V4L2-PIX-FMT-SRGGB12"><constant>V4L2_PIX_FMT_SRGGB12</constant></refname>
12 <refname id="V4L2-PIX-FMT-SGRBG12"><constant>V4L2_PIX_FMT_SGRBG12</constant></refname>
13 <refname id="V4L2-PIX-FMT-SGBRG12"><constant>V4L2_PIX_FMT_SGBRG12</constant></refname>
14 <refname id="V4L2-PIX-FMT-SBGGR12"><constant>V4L2_PIX_FMT_SBGGR12</constant></refname>
15 <refpurpose>12-bit Bayer formats expanded to 16 bits</refpurpose>
16 </refnamediv>
17 <refsect1>
18 <title>Description</title>
19
20 <para>The following four pixel formats are raw sRGB / Bayer formats with
2112 bits per colour. Each colour component is stored in a 16-bit word, with 6
22unused high bits filled with zeros. Each n-pixel row contains n/2 green samples
23and n/2 blue or red samples, with alternating red and blue rows. Bytes are
24stored in memory in little endian order. They are conventionally described
25as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of these
26formats</para>
27
28 <example>
29 <title><constant>V4L2_PIX_FMT_SBGGR12</constant> 4 &times; 4
30pixel image</title>
31
32 <formalpara>
33 <title>Byte Order.</title>
34 <para>Each cell is one byte, high 6 bits in high bytes are 0.
35 <informaltable frame="none">
36 <tgroup cols="5" align="center">
37 <colspec align="left" colwidth="2*" />
38 <tbody valign="top">
39 <row>
40 <entry>start&nbsp;+&nbsp;0:</entry>
41 <entry>B<subscript>00low</subscript></entry>
42 <entry>B<subscript>00high</subscript></entry>
43 <entry>G<subscript>01low</subscript></entry>
44 <entry>G<subscript>01high</subscript></entry>
45 <entry>B<subscript>02low</subscript></entry>
46 <entry>B<subscript>02high</subscript></entry>
47 <entry>G<subscript>03low</subscript></entry>
48 <entry>G<subscript>03high</subscript></entry>
49 </row>
50 <row>
51 <entry>start&nbsp;+&nbsp;8:</entry>
52 <entry>G<subscript>10low</subscript></entry>
53 <entry>G<subscript>10high</subscript></entry>
54 <entry>R<subscript>11low</subscript></entry>
55 <entry>R<subscript>11high</subscript></entry>
56 <entry>G<subscript>12low</subscript></entry>
57 <entry>G<subscript>12high</subscript></entry>
58 <entry>R<subscript>13low</subscript></entry>
59 <entry>R<subscript>13high</subscript></entry>
60 </row>
61 <row>
62 <entry>start&nbsp;+&nbsp;16:</entry>
63 <entry>B<subscript>20low</subscript></entry>
64 <entry>B<subscript>20high</subscript></entry>
65 <entry>G<subscript>21low</subscript></entry>
66 <entry>G<subscript>21high</subscript></entry>
67 <entry>B<subscript>22low</subscript></entry>
68 <entry>B<subscript>22high</subscript></entry>
69 <entry>G<subscript>23low</subscript></entry>
70 <entry>G<subscript>23high</subscript></entry>
71 </row>
72 <row>
73 <entry>start&nbsp;+&nbsp;24:</entry>
74 <entry>G<subscript>30low</subscript></entry>
75 <entry>G<subscript>30high</subscript></entry>
76 <entry>R<subscript>31low</subscript></entry>
77 <entry>R<subscript>31high</subscript></entry>
78 <entry>G<subscript>32low</subscript></entry>
79 <entry>G<subscript>32high</subscript></entry>
80 <entry>R<subscript>33low</subscript></entry>
81 <entry>R<subscript>33high</subscript></entry>
82 </row>
83 </tbody>
84 </tgroup>
85 </informaltable>
86 </para>
87 </formalpara>
88 </example>
89 </refsect1>
90</refentry>
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/v4l/pixfmt-yuv420m.xml
new file mode 100644
index 000000000000..f5d8f57495c8
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv420m.xml
@@ -0,0 +1,162 @@
1 <refentry id="V4L2-PIX-FMT-YUV420M">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname> <constant>V4L2_PIX_FMT_YUV420M</constant></refname>
8 <refpurpose>Variation of <constant>V4L2_PIX_FMT_YUV420</constant>
9 with planes non contiguous in memory. </refpurpose>
10 </refnamediv>
11
12 <refsect1>
13 <title>Description</title>
14
15 <para>This is a multi-planar format, as opposed to a packed format.
16The three components are separated into three sub- images or planes.
17
18The Y plane is first. The Y plane has one byte per pixel. The Cb data
19constitutes the second plane which is half the width and half
20the height of the Y plane (and of the image). Each Cb belongs to four
21pixels, a two-by-two square of the image. For example,
22Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
23Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
24Y'<subscript>11</subscript>. The Cr data, just like the Cb plane, is
25in the third plane. </para>
26
27 <para>If the Y plane has pad bytes after each row, then the Cb
28and Cr planes have half as many pad bytes after their rows. In other
29words, two Cx rows (including padding) is exactly as long as one Y row
30(including padding).</para>
31
32 <para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
33used only in drivers and applications that support the multi-planar API,
34described in <xref linkend="planar-apis"/>. </para>
35
36 <example>
37 <title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 &times; 4
38pixel image</title>
39
40 <formalpara>
41 <title>Byte Order.</title>
42 <para>Each cell is one byte.
43 <informaltable frame="none">
44 <tgroup cols="5" align="center">
45 <colspec align="left" colwidth="2*" />
46 <tbody valign="top">
47 <row>
48 <entry>start0&nbsp;+&nbsp;0:</entry>
49 <entry>Y'<subscript>00</subscript></entry>
50 <entry>Y'<subscript>01</subscript></entry>
51 <entry>Y'<subscript>02</subscript></entry>
52 <entry>Y'<subscript>03</subscript></entry>
53 </row>
54 <row>
55 <entry>start0&nbsp;+&nbsp;4:</entry>
56 <entry>Y'<subscript>10</subscript></entry>
57 <entry>Y'<subscript>11</subscript></entry>
58 <entry>Y'<subscript>12</subscript></entry>
59 <entry>Y'<subscript>13</subscript></entry>
60 </row>
61 <row>
62 <entry>start0&nbsp;+&nbsp;8:</entry>
63 <entry>Y'<subscript>20</subscript></entry>
64 <entry>Y'<subscript>21</subscript></entry>
65 <entry>Y'<subscript>22</subscript></entry>
66 <entry>Y'<subscript>23</subscript></entry>
67 </row>
68 <row>
69 <entry>start0&nbsp;+&nbsp;12:</entry>
70 <entry>Y'<subscript>30</subscript></entry>
71 <entry>Y'<subscript>31</subscript></entry>
72 <entry>Y'<subscript>32</subscript></entry>
73 <entry>Y'<subscript>33</subscript></entry>
74 </row>
75 <row><entry></entry></row>
76 <row>
77 <entry>start1&nbsp;+&nbsp;0:</entry>
78 <entry>Cb<subscript>00</subscript></entry>
79 <entry>Cb<subscript>01</subscript></entry>
80 </row>
81 <row>
82 <entry>start1&nbsp;+&nbsp;2:</entry>
83 <entry>Cb<subscript>10</subscript></entry>
84 <entry>Cb<subscript>11</subscript></entry>
85 </row>
86 <row><entry></entry></row>
87 <row>
88 <entry>start2&nbsp;+&nbsp;0:</entry>
89 <entry>Cr<subscript>00</subscript></entry>
90 <entry>Cr<subscript>01</subscript></entry>
91 </row>
92 <row>
93 <entry>start2&nbsp;+&nbsp;2:</entry>
94 <entry>Cr<subscript>10</subscript></entry>
95 <entry>Cr<subscript>11</subscript></entry>
96 </row>
97 </tbody>
98 </tgroup>
99 </informaltable>
100 </para>
101 </formalpara>
102
103 <formalpara>
104 <title>Color Sample Location.</title>
105 <para>
106 <informaltable frame="none">
107 <tgroup cols="7" align="center">
108 <tbody valign="top">
109 <row>
110 <entry></entry>
111 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
112 <entry>2</entry><entry></entry><entry>3</entry>
113 </row>
114 <row>
115 <entry>0</entry>
116 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
117 <entry>Y</entry><entry></entry><entry>Y</entry>
118 </row>
119 <row>
120 <entry></entry>
121 <entry></entry><entry>C</entry><entry></entry><entry></entry>
122 <entry></entry><entry>C</entry><entry></entry>
123 </row>
124 <row>
125 <entry>1</entry>
126 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
127 <entry>Y</entry><entry></entry><entry>Y</entry>
128 </row>
129 <row>
130 <entry></entry>
131 </row>
132 <row>
133 <entry>2</entry>
134 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
135 <entry>Y</entry><entry></entry><entry>Y</entry>
136 </row>
137 <row>
138 <entry></entry>
139 <entry></entry><entry>C</entry><entry></entry><entry></entry>
140 <entry></entry><entry>C</entry><entry></entry>
141 </row>
142 <row>
143 <entry>3</entry>
144 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
145 <entry>Y</entry><entry></entry><entry>Y</entry>
146 </row>
147 </tbody>
148 </tgroup>
149 </informaltable>
150 </para>
151 </formalpara>
152 </example>
153 </refsect1>
154 </refentry>
155
156 <!--
157Local Variables:
158mode: sgml
159sgml-parent-document: "pixfmt.sgml"
160indent-tabs-mode: nil
161End:
162 -->
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
index cfffc88d7383..c6fdcbbd1b41 100644
--- a/Documentation/DocBook/v4l/pixfmt.xml
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -2,12 +2,16 @@
2 2
3 <para>The V4L2 API was primarily designed for devices exchanging 3 <para>The V4L2 API was primarily designed for devices exchanging
4image data with applications. The 4image data with applications. The
5<structname>v4l2_pix_format</structname> structure defines the format 5<structname>v4l2_pix_format</structname> and <structname>v4l2_pix_format_mplane
6and layout of an image in memory. Image formats are negotiated with 6</structname> structures define the format and layout of an image in memory.
7the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video 7The former is used with the single-planar API, while the latter is used with the
8multi-planar version (see <xref linkend="planar-apis"/>). Image formats are
9negotiated with the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video
8capturing and output, for overlay frame buffer formats see also 10capturing and output, for overlay frame buffer formats see also
9&VIDIOC-G-FBUF;.)</para> 11&VIDIOC-G-FBUF;.)</para>
10 12
13<section>
14 <title>Single-planar format structure</title>
11 <table pgwide="1" frame="none" id="v4l2-pix-format"> 15 <table pgwide="1" frame="none" id="v4l2-pix-format">
12 <title>struct <structname>v4l2_pix_format</structname></title> 16 <title>struct <structname>v4l2_pix_format</structname></title>
13 <tgroup cols="3"> 17 <tgroup cols="3">
@@ -106,6 +110,98 @@ set this field to zero.</entry>
106 </tbody> 110 </tbody>
107 </tgroup> 111 </tgroup>
108 </table> 112 </table>
113</section>
114
115<section>
116 <title>Multi-planar format structures</title>
117 <para>The <structname>v4l2_plane_pix_format</structname> structures define
118 size and layout for each of the planes in a multi-planar format.
119 The <structname>v4l2_pix_format_mplane</structname> structure contains
120 information common to all planes (such as image width and height) and
121 an array of <structname>v4l2_plane_pix_format</structname> structures,
122 describing all planes of that format.</para>
123 <table pgwide="1" frame="none" id="v4l2-plane-pix-format">
124 <title>struct <structname>vl42_plane_pix_format</structname></title>
125 <tgroup cols="3">
126 &cs-str;
127 <tbody valign="top">
128 <row>
129 <entry>__u32</entry>
130 <entry><structfield>sizeimage</structfield></entry>
131 <entry>Maximum size in bytes required for image data in this plane.
132 </entry>
133 </row>
134 <row>
135 <entry>__u16</entry>
136 <entry><structfield>bytesperline</structfield></entry>
137 <entry>Distance in bytes between the leftmost pixels in two adjacent
138 lines.</entry>
139 </row>
140 <row>
141 <entry>__u16</entry>
142 <entry><structfield>reserved[7]</structfield></entry>
143 <entry>Reserved for future extensions. Should be zeroed by the
144 application.</entry>
145 </row>
146 </tbody>
147 </tgroup>
148 </table>
149 <table pgwide="1" frame="none" id="v4l2-pix-format-mplane">
150 <title>struct <structname>v4l2_pix_format_mplane</structname></title>
151 <tgroup cols="3">
152 &cs-str;
153 <tbody valign="top">
154 <row>
155 <entry>__u32</entry>
156 <entry><structfield>width</structfield></entry>
157 <entry>Image width in pixels.</entry>
158 </row>
159 <row>
160 <entry>__u32</entry>
161 <entry><structfield>height</structfield></entry>
162 <entry>Image height in pixels.</entry>
163 </row>
164 <row>
165 <entry>__u32</entry>
166 <entry><structfield>pixelformat</structfield></entry>
167 <entry>The pixel format. Both single- and multi-planar four character
168codes can be used.</entry>
169 </row>
170 <row>
171 <entry>&v4l2-field;</entry>
172 <entry><structfield>field</structfield></entry>
173 <entry>See &v4l2-pix-format;.</entry>
174 </row>
175 <row>
176 <entry>&v4l2-colorspace;</entry>
177 <entry><structfield>colorspace</structfield></entry>
178 <entry>See &v4l2-pix-format;.</entry>
179 </row>
180 <row>
181 <entry>&v4l2-plane-pix-format;</entry>
182 <entry><structfield>plane_fmt[VIDEO_MAX_PLANES]</structfield></entry>
183 <entry>An array of structures describing format of each plane this
184 pixel format consists of. The number of valid entries in this array
185 has to be put in the <structfield>num_planes</structfield>
186 field.</entry>
187 </row>
188 <row>
189 <entry>__u8</entry>
190 <entry><structfield>num_planes</structfield></entry>
191 <entry>Number of planes (i.e. separate memory buffers) for this format
192 and the number of valid entries in the
193 <structfield>plane_fmt</structfield> array.</entry>
194 </row>
195 <row>
196 <entry>__u8</entry>
197 <entry><structfield>reserved[11]</structfield></entry>
198 <entry>Reserved for future extensions. Should be zeroed by the
199 application.</entry>
200 </row>
201 </tbody>
202 </tgroup>
203 </table>
204</section>
109 205
110 <section> 206 <section>
111 <title>Standard Image Formats</title> 207 <title>Standard Image Formats</title>
@@ -142,11 +238,19 @@ leftmost pixel of the second row from the top, and so on. The last row
142has just as many pad bytes after it as the other rows.</para> 238has just as many pad bytes after it as the other rows.</para>
143 239
144 <para>In V4L2 each format has an identifier which looks like 240 <para>In V4L2 each format has an identifier which looks like
145<constant>PIX_FMT_XXX</constant>, defined in the <filename>videodev2.h</filename> 241<constant>PIX_FMT_XXX</constant>, defined in the <link
146header file. These identifiers 242linkend="videodev">videodev.h</link> header file. These identifiers
147represent <link linkend="v4l2-fourcc">four character codes</link> 243represent <link linkend="v4l2-fourcc">four character (FourCC) codes</link>
148which are also listed below, however they are not the same as those 244which are also listed below, however they are not the same as those
149used in the Windows world.</para> 245used in the Windows world.</para>
246
247 <para>For some formats, data is stored in separate, discontiguous
248memory buffers. Those formats are identified by a separate set of FourCC codes
249and are referred to as "multi-planar formats". For example, a YUV422 frame is
250normally stored in one memory buffer, but it can also be placed in two or three
251separate buffers, with Y component in one buffer and CbCr components in another
252in the 2-planar version or with each component in its own buffer in the
2533-planar case. Those sub-buffers are referred to as "planes".</para>
150 </section> 254 </section>
151 255
152 <section id="colorspaces"> 256 <section id="colorspaces">
@@ -599,10 +703,13 @@ information.</para>
599 &sub-vyuy; 703 &sub-vyuy;
600 &sub-y41p; 704 &sub-y41p;
601 &sub-yuv420; 705 &sub-yuv420;
706 &sub-yuv420m;
602 &sub-yuv410; 707 &sub-yuv410;
603 &sub-yuv422p; 708 &sub-yuv422p;
604 &sub-yuv411p; 709 &sub-yuv411p;
605 &sub-nv12; 710 &sub-nv12;
711 &sub-nv12m;
712 &sub-nv12mt;
606 &sub-nv16; 713 &sub-nv16;
607 </section> 714 </section>
608 715
diff --git a/Documentation/DocBook/v4l/planar-apis.xml b/Documentation/DocBook/v4l/planar-apis.xml
new file mode 100644
index 000000000000..878ce2040488
--- /dev/null
+++ b/Documentation/DocBook/v4l/planar-apis.xml
@@ -0,0 +1,62 @@
1<section id="planar-apis">
2 <title>Single- and multi-planar APIs</title>
3
4 <para>Some devices require data for each input or output video frame
5 to be placed in discontiguous memory buffers. In such cases, one
6 video frame has to be addressed using more than one memory address, i.e. one
7 pointer per "plane". A plane is a sub-buffer of the current frame. For
8 examples of such formats see <xref linkend="pixfmt" />.</para>
9
10 <para>Initially, V4L2 API did not support multi-planar buffers and a set of
11 extensions has been introduced to handle them. Those extensions constitute
12 what is being referred to as the "multi-planar API".</para>
13
14 <para>Some of the V4L2 API calls and structures are interpreted differently,
15 depending on whether single- or multi-planar API is being used. An application
16 can choose whether to use one or the other by passing a corresponding buffer
17 type to its ioctl calls. Multi-planar versions of buffer types are suffixed
18 with an `_MPLANE' string. For a list of available multi-planar buffer types
19 see &v4l2-buf-type;.
20 </para>
21
22 <section>
23 <title>Multi-planar formats</title>
24 <para>Multi-planar API introduces new multi-planar formats. Those formats
25 use a separate set of FourCC codes. It is important to distinguish between
26 the multi-planar API and a multi-planar format. Multi-planar API calls can
27 handle all single-planar formats as well (as long as they are passed in
28 multi-planar API structures), while the single-planar API cannot
29 handle multi-planar formats.</para>
30 </section>
31
32 <section>
33 <title>Calls that distinguish between single and multi-planar APIs</title>
34 <variablelist>
35 <varlistentry>
36 <term>&VIDIOC-QUERYCAP;</term>
37 <listitem><para>Two additional multi-planar capabilities are added. They can
38 be set together with non-multi-planar ones for devices that handle
39 both single- and multi-planar formats.</para></listitem>
40 </varlistentry>
41 <varlistentry>
42 <term>&VIDIOC-G-FMT;, &VIDIOC-S-FMT;, &VIDIOC-TRY-FMT;</term>
43 <listitem><para>New structures for describing multi-planar formats are added:
44 &v4l2-pix-format-mplane; and &v4l2-plane-pix-format;. Drivers may
45 define new multi-planar formats, which have distinct FourCC codes from
46 the existing single-planar ones.</para>
47 </listitem>
48 </varlistentry>
49 <varlistentry>
50 <term>&VIDIOC-QBUF;, &VIDIOC-DQBUF;, &VIDIOC-QUERYBUF;</term>
51 <listitem><para>A new &v4l2-plane; structure for describing planes is added.
52 Arrays of this structure are passed in the new
53 <structfield>m.planes</structfield> field of &v4l2-buffer;.</para>
54 </listitem>
55 </varlistentry>
56 <varlistentry>
57 <term>&VIDIOC-REQBUFS;</term>
58 <listitem><para>Will allocate multi-planar buffers as requested.</para></listitem>
59 </varlistentry>
60 </variablelist>
61 </section>
62</section>
diff --git a/Documentation/DocBook/v4l/subdev-formats.xml b/Documentation/DocBook/v4l/subdev-formats.xml
new file mode 100644
index 000000000000..7041127d6dfc
--- /dev/null
+++ b/Documentation/DocBook/v4l/subdev-formats.xml
@@ -0,0 +1,2467 @@
1<section id="v4l2-mbus-format">
2 <title>Media Bus Formats</title>
3
4 <table pgwide="1" frame="none" id="v4l2-mbus-framefmt">
5 <title>struct <structname>v4l2_mbus_framefmt</structname></title>
6 <tgroup cols="3">
7 &cs-str;
8 <tbody valign="top">
9 <row>
10 <entry>__u32</entry>
11 <entry><structfield>width</structfield></entry>
12 <entry>Image width, in pixels.</entry>
13 </row>
14 <row>
15 <entry>__u32</entry>
16 <entry><structfield>height</structfield></entry>
17 <entry>Image height, in pixels.</entry>
18 </row>
19 <row>
20 <entry>__u32</entry>
21 <entry><structfield>code</structfield></entry>
22 <entry>Format code, from &v4l2-mbus-pixelcode;.</entry>
23 </row>
24 <row>
25 <entry>__u32</entry>
26 <entry><structfield>field</structfield></entry>
27 <entry>Field order, from &v4l2-field;. See
28 <xref linkend="field-order" /> for details.</entry>
29 </row>
30 <row>
31 <entry>__u32</entry>
32 <entry><structfield>colorspace</structfield></entry>
33 <entry>Image colorspace, from &v4l2-colorspace;. See
34 <xref linkend="colorspaces" /> for details.</entry>
35 </row>
36 <row>
37 <entry>__u32</entry>
38 <entry><structfield>reserved</structfield>[7]</entry>
39 <entry>Reserved for future extensions. Applications and drivers must
40 set the array to zero.</entry>
41 </row>
42 </tbody>
43 </tgroup>
44 </table>
45
46 <section id="v4l2-mbus-pixelcode">
47 <title>Media Bus Pixel Codes</title>
48
49 <para>The media bus pixel codes describe image formats as flowing over
50 physical busses (both between separate physical components and inside SoC
51 devices). This should not be confused with the V4L2 pixel formats that
52 describe, using four character codes, image formats as stored in memory.
53 </para>
54
55 <para>While there is a relationship between image formats on busses and
56 image formats in memory (a raw Bayer image won't be magically converted to
57 JPEG just by storing it to memory), there is no one-to-one correspondance
58 between them.</para>
59
60 <section>
61 <title>Packed RGB Formats</title>
62
63 <para>Those formats transfer pixel data as red, green and blue components.
64 The format code is made of the following information.
65 <itemizedlist>
66 <listitem><para>The red, green and blue components order code, as encoded in a
67 pixel sample. Possible values are RGB and BGR.</para></listitem>
68 <listitem><para>The number of bits per component, for each component. The values
69 can be different for all components. Common values are 555 and 565.</para>
70 </listitem>
71 <listitem><para>The number of bus samples per pixel. Pixels that are wider than
72 the bus width must be transferred in multiple samples. Common values are
73 1 and 2.</para></listitem>
74 <listitem><para>The bus width.</para></listitem>
75 <listitem><para>For formats where the total number of bits per pixel is smaller
76 than the number of bus samples per pixel times the bus width, a padding
77 value stating if the bytes are padded in their most high order bits
78 (PADHI) or low order bits (PADLO).</para></listitem>
79 <listitem><para>For formats where the number of bus samples per pixel is larger
80 than 1, an endianness value stating if the pixel is transferred MSB first
81 (BE) or LSB first (LE).</para></listitem>
82 </itemizedlist>
83 </para>
84
85 <para>For instance, a format where pixels are encoded as 5-bits red, 5-bits
86 green and 5-bit blue values padded on the high bit, transferred as 2 8-bit
87 samples per pixel with the most significant bits (padding, red and half of
88 the green value) transferred first will be named
89 <constant>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</constant>.
90 </para>
91
92 <para>The following tables list existing packet RGB formats.</para>
93
94 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-rgb">
95 <title>RGB formats</title>
96 <tgroup cols="11">
97 <colspec colname="id" align="left" />
98 <colspec colname="code" align="center"/>
99 <colspec colname="bit" />
100 <colspec colnum="4" colname="b07" align="center" />
101 <colspec colnum="5" colname="b06" align="center" />
102 <colspec colnum="6" colname="b05" align="center" />
103 <colspec colnum="7" colname="b04" align="center" />
104 <colspec colnum="8" colname="b03" align="center" />
105 <colspec colnum="9" colname="b02" align="center" />
106 <colspec colnum="10" colname="b01" align="center" />
107 <colspec colnum="11" colname="b00" align="center" />
108 <spanspec namest="b07" nameend="b00" spanname="b0" />
109 <thead>
110 <row>
111 <entry>Identifier</entry>
112 <entry>Code</entry>
113 <entry></entry>
114 <entry spanname="b0">Data organization</entry>
115 </row>
116 <row>
117 <entry></entry>
118 <entry></entry>
119 <entry>Bit</entry>
120 <entry>7</entry>
121 <entry>6</entry>
122 <entry>5</entry>
123 <entry>4</entry>
124 <entry>3</entry>
125 <entry>2</entry>
126 <entry>1</entry>
127 <entry>0</entry>
128 </row>
129 </thead>
130 <tbody valign="top">
131 <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-BE">
132 <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE</entry>
133 <entry>0x1001</entry>
134 <entry></entry>
135 <entry>0</entry>
136 <entry>0</entry>
137 <entry>0</entry>
138 <entry>0</entry>
139 <entry>r<subscript>3</subscript></entry>
140 <entry>r<subscript>2</subscript></entry>
141 <entry>r<subscript>1</subscript></entry>
142 <entry>r<subscript>0</subscript></entry>
143 </row>
144 <row>
145 <entry></entry>
146 <entry></entry>
147 <entry></entry>
148 <entry>g<subscript>3</subscript></entry>
149 <entry>g<subscript>2</subscript></entry>
150 <entry>g<subscript>1</subscript></entry>
151 <entry>g<subscript>0</subscript></entry>
152 <entry>b<subscript>3</subscript></entry>
153 <entry>b<subscript>2</subscript></entry>
154 <entry>b<subscript>1</subscript></entry>
155 <entry>b<subscript>0</subscript></entry>
156 </row>
157 <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-LE">
158 <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE</entry>
159 <entry>0x1002</entry>
160 <entry></entry>
161 <entry>g<subscript>3</subscript></entry>
162 <entry>g<subscript>2</subscript></entry>
163 <entry>g<subscript>1</subscript></entry>
164 <entry>g<subscript>0</subscript></entry>
165 <entry>b<subscript>3</subscript></entry>
166 <entry>b<subscript>2</subscript></entry>
167 <entry>b<subscript>1</subscript></entry>
168 <entry>b<subscript>0</subscript></entry>
169 </row>
170 <row>
171 <entry></entry>
172 <entry></entry>
173 <entry></entry>
174 <entry>0</entry>
175 <entry>0</entry>
176 <entry>0</entry>
177 <entry>0</entry>
178 <entry>r<subscript>3</subscript></entry>
179 <entry>r<subscript>2</subscript></entry>
180 <entry>r<subscript>1</subscript></entry>
181 <entry>r<subscript>0</subscript></entry>
182 </row>
183 <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-BE">
184 <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</entry>
185 <entry>0x1003</entry>
186 <entry></entry>
187 <entry>0</entry>
188 <entry>r<subscript>4</subscript></entry>
189 <entry>r<subscript>3</subscript></entry>
190 <entry>r<subscript>2</subscript></entry>
191 <entry>r<subscript>1</subscript></entry>
192 <entry>r<subscript>0</subscript></entry>
193 <entry>g<subscript>4</subscript></entry>
194 <entry>g<subscript>3</subscript></entry>
195 </row>
196 <row>
197 <entry></entry>
198 <entry></entry>
199 <entry></entry>
200 <entry>g<subscript>2</subscript></entry>
201 <entry>g<subscript>1</subscript></entry>
202 <entry>g<subscript>0</subscript></entry>
203 <entry>b<subscript>4</subscript></entry>
204 <entry>b<subscript>3</subscript></entry>
205 <entry>b<subscript>2</subscript></entry>
206 <entry>b<subscript>1</subscript></entry>
207 <entry>b<subscript>0</subscript></entry>
208 </row>
209 <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-LE">
210 <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE</entry>
211 <entry>0x1004</entry>
212 <entry></entry>
213 <entry>g<subscript>2</subscript></entry>
214 <entry>g<subscript>1</subscript></entry>
215 <entry>g<subscript>0</subscript></entry>
216 <entry>b<subscript>4</subscript></entry>
217 <entry>b<subscript>3</subscript></entry>
218 <entry>b<subscript>2</subscript></entry>
219 <entry>b<subscript>1</subscript></entry>
220 <entry>b<subscript>0</subscript></entry>
221 </row>
222 <row>
223 <entry></entry>
224 <entry></entry>
225 <entry></entry>
226 <entry>0</entry>
227 <entry>r<subscript>4</subscript></entry>
228 <entry>r<subscript>3</subscript></entry>
229 <entry>r<subscript>2</subscript></entry>
230 <entry>r<subscript>1</subscript></entry>
231 <entry>r<subscript>0</subscript></entry>
232 <entry>g<subscript>4</subscript></entry>
233 <entry>g<subscript>3</subscript></entry>
234 </row>
235 <row id="V4L2-MBUS-FMT-BGR565-2X8-BE">
236 <entry>V4L2_MBUS_FMT_BGR565_2X8_BE</entry>
237 <entry>0x1005</entry>
238 <entry></entry>
239 <entry>b<subscript>4</subscript></entry>
240 <entry>b<subscript>3</subscript></entry>
241 <entry>b<subscript>2</subscript></entry>
242 <entry>b<subscript>1</subscript></entry>
243 <entry>b<subscript>0</subscript></entry>
244 <entry>g<subscript>5</subscript></entry>
245 <entry>g<subscript>4</subscript></entry>
246 <entry>g<subscript>3</subscript></entry>
247 </row>
248 <row>
249 <entry></entry>
250 <entry></entry>
251 <entry></entry>
252 <entry>g<subscript>2</subscript></entry>
253 <entry>g<subscript>1</subscript></entry>
254 <entry>g<subscript>0</subscript></entry>
255 <entry>r<subscript>4</subscript></entry>
256 <entry>r<subscript>3</subscript></entry>
257 <entry>r<subscript>2</subscript></entry>
258 <entry>r<subscript>1</subscript></entry>
259 <entry>r<subscript>0</subscript></entry>
260 </row>
261 <row id="V4L2-MBUS-FMT-BGR565-2X8-LE">
262 <entry>V4L2_MBUS_FMT_BGR565_2X8_LE</entry>
263 <entry>0x1006</entry>
264 <entry></entry>
265 <entry>g<subscript>2</subscript></entry>
266 <entry>g<subscript>1</subscript></entry>
267 <entry>g<subscript>0</subscript></entry>
268 <entry>r<subscript>4</subscript></entry>
269 <entry>r<subscript>3</subscript></entry>
270 <entry>r<subscript>2</subscript></entry>
271 <entry>r<subscript>1</subscript></entry>
272 <entry>r<subscript>0</subscript></entry>
273 </row>
274 <row>
275 <entry></entry>
276 <entry></entry>
277 <entry></entry>
278 <entry>b<subscript>4</subscript></entry>
279 <entry>b<subscript>3</subscript></entry>
280 <entry>b<subscript>2</subscript></entry>
281 <entry>b<subscript>1</subscript></entry>
282 <entry>b<subscript>0</subscript></entry>
283 <entry>g<subscript>5</subscript></entry>
284 <entry>g<subscript>4</subscript></entry>
285 <entry>g<subscript>3</subscript></entry>
286 </row>
287 <row id="V4L2-MBUS-FMT-RGB565-2X8-BE">
288 <entry>V4L2_MBUS_FMT_RGB565_2X8_BE</entry>
289 <entry>0x1007</entry>
290 <entry></entry>
291 <entry>r<subscript>4</subscript></entry>
292 <entry>r<subscript>3</subscript></entry>
293 <entry>r<subscript>2</subscript></entry>
294 <entry>r<subscript>1</subscript></entry>
295 <entry>r<subscript>0</subscript></entry>
296 <entry>g<subscript>5</subscript></entry>
297 <entry>g<subscript>4</subscript></entry>
298 <entry>g<subscript>3</subscript></entry>
299 </row>
300 <row>
301 <entry></entry>
302 <entry></entry>
303 <entry></entry>
304 <entry>g<subscript>2</subscript></entry>
305 <entry>g<subscript>1</subscript></entry>
306 <entry>g<subscript>0</subscript></entry>
307 <entry>b<subscript>4</subscript></entry>
308 <entry>b<subscript>3</subscript></entry>
309 <entry>b<subscript>2</subscript></entry>
310 <entry>b<subscript>1</subscript></entry>
311 <entry>b<subscript>0</subscript></entry>
312 </row>
313 <row id="V4L2-MBUS-FMT-RGB565-2X8-LE">
314 <entry>V4L2_MBUS_FMT_RGB565_2X8_LE</entry>
315 <entry>0x1008</entry>
316 <entry></entry>
317 <entry>g<subscript>2</subscript></entry>
318 <entry>g<subscript>1</subscript></entry>
319 <entry>g<subscript>0</subscript></entry>
320 <entry>b<subscript>4</subscript></entry>
321 <entry>b<subscript>3</subscript></entry>
322 <entry>b<subscript>2</subscript></entry>
323 <entry>b<subscript>1</subscript></entry>
324 <entry>b<subscript>0</subscript></entry>
325 </row>
326 <row>
327 <entry></entry>
328 <entry></entry>
329 <entry></entry>
330 <entry>r<subscript>4</subscript></entry>
331 <entry>r<subscript>3</subscript></entry>
332 <entry>r<subscript>2</subscript></entry>
333 <entry>r<subscript>1</subscript></entry>
334 <entry>r<subscript>0</subscript></entry>
335 <entry>g<subscript>5</subscript></entry>
336 <entry>g<subscript>4</subscript></entry>
337 <entry>g<subscript>3</subscript></entry>
338 </row>
339 </tbody>
340 </tgroup>
341 </table>
342 </section>
343
344 <section>
345 <title>Bayer Formats</title>
346
347 <para>Those formats transfer pixel data as red, green and blue components.
348 The format code is made of the following information.
349 <itemizedlist>
350 <listitem><para>The red, green and blue components order code, as encoded in a
351 pixel sample. The possible values are shown in <xref
352 linkend="bayer-patterns" />.</para></listitem>
353 <listitem><para>The number of bits per pixel component. All components are
354 transferred on the same number of bits. Common values are 8, 10 and 12.</para>
355 </listitem>
356 <listitem><para>If the pixel components are DPCM-compressed, a mention of the
357 DPCM compression and the number of bits per compressed pixel component.</para>
358 </listitem>
359 <listitem><para>The number of bus samples per pixel. Pixels that are wider than
360 the bus width must be transferred in multiple samples. Common values are
361 1 and 2.</para></listitem>
362 <listitem><para>The bus width.</para></listitem>
363 <listitem><para>For formats where the total number of bits per pixel is smaller
364 than the number of bus samples per pixel times the bus width, a padding
365 value stating if the bytes are padded in their most high order bits
366 (PADHI) or low order bits (PADLO).</para></listitem>
367 <listitem><para>For formats where the number of bus samples per pixel is larger
368 than 1, an endianness value stating if the pixel is transferred MSB first
369 (BE) or LSB first (LE).</para></listitem>
370 </itemizedlist>
371 </para>
372
373 <para>For instance, a format with uncompressed 10-bit Bayer components
374 arranged in a red, green, green, blue pattern transferred as 2 8-bit
375 samples per pixel with the least significant bits transferred first will
376 be named <constant>V4L2_MBUS_FMT_SRGGB10_2X8_PADHI_LE</constant>.
377 </para>
378
379 <figure id="bayer-patterns">
380 <title>Bayer Patterns</title>
381 <mediaobject>
382 <imageobject>
383 <imagedata fileref="bayer.pdf" format="PS" />
384 </imageobject>
385 <imageobject>
386 <imagedata fileref="bayer.png" format="PNG" />
387 </imageobject>
388 <textobject>
389 <phrase>Bayer filter color patterns</phrase>
390 </textobject>
391 </mediaobject>
392 </figure>
393
394 <para>The following table lists existing packet Bayer formats. The data
395 organization is given as an example for the first pixel only.</para>
396
397 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-bayer">
398 <title>Bayer Formats</title>
399 <tgroup cols="15">
400 <colspec colname="id" align="left" />
401 <colspec colname="code" align="center"/>
402 <colspec colname="bit" />
403 <colspec colnum="4" colname="b11" align="center" />
404 <colspec colnum="5" colname="b10" align="center" />
405 <colspec colnum="6" colname="b09" align="center" />
406 <colspec colnum="7" colname="b08" align="center" />
407 <colspec colnum="8" colname="b07" align="center" />
408 <colspec colnum="9" colname="b06" align="center" />
409 <colspec colnum="10" colname="b05" align="center" />
410 <colspec colnum="11" colname="b04" align="center" />
411 <colspec colnum="12" colname="b03" align="center" />
412 <colspec colnum="13" colname="b02" align="center" />
413 <colspec colnum="14" colname="b01" align="center" />
414 <colspec colnum="15" colname="b00" align="center" />
415 <spanspec namest="b11" nameend="b00" spanname="b0" />
416 <thead>
417 <row>
418 <entry>Identifier</entry>
419 <entry>Code</entry>
420 <entry></entry>
421 <entry spanname="b0">Data organization</entry>
422 </row>
423 <row>
424 <entry></entry>
425 <entry></entry>
426 <entry>Bit</entry>
427 <entry>11</entry>
428 <entry>10</entry>
429 <entry>9</entry>
430 <entry>8</entry>
431 <entry>7</entry>
432 <entry>6</entry>
433 <entry>5</entry>
434 <entry>4</entry>
435 <entry>3</entry>
436 <entry>2</entry>
437 <entry>1</entry>
438 <entry>0</entry>
439 </row>
440 </thead>
441 <tbody valign="top">
442 <row id="V4L2-MBUS-FMT-SBGGR8-1X8">
443 <entry>V4L2_MBUS_FMT_SBGGR8_1X8</entry>
444 <entry>0x3001</entry>
445 <entry></entry>
446 <entry>-</entry>
447 <entry>-</entry>
448 <entry>-</entry>
449 <entry>-</entry>
450 <entry>b<subscript>7</subscript></entry>
451 <entry>b<subscript>6</subscript></entry>
452 <entry>b<subscript>5</subscript></entry>
453 <entry>b<subscript>4</subscript></entry>
454 <entry>b<subscript>3</subscript></entry>
455 <entry>b<subscript>2</subscript></entry>
456 <entry>b<subscript>1</subscript></entry>
457 <entry>b<subscript>0</subscript></entry>
458 </row>
459 <row id="V4L2-MBUS-FMT-SGRBG8-1X8">
460 <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry>
461 <entry>0x3002</entry>
462 <entry></entry>
463 <entry>-</entry>
464 <entry>-</entry>
465 <entry>-</entry>
466 <entry>-</entry>
467 <entry>g<subscript>7</subscript></entry>
468 <entry>g<subscript>6</subscript></entry>
469 <entry>g<subscript>5</subscript></entry>
470 <entry>g<subscript>4</subscript></entry>
471 <entry>g<subscript>3</subscript></entry>
472 <entry>g<subscript>2</subscript></entry>
473 <entry>g<subscript>1</subscript></entry>
474 <entry>g<subscript>0</subscript></entry>
475 </row>
476 <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8">
477 <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry>
478 <entry>0x300b</entry>
479 <entry></entry>
480 <entry>-</entry>
481 <entry>-</entry>
482 <entry>-</entry>
483 <entry>-</entry>
484 <entry>b<subscript>7</subscript></entry>
485 <entry>b<subscript>6</subscript></entry>
486 <entry>b<subscript>5</subscript></entry>
487 <entry>b<subscript>4</subscript></entry>
488 <entry>b<subscript>3</subscript></entry>
489 <entry>b<subscript>2</subscript></entry>
490 <entry>b<subscript>1</subscript></entry>
491 <entry>b<subscript>0</subscript></entry>
492 </row>
493 <row id="V4L2-MBUS-FMT-SGBRG10-DPCM8-1X8">
494 <entry>V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8</entry>
495 <entry>0x300c</entry>
496 <entry></entry>
497 <entry>-</entry>
498 <entry>-</entry>
499 <entry>-</entry>
500 <entry>-</entry>
501 <entry>g<subscript>7</subscript></entry>
502 <entry>g<subscript>6</subscript></entry>
503 <entry>g<subscript>5</subscript></entry>
504 <entry>g<subscript>4</subscript></entry>
505 <entry>g<subscript>3</subscript></entry>
506 <entry>g<subscript>2</subscript></entry>
507 <entry>g<subscript>1</subscript></entry>
508 <entry>g<subscript>0</subscript></entry>
509 </row>
510 <row id="V4L2-MBUS-FMT-SGRBG10-DPCM8-1X8">
511 <entry>V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8</entry>
512 <entry>0x3009</entry>
513 <entry></entry>
514 <entry>-</entry>
515 <entry>-</entry>
516 <entry>-</entry>
517 <entry>-</entry>
518 <entry>g<subscript>7</subscript></entry>
519 <entry>g<subscript>6</subscript></entry>
520 <entry>g<subscript>5</subscript></entry>
521 <entry>g<subscript>4</subscript></entry>
522 <entry>g<subscript>3</subscript></entry>
523 <entry>g<subscript>2</subscript></entry>
524 <entry>g<subscript>1</subscript></entry>
525 <entry>g<subscript>0</subscript></entry>
526 </row>
527 <row id="V4L2-MBUS-FMT-SRGGB10-DPCM8-1X8">
528 <entry>V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8</entry>
529 <entry>0x300d</entry>
530 <entry></entry>
531 <entry>-</entry>
532 <entry>-</entry>
533 <entry>-</entry>
534 <entry>-</entry>
535 <entry>r<subscript>7</subscript></entry>
536 <entry>r<subscript>6</subscript></entry>
537 <entry>r<subscript>5</subscript></entry>
538 <entry>r<subscript>4</subscript></entry>
539 <entry>r<subscript>3</subscript></entry>
540 <entry>r<subscript>2</subscript></entry>
541 <entry>r<subscript>1</subscript></entry>
542 <entry>r<subscript>0</subscript></entry>
543 </row>
544 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-BE">
545 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE</entry>
546 <entry>0x3003</entry>
547 <entry></entry>
548 <entry>-</entry>
549 <entry>-</entry>
550 <entry>-</entry>
551 <entry>-</entry>
552 <entry>0</entry>
553 <entry>0</entry>
554 <entry>0</entry>
555 <entry>0</entry>
556 <entry>0</entry>
557 <entry>0</entry>
558 <entry>b<subscript>9</subscript></entry>
559 <entry>b<subscript>8</subscript></entry>
560 </row>
561 <row>
562 <entry></entry>
563 <entry></entry>
564 <entry></entry>
565 <entry>-</entry>
566 <entry>-</entry>
567 <entry>-</entry>
568 <entry>-</entry>
569 <entry>b<subscript>7</subscript></entry>
570 <entry>b<subscript>6</subscript></entry>
571 <entry>b<subscript>5</subscript></entry>
572 <entry>b<subscript>4</subscript></entry>
573 <entry>b<subscript>3</subscript></entry>
574 <entry>b<subscript>2</subscript></entry>
575 <entry>b<subscript>1</subscript></entry>
576 <entry>b<subscript>0</subscript></entry>
577 </row>
578 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-LE">
579 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE</entry>
580 <entry>0x3004</entry>
581 <entry></entry>
582 <entry>-</entry>
583 <entry>-</entry>
584 <entry>-</entry>
585 <entry>-</entry>
586 <entry>b<subscript>7</subscript></entry>
587 <entry>b<subscript>6</subscript></entry>
588 <entry>b<subscript>5</subscript></entry>
589 <entry>b<subscript>4</subscript></entry>
590 <entry>b<subscript>3</subscript></entry>
591 <entry>b<subscript>2</subscript></entry>
592 <entry>b<subscript>1</subscript></entry>
593 <entry>b<subscript>0</subscript></entry>
594 </row>
595 <row>
596 <entry></entry>
597 <entry></entry>
598 <entry></entry>
599 <entry>-</entry>
600 <entry>-</entry>
601 <entry>-</entry>
602 <entry>-</entry>
603 <entry>0</entry>
604 <entry>0</entry>
605 <entry>0</entry>
606 <entry>0</entry>
607 <entry>0</entry>
608 <entry>0</entry>
609 <entry>b<subscript>9</subscript></entry>
610 <entry>b<subscript>8</subscript></entry>
611 </row>
612 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-BE">
613 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE</entry>
614 <entry>0x3005</entry>
615 <entry></entry>
616 <entry>-</entry>
617 <entry>-</entry>
618 <entry>-</entry>
619 <entry>-</entry>
620 <entry>b<subscript>9</subscript></entry>
621 <entry>b<subscript>8</subscript></entry>
622 <entry>b<subscript>7</subscript></entry>
623 <entry>b<subscript>6</subscript></entry>
624 <entry>b<subscript>5</subscript></entry>
625 <entry>b<subscript>4</subscript></entry>
626 <entry>b<subscript>3</subscript></entry>
627 <entry>b<subscript>2</subscript></entry>
628 </row>
629 <row>
630 <entry></entry>
631 <entry></entry>
632 <entry></entry>
633 <entry>-</entry>
634 <entry>-</entry>
635 <entry>-</entry>
636 <entry>-</entry>
637 <entry>b<subscript>1</subscript></entry>
638 <entry>b<subscript>0</subscript></entry>
639 <entry>0</entry>
640 <entry>0</entry>
641 <entry>0</entry>
642 <entry>0</entry>
643 <entry>0</entry>
644 <entry>0</entry>
645 </row>
646 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-LE">
647 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE</entry>
648 <entry>0x3006</entry>
649 <entry></entry>
650 <entry>-</entry>
651 <entry>-</entry>
652 <entry>-</entry>
653 <entry>-</entry>
654 <entry>b<subscript>1</subscript></entry>
655 <entry>b<subscript>0</subscript></entry>
656 <entry>0</entry>
657 <entry>0</entry>
658 <entry>0</entry>
659 <entry>0</entry>
660 <entry>0</entry>
661 <entry>0</entry>
662 </row>
663 <row>
664 <entry></entry>
665 <entry></entry>
666 <entry></entry>
667 <entry>-</entry>
668 <entry>-</entry>
669 <entry>-</entry>
670 <entry>-</entry>
671 <entry>b<subscript>9</subscript></entry>
672 <entry>b<subscript>8</subscript></entry>
673 <entry>b<subscript>7</subscript></entry>
674 <entry>b<subscript>6</subscript></entry>
675 <entry>b<subscript>5</subscript></entry>
676 <entry>b<subscript>4</subscript></entry>
677 <entry>b<subscript>3</subscript></entry>
678 <entry>b<subscript>2</subscript></entry>
679 </row>
680 <row id="V4L2-MBUS-FMT-SBGGR10-1X10">
681 <entry>V4L2_MBUS_FMT_SBGGR10_1X10</entry>
682 <entry>0x3007</entry>
683 <entry></entry>
684 <entry>-</entry>
685 <entry>-</entry>
686 <entry>b<subscript>9</subscript></entry>
687 <entry>b<subscript>8</subscript></entry>
688 <entry>b<subscript>7</subscript></entry>
689 <entry>b<subscript>6</subscript></entry>
690 <entry>b<subscript>5</subscript></entry>
691 <entry>b<subscript>4</subscript></entry>
692 <entry>b<subscript>3</subscript></entry>
693 <entry>b<subscript>2</subscript></entry>
694 <entry>b<subscript>1</subscript></entry>
695 <entry>b<subscript>0</subscript></entry>
696 </row>
697 <row id="V4L2-MBUS-FMT-SGBRG10-1X10">
698 <entry>V4L2_MBUS_FMT_SGBRG10_1X10</entry>
699 <entry>0x300e</entry>
700 <entry></entry>
701 <entry>-</entry>
702 <entry>-</entry>
703 <entry>g<subscript>9</subscript></entry>
704 <entry>g<subscript>8</subscript></entry>
705 <entry>g<subscript>7</subscript></entry>
706 <entry>g<subscript>6</subscript></entry>
707 <entry>g<subscript>5</subscript></entry>
708 <entry>g<subscript>4</subscript></entry>
709 <entry>g<subscript>3</subscript></entry>
710 <entry>g<subscript>2</subscript></entry>
711 <entry>g<subscript>1</subscript></entry>
712 <entry>g<subscript>0</subscript></entry>
713 </row>
714 <row id="V4L2-MBUS-FMT-SGRBG10-1X10">
715 <entry>V4L2_MBUS_FMT_SGRBG10_1X10</entry>
716 <entry>0x300a</entry>
717 <entry></entry>
718 <entry>-</entry>
719 <entry>-</entry>
720 <entry>g<subscript>9</subscript></entry>
721 <entry>g<subscript>8</subscript></entry>
722 <entry>g<subscript>7</subscript></entry>
723 <entry>g<subscript>6</subscript></entry>
724 <entry>g<subscript>5</subscript></entry>
725 <entry>g<subscript>4</subscript></entry>
726 <entry>g<subscript>3</subscript></entry>
727 <entry>g<subscript>2</subscript></entry>
728 <entry>g<subscript>1</subscript></entry>
729 <entry>g<subscript>0</subscript></entry>
730 </row>
731 <row id="V4L2-MBUS-FMT-SRGGB10-1X10">
732 <entry>V4L2_MBUS_FMT_SRGGB10_1X10</entry>
733 <entry>0x300f</entry>
734 <entry></entry>
735 <entry>-</entry>
736 <entry>-</entry>
737 <entry>r<subscript>9</subscript></entry>
738 <entry>r<subscript>8</subscript></entry>
739 <entry>r<subscript>7</subscript></entry>
740 <entry>r<subscript>6</subscript></entry>
741 <entry>r<subscript>5</subscript></entry>
742 <entry>r<subscript>4</subscript></entry>
743 <entry>r<subscript>3</subscript></entry>
744 <entry>r<subscript>2</subscript></entry>
745 <entry>r<subscript>1</subscript></entry>
746 <entry>r<subscript>0</subscript></entry>
747 </row>
748 <row id="V4L2-MBUS-FMT-SBGGR12-1X12">
749 <entry>V4L2_MBUS_FMT_SBGGR12_1X12</entry>
750 <entry>0x3008</entry>
751 <entry></entry>
752 <entry>b<subscript>11</subscript></entry>
753 <entry>b<subscript>10</subscript></entry>
754 <entry>b<subscript>9</subscript></entry>
755 <entry>b<subscript>8</subscript></entry>
756 <entry>b<subscript>7</subscript></entry>
757 <entry>b<subscript>6</subscript></entry>
758 <entry>b<subscript>5</subscript></entry>
759 <entry>b<subscript>4</subscript></entry>
760 <entry>b<subscript>3</subscript></entry>
761 <entry>b<subscript>2</subscript></entry>
762 <entry>b<subscript>1</subscript></entry>
763 <entry>b<subscript>0</subscript></entry>
764 </row>
765 <row id="V4L2-MBUS-FMT-SGBRG12-1X12">
766 <entry>V4L2_MBUS_FMT_SGBRG12_1X12</entry>
767 <entry>0x3010</entry>
768 <entry></entry>
769 <entry>g<subscript>11</subscript></entry>
770 <entry>g<subscript>10</subscript></entry>
771 <entry>g<subscript>9</subscript></entry>
772 <entry>g<subscript>8</subscript></entry>
773 <entry>g<subscript>7</subscript></entry>
774 <entry>g<subscript>6</subscript></entry>
775 <entry>g<subscript>5</subscript></entry>
776 <entry>g<subscript>4</subscript></entry>
777 <entry>g<subscript>3</subscript></entry>
778 <entry>g<subscript>2</subscript></entry>
779 <entry>g<subscript>1</subscript></entry>
780 <entry>g<subscript>0</subscript></entry>
781 </row>
782 <row id="V4L2-MBUS-FMT-SGRBG12-1X12">
783 <entry>V4L2_MBUS_FMT_SGRBG12_1X12</entry>
784 <entry>0x3011</entry>
785 <entry></entry>
786 <entry>g<subscript>11</subscript></entry>
787 <entry>g<subscript>10</subscript></entry>
788 <entry>g<subscript>9</subscript></entry>
789 <entry>g<subscript>8</subscript></entry>
790 <entry>g<subscript>7</subscript></entry>
791 <entry>g<subscript>6</subscript></entry>
792 <entry>g<subscript>5</subscript></entry>
793 <entry>g<subscript>4</subscript></entry>
794 <entry>g<subscript>3</subscript></entry>
795 <entry>g<subscript>2</subscript></entry>
796 <entry>g<subscript>1</subscript></entry>
797 <entry>g<subscript>0</subscript></entry>
798 </row>
799 <row id="V4L2-MBUS-FMT-SRGGB12-1X12">
800 <entry>V4L2_MBUS_FMT_SRGGB12_1X12</entry>
801 <entry>0x3012</entry>
802 <entry></entry>
803 <entry>r<subscript>11</subscript></entry>
804 <entry>r<subscript>10</subscript></entry>
805 <entry>r<subscript>9</subscript></entry>
806 <entry>r<subscript>8</subscript></entry>
807 <entry>r<subscript>7</subscript></entry>
808 <entry>r<subscript>6</subscript></entry>
809 <entry>r<subscript>5</subscript></entry>
810 <entry>r<subscript>4</subscript></entry>
811 <entry>r<subscript>3</subscript></entry>
812 <entry>r<subscript>2</subscript></entry>
813 <entry>r<subscript>1</subscript></entry>
814 <entry>r<subscript>0</subscript></entry>
815 </row>
816 </tbody>
817 </tgroup>
818 </table>
819 </section>
820
821 <section>
822 <title>Packed YUV Formats</title>
823
824 <para>Those data formats transfer pixel data as (possibly downsampled) Y, U
825 and V components. The format code is made of the following information.
826 <itemizedlist>
827 <listitem><para>The Y, U and V components order code, as transferred on the
828 bus. Possible values are YUYV, UYVY, YVYU and VYUY.</para></listitem>
829 <listitem><para>The number of bits per pixel component. All components are
830 transferred on the same number of bits. Common values are 8, 10 and 12.</para>
831 </listitem>
832 <listitem><para>The number of bus samples per pixel. Pixels that are wider than
833 the bus width must be transferred in multiple samples. Common values are
834 1, 1.5 (encoded as 1_5) and 2.</para></listitem>
835 <listitem><para>The bus width. When the bus width is larger than the number of
836 bits per pixel component, several components are packed in a single bus
837 sample. The components are ordered as specified by the order code, with
838 components on the left of the code transferred in the high order bits.
839 Common values are 8 and 16.</para>
840 </listitem>
841 </itemizedlist>
842 </para>
843
844 <para>For instance, a format where pixels are encoded as 8-bit YUV values
845 downsampled to 4:2:2 and transferred as 2 8-bit bus samples per pixel in the
846 U, Y, V, Y order will be named <constant>V4L2_MBUS_FMT_UYVY8_2X8</constant>.
847 </para>
848
849 <para>The following table lisst existing packet YUV formats.</para>
850
851 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-yuv8">
852 <title>YUV Formats</title>
853 <tgroup cols="23">
854 <colspec colname="id" align="left" />
855 <colspec colname="code" align="center"/>
856 <colspec colname="bit" />
857 <colspec colnum="4" colname="b19" align="center" />
858 <colspec colnum="5" colname="b18" align="center" />
859 <colspec colnum="6" colname="b17" align="center" />
860 <colspec colnum="7" colname="b16" align="center" />
861 <colspec colnum="8" colname="b15" align="center" />
862 <colspec colnum="9" colname="b14" align="center" />
863 <colspec colnum="10" colname="b13" align="center" />
864 <colspec colnum="11" colname="b12" align="center" />
865 <colspec colnum="12" colname="b11" align="center" />
866 <colspec colnum="13" colname="b10" align="center" />
867 <colspec colnum="14" colname="b09" align="center" />
868 <colspec colnum="15" colname="b08" align="center" />
869 <colspec colnum="16" colname="b07" align="center" />
870 <colspec colnum="17" colname="b06" align="center" />
871 <colspec colnum="18" colname="b05" align="center" />
872 <colspec colnum="19" colname="b04" align="center" />
873 <colspec colnum="20" colname="b03" align="center" />
874 <colspec colnum="21" colname="b02" align="center" />
875 <colspec colnum="22" colname="b01" align="center" />
876 <colspec colnum="23" colname="b00" align="center" />
877 <spanspec namest="b19" nameend="b00" spanname="b0" />
878 <thead>
879 <row>
880 <entry>Identifier</entry>
881 <entry>Code</entry>
882 <entry></entry>
883 <entry spanname="b0">Data organization</entry>
884 </row>
885 <row>
886 <entry></entry>
887 <entry></entry>
888 <entry>Bit</entry>
889 <entry>19</entry>
890 <entry>18</entry>
891 <entry>17</entry>
892 <entry>16</entry>
893 <entry>15</entry>
894 <entry>14</entry>
895 <entry>13</entry>
896 <entry>12</entry>
897 <entry>11</entry>
898 <entry>10</entry>
899 <entry>9</entry>
900 <entry>8</entry>
901 <entry>7</entry>
902 <entry>6</entry>
903 <entry>5</entry>
904 <entry>4</entry>
905 <entry>3</entry>
906 <entry>2</entry>
907 <entry>1</entry>
908 <entry>0</entry>
909 </row>
910 </thead>
911 <tbody valign="top">
912 <row id="V4L2-MBUS-FMT-Y8-1X8">
913 <entry>V4L2_MBUS_FMT_Y8_1X8</entry>
914 <entry>0x2001</entry>
915 <entry></entry>
916 <entry>-</entry>
917 <entry>-</entry>
918 <entry>-</entry>
919 <entry>-</entry>
920 <entry>-</entry>
921 <entry>-</entry>
922 <entry>-</entry>
923 <entry>-</entry>
924 <entry>-</entry>
925 <entry>-</entry>
926 <entry>-</entry>
927 <entry>-</entry>
928 <entry>y<subscript>7</subscript></entry>
929 <entry>y<subscript>6</subscript></entry>
930 <entry>y<subscript>5</subscript></entry>
931 <entry>y<subscript>4</subscript></entry>
932 <entry>y<subscript>3</subscript></entry>
933 <entry>y<subscript>2</subscript></entry>
934 <entry>y<subscript>1</subscript></entry>
935 <entry>y<subscript>0</subscript></entry>
936 </row>
937 <row id="V4L2-MBUS-FMT-UYVY8-1_5X8">
938 <entry>V4L2_MBUS_FMT_UYVY8_1_5X8</entry>
939 <entry>0x2002</entry>
940 <entry></entry>
941 <entry>-</entry>
942 <entry>-</entry>
943 <entry>-</entry>
944 <entry>-</entry>
945 <entry>-</entry>
946 <entry>-</entry>
947 <entry>-</entry>
948 <entry>-</entry>
949 <entry>-</entry>
950 <entry>-</entry>
951 <entry>-</entry>
952 <entry>-</entry>
953 <entry>u<subscript>7</subscript></entry>
954 <entry>u<subscript>6</subscript></entry>
955 <entry>u<subscript>5</subscript></entry>
956 <entry>u<subscript>4</subscript></entry>
957 <entry>u<subscript>3</subscript></entry>
958 <entry>u<subscript>2</subscript></entry>
959 <entry>u<subscript>1</subscript></entry>
960 <entry>u<subscript>0</subscript></entry>
961 </row>
962 <row>
963 <entry></entry>
964 <entry></entry>
965 <entry></entry>
966 <entry>-</entry>
967 <entry>-</entry>
968 <entry>-</entry>
969 <entry>-</entry>
970 <entry>-</entry>
971 <entry>-</entry>
972 <entry>-</entry>
973 <entry>-</entry>
974 <entry>-</entry>
975 <entry>-</entry>
976 <entry>-</entry>
977 <entry>-</entry>
978 <entry>y<subscript>7</subscript></entry>
979 <entry>y<subscript>6</subscript></entry>
980 <entry>y<subscript>5</subscript></entry>
981 <entry>y<subscript>4</subscript></entry>
982 <entry>y<subscript>3</subscript></entry>
983 <entry>y<subscript>2</subscript></entry>
984 <entry>y<subscript>1</subscript></entry>
985 <entry>y<subscript>0</subscript></entry>
986 </row>
987 <row>
988 <entry></entry>
989 <entry></entry>
990 <entry></entry>
991 <entry>-</entry>
992 <entry>-</entry>
993 <entry>-</entry>
994 <entry>-</entry>
995 <entry>-</entry>
996 <entry>-</entry>
997 <entry>-</entry>
998 <entry>-</entry>
999 <entry>-</entry>
1000 <entry>-</entry>
1001 <entry>-</entry>
1002 <entry>-</entry>
1003 <entry>y<subscript>7</subscript></entry>
1004 <entry>y<subscript>6</subscript></entry>
1005 <entry>y<subscript>5</subscript></entry>
1006 <entry>y<subscript>4</subscript></entry>
1007 <entry>y<subscript>3</subscript></entry>
1008 <entry>y<subscript>2</subscript></entry>
1009 <entry>y<subscript>1</subscript></entry>
1010 <entry>y<subscript>0</subscript></entry>
1011 </row>
1012 <row>
1013 <entry></entry>
1014 <entry></entry>
1015 <entry></entry>
1016 <entry>-</entry>
1017 <entry>-</entry>
1018 <entry>-</entry>
1019 <entry>-</entry>
1020 <entry>-</entry>
1021 <entry>-</entry>
1022 <entry>-</entry>
1023 <entry>-</entry>
1024 <entry>-</entry>
1025 <entry>-</entry>
1026 <entry>-</entry>
1027 <entry>-</entry>
1028 <entry>v<subscript>7</subscript></entry>
1029 <entry>v<subscript>6</subscript></entry>
1030 <entry>v<subscript>5</subscript></entry>
1031 <entry>v<subscript>4</subscript></entry>
1032 <entry>v<subscript>3</subscript></entry>
1033 <entry>v<subscript>2</subscript></entry>
1034 <entry>v<subscript>1</subscript></entry>
1035 <entry>v<subscript>0</subscript></entry>
1036 </row>
1037 <row>
1038 <entry></entry>
1039 <entry></entry>
1040 <entry></entry>
1041 <entry>-</entry>
1042 <entry>-</entry>
1043 <entry>-</entry>
1044 <entry>-</entry>
1045 <entry>-</entry>
1046 <entry>-</entry>
1047 <entry>-</entry>
1048 <entry>-</entry>
1049 <entry>-</entry>
1050 <entry>-</entry>
1051 <entry>-</entry>
1052 <entry>-</entry>
1053 <entry>y<subscript>7</subscript></entry>
1054 <entry>y<subscript>6</subscript></entry>
1055 <entry>y<subscript>5</subscript></entry>
1056 <entry>y<subscript>4</subscript></entry>
1057 <entry>y<subscript>3</subscript></entry>
1058 <entry>y<subscript>2</subscript></entry>
1059 <entry>y<subscript>1</subscript></entry>
1060 <entry>y<subscript>0</subscript></entry>
1061 </row>
1062 <row>
1063 <entry></entry>
1064 <entry></entry>
1065 <entry></entry>
1066 <entry>-</entry>
1067 <entry>-</entry>
1068 <entry>-</entry>
1069 <entry>-</entry>
1070 <entry>-</entry>
1071 <entry>-</entry>
1072 <entry>-</entry>
1073 <entry>-</entry>
1074 <entry>-</entry>
1075 <entry>-</entry>
1076 <entry>-</entry>
1077 <entry>-</entry>
1078 <entry>y<subscript>7</subscript></entry>
1079 <entry>y<subscript>6</subscript></entry>
1080 <entry>y<subscript>5</subscript></entry>
1081 <entry>y<subscript>4</subscript></entry>
1082 <entry>y<subscript>3</subscript></entry>
1083 <entry>y<subscript>2</subscript></entry>
1084 <entry>y<subscript>1</subscript></entry>
1085 <entry>y<subscript>0</subscript></entry>
1086 </row>
1087 <row id="V4L2-MBUS-FMT-VYUY8-1_5X8">
1088 <entry>V4L2_MBUS_FMT_VYUY8_1_5X8</entry>
1089 <entry>0x2003</entry>
1090 <entry></entry>
1091 <entry>-</entry>
1092 <entry>-</entry>
1093 <entry>-</entry>
1094 <entry>-</entry>
1095 <entry>-</entry>
1096 <entry>-</entry>
1097 <entry>-</entry>
1098 <entry>-</entry>
1099 <entry>-</entry>
1100 <entry>-</entry>
1101 <entry>-</entry>
1102 <entry>-</entry>
1103 <entry>v<subscript>7</subscript></entry>
1104 <entry>v<subscript>6</subscript></entry>
1105 <entry>v<subscript>5</subscript></entry>
1106 <entry>v<subscript>4</subscript></entry>
1107 <entry>v<subscript>3</subscript></entry>
1108 <entry>v<subscript>2</subscript></entry>
1109 <entry>v<subscript>1</subscript></entry>
1110 <entry>v<subscript>0</subscript></entry>
1111 </row>
1112 <row>
1113 <entry></entry>
1114 <entry></entry>
1115 <entry></entry>
1116 <entry>-</entry>
1117 <entry>-</entry>
1118 <entry>-</entry>
1119 <entry>-</entry>
1120 <entry>-</entry>
1121 <entry>-</entry>
1122 <entry>-</entry>
1123 <entry>-</entry>
1124 <entry>-</entry>
1125 <entry>-</entry>
1126 <entry>-</entry>
1127 <entry>-</entry>
1128 <entry>y<subscript>7</subscript></entry>
1129 <entry>y<subscript>6</subscript></entry>
1130 <entry>y<subscript>5</subscript></entry>
1131 <entry>y<subscript>4</subscript></entry>
1132 <entry>y<subscript>3</subscript></entry>
1133 <entry>y<subscript>2</subscript></entry>
1134 <entry>y<subscript>1</subscript></entry>
1135 <entry>y<subscript>0</subscript></entry>
1136 </row>
1137 <row>
1138 <entry></entry>
1139 <entry></entry>
1140 <entry></entry>
1141 <entry>-</entry>
1142 <entry>-</entry>
1143 <entry>-</entry>
1144 <entry>-</entry>
1145 <entry>-</entry>
1146 <entry>-</entry>
1147 <entry>-</entry>
1148 <entry>-</entry>
1149 <entry>-</entry>
1150 <entry>-</entry>
1151 <entry>-</entry>
1152 <entry>-</entry>
1153 <entry>y<subscript>7</subscript></entry>
1154 <entry>y<subscript>6</subscript></entry>
1155 <entry>y<subscript>5</subscript></entry>
1156 <entry>y<subscript>4</subscript></entry>
1157 <entry>y<subscript>3</subscript></entry>
1158 <entry>y<subscript>2</subscript></entry>
1159 <entry>y<subscript>1</subscript></entry>
1160 <entry>y<subscript>0</subscript></entry>
1161 </row>
1162 <row>
1163 <entry></entry>
1164 <entry></entry>
1165 <entry></entry>
1166 <entry>-</entry>
1167 <entry>-</entry>
1168 <entry>-</entry>
1169 <entry>-</entry>
1170 <entry>-</entry>
1171 <entry>-</entry>
1172 <entry>-</entry>
1173 <entry>-</entry>
1174 <entry>-</entry>
1175 <entry>-</entry>
1176 <entry>-</entry>
1177 <entry>-</entry>
1178 <entry>u<subscript>7</subscript></entry>
1179 <entry>u<subscript>6</subscript></entry>
1180 <entry>u<subscript>5</subscript></entry>
1181 <entry>u<subscript>4</subscript></entry>
1182 <entry>u<subscript>3</subscript></entry>
1183 <entry>u<subscript>2</subscript></entry>
1184 <entry>u<subscript>1</subscript></entry>
1185 <entry>u<subscript>0</subscript></entry>
1186 </row>
1187 <row>
1188 <entry></entry>
1189 <entry></entry>
1190 <entry></entry>
1191 <entry>-</entry>
1192 <entry>-</entry>
1193 <entry>-</entry>
1194 <entry>-</entry>
1195 <entry>-</entry>
1196 <entry>-</entry>
1197 <entry>-</entry>
1198 <entry>-</entry>
1199 <entry>-</entry>
1200 <entry>-</entry>
1201 <entry>-</entry>
1202 <entry>-</entry>
1203 <entry>y<subscript>7</subscript></entry>
1204 <entry>y<subscript>6</subscript></entry>
1205 <entry>y<subscript>5</subscript></entry>
1206 <entry>y<subscript>4</subscript></entry>
1207 <entry>y<subscript>3</subscript></entry>
1208 <entry>y<subscript>2</subscript></entry>
1209 <entry>y<subscript>1</subscript></entry>
1210 <entry>y<subscript>0</subscript></entry>
1211 </row>
1212 <row>
1213 <entry></entry>
1214 <entry></entry>
1215 <entry></entry>
1216 <entry>-</entry>
1217 <entry>-</entry>
1218 <entry>-</entry>
1219 <entry>-</entry>
1220 <entry>-</entry>
1221 <entry>-</entry>
1222 <entry>-</entry>
1223 <entry>-</entry>
1224 <entry>-</entry>
1225 <entry>-</entry>
1226 <entry>-</entry>
1227 <entry>-</entry>
1228 <entry>y<subscript>7</subscript></entry>
1229 <entry>y<subscript>6</subscript></entry>
1230 <entry>y<subscript>5</subscript></entry>
1231 <entry>y<subscript>4</subscript></entry>
1232 <entry>y<subscript>3</subscript></entry>
1233 <entry>y<subscript>2</subscript></entry>
1234 <entry>y<subscript>1</subscript></entry>
1235 <entry>y<subscript>0</subscript></entry>
1236 </row>
1237 <row id="V4L2-MBUS-FMT-YUYV8-1_5X8">
1238 <entry>V4L2_MBUS_FMT_YUYV8_1_5X8</entry>
1239 <entry>0x2004</entry>
1240 <entry></entry>
1241 <entry>-</entry>
1242 <entry>-</entry>
1243 <entry>-</entry>
1244 <entry>-</entry>
1245 <entry>-</entry>
1246 <entry>-</entry>
1247 <entry>-</entry>
1248 <entry>-</entry>
1249 <entry>-</entry>
1250 <entry>-</entry>
1251 <entry>-</entry>
1252 <entry>-</entry>
1253 <entry>y<subscript>7</subscript></entry>
1254 <entry>y<subscript>6</subscript></entry>
1255 <entry>y<subscript>5</subscript></entry>
1256 <entry>y<subscript>4</subscript></entry>
1257 <entry>y<subscript>3</subscript></entry>
1258 <entry>y<subscript>2</subscript></entry>
1259 <entry>y<subscript>1</subscript></entry>
1260 <entry>y<subscript>0</subscript></entry>
1261 </row>
1262 <row>
1263 <entry></entry>
1264 <entry></entry>
1265 <entry></entry>
1266 <entry>-</entry>
1267 <entry>-</entry>
1268 <entry>-</entry>
1269 <entry>-</entry>
1270 <entry>-</entry>
1271 <entry>-</entry>
1272 <entry>-</entry>
1273 <entry>-</entry>
1274 <entry>-</entry>
1275 <entry>-</entry>
1276 <entry>-</entry>
1277 <entry>-</entry>
1278 <entry>y<subscript>7</subscript></entry>
1279 <entry>y<subscript>6</subscript></entry>
1280 <entry>y<subscript>5</subscript></entry>
1281 <entry>y<subscript>4</subscript></entry>
1282 <entry>y<subscript>3</subscript></entry>
1283 <entry>y<subscript>2</subscript></entry>
1284 <entry>y<subscript>1</subscript></entry>
1285 <entry>y<subscript>0</subscript></entry>
1286 </row>
1287 <row>
1288 <entry></entry>
1289 <entry></entry>
1290 <entry></entry>
1291 <entry>-</entry>
1292 <entry>-</entry>
1293 <entry>-</entry>
1294 <entry>-</entry>
1295 <entry>-</entry>
1296 <entry>-</entry>
1297 <entry>-</entry>
1298 <entry>-</entry>
1299 <entry>-</entry>
1300 <entry>-</entry>
1301 <entry>-</entry>
1302 <entry>-</entry>
1303 <entry>u<subscript>7</subscript></entry>
1304 <entry>u<subscript>6</subscript></entry>
1305 <entry>u<subscript>5</subscript></entry>
1306 <entry>u<subscript>4</subscript></entry>
1307 <entry>u<subscript>3</subscript></entry>
1308 <entry>u<subscript>2</subscript></entry>
1309 <entry>u<subscript>1</subscript></entry>
1310 <entry>u<subscript>0</subscript></entry>
1311 </row>
1312 <row>
1313 <entry></entry>
1314 <entry></entry>
1315 <entry></entry>
1316 <entry>-</entry>
1317 <entry>-</entry>
1318 <entry>-</entry>
1319 <entry>-</entry>
1320 <entry>-</entry>
1321 <entry>-</entry>
1322 <entry>-</entry>
1323 <entry>-</entry>
1324 <entry>-</entry>
1325 <entry>-</entry>
1326 <entry>-</entry>
1327 <entry>-</entry>
1328 <entry>y<subscript>7</subscript></entry>
1329 <entry>y<subscript>6</subscript></entry>
1330 <entry>y<subscript>5</subscript></entry>
1331 <entry>y<subscript>4</subscript></entry>
1332 <entry>y<subscript>3</subscript></entry>
1333 <entry>y<subscript>2</subscript></entry>
1334 <entry>y<subscript>1</subscript></entry>
1335 <entry>y<subscript>0</subscript></entry>
1336 </row>
1337 <row>
1338 <entry></entry>
1339 <entry></entry>
1340 <entry></entry>
1341 <entry>-</entry>
1342 <entry>-</entry>
1343 <entry>-</entry>
1344 <entry>-</entry>
1345 <entry>-</entry>
1346 <entry>-</entry>
1347 <entry>-</entry>
1348 <entry>-</entry>
1349 <entry>-</entry>
1350 <entry>-</entry>
1351 <entry>-</entry>
1352 <entry>-</entry>
1353 <entry>y<subscript>7</subscript></entry>
1354 <entry>y<subscript>6</subscript></entry>
1355 <entry>y<subscript>5</subscript></entry>
1356 <entry>y<subscript>4</subscript></entry>
1357 <entry>y<subscript>3</subscript></entry>
1358 <entry>y<subscript>2</subscript></entry>
1359 <entry>y<subscript>1</subscript></entry>
1360 <entry>y<subscript>0</subscript></entry>
1361 </row>
1362 <row>
1363 <entry></entry>
1364 <entry></entry>
1365 <entry></entry>
1366 <entry>-</entry>
1367 <entry>-</entry>
1368 <entry>-</entry>
1369 <entry>-</entry>
1370 <entry>-</entry>
1371 <entry>-</entry>
1372 <entry>-</entry>
1373 <entry>-</entry>
1374 <entry>-</entry>
1375 <entry>-</entry>
1376 <entry>-</entry>
1377 <entry>-</entry>
1378 <entry>v<subscript>7</subscript></entry>
1379 <entry>v<subscript>6</subscript></entry>
1380 <entry>v<subscript>5</subscript></entry>
1381 <entry>v<subscript>4</subscript></entry>
1382 <entry>v<subscript>3</subscript></entry>
1383 <entry>v<subscript>2</subscript></entry>
1384 <entry>v<subscript>1</subscript></entry>
1385 <entry>v<subscript>0</subscript></entry>
1386 </row>
1387 <row id="V4L2-MBUS-FMT-YVYU8-1_5X8">
1388 <entry>V4L2_MBUS_FMT_YVYU8_1_5X8</entry>
1389 <entry>0x2005</entry>
1390 <entry></entry>
1391 <entry>-</entry>
1392 <entry>-</entry>
1393 <entry>-</entry>
1394 <entry>-</entry>
1395 <entry>-</entry>
1396 <entry>-</entry>
1397 <entry>-</entry>
1398 <entry>-</entry>
1399 <entry>-</entry>
1400 <entry>-</entry>
1401 <entry>-</entry>
1402 <entry>-</entry>
1403 <entry>y<subscript>7</subscript></entry>
1404 <entry>y<subscript>6</subscript></entry>
1405 <entry>y<subscript>5</subscript></entry>
1406 <entry>y<subscript>4</subscript></entry>
1407 <entry>y<subscript>3</subscript></entry>
1408 <entry>y<subscript>2</subscript></entry>
1409 <entry>y<subscript>1</subscript></entry>
1410 <entry>y<subscript>0</subscript></entry>
1411 </row>
1412 <row>
1413 <entry></entry>
1414 <entry></entry>
1415 <entry></entry>
1416 <entry>-</entry>
1417 <entry>-</entry>
1418 <entry>-</entry>
1419 <entry>-</entry>
1420 <entry>-</entry>
1421 <entry>-</entry>
1422 <entry>-</entry>
1423 <entry>-</entry>
1424 <entry>-</entry>
1425 <entry>-</entry>
1426 <entry>-</entry>
1427 <entry>-</entry>
1428 <entry>y<subscript>7</subscript></entry>
1429 <entry>y<subscript>6</subscript></entry>
1430 <entry>y<subscript>5</subscript></entry>
1431 <entry>y<subscript>4</subscript></entry>
1432 <entry>y<subscript>3</subscript></entry>
1433 <entry>y<subscript>2</subscript></entry>
1434 <entry>y<subscript>1</subscript></entry>
1435 <entry>y<subscript>0</subscript></entry>
1436 </row>
1437 <row>
1438 <entry></entry>
1439 <entry></entry>
1440 <entry></entry>
1441 <entry>-</entry>
1442 <entry>-</entry>
1443 <entry>-</entry>
1444 <entry>-</entry>
1445 <entry>-</entry>
1446 <entry>-</entry>
1447 <entry>-</entry>
1448 <entry>-</entry>
1449 <entry>-</entry>
1450 <entry>-</entry>
1451 <entry>-</entry>
1452 <entry>-</entry>
1453 <entry>v<subscript>7</subscript></entry>
1454 <entry>v<subscript>6</subscript></entry>
1455 <entry>v<subscript>5</subscript></entry>
1456 <entry>v<subscript>4</subscript></entry>
1457 <entry>v<subscript>3</subscript></entry>
1458 <entry>v<subscript>2</subscript></entry>
1459 <entry>v<subscript>1</subscript></entry>
1460 <entry>v<subscript>0</subscript></entry>
1461 </row>
1462 <row>
1463 <entry></entry>
1464 <entry></entry>
1465 <entry></entry>
1466 <entry>-</entry>
1467 <entry>-</entry>
1468 <entry>-</entry>
1469 <entry>-</entry>
1470 <entry>-</entry>
1471 <entry>-</entry>
1472 <entry>-</entry>
1473 <entry>-</entry>
1474 <entry>-</entry>
1475 <entry>-</entry>
1476 <entry>-</entry>
1477 <entry>-</entry>
1478 <entry>y<subscript>7</subscript></entry>
1479 <entry>y<subscript>6</subscript></entry>
1480 <entry>y<subscript>5</subscript></entry>
1481 <entry>y<subscript>4</subscript></entry>
1482 <entry>y<subscript>3</subscript></entry>
1483 <entry>y<subscript>2</subscript></entry>
1484 <entry>y<subscript>1</subscript></entry>
1485 <entry>y<subscript>0</subscript></entry>
1486 </row>
1487 <row>
1488 <entry></entry>
1489 <entry></entry>
1490 <entry></entry>
1491 <entry>-</entry>
1492 <entry>-</entry>
1493 <entry>-</entry>
1494 <entry>-</entry>
1495 <entry>-</entry>
1496 <entry>-</entry>
1497 <entry>-</entry>
1498 <entry>-</entry>
1499 <entry>-</entry>
1500 <entry>-</entry>
1501 <entry>-</entry>
1502 <entry>-</entry>
1503 <entry>y<subscript>7</subscript></entry>
1504 <entry>y<subscript>6</subscript></entry>
1505 <entry>y<subscript>5</subscript></entry>
1506 <entry>y<subscript>4</subscript></entry>
1507 <entry>y<subscript>3</subscript></entry>
1508 <entry>y<subscript>2</subscript></entry>
1509 <entry>y<subscript>1</subscript></entry>
1510 <entry>y<subscript>0</subscript></entry>
1511 </row>
1512 <row>
1513 <entry></entry>
1514 <entry></entry>
1515 <entry></entry>
1516 <entry>-</entry>
1517 <entry>-</entry>
1518 <entry>-</entry>
1519 <entry>-</entry>
1520 <entry>-</entry>
1521 <entry>-</entry>
1522 <entry>-</entry>
1523 <entry>-</entry>
1524 <entry>-</entry>
1525 <entry>-</entry>
1526 <entry>-</entry>
1527 <entry>-</entry>
1528 <entry>u<subscript>7</subscript></entry>
1529 <entry>u<subscript>6</subscript></entry>
1530 <entry>u<subscript>5</subscript></entry>
1531 <entry>u<subscript>4</subscript></entry>
1532 <entry>u<subscript>3</subscript></entry>
1533 <entry>u<subscript>2</subscript></entry>
1534 <entry>u<subscript>1</subscript></entry>
1535 <entry>u<subscript>0</subscript></entry>
1536 </row>
1537 <row id="V4L2-MBUS-FMT-UYVY8-2X8">
1538 <entry>V4L2_MBUS_FMT_UYVY8_2X8</entry>
1539 <entry>0x2006</entry>
1540 <entry></entry>
1541 <entry>-</entry>
1542 <entry>-</entry>
1543 <entry>-</entry>
1544 <entry>-</entry>
1545 <entry>-</entry>
1546 <entry>-</entry>
1547 <entry>-</entry>
1548 <entry>-</entry>
1549 <entry>-</entry>
1550 <entry>-</entry>
1551 <entry>-</entry>
1552 <entry>-</entry>
1553 <entry>u<subscript>7</subscript></entry>
1554 <entry>u<subscript>6</subscript></entry>
1555 <entry>u<subscript>5</subscript></entry>
1556 <entry>u<subscript>4</subscript></entry>
1557 <entry>u<subscript>3</subscript></entry>
1558 <entry>u<subscript>2</subscript></entry>
1559 <entry>u<subscript>1</subscript></entry>
1560 <entry>u<subscript>0</subscript></entry>
1561 </row>
1562 <row>
1563 <entry></entry>
1564 <entry></entry>
1565 <entry></entry>
1566 <entry>-</entry>
1567 <entry>-</entry>
1568 <entry>-</entry>
1569 <entry>-</entry>
1570 <entry>-</entry>
1571 <entry>-</entry>
1572 <entry>-</entry>
1573 <entry>-</entry>
1574 <entry>-</entry>
1575 <entry>-</entry>
1576 <entry>-</entry>
1577 <entry>-</entry>
1578 <entry>y<subscript>7</subscript></entry>
1579 <entry>y<subscript>6</subscript></entry>
1580 <entry>y<subscript>5</subscript></entry>
1581 <entry>y<subscript>4</subscript></entry>
1582 <entry>y<subscript>3</subscript></entry>
1583 <entry>y<subscript>2</subscript></entry>
1584 <entry>y<subscript>1</subscript></entry>
1585 <entry>y<subscript>0</subscript></entry>
1586 </row>
1587 <row>
1588 <entry></entry>
1589 <entry></entry>
1590 <entry></entry>
1591 <entry>-</entry>
1592 <entry>-</entry>
1593 <entry>-</entry>
1594 <entry>-</entry>
1595 <entry>-</entry>
1596 <entry>-</entry>
1597 <entry>-</entry>
1598 <entry>-</entry>
1599 <entry>-</entry>
1600 <entry>-</entry>
1601 <entry>-</entry>
1602 <entry>-</entry>
1603 <entry>v<subscript>7</subscript></entry>
1604 <entry>v<subscript>6</subscript></entry>
1605 <entry>v<subscript>5</subscript></entry>
1606 <entry>v<subscript>4</subscript></entry>
1607 <entry>v<subscript>3</subscript></entry>
1608 <entry>v<subscript>2</subscript></entry>
1609 <entry>v<subscript>1</subscript></entry>
1610 <entry>v<subscript>0</subscript></entry>
1611 </row>
1612 <row>
1613 <entry></entry>
1614 <entry></entry>
1615 <entry></entry>
1616 <entry>-</entry>
1617 <entry>-</entry>
1618 <entry>-</entry>
1619 <entry>-</entry>
1620 <entry>-</entry>
1621 <entry>-</entry>
1622 <entry>-</entry>
1623 <entry>-</entry>
1624 <entry>-</entry>
1625 <entry>-</entry>
1626 <entry>-</entry>
1627 <entry>-</entry>
1628 <entry>y<subscript>7</subscript></entry>
1629 <entry>y<subscript>6</subscript></entry>
1630 <entry>y<subscript>5</subscript></entry>
1631 <entry>y<subscript>4</subscript></entry>
1632 <entry>y<subscript>3</subscript></entry>
1633 <entry>y<subscript>2</subscript></entry>
1634 <entry>y<subscript>1</subscript></entry>
1635 <entry>y<subscript>0</subscript></entry>
1636 </row>
1637 <row id="V4L2-MBUS-FMT-VYUY8-2X8">
1638 <entry>V4L2_MBUS_FMT_VYUY8_2X8</entry>
1639 <entry>0x2007</entry>
1640 <entry></entry>
1641 <entry>-</entry>
1642 <entry>-</entry>
1643 <entry>-</entry>
1644 <entry>-</entry>
1645 <entry>-</entry>
1646 <entry>-</entry>
1647 <entry>-</entry>
1648 <entry>-</entry>
1649 <entry>-</entry>
1650 <entry>-</entry>
1651 <entry>-</entry>
1652 <entry>-</entry>
1653 <entry>v<subscript>7</subscript></entry>
1654 <entry>v<subscript>6</subscript></entry>
1655 <entry>v<subscript>5</subscript></entry>
1656 <entry>v<subscript>4</subscript></entry>
1657 <entry>v<subscript>3</subscript></entry>
1658 <entry>v<subscript>2</subscript></entry>
1659 <entry>v<subscript>1</subscript></entry>
1660 <entry>v<subscript>0</subscript></entry>
1661 </row>
1662 <row>
1663 <entry></entry>
1664 <entry></entry>
1665 <entry></entry>
1666 <entry>-</entry>
1667 <entry>-</entry>
1668 <entry>-</entry>
1669 <entry>-</entry>
1670 <entry>-</entry>
1671 <entry>-</entry>
1672 <entry>-</entry>
1673 <entry>-</entry>
1674 <entry>-</entry>
1675 <entry>-</entry>
1676 <entry>-</entry>
1677 <entry>-</entry>
1678 <entry>y<subscript>7</subscript></entry>
1679 <entry>y<subscript>6</subscript></entry>
1680 <entry>y<subscript>5</subscript></entry>
1681 <entry>y<subscript>4</subscript></entry>
1682 <entry>y<subscript>3</subscript></entry>
1683 <entry>y<subscript>2</subscript></entry>
1684 <entry>y<subscript>1</subscript></entry>
1685 <entry>y<subscript>0</subscript></entry>
1686 </row>
1687 <row>
1688 <entry></entry>
1689 <entry></entry>
1690 <entry></entry>
1691 <entry>-</entry>
1692 <entry>-</entry>
1693 <entry>-</entry>
1694 <entry>-</entry>
1695 <entry>-</entry>
1696 <entry>-</entry>
1697 <entry>-</entry>
1698 <entry>-</entry>
1699 <entry>-</entry>
1700 <entry>-</entry>
1701 <entry>-</entry>
1702 <entry>-</entry>
1703 <entry>u<subscript>7</subscript></entry>
1704 <entry>u<subscript>6</subscript></entry>
1705 <entry>u<subscript>5</subscript></entry>
1706 <entry>u<subscript>4</subscript></entry>
1707 <entry>u<subscript>3</subscript></entry>
1708 <entry>u<subscript>2</subscript></entry>
1709 <entry>u<subscript>1</subscript></entry>
1710 <entry>u<subscript>0</subscript></entry>
1711 </row>
1712 <row>
1713 <entry></entry>
1714 <entry></entry>
1715 <entry></entry>
1716 <entry>-</entry>
1717 <entry>-</entry>
1718 <entry>-</entry>
1719 <entry>-</entry>
1720 <entry>-</entry>
1721 <entry>-</entry>
1722 <entry>-</entry>
1723 <entry>-</entry>
1724 <entry>-</entry>
1725 <entry>-</entry>
1726 <entry>-</entry>
1727 <entry>-</entry>
1728 <entry>y<subscript>7</subscript></entry>
1729 <entry>y<subscript>6</subscript></entry>
1730 <entry>y<subscript>5</subscript></entry>
1731 <entry>y<subscript>4</subscript></entry>
1732 <entry>y<subscript>3</subscript></entry>
1733 <entry>y<subscript>2</subscript></entry>
1734 <entry>y<subscript>1</subscript></entry>
1735 <entry>y<subscript>0</subscript></entry>
1736 </row>
1737 <row id="V4L2-MBUS-FMT-YUYV8-2X8">
1738 <entry>V4L2_MBUS_FMT_YUYV8_2X8</entry>
1739 <entry>0x2008</entry>
1740 <entry></entry>
1741 <entry>-</entry>
1742 <entry>-</entry>
1743 <entry>-</entry>
1744 <entry>-</entry>
1745 <entry>-</entry>
1746 <entry>-</entry>
1747 <entry>-</entry>
1748 <entry>-</entry>
1749 <entry>-</entry>
1750 <entry>-</entry>
1751 <entry>-</entry>
1752 <entry>-</entry>
1753 <entry>y<subscript>7</subscript></entry>
1754 <entry>y<subscript>6</subscript></entry>
1755 <entry>y<subscript>5</subscript></entry>
1756 <entry>y<subscript>4</subscript></entry>
1757 <entry>y<subscript>3</subscript></entry>
1758 <entry>y<subscript>2</subscript></entry>
1759 <entry>y<subscript>1</subscript></entry>
1760 <entry>y<subscript>0</subscript></entry>
1761 </row>
1762 <row>
1763 <entry></entry>
1764 <entry></entry>
1765 <entry></entry>
1766 <entry>-</entry>
1767 <entry>-</entry>
1768 <entry>-</entry>
1769 <entry>-</entry>
1770 <entry>-</entry>
1771 <entry>-</entry>
1772 <entry>-</entry>
1773 <entry>-</entry>
1774 <entry>-</entry>
1775 <entry>-</entry>
1776 <entry>-</entry>
1777 <entry>-</entry>
1778 <entry>u<subscript>7</subscript></entry>
1779 <entry>u<subscript>6</subscript></entry>
1780 <entry>u<subscript>5</subscript></entry>
1781 <entry>u<subscript>4</subscript></entry>
1782 <entry>u<subscript>3</subscript></entry>
1783 <entry>u<subscript>2</subscript></entry>
1784 <entry>u<subscript>1</subscript></entry>
1785 <entry>u<subscript>0</subscript></entry>
1786 </row>
1787 <row>
1788 <entry></entry>
1789 <entry></entry>
1790 <entry></entry>
1791 <entry>-</entry>
1792 <entry>-</entry>
1793 <entry>-</entry>
1794 <entry>-</entry>
1795 <entry>-</entry>
1796 <entry>-</entry>
1797 <entry>-</entry>
1798 <entry>-</entry>
1799 <entry>-</entry>
1800 <entry>-</entry>
1801 <entry>-</entry>
1802 <entry>-</entry>
1803 <entry>y<subscript>7</subscript></entry>
1804 <entry>y<subscript>6</subscript></entry>
1805 <entry>y<subscript>5</subscript></entry>
1806 <entry>y<subscript>4</subscript></entry>
1807 <entry>y<subscript>3</subscript></entry>
1808 <entry>y<subscript>2</subscript></entry>
1809 <entry>y<subscript>1</subscript></entry>
1810 <entry>y<subscript>0</subscript></entry>
1811 </row>
1812 <row>
1813 <entry></entry>
1814 <entry></entry>
1815 <entry></entry>
1816 <entry>-</entry>
1817 <entry>-</entry>
1818 <entry>-</entry>
1819 <entry>-</entry>
1820 <entry>-</entry>
1821 <entry>-</entry>
1822 <entry>-</entry>
1823 <entry>-</entry>
1824 <entry>-</entry>
1825 <entry>-</entry>
1826 <entry>-</entry>
1827 <entry>-</entry>
1828 <entry>v<subscript>7</subscript></entry>
1829 <entry>v<subscript>6</subscript></entry>
1830 <entry>v<subscript>5</subscript></entry>
1831 <entry>v<subscript>4</subscript></entry>
1832 <entry>v<subscript>3</subscript></entry>
1833 <entry>v<subscript>2</subscript></entry>
1834 <entry>v<subscript>1</subscript></entry>
1835 <entry>v<subscript>0</subscript></entry>
1836 </row>
1837 <row id="V4L2-MBUS-FMT-YVYU8-2X8">
1838 <entry>V4L2_MBUS_FMT_YVYU8_2X8</entry>
1839 <entry>0x2009</entry>
1840 <entry></entry>
1841 <entry>-</entry>
1842 <entry>-</entry>
1843 <entry>-</entry>
1844 <entry>-</entry>
1845 <entry>-</entry>
1846 <entry>-</entry>
1847 <entry>-</entry>
1848 <entry>-</entry>
1849 <entry>-</entry>
1850 <entry>-</entry>
1851 <entry>-</entry>
1852 <entry>-</entry>
1853 <entry>y<subscript>7</subscript></entry>
1854 <entry>y<subscript>6</subscript></entry>
1855 <entry>y<subscript>5</subscript></entry>
1856 <entry>y<subscript>4</subscript></entry>
1857 <entry>y<subscript>3</subscript></entry>
1858 <entry>y<subscript>2</subscript></entry>
1859 <entry>y<subscript>1</subscript></entry>
1860 <entry>y<subscript>0</subscript></entry>
1861 </row>
1862 <row>
1863 <entry></entry>
1864 <entry></entry>
1865 <entry></entry>
1866 <entry>-</entry>
1867 <entry>-</entry>
1868 <entry>-</entry>
1869 <entry>-</entry>
1870 <entry>-</entry>
1871 <entry>-</entry>
1872 <entry>-</entry>
1873 <entry>-</entry>
1874 <entry>-</entry>
1875 <entry>-</entry>
1876 <entry>-</entry>
1877 <entry>-</entry>
1878 <entry>v<subscript>7</subscript></entry>
1879 <entry>v<subscript>6</subscript></entry>
1880 <entry>v<subscript>5</subscript></entry>
1881 <entry>v<subscript>4</subscript></entry>
1882 <entry>v<subscript>3</subscript></entry>
1883 <entry>v<subscript>2</subscript></entry>
1884 <entry>v<subscript>1</subscript></entry>
1885 <entry>v<subscript>0</subscript></entry>
1886 </row>
1887 <row>
1888 <entry></entry>
1889 <entry></entry>
1890 <entry></entry>
1891 <entry>-</entry>
1892 <entry>-</entry>
1893 <entry>-</entry>
1894 <entry>-</entry>
1895 <entry>-</entry>
1896 <entry>-</entry>
1897 <entry>-</entry>
1898 <entry>-</entry>
1899 <entry>-</entry>
1900 <entry>-</entry>
1901 <entry>-</entry>
1902 <entry>-</entry>
1903 <entry>y<subscript>7</subscript></entry>
1904 <entry>y<subscript>6</subscript></entry>
1905 <entry>y<subscript>5</subscript></entry>
1906 <entry>y<subscript>4</subscript></entry>
1907 <entry>y<subscript>3</subscript></entry>
1908 <entry>y<subscript>2</subscript></entry>
1909 <entry>y<subscript>1</subscript></entry>
1910 <entry>y<subscript>0</subscript></entry>
1911 </row>
1912 <row>
1913 <entry></entry>
1914 <entry></entry>
1915 <entry></entry>
1916 <entry>-</entry>
1917 <entry>-</entry>
1918 <entry>-</entry>
1919 <entry>-</entry>
1920 <entry>-</entry>
1921 <entry>-</entry>
1922 <entry>-</entry>
1923 <entry>-</entry>
1924 <entry>-</entry>
1925 <entry>-</entry>
1926 <entry>-</entry>
1927 <entry>-</entry>
1928 <entry>u<subscript>7</subscript></entry>
1929 <entry>u<subscript>6</subscript></entry>
1930 <entry>u<subscript>5</subscript></entry>
1931 <entry>u<subscript>4</subscript></entry>
1932 <entry>u<subscript>3</subscript></entry>
1933 <entry>u<subscript>2</subscript></entry>
1934 <entry>u<subscript>1</subscript></entry>
1935 <entry>u<subscript>0</subscript></entry>
1936 </row>
1937 <row id="V4L2-MBUS-FMT-Y10-1X10">
1938 <entry>V4L2_MBUS_FMT_Y10_1X10</entry>
1939 <entry>0x200a</entry>
1940 <entry></entry>
1941 <entry>-</entry>
1942 <entry>-</entry>
1943 <entry>-</entry>
1944 <entry>-</entry>
1945 <entry>-</entry>
1946 <entry>-</entry>
1947 <entry>-</entry>
1948 <entry>-</entry>
1949 <entry>-</entry>
1950 <entry>-</entry>
1951 <entry>y<subscript>9</subscript></entry>
1952 <entry>y<subscript>8</subscript></entry>
1953 <entry>y<subscript>7</subscript></entry>
1954 <entry>y<subscript>6</subscript></entry>
1955 <entry>y<subscript>5</subscript></entry>
1956 <entry>y<subscript>4</subscript></entry>
1957 <entry>y<subscript>3</subscript></entry>
1958 <entry>y<subscript>2</subscript></entry>
1959 <entry>y<subscript>1</subscript></entry>
1960 <entry>y<subscript>0</subscript></entry>
1961 </row>
1962 <row id="V4L2-MBUS-FMT-YUYV10-2X10">
1963 <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry>
1964 <entry>0x200b</entry>
1965 <entry></entry>
1966 <entry>-</entry>
1967 <entry>-</entry>
1968 <entry>-</entry>
1969 <entry>-</entry>
1970 <entry>-</entry>
1971 <entry>-</entry>
1972 <entry>-</entry>
1973 <entry>-</entry>
1974 <entry>-</entry>
1975 <entry>-</entry>
1976 <entry>y<subscript>9</subscript></entry>
1977 <entry>y<subscript>8</subscript></entry>
1978 <entry>y<subscript>7</subscript></entry>
1979 <entry>y<subscript>6</subscript></entry>
1980 <entry>y<subscript>5</subscript></entry>
1981 <entry>y<subscript>4</subscript></entry>
1982 <entry>y<subscript>3</subscript></entry>
1983 <entry>y<subscript>2</subscript></entry>
1984 <entry>y<subscript>1</subscript></entry>
1985 <entry>y<subscript>0</subscript></entry>
1986 </row>
1987 <row>
1988 <entry></entry>
1989 <entry></entry>
1990 <entry></entry>
1991 <entry>-</entry>
1992 <entry>-</entry>
1993 <entry>-</entry>
1994 <entry>-</entry>
1995 <entry>-</entry>
1996 <entry>-</entry>
1997 <entry>-</entry>
1998 <entry>-</entry>
1999 <entry>-</entry>
2000 <entry>-</entry>
2001 <entry>u<subscript>9</subscript></entry>
2002 <entry>u<subscript>8</subscript></entry>
2003 <entry>u<subscript>7</subscript></entry>
2004 <entry>u<subscript>6</subscript></entry>
2005 <entry>u<subscript>5</subscript></entry>
2006 <entry>u<subscript>4</subscript></entry>
2007 <entry>u<subscript>3</subscript></entry>
2008 <entry>u<subscript>2</subscript></entry>
2009 <entry>u<subscript>1</subscript></entry>
2010 <entry>u<subscript>0</subscript></entry>
2011 </row>
2012 <row>
2013 <entry></entry>
2014 <entry></entry>
2015 <entry></entry>
2016 <entry>-</entry>
2017 <entry>-</entry>
2018 <entry>-</entry>
2019 <entry>-</entry>
2020 <entry>-</entry>
2021 <entry>-</entry>
2022 <entry>-</entry>
2023 <entry>-</entry>
2024 <entry>-</entry>
2025 <entry>-</entry>
2026 <entry>y<subscript>9</subscript></entry>
2027 <entry>y<subscript>8</subscript></entry>
2028 <entry>y<subscript>7</subscript></entry>
2029 <entry>y<subscript>6</subscript></entry>
2030 <entry>y<subscript>5</subscript></entry>
2031 <entry>y<subscript>4</subscript></entry>
2032 <entry>y<subscript>3</subscript></entry>
2033 <entry>y<subscript>2</subscript></entry>
2034 <entry>y<subscript>1</subscript></entry>
2035 <entry>y<subscript>0</subscript></entry>
2036 </row>
2037 <row>
2038 <entry></entry>
2039 <entry></entry>
2040 <entry></entry>
2041 <entry>-</entry>
2042 <entry>-</entry>
2043 <entry>-</entry>
2044 <entry>-</entry>
2045 <entry>-</entry>
2046 <entry>-</entry>
2047 <entry>-</entry>
2048 <entry>-</entry>
2049 <entry>-</entry>
2050 <entry>-</entry>
2051 <entry>v<subscript>9</subscript></entry>
2052 <entry>v<subscript>8</subscript></entry>
2053 <entry>v<subscript>7</subscript></entry>
2054 <entry>v<subscript>6</subscript></entry>
2055 <entry>v<subscript>5</subscript></entry>
2056 <entry>v<subscript>4</subscript></entry>
2057 <entry>v<subscript>3</subscript></entry>
2058 <entry>v<subscript>2</subscript></entry>
2059 <entry>v<subscript>1</subscript></entry>
2060 <entry>v<subscript>0</subscript></entry>
2061 </row>
2062 <row id="V4L2-MBUS-FMT-YVYU10-2X10">
2063 <entry>V4L2_MBUS_FMT_YVYU10_2X10</entry>
2064 <entry>0x200c</entry>
2065 <entry></entry>
2066 <entry>-</entry>
2067 <entry>-</entry>
2068 <entry>-</entry>
2069 <entry>-</entry>
2070 <entry>-</entry>
2071 <entry>-</entry>
2072 <entry>-</entry>
2073 <entry>-</entry>
2074 <entry>-</entry>
2075 <entry>-</entry>
2076 <entry>y<subscript>9</subscript></entry>
2077 <entry>y<subscript>8</subscript></entry>
2078 <entry>y<subscript>7</subscript></entry>
2079 <entry>y<subscript>6</subscript></entry>
2080 <entry>y<subscript>5</subscript></entry>
2081 <entry>y<subscript>4</subscript></entry>
2082 <entry>y<subscript>3</subscript></entry>
2083 <entry>y<subscript>2</subscript></entry>
2084 <entry>y<subscript>1</subscript></entry>
2085 <entry>y<subscript>0</subscript></entry>
2086 </row>
2087 <row>
2088 <entry></entry>
2089 <entry></entry>
2090 <entry></entry>
2091 <entry>-</entry>
2092 <entry>-</entry>
2093 <entry>-</entry>
2094 <entry>-</entry>
2095 <entry>-</entry>
2096 <entry>-</entry>
2097 <entry>-</entry>
2098 <entry>-</entry>
2099 <entry>-</entry>
2100 <entry>-</entry>
2101 <entry>v<subscript>9</subscript></entry>
2102 <entry>v<subscript>8</subscript></entry>
2103 <entry>v<subscript>7</subscript></entry>
2104 <entry>v<subscript>6</subscript></entry>
2105 <entry>v<subscript>5</subscript></entry>
2106 <entry>v<subscript>4</subscript></entry>
2107 <entry>v<subscript>3</subscript></entry>
2108 <entry>v<subscript>2</subscript></entry>
2109 <entry>v<subscript>1</subscript></entry>
2110 <entry>v<subscript>0</subscript></entry>
2111 </row>
2112 <row>
2113 <entry></entry>
2114 <entry></entry>
2115 <entry></entry>
2116 <entry>-</entry>
2117 <entry>-</entry>
2118 <entry>-</entry>
2119 <entry>-</entry>
2120 <entry>-</entry>
2121 <entry>-</entry>
2122 <entry>-</entry>
2123 <entry>-</entry>
2124 <entry>-</entry>
2125 <entry>-</entry>
2126 <entry>y<subscript>9</subscript></entry>
2127 <entry>y<subscript>8</subscript></entry>
2128 <entry>y<subscript>7</subscript></entry>
2129 <entry>y<subscript>6</subscript></entry>
2130 <entry>y<subscript>5</subscript></entry>
2131 <entry>y<subscript>4</subscript></entry>
2132 <entry>y<subscript>3</subscript></entry>
2133 <entry>y<subscript>2</subscript></entry>
2134 <entry>y<subscript>1</subscript></entry>
2135 <entry>y<subscript>0</subscript></entry>
2136 </row>
2137 <row>
2138 <entry></entry>
2139 <entry></entry>
2140 <entry></entry>
2141 <entry>-</entry>
2142 <entry>-</entry>
2143 <entry>-</entry>
2144 <entry>-</entry>
2145 <entry>-</entry>
2146 <entry>-</entry>
2147 <entry>-</entry>
2148 <entry>-</entry>
2149 <entry>-</entry>
2150 <entry>-</entry>
2151 <entry>u<subscript>9</subscript></entry>
2152 <entry>u<subscript>8</subscript></entry>
2153 <entry>u<subscript>7</subscript></entry>
2154 <entry>u<subscript>6</subscript></entry>
2155 <entry>u<subscript>5</subscript></entry>
2156 <entry>u<subscript>4</subscript></entry>
2157 <entry>u<subscript>3</subscript></entry>
2158 <entry>u<subscript>2</subscript></entry>
2159 <entry>u<subscript>1</subscript></entry>
2160 <entry>u<subscript>0</subscript></entry>
2161 </row>
2162 <row id="V4L2-MBUS-FMT-UYVY8-1X16">
2163 <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry>
2164 <entry>0x200f</entry>
2165 <entry></entry>
2166 <entry>-</entry>
2167 <entry>-</entry>
2168 <entry>-</entry>
2169 <entry>-</entry>
2170 <entry>u<subscript>7</subscript></entry>
2171 <entry>u<subscript>6</subscript></entry>
2172 <entry>u<subscript>5</subscript></entry>
2173 <entry>u<subscript>4</subscript></entry>
2174 <entry>u<subscript>3</subscript></entry>
2175 <entry>u<subscript>2</subscript></entry>
2176 <entry>u<subscript>1</subscript></entry>
2177 <entry>u<subscript>0</subscript></entry>
2178 <entry>y<subscript>7</subscript></entry>
2179 <entry>y<subscript>6</subscript></entry>
2180 <entry>y<subscript>5</subscript></entry>
2181 <entry>y<subscript>4</subscript></entry>
2182 <entry>y<subscript>3</subscript></entry>
2183 <entry>y<subscript>2</subscript></entry>
2184 <entry>y<subscript>1</subscript></entry>
2185 <entry>y<subscript>0</subscript></entry>
2186 </row>
2187 <row>
2188 <entry></entry>
2189 <entry></entry>
2190 <entry></entry>
2191 <entry>-</entry>
2192 <entry>-</entry>
2193 <entry>-</entry>
2194 <entry>-</entry>
2195 <entry>v<subscript>7</subscript></entry>
2196 <entry>v<subscript>6</subscript></entry>
2197 <entry>v<subscript>5</subscript></entry>
2198 <entry>v<subscript>4</subscript></entry>
2199 <entry>v<subscript>3</subscript></entry>
2200 <entry>v<subscript>2</subscript></entry>
2201 <entry>v<subscript>1</subscript></entry>
2202 <entry>v<subscript>0</subscript></entry>
2203 <entry>y<subscript>7</subscript></entry>
2204 <entry>y<subscript>6</subscript></entry>
2205 <entry>y<subscript>5</subscript></entry>
2206 <entry>y<subscript>4</subscript></entry>
2207 <entry>y<subscript>3</subscript></entry>
2208 <entry>y<subscript>2</subscript></entry>
2209 <entry>y<subscript>1</subscript></entry>
2210 <entry>y<subscript>0</subscript></entry>
2211 </row>
2212 <row id="V4L2-MBUS-FMT-VYUY8-1X16">
2213 <entry>V4L2_MBUS_FMT_VYUY8_1X16</entry>
2214 <entry>0x2010</entry>
2215 <entry></entry>
2216 <entry>-</entry>
2217 <entry>-</entry>
2218 <entry>-</entry>
2219 <entry>-</entry>
2220 <entry>v<subscript>7</subscript></entry>
2221 <entry>v<subscript>6</subscript></entry>
2222 <entry>v<subscript>5</subscript></entry>
2223 <entry>v<subscript>4</subscript></entry>
2224 <entry>v<subscript>3</subscript></entry>
2225 <entry>v<subscript>2</subscript></entry>
2226 <entry>v<subscript>1</subscript></entry>
2227 <entry>v<subscript>0</subscript></entry>
2228 <entry>y<subscript>7</subscript></entry>
2229 <entry>y<subscript>6</subscript></entry>
2230 <entry>y<subscript>5</subscript></entry>
2231 <entry>y<subscript>4</subscript></entry>
2232 <entry>y<subscript>3</subscript></entry>
2233 <entry>y<subscript>2</subscript></entry>
2234 <entry>y<subscript>1</subscript></entry>
2235 <entry>y<subscript>0</subscript></entry>
2236 </row>
2237 <row>
2238 <entry></entry>
2239 <entry></entry>
2240 <entry></entry>
2241 <entry>-</entry>
2242 <entry>-</entry>
2243 <entry>-</entry>
2244 <entry>-</entry>
2245 <entry>u<subscript>7</subscript></entry>
2246 <entry>u<subscript>6</subscript></entry>
2247 <entry>u<subscript>5</subscript></entry>
2248 <entry>u<subscript>4</subscript></entry>
2249 <entry>u<subscript>3</subscript></entry>
2250 <entry>u<subscript>2</subscript></entry>
2251 <entry>u<subscript>1</subscript></entry>
2252 <entry>u<subscript>0</subscript></entry>
2253 <entry>y<subscript>7</subscript></entry>
2254 <entry>y<subscript>6</subscript></entry>
2255 <entry>y<subscript>5</subscript></entry>
2256 <entry>y<subscript>4</subscript></entry>
2257 <entry>y<subscript>3</subscript></entry>
2258 <entry>y<subscript>2</subscript></entry>
2259 <entry>y<subscript>1</subscript></entry>
2260 <entry>y<subscript>0</subscript></entry>
2261 </row>
2262 <row id="V4L2-MBUS-FMT-YUYV8-1X16">
2263 <entry>V4L2_MBUS_FMT_YUYV8_1X16</entry>
2264 <entry>0x2011</entry>
2265 <entry></entry>
2266 <entry>-</entry>
2267 <entry>-</entry>
2268 <entry>-</entry>
2269 <entry>-</entry>
2270 <entry>y<subscript>7</subscript></entry>
2271 <entry>y<subscript>6</subscript></entry>
2272 <entry>y<subscript>5</subscript></entry>
2273 <entry>y<subscript>4</subscript></entry>
2274 <entry>y<subscript>3</subscript></entry>
2275 <entry>y<subscript>2</subscript></entry>
2276 <entry>y<subscript>1</subscript></entry>
2277 <entry>y<subscript>0</subscript></entry>
2278 <entry>u<subscript>7</subscript></entry>
2279 <entry>u<subscript>6</subscript></entry>
2280 <entry>u<subscript>5</subscript></entry>
2281 <entry>u<subscript>4</subscript></entry>
2282 <entry>u<subscript>3</subscript></entry>
2283 <entry>u<subscript>2</subscript></entry>
2284 <entry>u<subscript>1</subscript></entry>
2285 <entry>u<subscript>0</subscript></entry>
2286 </row>
2287 <row>
2288 <entry></entry>
2289 <entry></entry>
2290 <entry></entry>
2291 <entry>-</entry>
2292 <entry>-</entry>
2293 <entry>-</entry>
2294 <entry>-</entry>
2295 <entry>y<subscript>7</subscript></entry>
2296 <entry>y<subscript>6</subscript></entry>
2297 <entry>y<subscript>5</subscript></entry>
2298 <entry>y<subscript>4</subscript></entry>
2299 <entry>y<subscript>3</subscript></entry>
2300 <entry>y<subscript>2</subscript></entry>
2301 <entry>y<subscript>1</subscript></entry>
2302 <entry>y<subscript>0</subscript></entry>
2303 <entry>v<subscript>7</subscript></entry>
2304 <entry>v<subscript>6</subscript></entry>
2305 <entry>v<subscript>5</subscript></entry>
2306 <entry>v<subscript>4</subscript></entry>
2307 <entry>v<subscript>3</subscript></entry>
2308 <entry>v<subscript>2</subscript></entry>
2309 <entry>v<subscript>1</subscript></entry>
2310 <entry>v<subscript>0</subscript></entry>
2311 </row>
2312 <row id="V4L2-MBUS-FMT-YVYU8-1X16">
2313 <entry>V4L2_MBUS_FMT_YVYU8_1X16</entry>
2314 <entry>0x2012</entry>
2315 <entry></entry>
2316 <entry>-</entry>
2317 <entry>-</entry>
2318 <entry>-</entry>
2319 <entry>-</entry>
2320 <entry>y<subscript>7</subscript></entry>
2321 <entry>y<subscript>6</subscript></entry>
2322 <entry>y<subscript>5</subscript></entry>
2323 <entry>y<subscript>4</subscript></entry>
2324 <entry>y<subscript>3</subscript></entry>
2325 <entry>y<subscript>2</subscript></entry>
2326 <entry>y<subscript>1</subscript></entry>
2327 <entry>y<subscript>0</subscript></entry>
2328 <entry>v<subscript>7</subscript></entry>
2329 <entry>v<subscript>6</subscript></entry>
2330 <entry>v<subscript>5</subscript></entry>
2331 <entry>v<subscript>4</subscript></entry>
2332 <entry>v<subscript>3</subscript></entry>
2333 <entry>v<subscript>2</subscript></entry>
2334 <entry>v<subscript>1</subscript></entry>
2335 <entry>v<subscript>0</subscript></entry>
2336 </row>
2337 <row>
2338 <entry></entry>
2339 <entry></entry>
2340 <entry></entry>
2341 <entry>-</entry>
2342 <entry>-</entry>
2343 <entry>-</entry>
2344 <entry>-</entry>
2345 <entry>y<subscript>7</subscript></entry>
2346 <entry>y<subscript>6</subscript></entry>
2347 <entry>y<subscript>5</subscript></entry>
2348 <entry>y<subscript>4</subscript></entry>
2349 <entry>y<subscript>3</subscript></entry>
2350 <entry>y<subscript>2</subscript></entry>
2351 <entry>y<subscript>1</subscript></entry>
2352 <entry>y<subscript>0</subscript></entry>
2353 <entry>u<subscript>7</subscript></entry>
2354 <entry>u<subscript>6</subscript></entry>
2355 <entry>u<subscript>5</subscript></entry>
2356 <entry>u<subscript>4</subscript></entry>
2357 <entry>u<subscript>3</subscript></entry>
2358 <entry>u<subscript>2</subscript></entry>
2359 <entry>u<subscript>1</subscript></entry>
2360 <entry>u<subscript>0</subscript></entry>
2361 </row>
2362 <row id="V4L2-MBUS-FMT-YUYV10-1X20">
2363 <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry>
2364 <entry>0x200d</entry>
2365 <entry></entry>
2366 <entry>y<subscript>9</subscript></entry>
2367 <entry>y<subscript>8</subscript></entry>
2368 <entry>y<subscript>7</subscript></entry>
2369 <entry>y<subscript>6</subscript></entry>
2370 <entry>y<subscript>5</subscript></entry>
2371 <entry>y<subscript>4</subscript></entry>
2372 <entry>y<subscript>3</subscript></entry>
2373 <entry>y<subscript>2</subscript></entry>
2374 <entry>y<subscript>1</subscript></entry>
2375 <entry>y<subscript>0</subscript></entry>
2376 <entry>u<subscript>9</subscript></entry>
2377 <entry>u<subscript>8</subscript></entry>
2378 <entry>u<subscript>7</subscript></entry>
2379 <entry>u<subscript>6</subscript></entry>
2380 <entry>u<subscript>5</subscript></entry>
2381 <entry>u<subscript>4</subscript></entry>
2382 <entry>u<subscript>3</subscript></entry>
2383 <entry>u<subscript>2</subscript></entry>
2384 <entry>u<subscript>1</subscript></entry>
2385 <entry>u<subscript>0</subscript></entry>
2386 </row>
2387 <row>
2388 <entry></entry>
2389 <entry></entry>
2390 <entry></entry>
2391 <entry>y<subscript>9</subscript></entry>
2392 <entry>y<subscript>8</subscript></entry>
2393 <entry>y<subscript>7</subscript></entry>
2394 <entry>y<subscript>6</subscript></entry>
2395 <entry>y<subscript>5</subscript></entry>
2396 <entry>y<subscript>4</subscript></entry>
2397 <entry>y<subscript>3</subscript></entry>
2398 <entry>y<subscript>2</subscript></entry>
2399 <entry>y<subscript>1</subscript></entry>
2400 <entry>y<subscript>0</subscript></entry>
2401 <entry>v<subscript>9</subscript></entry>
2402 <entry>v<subscript>8</subscript></entry>
2403 <entry>v<subscript>7</subscript></entry>
2404 <entry>v<subscript>6</subscript></entry>
2405 <entry>v<subscript>5</subscript></entry>
2406 <entry>v<subscript>4</subscript></entry>
2407 <entry>v<subscript>3</subscript></entry>
2408 <entry>v<subscript>2</subscript></entry>
2409 <entry>v<subscript>1</subscript></entry>
2410 <entry>v<subscript>0</subscript></entry>
2411 </row>
2412 <row id="V4L2-MBUS-FMT-YVYU10-1X20">
2413 <entry>V4L2_MBUS_FMT_YVYU10_1X20</entry>
2414 <entry>0x200e</entry>
2415 <entry></entry>
2416 <entry>y<subscript>9</subscript></entry>
2417 <entry>y<subscript>8</subscript></entry>
2418 <entry>y<subscript>7</subscript></entry>
2419 <entry>y<subscript>6</subscript></entry>
2420 <entry>y<subscript>5</subscript></entry>
2421 <entry>y<subscript>4</subscript></entry>
2422 <entry>y<subscript>3</subscript></entry>
2423 <entry>y<subscript>2</subscript></entry>
2424 <entry>y<subscript>1</subscript></entry>
2425 <entry>y<subscript>0</subscript></entry>
2426 <entry>v<subscript>9</subscript></entry>
2427 <entry>v<subscript>8</subscript></entry>
2428 <entry>v<subscript>7</subscript></entry>
2429 <entry>v<subscript>6</subscript></entry>
2430 <entry>v<subscript>5</subscript></entry>
2431 <entry>v<subscript>4</subscript></entry>
2432 <entry>v<subscript>3</subscript></entry>
2433 <entry>v<subscript>2</subscript></entry>
2434 <entry>v<subscript>1</subscript></entry>
2435 <entry>v<subscript>0</subscript></entry>
2436 </row>
2437 <row>
2438 <entry></entry>
2439 <entry></entry>
2440 <entry></entry>
2441 <entry>y<subscript>9</subscript></entry>
2442 <entry>y<subscript>8</subscript></entry>
2443 <entry>y<subscript>7</subscript></entry>
2444 <entry>y<subscript>6</subscript></entry>
2445 <entry>y<subscript>5</subscript></entry>
2446 <entry>y<subscript>4</subscript></entry>
2447 <entry>y<subscript>3</subscript></entry>
2448 <entry>y<subscript>2</subscript></entry>
2449 <entry>y<subscript>1</subscript></entry>
2450 <entry>y<subscript>0</subscript></entry>
2451 <entry>u<subscript>9</subscript></entry>
2452 <entry>u<subscript>8</subscript></entry>
2453 <entry>u<subscript>7</subscript></entry>
2454 <entry>u<subscript>6</subscript></entry>
2455 <entry>u<subscript>5</subscript></entry>
2456 <entry>u<subscript>4</subscript></entry>
2457 <entry>u<subscript>3</subscript></entry>
2458 <entry>u<subscript>2</subscript></entry>
2459 <entry>u<subscript>1</subscript></entry>
2460 <entry>u<subscript>0</subscript></entry>
2461 </row>
2462 </tbody>
2463 </tgroup>
2464 </table>
2465 </section>
2466 </section>
2467</section>
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
index 9288af96de34..a7fd76d0dac1 100644
--- a/Documentation/DocBook/v4l/v4l2.xml
+++ b/Documentation/DocBook/v4l/v4l2.xml
@@ -85,6 +85,17 @@ Remote Controller chapter.</contrib>
85 </address> 85 </address>
86 </affiliation> 86 </affiliation>
87 </author> 87 </author>
88
89 <author>
90 <firstname>Pawel</firstname>
91 <surname>Osciak</surname>
92 <contrib>Designed and documented the multi-planar API.</contrib>
93 <affiliation>
94 <address>
95 <email>pawel AT osciak.com</email>
96 </address>
97 </affiliation>
98 </author>
88 </authorgroup> 99 </authorgroup>
89 100
90 <copyright> 101 <copyright>
@@ -102,7 +113,8 @@ Remote Controller chapter.</contrib>
102 <year>2010</year> 113 <year>2010</year>
103 <year>2011</year> 114 <year>2011</year>
104 <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin 115 <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
105Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder> 116Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
117 Pawel Osciak</holder>
106 </copyright> 118 </copyright>
107 <legalnotice> 119 <legalnotice>
108 <para>Except when explicitly stated as GPL, programming examples within 120 <para>Except when explicitly stated as GPL, programming examples within
@@ -116,6 +128,13 @@ structs, ioctls) must be noted in more detail in the history chapter
116applications. --> 128applications. -->
117 129
118 <revision> 130 <revision>
131 <revnumber>2.6.39</revnumber>
132 <date>2011-03-01</date>
133 <authorinitials>mcc, po</authorinitials>
134 <revremark>Removed VIDIOC_*_OLD from videodev2.h header and update it to reflect latest changes. Added the <link linkend="planar-apis">multi-planar API</link>.</revremark>
135 </revision>
136
137 <revision>
119 <revnumber>2.6.37</revnumber> 138 <revnumber>2.6.37</revnumber>
120 <date>2010-08-06</date> 139 <date>2010-08-06</date>
121 <authorinitials>hv</authorinitials> 140 <authorinitials>hv</authorinitials>
@@ -382,7 +401,7 @@ and discussions on the V4L mailing list.</revremark>
382</partinfo> 401</partinfo>
383 402
384<title>Video for Linux Two API Specification</title> 403<title>Video for Linux Two API Specification</title>
385 <subtitle>Revision 2.6.38</subtitle> 404 <subtitle>Revision 2.6.39</subtitle>
386 405
387 <chapter id="common"> 406 <chapter id="common">
388 &sub-common; 407 &sub-common;
@@ -411,6 +430,7 @@ and discussions on the V4L mailing list.</revremark>
411 <section id="radio"> &sub-dev-radio; </section> 430 <section id="radio"> &sub-dev-radio; </section>
412 <section id="rds"> &sub-dev-rds; </section> 431 <section id="rds"> &sub-dev-rds; </section>
413 <section id="event"> &sub-dev-event; </section> 432 <section id="event"> &sub-dev-event; </section>
433 <section id="subdev"> &sub-dev-subdev; </section>
414 </chapter> 434 </chapter>
415 435
416 <chapter id="driver"> 436 <chapter id="driver">
@@ -478,6 +498,12 @@ and discussions on the V4L mailing list.</revremark>
478 &sub-reqbufs; 498 &sub-reqbufs;
479 &sub-s-hw-freq-seek; 499 &sub-s-hw-freq-seek;
480 &sub-streamon; 500 &sub-streamon;
501 &sub-subdev-enum-frame-interval;
502 &sub-subdev-enum-frame-size;
503 &sub-subdev-enum-mbus-code;
504 &sub-subdev-g-crop;
505 &sub-subdev-g-fmt;
506 &sub-subdev-g-frame-interval;
481 &sub-subscribe-event; 507 &sub-subscribe-event;
482 <!-- End of ioctls. --> 508 <!-- End of ioctls. -->
483 &sub-mmap; 509 &sub-mmap;
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml
index 325b23b6964c..2b796a2ee98a 100644
--- a/Documentation/DocBook/v4l/videodev2.h.xml
+++ b/Documentation/DocBook/v4l/videodev2.h.xml
@@ -71,6 +71,7 @@
71 * Moved from videodev.h 71 * Moved from videodev.h
72 */ 72 */
73#define VIDEO_MAX_FRAME 32 73#define VIDEO_MAX_FRAME 32
74#define VIDEO_MAX_PLANES 8
74 75
75#ifndef __KERNEL__ 76#ifndef __KERNEL__
76 77
@@ -158,9 +159,23 @@ enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> {
158 /* Experimental */ 159 /* Experimental */
159 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, 160 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
160#endif 161#endif
162 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
163 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
161 V4L2_BUF_TYPE_PRIVATE = 0x80, 164 V4L2_BUF_TYPE_PRIVATE = 0x80,
162}; 165};
163 166
167#define V4L2_TYPE_IS_MULTIPLANAR(type) \
168 ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \
169 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
170
171#define V4L2_TYPE_IS_OUTPUT(type) \
172 ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \
173 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \
174 || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \
175 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \
176 || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \
177 || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
178
164enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> { 179enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> {
165 V4L2_TUNER_RADIO = 1, 180 V4L2_TUNER_RADIO = 1,
166 V4L2_TUNER_ANALOG_TV = 2, 181 V4L2_TUNER_ANALOG_TV = 2,
@@ -246,6 +261,11 @@ struct <link linkend="v4l2-capability">v4l2_capability</link> {
246#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ 261#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
247#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ 262#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
248 263
264/* Is a video capture device that supports multiplanar formats */
265#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
266/* Is a video output device that supports multiplanar formats */
267#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
268
249#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ 269#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
250#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ 270#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
251#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ 271#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
@@ -320,6 +340,13 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
320#define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link> v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ 340#define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link> v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
321#define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link> v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ 341#define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link> v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
322 342
343/* two non contiguous planes - one Y, one Cr + Cb interleaved */
344#define <link linkend="V4L2-PIX-FMT-NV12M">V4L2_PIX_FMT_NV12M</link> v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
345#define <link linkend="V4L2-PIX-FMT-NV12MT">V4L2_PIX_FMT_NV12MT</link> v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
346
347/* three non contiguous planes - Y, Cb, Cr */
348#define <link linkend="V4L2-PIX-FMT-YUV420M">V4L2_PIX_FMT_YUV420M</link> v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */
349
323/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ 350/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
324#define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ 351#define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
325#define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ 352#define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
@@ -518,6 +545,62 @@ struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> {
518 __u32 reserved[2]; 545 __u32 reserved[2];
519}; 546};
520 547
548/**
549 * struct <link linkend="v4l2-plane">v4l2_plane</link> - plane info for multi-planar buffers
550 * @bytesused: number of bytes occupied by data in the plane (payload)
551 * @length: size of this plane (NOT the payload) in bytes
552 * @mem_offset: when memory in the associated struct <link linkend="v4l2-buffer">v4l2_buffer</link> is
553 * V4L2_MEMORY_MMAP, equals the offset from the start of
554 * the device memory for this plane (or is a "cookie" that
555 * should be passed to mmap() called on the video node)
556 * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
557 * pointing to this plane
558 * @data_offset: offset in the plane to the start of data; usually 0,
559 * unless there is a header in front of the data
560 *
561 * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer
562 * with two planes can have one plane for Y, and another for interleaved CbCr
563 * components. Each plane can reside in a separate memory buffer, or even in
564 * a completely separate memory node (e.g. in embedded devices).
565 */
566struct <link linkend="v4l2-plane">v4l2_plane</link> {
567 __u32 bytesused;
568 __u32 length;
569 union {
570 __u32 mem_offset;
571 unsigned long userptr;
572 } m;
573 __u32 data_offset;
574 __u32 reserved[11];
575};
576
577/**
578 * struct <link linkend="v4l2-buffer">v4l2_buffer</link> - video buffer info
579 * @index: id number of the buffer
580 * @type: buffer type (type == *_MPLANE for multiplanar buffers)
581 * @bytesused: number of bytes occupied by data in the buffer (payload);
582 * unused (set to 0) for multiplanar buffers
583 * @flags: buffer informational flags
584 * @field: field order of the image in the buffer
585 * @timestamp: frame timestamp
586 * @timecode: frame timecode
587 * @sequence: sequence count of this frame
588 * @memory: the method, in which the actual video data is passed
589 * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
590 * offset from the start of the device memory for this plane,
591 * (or a "cookie" that should be passed to mmap() as offset)
592 * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
593 * a userspace pointer pointing to this buffer
594 * @planes: for multiplanar buffers; userspace pointer to the array of plane
595 * info structs for this buffer
596 * @length: size in bytes of the buffer (NOT its payload) for single-plane
597 * buffers (when type != *_MPLANE); number of elements in the
598 * planes array for multi-plane buffers
599 * @input: input number from which the video data has has been captured
600 *
601 * Contains data exchanged by application and driver using one of the Streaming
602 * I/O methods.
603 */
521struct <link linkend="v4l2-buffer">v4l2_buffer</link> { 604struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
522 __u32 index; 605 __u32 index;
523 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type; 606 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
@@ -533,6 +616,7 @@ struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
533 union { 616 union {
534 __u32 offset; 617 __u32 offset;
535 unsigned long userptr; 618 unsigned long userptr;
619 struct <link linkend="v4l2-plane">v4l2_plane</link> *planes;
536 } m; 620 } m;
537 __u32 length; 621 __u32 length;
538 __u32 input; 622 __u32 input;
@@ -1623,12 +1707,56 @@ struct <link linkend="v4l2-mpeg-vbi-fmt-ivtv">v4l2_mpeg_vbi_fmt_ivtv</link> {
1623 * A G G R E G A T E S T R U C T U R E S 1707 * A G G R E G A T E S T R U C T U R E S
1624 */ 1708 */
1625 1709
1626/* Stream data format 1710/**
1711 * struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> - additional, per-plane format definition
1712 * @sizeimage: maximum size in bytes required for data, for which
1713 * this plane will be used
1714 * @bytesperline: distance in bytes between the leftmost pixels in two
1715 * adjacent lines
1716 */
1717struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> {
1718 __u32 sizeimage;
1719 __u16 bytesperline;
1720 __u16 reserved[7];
1721} __attribute__ ((packed));
1722
1723/**
1724 * struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> - multiplanar format definition
1725 * @width: image width in pixels
1726 * @height: image height in pixels
1727 * @pixelformat: little endian four character code (fourcc)
1728 * @field: field order (for interlaced video)
1729 * @colorspace: supplemental to pixelformat
1730 * @plane_fmt: per-plane information
1731 * @num_planes: number of planes for this format
1732 */
1733struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> {
1734 __u32 width;
1735 __u32 height;
1736 __u32 pixelformat;
1737 enum <link linkend="v4l2-field">v4l2_field</link> field;
1738 enum <link linkend="v4l2-colorspace">v4l2_colorspace</link> colorspace;
1739
1740 struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> plane_fmt[VIDEO_MAX_PLANES];
1741 __u8 num_planes;
1742 __u8 reserved[11];
1743} __attribute__ ((packed));
1744
1745/**
1746 * struct <link linkend="v4l2-format">v4l2_format</link> - stream data format
1747 * @type: type of the data stream
1748 * @pix: definition of an image format
1749 * @pix_mp: definition of a multiplanar image format
1750 * @win: definition of an overlaid image
1751 * @vbi: raw VBI capture or output parameters
1752 * @sliced: sliced VBI capture or output parameters
1753 * @raw_data: placeholder for future extensions and custom formats
1627 */ 1754 */
1628struct <link linkend="v4l2-format">v4l2_format</link> { 1755struct <link linkend="v4l2-format">v4l2_format</link> {
1629 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type; 1756 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
1630 union { 1757 union {
1631 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ 1758 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
1759 struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
1632 struct <link linkend="v4l2-window">v4l2_window</link> win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ 1760 struct <link linkend="v4l2-window">v4l2_window</link> win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
1633 struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link> vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ 1761 struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link> vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
1634 struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link> sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ 1762 struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link> sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
@@ -1636,7 +1764,6 @@ struct <link linkend="v4l2-format">v4l2_format</link> {
1636 } fmt; 1764 } fmt;
1637}; 1765};
1638 1766
1639
1640/* Stream type-dependent parameters 1767/* Stream type-dependent parameters
1641 */ 1768 */
1642struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> { 1769struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> {
@@ -1809,16 +1936,6 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
1809/* Reminder: when adding new ioctls please add support for them to 1936/* Reminder: when adding new ioctls please add support for them to
1810 drivers/media/video/v4l2-compat-ioctl32.c as well! */ 1937 drivers/media/video/v4l2-compat-ioctl32.c as well! */
1811 1938
1812#ifdef __OLD_VIDIOC_
1813/* for compatibility, will go away some day */
1814#define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
1815#define VIDIOC_S_PARM_OLD _IOW('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
1816#define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>)
1817#define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>)
1818#define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
1819#define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>)
1820#endif
1821
1822#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ 1939#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
1823 1940
1824#endif /* __LINUX_VIDEODEV2_H */ 1941#endif /* __LINUX_VIDEODEV2_H */
diff --git a/Documentation/DocBook/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
index 960d44615ca6..71d373b6d36a 100644
--- a/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
+++ b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
@@ -76,7 +76,9 @@ pixelformat</structfield> field.</entry>
76 <entry>Type of the data stream, set by the application. 76 <entry>Type of the data stream, set by the application.
77Only these types are valid here: 77Only these types are valid here:
78<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>, 78<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
79<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>,
79<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>, 80<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
81<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>,
80<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver 82<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
81defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant> 83defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
82and higher.</entry> 84and higher.</entry>
diff --git a/Documentation/DocBook/v4l/vidioc-g-fmt.xml b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
index 7c7d1b72c40d..a4ae59b664eb 100644
--- a/Documentation/DocBook/v4l/vidioc-g-fmt.xml
+++ b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
@@ -60,11 +60,13 @@ application.</para>
60<structfield>type</structfield> field of a struct 60<structfield>type</structfield> field of a struct
61<structname>v4l2_format</structname> to the respective buffer (stream) 61<structname>v4l2_format</structname> to the respective buffer (stream)
62type. For example video capture devices use 62type. For example video capture devices use
63<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>. When the application 63<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or
64<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. When the application
64calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to 65calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to
65this structure the driver fills the respective member of the 66this structure the driver fills the respective member of the
66<structfield>fmt</structfield> union. In case of video capture devices 67<structfield>fmt</structfield> union. In case of video capture devices
67that is the &v4l2-pix-format; <structfield>pix</structfield> member. 68that is either the &v4l2-pix-format; <structfield>pix</structfield> or
69the &v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member.
68When the requested buffer type is not supported drivers return an 70When the requested buffer type is not supported drivers return an
69&EINVAL;.</para> 71&EINVAL;.</para>
70 72
@@ -134,6 +136,15 @@ devices.</entry>
134 </row> 136 </row>
135 <row> 137 <row>
136 <entry></entry> 138 <entry></entry>
139 <entry>&v4l2-pix-format-mplane;</entry>
140 <entry><structfield>pix_mp</structfield></entry>
141 <entry>Definition of an image format, see <xref
142 linkend="pixfmt" />, used by video capture and output
143devices that support the <link linkend="planar-apis">multi-planar
144version of the API</link>.</entry>
145 </row>
146 <row>
147 <entry></entry>
137 <entry>&v4l2-window;</entry> 148 <entry>&v4l2-window;</entry>
138 <entry><structfield>win</structfield></entry> 149 <entry><structfield>win</structfield></entry>
139 <entry>Definition of an overlaid image, see <xref 150 <entry>Definition of an overlaid image, see <xref
diff --git a/Documentation/DocBook/v4l/vidioc-qbuf.xml b/Documentation/DocBook/v4l/vidioc-qbuf.xml
index ab691ebf3b93..f2b11f8a4031 100644
--- a/Documentation/DocBook/v4l/vidioc-qbuf.xml
+++ b/Documentation/DocBook/v4l/vidioc-qbuf.xml
@@ -64,7 +64,8 @@ zero to the number of buffers allocated with &VIDIOC-REQBUFS;
64contents of the struct <structname>v4l2_buffer</structname> returned 64contents of the struct <structname>v4l2_buffer</structname> returned
65by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is 65by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is
66intended for output (<structfield>type</structfield> is 66intended for output (<structfield>type</structfield> is
67<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or 67<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
68<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>, or
68<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also 69<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also
69initialize the <structfield>bytesused</structfield>, 70initialize the <structfield>bytesused</structfield>,
70<structfield>field</structfield> and 71<structfield>field</structfield> and
@@ -75,7 +76,11 @@ supports capturing from specific video inputs and you want to specify a video
75input, then <structfield>flags</structfield> should be set to 76input, then <structfield>flags</structfield> should be set to
76<constant>V4L2_BUF_FLAG_INPUT</constant> and the field 77<constant>V4L2_BUF_FLAG_INPUT</constant> and the field
77<structfield>input</structfield> must be initialized to the desired input. 78<structfield>input</structfield> must be initialized to the desired input.
78The <structfield>reserved</structfield> field must be set to 0. 79The <structfield>reserved</structfield> field must be set to 0. When using
80the <link linkend="planar-apis">multi-planar API</link>, the
81<structfield>m.planes</structfield> field must contain a userspace pointer
82to a filled-in array of &v4l2-plane; and the <structfield>length</structfield>
83field must be set to the number of elements in that array.
79</para> 84</para>
80 85
81 <para>To enqueue a <link linkend="mmap">memory mapped</link> 86 <para>To enqueue a <link linkend="mmap">memory mapped</link>
@@ -93,10 +98,13 @@ structure the driver sets the
93buffer applications set the <structfield>memory</structfield> 98buffer applications set the <structfield>memory</structfield>
94field to <constant>V4L2_MEMORY_USERPTR</constant>, the 99field to <constant>V4L2_MEMORY_USERPTR</constant>, the
95<structfield>m.userptr</structfield> field to the address of the 100<structfield>m.userptr</structfield> field to the address of the
96buffer and <structfield>length</structfield> to its size. 101buffer and <structfield>length</structfield> to its size. When the multi-planar
97When <constant>VIDIOC_QBUF</constant> is called with a pointer to this 102API is used, <structfield>m.userptr</structfield> and
98structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant> 103<structfield>length</structfield> members of the passed array of &v4l2-plane;
99flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and 104have to be used instead. When <constant>VIDIOC_QBUF</constant> is called with
105a pointer to this structure the driver sets the
106<constant>V4L2_BUF_FLAG_QUEUED</constant> flag and clears the
107<constant>V4L2_BUF_FLAG_MAPPED</constant> and
100<constant>V4L2_BUF_FLAG_DONE</constant> flags in the 108<constant>V4L2_BUF_FLAG_DONE</constant> flags in the
101<structfield>flags</structfield> field, or it returns an error code. 109<structfield>flags</structfield> field, or it returns an error code.
102This ioctl locks the memory pages of the buffer in physical memory, 110This ioctl locks the memory pages of the buffer in physical memory,
@@ -115,7 +123,9 @@ remaining fields or returns an error code. The driver may also set
115<constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield> 123<constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield>
116field. It indicates a non-critical (recoverable) streaming error. In such case 124field. It indicates a non-critical (recoverable) streaming error. In such case
117the application may continue as normal, but should be aware that data in the 125the application may continue as normal, but should be aware that data in the
118dequeued buffer might be corrupted.</para> 126dequeued buffer might be corrupted. When using the multi-planar API, the
127planes array does not have to be passed; the <structfield>m.planes</structfield>
128member must be set to NULL in that case.</para>
119 129
120 <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no 130 <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
121buffer is in the outgoing queue. When the 131buffer is in the outgoing queue. When the
diff --git a/Documentation/DocBook/v4l/vidioc-querybuf.xml b/Documentation/DocBook/v4l/vidioc-querybuf.xml
index e649805a4908..5c104d42d31c 100644
--- a/Documentation/DocBook/v4l/vidioc-querybuf.xml
+++ b/Documentation/DocBook/v4l/vidioc-querybuf.xml
@@ -61,6 +61,10 @@ buffer at any time after buffers have been allocated with the
61to the number of buffers allocated with &VIDIOC-REQBUFS; 61to the number of buffers allocated with &VIDIOC-REQBUFS;
62 (&v4l2-requestbuffers; <structfield>count</structfield>) minus one. 62 (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
63The <structfield>reserved</structfield> field should to set to 0. 63The <structfield>reserved</structfield> field should to set to 0.
64When using the <link linkend="planar-apis">multi-planar API</link>, the
65<structfield>m.planes</structfield> field must contain a userspace pointer to an
66array of &v4l2-plane; and the <structfield>length</structfield> field has
67to be set to the number of elements in that array.
64After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to 68After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to
65 this structure drivers return an error code or fill the rest of 69 this structure drivers return an error code or fill the rest of
66the structure.</para> 70the structure.</para>
@@ -70,11 +74,13 @@ the structure.</para>
70<constant>V4L2_BUF_FLAG_QUEUED</constant> and 74<constant>V4L2_BUF_FLAG_QUEUED</constant> and
71<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The 75<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
72<structfield>memory</structfield> field will be set to the current 76<structfield>memory</structfield> field will be set to the current
73I/O method, the <structfield>m.offset</structfield> 77I/O method. For the single-planar API, the <structfield>m.offset</structfield>
74contains the offset of the buffer from the start of the device memory, 78contains the offset of the buffer from the start of the device memory,
75the <structfield>length</structfield> field its size. The driver may 79the <structfield>length</structfield> field its size. For the multi-planar API,
76or may not set the remaining fields and flags, they are meaningless in 80fields <structfield>m.mem_offset</structfield> and
77this context.</para> 81<structfield>length</structfield> in the <structfield>m.planes</structfield>
82array elements will be used instead. The driver may or may not set the remaining
83fields and flags, they are meaningless in this context.</para>
78 84
79 <para>The <structname>v4l2_buffer</structname> structure is 85 <para>The <structname>v4l2_buffer</structname> structure is
80 specified in <xref linkend="buffer" />.</para> 86 specified in <xref linkend="buffer" />.</para>
diff --git a/Documentation/DocBook/v4l/vidioc-querycap.xml b/Documentation/DocBook/v4l/vidioc-querycap.xml
index d499da93a450..f29f1b86213c 100644
--- a/Documentation/DocBook/v4l/vidioc-querycap.xml
+++ b/Documentation/DocBook/v4l/vidioc-querycap.xml
@@ -142,16 +142,30 @@ this array to zero.</entry>
142 <row> 142 <row>
143 <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry> 143 <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
144 <entry>0x00000001</entry> 144 <entry>0x00000001</entry>
145 <entry>The device supports the <link 145 <entry>The device supports the single-planar API through the <link
146linkend="capture">Video Capture</link> interface.</entry> 146linkend="capture">Video Capture</link> interface.</entry>
147 </row> 147 </row>
148 <row> 148 <row>
149 <entry><constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant></entry>
150 <entry>0x00001000</entry>
151 <entry>The device supports the
152 <link linkend="planar-apis">multi-planar API</link> through the
153 <link linkend="capture">Video Capture</link> interface.</entry>
154 </row>
155 <row>
149 <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry> 156 <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry>
150 <entry>0x00000002</entry> 157 <entry>0x00000002</entry>
151 <entry>The device supports the <link 158 <entry>The device supports the single-planar API through the <link
152linkend="output">Video Output</link> interface.</entry> 159linkend="output">Video Output</link> interface.</entry>
153 </row> 160 </row>
154 <row> 161 <row>
162 <entry><constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant></entry>
163 <entry>0x00002000</entry>
164 <entry>The device supports the
165 <link linkend="planar-apis">multi-planar API</link> through the
166 <link linkend="output">Video Output</link> interface.</entry>
167 </row>
168 <row>
155 <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry> 169 <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
156 <entry>0x00000004</entry> 170 <entry>0x00000004</entry>
157 <entry>The device supports the <link 171 <entry>The device supports the <link
diff --git a/Documentation/DocBook/v4l/vidioc-streamon.xml b/Documentation/DocBook/v4l/vidioc-streamon.xml
index e42bff1f2c0a..75ed39bf4d2b 100644
--- a/Documentation/DocBook/v4l/vidioc-streamon.xml
+++ b/Documentation/DocBook/v4l/vidioc-streamon.xml
@@ -93,6 +93,15 @@ synchronize with other events.</para>
93been allocated (memory mapping) or enqueued (output) yet.</para> 93been allocated (memory mapping) or enqueued (output) yet.</para>
94 </listitem> 94 </listitem>
95 </varlistentry> 95 </varlistentry>
96 <varlistentry>
97 <term><errorcode>EPIPE</errorcode></term>
98 <listitem>
99 <para>The driver implements <link
100 linkend="pad-level-formats">pad-level format configuration</link> and
101 the pipeline configuration is invalid.
102 </para>
103 </listitem>
104 </varlistentry>
96 </variablelist> 105 </variablelist>
97 </refsect1> 106 </refsect1>
98</refentry> 107</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml
new file mode 100644
index 000000000000..2f8f4f0a0235
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml
@@ -0,0 +1,152 @@
1<refentry id="vidioc-subdev-enum-frame-interval">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refname>
9 <refpurpose>Enumerate frame intervals</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_subdev_frame_interval_enum *
19 <parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <note>
53 <title>Experimental</title>
54 <para>This is an <link linkend="experimental">experimental</link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>This ioctl lets applications enumerate available frame intervals on a
59 given sub-device pad. Frame intervals only makes sense for sub-devices that
60 can control the frame period on their own. This includes, for instance,
61 image sensors and TV tuners.</para>
62
63 <para>For the common use case of image sensors, the frame intervals
64 available on the sub-device output pad depend on the frame format and size
65 on the same pad. Applications must thus specify the desired format and size
66 when enumerating frame intervals.</para>
67
68 <para>To enumerate frame intervals applications initialize the
69 <structfield>index</structfield>, <structfield>pad</structfield>,
70 <structfield>code</structfield>, <structfield>width</structfield> and
71 <structfield>height</structfield> fields of
72 &v4l2-subdev-frame-interval-enum; and call the
73 <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer
74 to this structure. Drivers fill the rest of the structure or return
75 an &EINVAL; if one of the input fields is invalid. All frame intervals are
76 enumerable by beginning at index zero and incrementing by one until
77 <errorcode>EINVAL</errorcode> is returned.</para>
78
79 <para>Available frame intervals may depend on the current 'try' formats
80 at other pads of the sub-device, as well as on the current active links. See
81 &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para>
82
83 <para>Sub-devices that support the frame interval enumeration ioctl should
84 implemented it on a single pad only. Its behaviour when supported on
85 multiple pads of the same sub-device is not defined.</para>
86
87 <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval-enum">
88 <title>struct <structname>v4l2_subdev_frame_interval_enum</structname></title>
89 <tgroup cols="3">
90 &cs-str;
91 <tbody valign="top">
92 <row>
93 <entry>__u32</entry>
94 <entry><structfield>index</structfield></entry>
95 <entry>Number of the format in the enumeration, set by the
96 application.</entry>
97 </row>
98 <row>
99 <entry>__u32</entry>
100 <entry><structfield>pad</structfield></entry>
101 <entry>Pad number as reported by the media controller API.</entry>
102 </row>
103 <row>
104 <entry>__u32</entry>
105 <entry><structfield>code</structfield></entry>
106 <entry>The media bus format code, as defined in
107 <xref linkend="v4l2-mbus-format" />.</entry>
108 </row>
109 <row>
110 <entry>__u32</entry>
111 <entry><structfield>width</structfield></entry>
112 <entry>Frame width, in pixels.</entry>
113 </row>
114 <row>
115 <entry>__u32</entry>
116 <entry><structfield>height</structfield></entry>
117 <entry>Frame height, in pixels.</entry>
118 </row>
119 <row>
120 <entry>&v4l2-fract;</entry>
121 <entry><structfield>interval</structfield></entry>
122 <entry>Period, in seconds, between consecutive video frames.</entry>
123 </row>
124 <row>
125 <entry>__u32</entry>
126 <entry><structfield>reserved</structfield>[9]</entry>
127 <entry>Reserved for future extensions. Applications and drivers must
128 set the array to zero.</entry>
129 </row>
130 </tbody>
131 </tgroup>
132 </table>
133 </refsect1>
134
135 <refsect1>
136 &return-value;
137
138 <variablelist>
139 <varlistentry>
140 <term><errorcode>EINVAL</errorcode></term>
141 <listitem>
142 <para>The &v4l2-subdev-frame-interval-enum;
143 <structfield>pad</structfield> references a non-existing pad, one of
144 the <structfield>code</structfield>, <structfield>width</structfield>
145 or <structfield>height</structfield> fields are invalid for the given
146 pad or the <structfield>index</structfield> field is out of bounds.
147 </para>
148 </listitem>
149 </varlistentry>
150 </variablelist>
151 </refsect1>
152</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml
new file mode 100644
index 000000000000..79ce42b7c60c
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml
@@ -0,0 +1,154 @@
1<refentry id="vidioc-subdev-enum-frame-size">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refname>
9 <refpurpose>Enumerate media bus frame sizes</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_subdev_frame_size_enum *
19 <parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <note>
53 <title>Experimental</title>
54 <para>This is an <link linkend="experimental">experimental</link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>This ioctl allows applications to enumerate all frame sizes
59 supported by a sub-device on the given pad for the given media bus format.
60 Supported formats can be retrieved with the &VIDIOC-SUBDEV-ENUM-MBUS-CODE;
61 ioctl.</para>
62
63 <para>To enumerate frame sizes applications initialize the
64 <structfield>pad</structfield>, <structfield>code</structfield> and
65 <structfield>index</structfield> fields of the
66 &v4l2-subdev-mbus-code-enum; and call the
67 <constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to
68 the structure. Drivers fill the minimum and maximum frame sizes or return
69 an &EINVAL; if one of the input parameters is invalid.</para>
70
71 <para>Sub-devices that only support discrete frame sizes (such as most
72 sensors) will return one or more frame sizes with identical minimum and
73 maximum values.</para>
74
75 <para>Not all possible sizes in given [minimum, maximum] ranges need to be
76 supported. For instance, a scaler that uses a fixed-point scaling ratio
77 might not be able to produce every frame size between the minimum and
78 maximum values. Applications must use the &VIDIOC-SUBDEV-S-FMT; ioctl to
79 try the sub-device for an exact supported frame size.</para>
80
81 <para>Available frame sizes may depend on the current 'try' formats at other
82 pads of the sub-device, as well as on the current active links and the
83 current values of V4L2 controls. See &VIDIOC-SUBDEV-G-FMT; for more
84 information about try formats.</para>
85
86 <table pgwide="1" frame="none" id="v4l2-subdev-frame-size-enum">
87 <title>struct <structname>v4l2_subdev_frame_size_enum</structname></title>
88 <tgroup cols="3">
89 &cs-str;
90 <tbody valign="top">
91 <row>
92 <entry>__u32</entry>
93 <entry><structfield>index</structfield></entry>
94 <entry>Number of the format in the enumeration, set by the
95 application.</entry>
96 </row>
97 <row>
98 <entry>__u32</entry>
99 <entry><structfield>pad</structfield></entry>
100 <entry>Pad number as reported by the media controller API.</entry>
101 </row>
102 <row>
103 <entry>__u32</entry>
104 <entry><structfield>code</structfield></entry>
105 <entry>The media bus format code, as defined in
106 <xref linkend="v4l2-mbus-format" />.</entry>
107 </row>
108 <row>
109 <entry>__u32</entry>
110 <entry><structfield>min_width</structfield></entry>
111 <entry>Minimum frame width, in pixels.</entry>
112 </row>
113 <row>
114 <entry>__u32</entry>
115 <entry><structfield>max_width</structfield></entry>
116 <entry>Maximum frame width, in pixels.</entry>
117 </row>
118 <row>
119 <entry>__u32</entry>
120 <entry><structfield>min_height</structfield></entry>
121 <entry>Minimum frame height, in pixels.</entry>
122 </row>
123 <row>
124 <entry>__u32</entry>
125 <entry><structfield>max_height</structfield></entry>
126 <entry>Maximum frame height, in pixels.</entry>
127 </row>
128 <row>
129 <entry>__u32</entry>
130 <entry><structfield>reserved</structfield>[9]</entry>
131 <entry>Reserved for future extensions. Applications and drivers must
132 set the array to zero.</entry>
133 </row>
134 </tbody>
135 </tgroup>
136 </table>
137 </refsect1>
138
139 <refsect1>
140 &return-value;
141
142 <variablelist>
143 <varlistentry>
144 <term><errorcode>EINVAL</errorcode></term>
145 <listitem>
146 <para>The &v4l2-subdev-frame-size-enum; <structfield>pad</structfield>
147 references a non-existing pad, the <structfield>code</structfield> is
148 invalid for the given pad or the <structfield>index</structfield>
149 field is out of bounds.</para>
150 </listitem>
151 </varlistentry>
152 </variablelist>
153 </refsect1>
154</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml b/Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml
new file mode 100644
index 000000000000..a6b3432449f6
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml
@@ -0,0 +1,119 @@
1<refentry id="vidioc-subdev-enum-mbus-code">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_MBUS_CODE</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_ENUM_MBUS_CODE</refname>
9 <refpurpose>Enumerate media bus formats</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_subdev_mbus_code_enum *
19 <parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_SUBDEV_ENUM_MBUS_CODE</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <note>
53 <title>Experimental</title>
54 <para>This is an <link linkend="experimental">experimental</link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>To enumerate media bus formats available at a given sub-device pad
59 applications initialize the <structfield>pad</structfield> and
60 <structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and
61 call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a
62 pointer to this structure. Drivers fill the rest of the structure or return
63 an &EINVAL; if either the <structfield>pad</structfield> or
64 <structfield>index</structfield> are invalid. All media bus formats are
65 enumerable by beginning at index zero and incrementing by one until
66 <errorcode>EINVAL</errorcode> is returned.</para>
67
68 <para>Available media bus formats may depend on the current 'try' formats
69 at other pads of the sub-device, as well as on the current active links. See
70 &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para>
71
72 <table pgwide="1" frame="none" id="v4l2-subdev-mbus-code-enum">
73 <title>struct <structname>v4l2_subdev_mbus_code_enum</structname></title>
74 <tgroup cols="3">
75 &cs-str;
76 <tbody valign="top">
77 <row>
78 <entry>__u32</entry>
79 <entry><structfield>pad</structfield></entry>
80 <entry>Pad number as reported by the media controller API.</entry>
81 </row>
82 <row>
83 <entry>__u32</entry>
84 <entry><structfield>index</structfield></entry>
85 <entry>Number of the format in the enumeration, set by the
86 application.</entry>
87 </row>
88 <row>
89 <entry>__u32</entry>
90 <entry><structfield>code</structfield></entry>
91 <entry>The media bus format code, as defined in
92 <xref linkend="v4l2-mbus-format" />.</entry>
93 </row>
94 <row>
95 <entry>__u32</entry>
96 <entry><structfield>reserved</structfield>[9]</entry>
97 <entry>Reserved for future extensions. Applications and drivers must
98 set the array to zero.</entry>
99 </row>
100 </tbody>
101 </tgroup>
102 </table>
103 </refsect1>
104
105 <refsect1>
106 &return-value;
107
108 <variablelist>
109 <varlistentry>
110 <term><errorcode>EINVAL</errorcode></term>
111 <listitem>
112 <para>The &v4l2-subdev-mbus-code-enum; <structfield>pad</structfield>
113 references a non-existing pad, or the <structfield>index</structfield>
114 field is out of bounds.</para>
115 </listitem>
116 </varlistentry>
117 </variablelist>
118 </refsect1>
119</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
new file mode 100644
index 000000000000..06197323a8cc
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
@@ -0,0 +1,155 @@
1<refentry id="vidioc-subdev-g-crop">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_G_CROP</refname>
9 <refname>VIDIOC_SUBDEV_S_CROP</refname>
10 <refpurpose>Get or set the crop rectangle on a subdev pad</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 <funcsynopsis>
23 <funcprototype>
24 <funcdef>int <function>ioctl</function></funcdef>
25 <paramdef>int <parameter>fd</parameter></paramdef>
26 <paramdef>int <parameter>request</parameter></paramdef>
27 <paramdef>const struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef>
28 </funcprototype>
29 </funcsynopsis>
30 </refsynopsisdiv>
31
32 <refsect1>
33 <title>Arguments</title>
34
35 <variablelist>
36 <varlistentry>
37 <term><parameter>fd</parameter></term>
38 <listitem>
39 <para>&fd;</para>
40 </listitem>
41 </varlistentry>
42 <varlistentry>
43 <term><parameter>request</parameter></term>
44 <listitem>
45 <para>VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</para>
46 </listitem>
47 </varlistentry>
48 <varlistentry>
49 <term><parameter>argp</parameter></term>
50 <listitem>
51 <para></para>
52 </listitem>
53 </varlistentry>
54 </variablelist>
55 </refsect1>
56
57 <refsect1>
58 <title>Description</title>
59
60 <note>
61 <title>Experimental</title>
62 <para>This is an <link linkend="experimental">experimental</link>
63 interface and may change in the future.</para>
64 </note>
65
66 <para>To retrieve the current crop rectangle applications set the
67 <structfield>pad</structfield> field of a &v4l2-subdev-crop; to the
68 desired pad number as reported by the media API and the
69 <structfield>which</structfield> field to
70 <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. They then call the
71 <constant>VIDIOC_SUBDEV_G_CROP</constant> ioctl with a pointer to this
72 structure. The driver fills the members of the <structfield>rect</structfield>
73 field or returns &EINVAL; if the input arguments are invalid, or if cropping
74 is not supported on the given pad.</para>
75
76 <para>To change the current crop rectangle applications set both the
77 <structfield>pad</structfield> and <structfield>which</structfield> fields
78 and all members of the <structfield>rect</structfield> field. They then call
79 the <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctl with a pointer to this
80 structure. The driver verifies the requested crop rectangle, adjusts it
81 based on the hardware capabilities and configures the device. Upon return
82 the &v4l2-subdev-crop; contains the current format as would be returned
83 by a <constant>VIDIOC_SUBDEV_G_CROP</constant> call.</para>
84
85 <para>Applications can query the device capabilities by setting the
86 <structfield>which</structfield> to
87 <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' crop
88 rectangles are not applied to the device by the driver, but are mangled
89 exactly as active crop rectangles and stored in the sub-device file handle.
90 Two applications querying the same sub-device would thus not interact with
91 each other.</para>
92
93 <para>Drivers must not return an error solely because the requested crop
94 rectangle doesn't match the device capabilities. They must instead modify
95 the rectangle to match what the hardware can provide. The modified format
96 should be as close as possible to the original request.</para>
97
98 <table pgwide="1" frame="none" id="v4l2-subdev-crop">
99 <title>struct <structname>v4l2_subdev_crop</structname></title>
100 <tgroup cols="3">
101 &cs-str;
102 <tbody valign="top">
103 <row>
104 <entry>__u32</entry>
105 <entry><structfield>pad</structfield></entry>
106 <entry>Pad number as reported by the media framework.</entry>
107 </row>
108 <row>
109 <entry>__u32</entry>
110 <entry><structfield>which</structfield></entry>
111 <entry>Crop rectangle to get or set, from
112 &v4l2-subdev-format-whence;.</entry>
113 </row>
114 <row>
115 <entry>&v4l2-rect;</entry>
116 <entry><structfield>rect</structfield></entry>
117 <entry>Crop rectangle boundaries, in pixels.</entry>
118 </row>
119 <row>
120 <entry>__u32</entry>
121 <entry><structfield>reserved</structfield>[8]</entry>
122 <entry>Reserved for future extensions. Applications and drivers must
123 set the array to zero.</entry>
124 </row>
125 </tbody>
126 </tgroup>
127 </table>
128 </refsect1>
129
130 <refsect1>
131 &return-value;
132
133 <variablelist>
134 <varlistentry>
135 <term><errorcode>EBUSY</errorcode></term>
136 <listitem>
137 <para>The crop rectangle can't be changed because the pad is currently
138 busy. This can be caused, for instance, by an active video stream on
139 the pad. The ioctl must not be retried without performing another
140 action to fix the problem first. Only returned by
141 <constant>VIDIOC_SUBDEV_S_CROP</constant></para>
142 </listitem>
143 </varlistentry>
144 <varlistentry>
145 <term><errorcode>EINVAL</errorcode></term>
146 <listitem>
147 <para>The &v4l2-subdev-crop; <structfield>pad</structfield>
148 references a non-existing pad, the <structfield>which</structfield>
149 field references a non-existing format, or cropping is not supported
150 on the given subdev pad.</para>
151 </listitem>
152 </varlistentry>
153 </variablelist>
154 </refsect1>
155</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml
new file mode 100644
index 000000000000..f367c570c530
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml
@@ -0,0 +1,180 @@
1<refentry id="vidioc-subdev-g-fmt">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_G_FMT</refname>
9 <refname>VIDIOC_SUBDEV_S_FMT</refname>
10 <refpurpose>Get or set the data format on a subdev pad</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_subdev_format *<parameter>argp</parameter>
20 </paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 </refsynopsisdiv>
24
25 <refsect1>
26 <title>Arguments</title>
27
28 <variablelist>
29 <varlistentry>
30 <term><parameter>fd</parameter></term>
31 <listitem>
32 <para>&fd;</para>
33 </listitem>
34 </varlistentry>
35 <varlistentry>
36 <term><parameter>request</parameter></term>
37 <listitem>
38 <para>VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</para>
39 </listitem>
40 </varlistentry>
41 <varlistentry>
42 <term><parameter>argp</parameter></term>
43 <listitem>
44 <para></para>
45 </listitem>
46 </varlistentry>
47 </variablelist>
48 </refsect1>
49
50 <refsect1>
51 <title>Description</title>
52
53 <note>
54 <title>Experimental</title>
55 <para>This is an <link linkend="experimental">experimental</link>
56 interface and may change in the future.</para>
57 </note>
58
59 <para>These ioctls are used to negotiate the frame format at specific
60 subdev pads in the image pipeline.</para>
61
62 <para>To retrieve the current format applications set the
63 <structfield>pad</structfield> field of a &v4l2-subdev-format; to the
64 desired pad number as reported by the media API and the
65 <structfield>which</structfield> field to
66 <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. When they call the
67 <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl with a pointer to this
68 structure the driver fills the members of the <structfield>format</structfield>
69 field.</para>
70
71 <para>To change the current format applications set both the
72 <structfield>pad</structfield> and <structfield>which</structfield> fields
73 and all members of the <structfield>format</structfield> field. When they
74 call the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl with a pointer to this
75 structure the driver verifies the requested format, adjusts it based on the
76 hardware capabilities and configures the device. Upon return the
77 &v4l2-subdev-format; contains the current format as would be returned by a
78 <constant>VIDIOC_SUBDEV_G_FMT</constant> call.</para>
79
80 <para>Applications can query the device capabilities by setting the
81 <structfield>which</structfield> to
82 <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' formats are not
83 applied to the device by the driver, but are changed exactly as active
84 formats and stored in the sub-device file handle. Two applications querying
85 the same sub-device would thus not interact with each other.</para>
86
87 <para>For instance, to try a format at the output pad of a sub-device,
88 applications would first set the try format at the sub-device input with the
89 <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl. They would then either
90 retrieve the default format at the output pad with the
91 <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl, or set the desired output
92 pad format with the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl and check
93 the returned value.</para>
94
95 <para>Try formats do not depend on active formats, but can depend on the
96 current links configuration or sub-device controls value. For instance, a
97 low-pass noise filter might crop pixels at the frame boundaries, modifying
98 its output frame size.</para>
99
100 <para>Drivers must not return an error solely because the requested format
101 doesn't match the device capabilities. They must instead modify the format
102 to match what the hardware can provide. The modified format should be as
103 close as possible to the original request.</para>
104
105 <table pgwide="1" frame="none" id="v4l2-subdev-format">
106 <title>struct <structname>v4l2_subdev_format</structname></title>
107 <tgroup cols="3">
108 &cs-str;
109 <tbody valign="top">
110 <row>
111 <entry>__u32</entry>
112 <entry><structfield>pad</structfield></entry>
113 <entry>Pad number as reported by the media controller API.</entry>
114 </row>
115 <row>
116 <entry>__u32</entry>
117 <entry><structfield>which</structfield></entry>
118 <entry>Format to modified, from &v4l2-subdev-format-whence;.</entry>
119 </row>
120 <row>
121 <entry>&v4l2-mbus-framefmt;</entry>
122 <entry><structfield>format</structfield></entry>
123 <entry>Definition of an image format, see <xref
124 linkend="v4l2-mbus-framefmt" /> for details.</entry>
125 </row>
126 <row>
127 <entry>__u32</entry>
128 <entry><structfield>reserved</structfield>[8]</entry>
129 <entry>Reserved for future extensions. Applications and drivers must
130 set the array to zero.</entry>
131 </row>
132 </tbody>
133 </tgroup>
134 </table>
135
136 <table pgwide="1" frame="none" id="v4l2-subdev-format-whence">
137 <title>enum <structname>v4l2_subdev_format_whence</structname></title>
138 <tgroup cols="3">
139 &cs-def;
140 <tbody valign="top">
141 <row>
142 <entry>V4L2_SUBDEV_FORMAT_TRY</entry>
143 <entry>0</entry>
144 <entry>Try formats, used for querying device capabilities.</entry>
145 </row>
146 <row>
147 <entry>V4L2_SUBDEV_FORMAT_ACTIVE</entry>
148 <entry>1</entry>
149 <entry>Active formats, applied to the hardware.</entry>
150 </row>
151 </tbody>
152 </tgroup>
153 </table>
154 </refsect1>
155
156 <refsect1>
157 &return-value;
158
159 <variablelist>
160 <varlistentry>
161 <term><errorcode>EBUSY</errorcode></term>
162 <listitem>
163 <para>The format can't be changed because the pad is currently busy.
164 This can be caused, for instance, by an active video stream on the
165 pad. The ioctl must not be retried without performing another action
166 to fix the problem first. Only returned by
167 <constant>VIDIOC_SUBDEV_S_FMT</constant></para>
168 </listitem>
169 </varlistentry>
170 <varlistentry>
171 <term><errorcode>EINVAL</errorcode></term>
172 <listitem>
173 <para>The &v4l2-subdev-format; <structfield>pad</structfield>
174 references a non-existing pad, or the <structfield>which</structfield>
175 field references a non-existing format.</para>
176 </listitem>
177 </varlistentry>
178 </variablelist>
179 </refsect1>
180</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml
new file mode 100644
index 000000000000..0bc3ea22d31f
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml
@@ -0,0 +1,141 @@
1<refentry id="vidioc-subdev-g-frame-interval">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_G_FRAME_INTERVAL</refname>
9 <refname>VIDIOC_SUBDEV_S_FRAME_INTERVAL</refname>
10 <refpurpose>Get or set the frame interval on a subdev pad</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_subdev_frame_interval *<parameter>argp</parameter>
20 </paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 </refsynopsisdiv>
24
25 <refsect1>
26 <title>Arguments</title>
27
28 <variablelist>
29 <varlistentry>
30 <term><parameter>fd</parameter></term>
31 <listitem>
32 <para>&fd;</para>
33 </listitem>
34 </varlistentry>
35 <varlistentry>
36 <term><parameter>request</parameter></term>
37 <listitem>
38 <para>VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</para>
39 </listitem>
40 </varlistentry>
41 <varlistentry>
42 <term><parameter>argp</parameter></term>
43 <listitem>
44 <para></para>
45 </listitem>
46 </varlistentry>
47 </variablelist>
48 </refsect1>
49
50 <refsect1>
51 <title>Description</title>
52
53 <note>
54 <title>Experimental</title>
55 <para>This is an <link linkend="experimental">experimental</link>
56 interface and may change in the future.</para>
57 </note>
58
59 <para>These ioctls are used to get and set the frame interval at specific
60 subdev pads in the image pipeline. The frame interval only makes sense for
61 sub-devices that can control the frame period on their own. This includes,
62 for instance, image sensors and TV tuners. Sub-devices that don't support
63 frame intervals must not implement these ioctls.</para>
64
65 <para>To retrieve the current frame interval applications set the
66 <structfield>pad</structfield> field of a &v4l2-subdev-frame-interval; to
67 the desired pad number as reported by the media controller API. When they
68 call the <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> ioctl with a
69 pointer to this structure the driver fills the members of the
70 <structfield>interval</structfield> field.</para>
71
72 <para>To change the current frame interval applications set both the
73 <structfield>pad</structfield> field and all members of the
74 <structfield>interval</structfield> field. When they call the
75 <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant> ioctl with a pointer to
76 this structure the driver verifies the requested interval, adjusts it based
77 on the hardware capabilities and configures the device. Upon return the
78 &v4l2-subdev-frame-interval; contains the current frame interval as would be
79 returned by a <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> call.
80 </para>
81
82 <para>Drivers must not return an error solely because the requested interval
83 doesn't match the device capabilities. They must instead modify the interval
84 to match what the hardware can provide. The modified interval should be as
85 close as possible to the original request.</para>
86
87 <para>Sub-devices that support the frame interval ioctls should implement
88 them on a single pad only. Their behaviour when supported on multiple pads
89 of the same sub-device is not defined.</para>
90
91 <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval">
92 <title>struct <structname>v4l2_subdev_frame_interval</structname></title>
93 <tgroup cols="3">
94 &cs-str;
95 <tbody valign="top">
96 <row>
97 <entry>__u32</entry>
98 <entry><structfield>pad</structfield></entry>
99 <entry>Pad number as reported by the media controller API.</entry>
100 </row>
101 <row>
102 <entry>&v4l2-fract;</entry>
103 <entry><structfield>interval</structfield></entry>
104 <entry>Period, in seconds, between consecutive video frames.</entry>
105 </row>
106 <row>
107 <entry>__u32</entry>
108 <entry><structfield>reserved</structfield>[9]</entry>
109 <entry>Reserved for future extensions. Applications and drivers must
110 set the array to zero.</entry>
111 </row>
112 </tbody>
113 </tgroup>
114 </table>
115 </refsect1>
116
117 <refsect1>
118 &return-value;
119
120 <variablelist>
121 <varlistentry>
122 <term><errorcode>EBUSY</errorcode></term>
123 <listitem>
124 <para>The frame interval can't be changed because the pad is currently
125 busy. This can be caused, for instance, by an active video stream on
126 the pad. The ioctl must not be retried without performing another
127 action to fix the problem first. Only returned by
128 <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></para>
129 </listitem>
130 </varlistentry>
131 <varlistentry>
132 <term><errorcode>EINVAL</errorcode></term>
133 <listitem>
134 <para>The &v4l2-subdev-frame-interval; <structfield>pad</structfield>
135 references a non-existing pad, or the pad doesn't support frame
136 intervals.</para>
137 </listitem>
138 </varlistentry>
139 </variablelist>
140 </refsect1>
141</refentry>
diff --git a/Documentation/acpi/apei/output_format.txt b/Documentation/acpi/apei/output_format.txt
index 9146952c612a..0c49c197c47a 100644
--- a/Documentation/acpi/apei/output_format.txt
+++ b/Documentation/acpi/apei/output_format.txt
@@ -92,6 +92,11 @@ vendor_id: <integer>, device_id: <integer>
92class_code: <integer>] 92class_code: <integer>]
93[serial number: <integer>, <integer>] 93[serial number: <integer>, <integer>]
94[bridge: secondary_status: <integer>, control: <integer>] 94[bridge: secondary_status: <integer>, control: <integer>]
95[aer_status: <integer>, aer_mask: <integer>
96<aer status string>
97[aer_uncor_severity: <integer>]
98aer_layer=<aer layer string>, aer_agent=<aer agent string>
99aer_tlp_header: <integer> <integer> <integer> <integer>]
95 100
96<pcie port type string>* := PCIe end point | legacy PCI end point | \ 101<pcie port type string>* := PCIe end point | legacy PCI end point | \
97unknown | unknown | root port | upstream switch port | \ 102unknown | unknown | root port | upstream switch port | \
@@ -99,6 +104,26 @@ downstream switch port | PCIe to PCI/PCI-X bridge | \
99PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \ 104PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \
100root complex event collector 105root complex event collector
101 106
107if section severity is fatal or recoverable
108<aer status string># :=
109unknown | unknown | unknown | unknown | Data Link Protocol | \
110unknown | unknown | unknown | unknown | unknown | unknown | unknown | \
111Poisoned TLP | Flow Control Protocol | Completion Timeout | \
112Completer Abort | Unexpected Completion | Receiver Overflow | \
113Malformed TLP | ECRC | Unsupported Request
114else
115<aer status string># :=
116Receiver Error | unknown | unknown | unknown | unknown | unknown | \
117Bad TLP | Bad DLLP | RELAY_NUM Rollover | unknown | unknown | unknown | \
118Replay Timer Timeout | Advisory Non-Fatal
119fi
120
121<aer layer string> :=
122Physical Layer | Data Link Layer | Transaction Layer
123
124<aer agent string> :=
125Receiver ID | Requester ID | Completer ID | Transmitter ID
126
102Where, [] designate corresponding content is optional 127Where, [] designate corresponding content is optional
103 128
104All <field string> description with * has the following format: 129All <field string> description with * has the following format:
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index b9a83dd24732..2a7b38c832c7 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -963,11 +963,6 @@ elevator_dispatch_fn* fills the dispatch queue with ready requests.
963 963
964elevator_add_req_fn* called to add a new request into the scheduler 964elevator_add_req_fn* called to add a new request into the scheduler
965 965
966elevator_queue_empty_fn returns true if the merge queue is empty.
967 Drivers shouldn't use this, but rather check
968 if elv_next_request is NULL (without losing the
969 request if one exists!)
970
971elevator_former_req_fn 966elevator_former_req_fn
972elevator_latter_req_fn These return the request before or after the 967elevator_latter_req_fn These return the request before or after the
973 one specified in disk sort order. Used by the 968 one specified in disk sort order. Used by the
diff --git a/Documentation/cgroups/blkio-controller.txt b/Documentation/cgroups/blkio-controller.txt
index 4ed7b5ceeed2..465351d4cf85 100644
--- a/Documentation/cgroups/blkio-controller.txt
+++ b/Documentation/cgroups/blkio-controller.txt
@@ -140,7 +140,7 @@ Proportional weight policy files
140 - Specifies per cgroup weight. This is default weight of the group 140 - Specifies per cgroup weight. This is default weight of the group
141 on all the devices until and unless overridden by per device rule. 141 on all the devices until and unless overridden by per device rule.
142 (See blkio.weight_device). 142 (See blkio.weight_device).
143 Currently allowed range of weights is from 100 to 1000. 143 Currently allowed range of weights is from 10 to 1000.
144 144
145- blkio.weight_device 145- blkio.weight_device
146 - One can specify per cgroup per device rules using this interface. 146 - One can specify per cgroup per device rules using this interface.
@@ -343,34 +343,6 @@ Common files among various policies
343 343
344CFQ sysfs tunable 344CFQ sysfs tunable
345================= 345=================
346/sys/block/<disk>/queue/iosched/group_isolation
347-----------------------------------------------
348
349If group_isolation=1, it provides stronger isolation between groups at the
350expense of throughput. By default group_isolation is 0. In general that
351means that if group_isolation=0, expect fairness for sequential workload
352only. Set group_isolation=1 to see fairness for random IO workload also.
353
354Generally CFQ will put random seeky workload in sync-noidle category. CFQ
355will disable idling on these queues and it does a collective idling on group
356of such queues. Generally these are slow moving queues and if there is a
357sync-noidle service tree in each group, that group gets exclusive access to
358disk for certain period. That means it will bring the throughput down if
359group does not have enough IO to drive deeper queue depths and utilize disk
360capacity to the fullest in the slice allocated to it. But the flip side is
361that even a random reader should get better latencies and overall throughput
362if there are lots of sequential readers/sync-idle workload running in the
363system.
364
365If group_isolation=0, then CFQ automatically moves all the random seeky queues
366in the root group. That means there will be no service differentiation for
367that kind of workload. This leads to better throughput as we do collective
368idling on root sync-noidle tree.
369
370By default one should run with group_isolation=0. If that is not sufficient
371and one wants stronger isolation between groups, then set group_isolation=1
372but this will come at cost of reduced throughput.
373
374/sys/block/<disk>/queue/iosched/slice_idle 346/sys/block/<disk>/queue/iosched/slice_idle
375------------------------------------------ 347------------------------------------------
376On a faster hardware CFQ can be slow, especially with sequential workload. 348On a faster hardware CFQ can be slow, especially with sequential workload.
diff --git a/Documentation/devicetree/bindings/fb/sm501fb.txt b/Documentation/devicetree/bindings/fb/sm501fb.txt
new file mode 100644
index 000000000000..7d319fba9b5b
--- /dev/null
+++ b/Documentation/devicetree/bindings/fb/sm501fb.txt
@@ -0,0 +1,34 @@
1* SM SM501
2
3The SM SM501 is a LCD controller, with proper hardware, it can also
4drive DVI monitors.
5
6Required properties:
7- compatible : should be "smi,sm501".
8- reg : contain two entries:
9 - First entry: System Configuration register
10 - Second entry: IO space (Display Controller register)
11- interrupts : SMI interrupt to the cpu should be described here.
12- interrupt-parent : the phandle for the interrupt controller that
13 services interrupts for this device.
14
15Optional properties:
16- mode : select a video mode:
17 <xres>x<yres>[-<bpp>][@<refresh>]
18- edid : verbatim EDID data block describing attached display.
19 Data from the detailed timing descriptor will be used to
20 program the display controller.
21- little-endian: availiable on big endian systems, to
22 set different foreign endian.
23- big-endian: availiable on little endian systems, to
24 set different foreign endian.
25
26Example for MPC5200:
27 display@1,0 {
28 compatible = "smi,sm501";
29 reg = <1 0x00000000 0x00800000
30 1 0x03e00000 0x00200000>;
31 interrupts = <1 1 3>;
32 mode = "640x480-32@60";
33 edid = [edid-data];
34 };
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 59690de8ebfe..3348d313fbe0 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -556,6 +556,9 @@ sub ngene {
556 my $hash1 = "d798d5a757121174f0dbc5f2833c0c85"; 556 my $hash1 = "d798d5a757121174f0dbc5f2833c0c85";
557 my $file2 = "ngene_17.fw"; 557 my $file2 = "ngene_17.fw";
558 my $hash2 = "26b687136e127b8ac24b81e0eeafc20b"; 558 my $hash2 = "26b687136e127b8ac24b81e0eeafc20b";
559 my $url2 = "http://l4m-daten.de/downloads/firmware/dvb-s2/linux/all/";
560 my $file3 = "ngene_18.fw";
561 my $hash3 = "ebce3ea769a53e3e0b0197c3b3f127e3";
559 562
560 checkstandard(); 563 checkstandard();
561 564
@@ -565,7 +568,10 @@ sub ngene {
565 wgetfile($file2, $url . $file2); 568 wgetfile($file2, $url . $file2);
566 verify($file2, $hash2); 569 verify($file2, $hash2);
567 570
568 "$file1, $file2"; 571 wgetfile($file3, $url2 . $file3);
572 verify($file3, $hash3);
573
574 "$file1, $file2, $file3";
569} 575}
570 576
571sub az6027{ 577sub az6027{
diff --git a/Documentation/dvb/lmedm04.txt b/Documentation/dvb/lmedm04.txt
index 641886504201..10b5f0411386 100644
--- a/Documentation/dvb/lmedm04.txt
+++ b/Documentation/dvb/lmedm04.txt
@@ -4,7 +4,7 @@ following file(s) to this directory.
4for DM04+/QQBOX LME2510C (Sharp 7395 Tuner) 4for DM04+/QQBOX LME2510C (Sharp 7395 Tuner)
5------------------------------------------- 5-------------------------------------------
6 6
7The Sharp 7395 driver can be found in windows/system32/driver 7The Sharp 7395 driver can be found in windows/system32/drivers
8 8
9US2A0D.sys (dated 17 Mar 2009) 9US2A0D.sys (dated 17 Mar 2009)
10 10
@@ -44,7 +44,7 @@ and run
44 44
45 45
46Other LG firmware can be extracted manually from US280D.sys 46Other LG firmware can be extracted manually from US280D.sys
47only found in windows/system32/driver. 47only found in windows/system32/drivers
48 48
49dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw 49dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw
50 50
@@ -55,4 +55,16 @@ dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw
55 55
56--------------------------------------------------------------------- 56---------------------------------------------------------------------
57 57
58The Sharp 0194 tuner driver can be found in windows/system32/drivers
59
60US290D.sys (dated 09 Apr 2009)
61
62For LME2510
63dd if=US290D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-s0194.fw
64
65
66For LME2510C
67dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw
68
69
58Copy the firmware file(s) to /lib/firmware 70Copy the firmware file(s) to /lib/firmware
diff --git a/Documentation/fb/sm501.txt b/Documentation/fb/sm501.txt
new file mode 100644
index 000000000000..8d17aebd2648
--- /dev/null
+++ b/Documentation/fb/sm501.txt
@@ -0,0 +1,10 @@
1Configuration:
2
3You can pass the following kernel command line options to sm501 videoframebuffer:
4
5 sm501fb.bpp= SM501 Display driver:
6 Specifiy bits-per-pixel if not specified by 'mode'
7
8 sm501fb.mode= SM501 Display driver:
9 Specify resolution as
10 "<xres>x<yres>[-<bpp>][@<refresh>]"
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 895330940f5d..274b32d12532 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -108,42 +108,6 @@ Who: Pavel Machek <pavel@ucw.cz>
108 108
109--------------------------- 109---------------------------
110 110
111What: Video4Linux obsolete drivers using V4L1 API
112When: kernel 2.6.39
113Files: drivers/staging/se401/* drivers/staging/usbvideo/*
114Check: drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c
115Why: There are some drivers still using V4L1 API, despite all efforts we've done
116 to migrate. Those drivers are for obsolete hardware that the old maintainer
117 didn't care (or not have the hardware anymore), and that no other developer
118 could find any hardware to buy. They probably have no practical usage today,
119 and people with such old hardware could probably keep using an older version
120 of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody
121 cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39.
122Who: Mauro Carvalho Chehab <mchehab@infradead.org>
123
124---------------------------
125
126What: Video4Linux: Remove obsolete ioctl's
127When: kernel 2.6.39
128Files: include/media/videodev2.h
129Why: Some ioctl's were defined wrong on 2.6.2 and 2.6.6, using the wrong
130 type of R/W arguments. They were fixed, but the old ioctl names are
131 still there, maintained to avoid breaking binary compatibility:
132 #define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
133 #define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm)
134 #define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control)
135 #define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio)
136 #define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout)
137 #define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap)
138 There's no sense on preserving those forever, as it is very doubtful
139 that someone would try to use a such old binary with a modern kernel.
140 Removing them will allow us to remove some magic done at the V4L ioctl
141 handler.
142
143Who: Mauro Carvalho Chehab <mchehab@infradead.org>
144
145---------------------------
146
147What: sys_sysctl 111What: sys_sysctl
148When: September 2010 112When: September 2010
149Option: CONFIG_SYSCTL_SYSCALL 113Option: CONFIG_SYSCTL_SYSCALL
@@ -270,14 +234,6 @@ Who: Zhang Rui <rui.zhang@intel.com>
270 234
271--------------------------- 235---------------------------
272 236
273What: /proc/acpi/button
274When: August 2007
275Why: /proc/acpi/button has been replaced by events to the input layer
276 since 2.6.20.
277Who: Len Brown <len.brown@intel.com>
278
279---------------------------
280
281What: /proc/acpi/event 237What: /proc/acpi/event
282When: February 2008 238When: February 2008
283Why: /proc/acpi/event has been replaced by events via the input layer 239Why: /proc/acpi/event has been replaced by events via the input layer
diff --git a/Documentation/filesystems/exofs.txt b/Documentation/filesystems/exofs.txt
index abd2a9b5b787..23583a136975 100644
--- a/Documentation/filesystems/exofs.txt
+++ b/Documentation/filesystems/exofs.txt
@@ -104,7 +104,15 @@ Where:
104 exofs specific options: Options are separated by commas (,) 104 exofs specific options: Options are separated by commas (,)
105 pid=<integer> - The partition number to mount/create as 105 pid=<integer> - The partition number to mount/create as
106 container of the filesystem. 106 container of the filesystem.
107 This option is mandatory. 107 This option is mandatory. integer can be
108 Hex by pre-pending an 0x to the number.
109 osdname=<id> - Mount by a device's osdname.
110 osdname is usually a 36 character uuid of the
111 form "d2683732-c906-4ee1-9dbd-c10c27bb40df".
112 It is one of the device's uuid specified in the
113 mkfs.exofs format command.
114 If this option is specified then the /dev/osdX
115 above can be empty and is ignored.
108 to=<integer> - Timeout in ticks for a single command. 116 to=<integer> - Timeout in ticks for a single command.
109 default is (60 * HZ) [for debugging only] 117 default is (60 * HZ) [for debugging only]
110 118
diff --git a/Documentation/filesystems/squashfs.txt b/Documentation/filesystems/squashfs.txt
index 66699afd66ca..2d78f1911844 100644
--- a/Documentation/filesystems/squashfs.txt
+++ b/Documentation/filesystems/squashfs.txt
@@ -59,12 +59,15 @@ obtained from this site also.
593. SQUASHFS FILESYSTEM DESIGN 593. SQUASHFS FILESYSTEM DESIGN
60----------------------------- 60-----------------------------
61 61
62A squashfs filesystem consists of a maximum of eight parts, packed together on a byte 62A squashfs filesystem consists of a maximum of nine parts, packed together on a
63alignment: 63byte alignment:
64 64
65 --------------- 65 ---------------
66 | superblock | 66 | superblock |
67 |---------------| 67 |---------------|
68 | compression |
69 | options |
70 |---------------|
68 | datablocks | 71 | datablocks |
69 | & fragments | 72 | & fragments |
70 |---------------| 73 |---------------|
@@ -91,7 +94,14 @@ the source directory, and checked for duplicates. Once all file data has been
91written the completed inode, directory, fragment, export and uid/gid lookup 94written the completed inode, directory, fragment, export and uid/gid lookup
92tables are written. 95tables are written.
93 96
943.1 Inodes 973.1 Compression options
98-----------------------
99
100Compressors can optionally support compression specific options (e.g.
101dictionary size). If non-default compression options have been used, then
102these are stored here.
103
1043.2 Inodes
95---------- 105----------
96 106
97Metadata (inodes and directories) are compressed in 8Kbyte blocks. Each 107Metadata (inodes and directories) are compressed in 8Kbyte blocks. Each
@@ -114,7 +124,7 @@ directory inode are defined: inodes optimised for frequently occurring
114regular files and directories, and extended types where extra 124regular files and directories, and extended types where extra
115information has to be stored. 125information has to be stored.
116 126
1173.2 Directories 1273.3 Directories
118--------------- 128---------------
119 129
120Like inodes, directories are packed into compressed metadata blocks, stored 130Like inodes, directories are packed into compressed metadata blocks, stored
@@ -144,7 +154,7 @@ decompressed to do a lookup irrespective of the length of the directory.
144This scheme has the advantage that it doesn't require extra memory overhead 154This scheme has the advantage that it doesn't require extra memory overhead
145and doesn't require much extra storage on disk. 155and doesn't require much extra storage on disk.
146 156
1473.3 File data 1573.4 File data
148------------- 158-------------
149 159
150Regular files consist of a sequence of contiguous compressed blocks, and/or a 160Regular files consist of a sequence of contiguous compressed blocks, and/or a
@@ -163,7 +173,7 @@ Larger files use multiple slots, with 1.75 TiB files using all 8 slots.
163The index cache is designed to be memory efficient, and by default uses 173The index cache is designed to be memory efficient, and by default uses
16416 KiB. 17416 KiB.
165 175
1663.4 Fragment lookup table 1763.5 Fragment lookup table
167------------------------- 177-------------------------
168 178
169Regular files can contain a fragment index which is mapped to a fragment 179Regular files can contain a fragment index which is mapped to a fragment
@@ -173,7 +183,7 @@ A second index table is used to locate these. This second index table for
173speed of access (and because it is small) is read at mount time and cached 183speed of access (and because it is small) is read at mount time and cached
174in memory. 184in memory.
175 185
1763.5 Uid/gid lookup table 1863.6 Uid/gid lookup table
177------------------------ 187------------------------
178 188
179For space efficiency regular files store uid and gid indexes, which are 189For space efficiency regular files store uid and gid indexes, which are
@@ -182,7 +192,7 @@ stored compressed into metadata blocks. A second index table is used to
182locate these. This second index table for speed of access (and because it 192locate these. This second index table for speed of access (and because it
183is small) is read at mount time and cached in memory. 193is small) is read at mount time and cached in memory.
184 194
1853.6 Export table 1953.7 Export table
186---------------- 196----------------
187 197
188To enable Squashfs filesystems to be exportable (via NFS etc.) filesystems 198To enable Squashfs filesystems to be exportable (via NFS etc.) filesystems
@@ -196,7 +206,7 @@ This table is stored compressed into metadata blocks. A second index table is
196used to locate these. This second index table for speed of access (and because 206used to locate these. This second index table for speed of access (and because
197it is small) is read at mount time and cached in memory. 207it is small) is read at mount time and cached in memory.
198 208
1993.7 Xattr table 2093.8 Xattr table
200--------------- 210---------------
201 211
202The xattr table contains extended attributes for each inode. The xattrs 212The xattr table contains extended attributes for each inode. The xattrs
diff --git a/Documentation/hwmon/twl4030-madc-hwmon b/Documentation/hwmon/twl4030-madc-hwmon
new file mode 100644
index 000000000000..ef7984317cec
--- /dev/null
+++ b/Documentation/hwmon/twl4030-madc-hwmon
@@ -0,0 +1,45 @@
1Kernel driver twl4030-madc
2=========================
3
4Supported chips:
5 * Texas Instruments TWL4030
6 Prefix: 'twl4030-madc'
7
8
9Authors:
10 J Keerthy <j-keerthy@ti.com>
11
12Description
13-----------
14
15The Texas Instruments TWL4030 is a Power Management and Audio Circuit. Among
16other things it contains a 10-bit A/D converter MADC. The converter has 16
17channels which can be used in different modes.
18
19
20See this table for the meaning of the different channels
21
22Channel Signal
23------------------------------------------
240 Battery type(BTYPE)
251 BCI: Battery temperature (BTEMP)
262 GP analog input
273 GP analog input
284 GP analog input
295 GP analog input
306 GP analog input
317 GP analog input
328 BCI: VBUS voltage(VBUS)
339 Backup Battery voltage (VBKP)
3410 BCI: Battery charger current (ICHG)
3511 BCI: Battery charger voltage (VCHG)
3612 BCI: Main battery voltage (VBAT)
3713 Reserved
3814 Reserved
3915 VRUSB Supply/Speaker left/Speaker right polarization level
40
41
42The Sysfs nodes will represent the voltage in the units of mV,
43the temperature channel shows the converted temperature in
44degree celcius. The Battery charging current channel represents
45battery charging current in mA.
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index e68543f767d5..a0a5d82b6b0b 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -273,6 +273,7 @@ Code Seq#(hex) Include File Comments
273'z' 40-7F CAN bus card conflict! 273'z' 40-7F CAN bus card conflict!
274 <mailto:oe@port.de> 274 <mailto:oe@port.de>
275'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict! 275'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict!
276'|' 00-7F linux/media.h
2760x80 00-1F linux/fb.h 2770x80 00-1F linux/fb.h
2770x89 00-06 arch/x86/include/asm/sockios.h 2780x89 00-06 arch/x86/include/asm/sockios.h
2780x89 0B-DF linux/sockios.h 2790x89 0B-DF linux/sockios.h
diff --git a/Documentation/iostats.txt b/Documentation/iostats.txt
index f6dece5b7014..c76c21d87e85 100644
--- a/Documentation/iostats.txt
+++ b/Documentation/iostats.txt
@@ -1,8 +1,6 @@
1I/O statistics fields 1I/O statistics fields
2--------------- 2---------------
3 3
4Last modified Sep 30, 2003
5
6Since 2.4.20 (and some versions before, with patches), and 2.5.45, 4Since 2.4.20 (and some versions before, with patches), and 2.5.45,
7more extensive disk statistics have been introduced to help measure disk 5more extensive disk statistics have been introduced to help measure disk
8activity. Tools such as sar and iostat typically interpret these and do 6activity. Tools such as sar and iostat typically interpret these and do
@@ -46,11 +44,12 @@ the above example, the first field of statistics would be 446216.
46By contrast, in 2.6 if you look at /sys/block/hda/stat, you'll 44By contrast, in 2.6 if you look at /sys/block/hda/stat, you'll
47find just the eleven fields, beginning with 446216. If you look at 45find just the eleven fields, beginning with 446216. If you look at
48/proc/diskstats, the eleven fields will be preceded by the major and 46/proc/diskstats, the eleven fields will be preceded by the major and
49minor device numbers, and device name. Each of these formats provide 47minor device numbers, and device name. Each of these formats provides
50eleven fields of statistics, each meaning exactly the same things. 48eleven fields of statistics, each meaning exactly the same things.
51All fields except field 9 are cumulative since boot. Field 9 should 49All fields except field 9 are cumulative since boot. Field 9 should
52go to zero as I/Os complete; all others only increase. Yes, these are 50go to zero as I/Os complete; all others only increase (unless they
5332 bit unsigned numbers, and on a very busy or long-lived system they 51overflow and wrap). Yes, these are (32-bit or 64-bit) unsigned long
52(native word size) numbers, and on a very busy or long-lived system they
54may wrap. Applications should be prepared to deal with that; unless 53may wrap. Applications should be prepared to deal with that; unless
55your observations are measured in large numbers of minutes or hours, 54your observations are measured in large numbers of minutes or hours,
56they should not wrap twice before you notice them. 55they should not wrap twice before you notice them.
@@ -96,11 +95,11 @@ introduced when changes collide, so (for instance) adding up all the
96read I/Os issued per partition should equal those made to the disks ... 95read I/Os issued per partition should equal those made to the disks ...
97but due to the lack of locking it may only be very close. 96but due to the lack of locking it may only be very close.
98 97
99In 2.6, there are counters for each cpu, which made the lack of locking 98In 2.6, there are counters for each CPU, which make the lack of locking
100almost a non-issue. When the statistics are read, the per-cpu counters 99almost a non-issue. When the statistics are read, the per-CPU counters
101are summed (possibly overflowing the unsigned 32-bit variable they are 100are summed (possibly overflowing the unsigned long variable they are
102summed to) and the result given to the user. There is no convenient 101summed to) and the result given to the user. There is no convenient
103user interface for accessing the per-cpu counters themselves. 102user interface for accessing the per-CPU counters themselves.
104 103
105Disks vs Partitions 104Disks vs Partitions
106------------------- 105-------------------
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
new file mode 100644
index 000000000000..fd48add02cb0
--- /dev/null
+++ b/Documentation/media-framework.txt
@@ -0,0 +1,353 @@
1Linux kernel media framework
2============================
3
4This document describes the Linux kernel media framework, its data structures,
5functions and their usage.
6
7
8Introduction
9------------
10
11The media controller API is documented in DocBook format in
12Documentation/DocBook/v4l/media-controller.xml. This document will focus on
13the kernel-side implementation of the media framework.
14
15
16Abstract media device model
17---------------------------
18
19Discovering a device internal topology, and configuring it at runtime, is one
20of the goals of the media framework. To achieve this, hardware devices are
21modeled as an oriented graph of building blocks called entities connected
22through pads.
23
24An entity is a basic media hardware building block. It can correspond to
25a large variety of logical blocks such as physical hardware devices
26(CMOS sensor for instance), logical hardware devices (a building block
27in a System-on-Chip image processing pipeline), DMA channels or physical
28connectors.
29
30A pad is a connection endpoint through which an entity can interact with
31other entities. Data (not restricted to video) produced by an entity
32flows from the entity's output to one or more entity inputs. Pads should
33not be confused with physical pins at chip boundaries.
34
35A link is a point-to-point oriented connection between two pads, either
36on the same entity or on different entities. Data flows from a source
37pad to a sink pad.
38
39
40Media device
41------------
42
43A media device is represented by a struct media_device instance, defined in
44include/media/media-device.h. Allocation of the structure is handled by the
45media device driver, usually by embedding the media_device instance in a
46larger driver-specific structure.
47
48Drivers register media device instances by calling
49
50 media_device_register(struct media_device *mdev);
51
52The caller is responsible for initializing the media_device structure before
53registration. The following fields must be set:
54
55 - dev must point to the parent device (usually a pci_dev, usb_interface or
56 platform_device instance).
57
58 - model must be filled with the device model name as a NUL-terminated UTF-8
59 string. The device/model revision must not be stored in this field.
60
61The following fields are optional:
62
63 - serial is a unique serial number stored as a NUL-terminated ASCII string.
64 The field is big enough to store a GUID in text form. If the hardware
65 doesn't provide a unique serial number this field must be left empty.
66
67 - bus_info represents the location of the device in the system as a
68 NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to
69 "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices,
70 the usb_make_path() function must be used. This field is used by
71 applications to distinguish between otherwise identical devices that don't
72 provide a serial number.
73
74 - hw_revision is the hardware device revision in a driver-specific format.
75 When possible the revision should be formatted with the KERNEL_VERSION
76 macro.
77
78 - driver_version is formatted with the KERNEL_VERSION macro. The version
79 minor must be incremented when new features are added to the userspace API
80 without breaking binary compatibility. The version major must be
81 incremented when binary compatibility is broken.
82
83Upon successful registration a character device named media[0-9]+ is created.
84The device major and minor numbers are dynamic. The model name is exported as
85a sysfs attribute.
86
87Drivers unregister media device instances by calling
88
89 media_device_unregister(struct media_device *mdev);
90
91Unregistering a media device that hasn't been registered is *NOT* safe.
92
93
94Entities, pads and links
95------------------------
96
97- Entities
98
99Entities are represented by a struct media_entity instance, defined in
100include/media/media-entity.h. The structure is usually embedded into a
101higher-level structure, such as a v4l2_subdev or video_device instance,
102although drivers can allocate entities directly.
103
104Drivers initialize entities by calling
105
106 media_entity_init(struct media_entity *entity, u16 num_pads,
107 struct media_pad *pads, u16 extra_links);
108
109The media_entity name, type, flags, revision and group_id fields can be
110initialized before or after calling media_entity_init. Entities embedded in
111higher-level standard structures can have some of those fields set by the
112higher-level framework.
113
114As the number of pads is known in advance, the pads array is not allocated
115dynamically but is managed by the entity driver. Most drivers will embed the
116pads array in a driver-specific structure, avoiding dynamic allocation.
117
118Drivers must set the direction of every pad in the pads array before calling
119media_entity_init. The function will initialize the other pads fields.
120
121Unlike the number of pads, the total number of links isn't always known in
122advance by the entity driver. As an initial estimate, media_entity_init
123pre-allocates a number of links equal to the number of pads plus an optional
124number of extra links. The links array will be reallocated if it grows beyond
125the initial estimate.
126
127Drivers register entities with a media device by calling
128
129 media_device_register_entity(struct media_device *mdev,
130 struct media_entity *entity);
131
132Entities are identified by a unique positive integer ID. Drivers can provide an
133ID by filling the media_entity id field prior to registration, or request the
134media controller framework to assign an ID automatically. Drivers that provide
135IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be
136contiguous even when they are all assigned automatically by the framework.
137
138Drivers unregister entities by calling
139
140 media_device_unregister_entity(struct media_entity *entity);
141
142Unregistering an entity will not change the IDs of the other entities, and the
143ID will never be reused for a newly registered entity.
144
145When a media device is unregistered, all its entities are unregistered
146automatically. No manual entities unregistration is then required.
147
148Drivers free resources associated with an entity by calling
149
150 media_entity_cleanup(struct media_entity *entity);
151
152This function must be called during the cleanup phase after unregistering the
153entity. Note that the media_entity instance itself must be freed explicitly by
154the driver if required.
155
156Entities have flags that describe the entity capabilities and state.
157
158 MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type.
159 This can be used to report the default audio and video devices or the
160 default camera sensor.
161
162Logical entity groups can be defined by setting the group ID of all member
163entities to the same non-zero value. An entity group serves no purpose in the
164kernel, but is reported to userspace during entities enumeration. The group_id
165field belongs to the media device driver and must not by touched by entity
166drivers.
167
168Media device drivers should define groups if several entities are logically
169bound together. Example usages include reporting
170
171 - ALSA, VBI and video nodes that carry the same media stream
172 - lens and flash controllers associated with a sensor
173
174- Pads
175
176Pads are represented by a struct media_pad instance, defined in
177include/media/media-entity.h. Each entity stores its pads in a pads array
178managed by the entity driver. Drivers usually embed the array in a
179driver-specific structure.
180
181Pads are identified by their entity and their 0-based index in the pads array.
182Both information are stored in the media_pad structure, making the media_pad
183pointer the canonical way to store and pass link references.
184
185Pads have flags that describe the pad capabilities and state.
186
187 MEDIA_PAD_FL_SINK indicates that the pad supports sinking data.
188 MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data.
189
190One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for
191each pad.
192
193- Links
194
195Links are represented by a struct media_link instance, defined in
196include/media/media-entity.h. Each entity stores all links originating at or
197targetting any of its pads in a links array. A given link is thus stored
198twice, once in the source entity and once in the target entity. The array is
199pre-allocated and grows dynamically as needed.
200
201Drivers create links by calling
202
203 media_entity_create_link(struct media_entity *source, u16 source_pad,
204 struct media_entity *sink, u16 sink_pad,
205 u32 flags);
206
207An entry in the link array of each entity is allocated and stores pointers
208to source and sink pads.
209
210Links have flags that describe the link capabilities and state.
211
212 MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used
213 to transfer media data. When two or more links target a sink pad, only
214 one of them can be enabled at a time.
215 MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be
216 modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then
217 MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always
218 enabled.
219
220
221Graph traversal
222---------------
223
224The media framework provides APIs to iterate over entities in a graph.
225
226To iterate over all entities belonging to a media device, drivers can use the
227media_device_for_each_entity macro, defined in include/media/media-device.h.
228
229 struct media_entity *entity;
230
231 media_device_for_each_entity(entity, mdev) {
232 /* entity will point to each entity in turn */
233 ...
234 }
235
236Drivers might also need to iterate over all entities in a graph that can be
237reached only through enabled links starting at a given entity. The media
238framework provides a depth-first graph traversal API for that purpose.
239
240Note that graphs with cycles (whether directed or undirected) are *NOT*
241supported by the graph traversal API. To prevent infinite loops, the graph
242traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH,
243currently defined as 16.
244
245Drivers initiate a graph traversal by calling
246
247 media_entity_graph_walk_start(struct media_entity_graph *graph,
248 struct media_entity *entity);
249
250The graph structure, provided by the caller, is initialized to start graph
251traversal at the given entity.
252
253Drivers can then retrieve the next entity by calling
254
255 media_entity_graph_walk_next(struct media_entity_graph *graph);
256
257When the graph traversal is complete the function will return NULL.
258
259Graph traversal can be interrupted at any moment. No cleanup function call is
260required and the graph structure can be freed normally.
261
262Helper functions can be used to find a link between two given pads, or a pad
263connected to another pad through an enabled link
264
265 media_entity_find_link(struct media_pad *source,
266 struct media_pad *sink);
267
268 media_entity_remote_source(struct media_pad *pad);
269
270Refer to the kerneldoc documentation for more information.
271
272
273Use count and power handling
274----------------------------
275
276Due to the wide differences between drivers regarding power management needs,
277the media controller does not implement power management. However, the
278media_entity structure includes a use_count field that media drivers can use to
279track the number of users of every entity for power management needs.
280
281The use_count field is owned by media drivers and must not be touched by entity
282drivers. Access to the field must be protected by the media device graph_mutex
283lock.
284
285
286Links setup
287-----------
288
289Link properties can be modified at runtime by calling
290
291 media_entity_setup_link(struct media_link *link, u32 flags);
292
293The flags argument contains the requested new link flags.
294
295The only configurable property is the ENABLED link flag to enable/disable a
296link. Links marked with the IMMUTABLE link flag can not be enabled or disabled.
297
298When a link is enabled or disabled, the media framework calls the
299link_setup operation for the two entities at the source and sink of the link,
300in that order. If the second link_setup call fails, another link_setup call is
301made on the first entity to restore the original link flags.
302
303Media device drivers can be notified of link setup operations by setting the
304media_device::link_notify pointer to a callback function. If provided, the
305notification callback will be called before enabling and after disabling
306links.
307
308Entity drivers must implement the link_setup operation if any of their links
309is non-immutable. The operation must either configure the hardware or store
310the configuration information to be applied later.
311
312Link configuration must not have any side effect on other links. If an enabled
313link at a sink pad prevents another link at the same pad from being disabled,
314the link_setup operation must return -EBUSY and can't implicitly disable the
315first enabled link.
316
317
318Pipelines and media streams
319---------------------------
320
321When starting streaming, drivers must notify all entities in the pipeline to
322prevent link states from being modified during streaming by calling
323
324 media_entity_pipeline_start(struct media_entity *entity,
325 struct media_pipeline *pipe);
326
327The function will mark all entities connected to the given entity through
328enabled links, either directly or indirectly, as streaming.
329
330The media_pipeline instance pointed to by the pipe argument will be stored in
331every entity in the pipeline. Drivers should embed the media_pipeline structure
332in higher-level pipeline structures and can then access the pipeline through
333the media_entity pipe field.
334
335Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must
336be identical for all nested calls to the function.
337
338When stopping the stream, drivers must notify the entities with
339
340 media_entity_pipeline_stop(struct media_entity *entity);
341
342If multiple calls to media_entity_pipeline_start() have been made the same
343number of media_entity_pipeline_stop() calls are required to stop streaming. The
344media_entity pipe field is reset to NULL on the last nested stop call.
345
346Link configuration will fail with -EBUSY by default if either end of the link is
347a streaming entity. Links that can be modified while streaming must be marked
348with the MEDIA_LNK_FL_DYNAMIC flag.
349
350If other operations need to be disallowed on streaming entities (such as
351changing entities configuration parameters) drivers can explictly check the
352media_entity stream_count field to find out if an entity is streaming. This
353operation must be done with the media_device graph_mutex held.
diff --git a/Documentation/video4linux/README.ivtv b/Documentation/video4linux/README.ivtv
index 42b06686eb78..2579b5b709ed 100644
--- a/Documentation/video4linux/README.ivtv
+++ b/Documentation/video4linux/README.ivtv
@@ -36,8 +36,7 @@ Additional features for the PVR-350 (CX23415 based):
36 * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the 36 * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
37 video signal) 37 video signal)
38 * Provides a framebuffer (allowing X applications to appear on the video 38 * Provides a framebuffer (allowing X applications to appear on the video
39 device) (this framebuffer is not yet part of the kernel. In the meantime it 39 device)
40 is available from www.ivtvdriver.org).
41 * Supports raw YUV output. 40 * Supports raw YUV output.
42 41
43IMPORTANT: In case of problems first read this page: 42IMPORTANT: In case of problems first read this page:
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 261776e0c5e1..5c542e60f51d 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -103,6 +103,7 @@ spca561 046d:092d Logitech QC Elch2
103spca561 046d:092e Logitech QC Elch2 103spca561 046d:092e Logitech QC Elch2
104spca561 046d:092f Logitech QuickCam Express Plus 104spca561 046d:092f Logitech QuickCam Express Plus
105sunplus 046d:0960 Logitech ClickSmart 420 105sunplus 046d:0960 Logitech ClickSmart 420
106nw80x 046d:d001 Logitech QuickCam Pro (dark focus ring)
106sunplus 0471:0322 Philips DMVC1300K 107sunplus 0471:0322 Philips DMVC1300K
107zc3xx 0471:0325 Philips SPC 200 NC 108zc3xx 0471:0325 Philips SPC 200 NC
108zc3xx 0471:0326 Philips SPC 300 NC 109zc3xx 0471:0326 Philips SPC 300 NC
@@ -150,10 +151,12 @@ sunplus 04fc:5330 Digitrex 2110
150sunplus 04fc:5360 Sunplus Generic 151sunplus 04fc:5360 Sunplus Generic
151spca500 04fc:7333 PalmPixDC85 152spca500 04fc:7333 PalmPixDC85
152sunplus 04fc:ffff Pure DigitalDakota 153sunplus 04fc:ffff Pure DigitalDakota
154nw80x 0502:d001 DVC V6
153spca501 0506:00df 3Com HomeConnect Lite 155spca501 0506:00df 3Com HomeConnect Lite
154sunplus 052b:1507 Megapixel 5 Pretec DC-1007 156sunplus 052b:1507 Megapixel 5 Pretec DC-1007
155sunplus 052b:1513 Megapix V4 157sunplus 052b:1513 Megapix V4
156sunplus 052b:1803 MegaImage VI 158sunplus 052b:1803 MegaImage VI
159nw80x 052b:d001 EZCam Pro p35u
157tv8532 0545:808b Veo Stingray 160tv8532 0545:808b Veo Stingray
158tv8532 0545:8333 Veo Stingray 161tv8532 0545:8333 Veo Stingray
159sunplus 0546:3155 Polaroid PDC3070 162sunplus 0546:3155 Polaroid PDC3070
@@ -177,6 +180,7 @@ sunplus 055f:c530 Mustek Gsmart LCD 3
177sunplus 055f:c540 Gsmart D30 180sunplus 055f:c540 Gsmart D30
178sunplus 055f:c630 Mustek MDC4000 181sunplus 055f:c630 Mustek MDC4000
179sunplus 055f:c650 Mustek MDC5500Z 182sunplus 055f:c650 Mustek MDC5500Z
183nw80x 055f:d001 Mustek Wcam 300 mini
180zc3xx 055f:d003 Mustek WCam300A 184zc3xx 055f:d003 Mustek WCam300A
181zc3xx 055f:d004 Mustek WCam300 AN 185zc3xx 055f:d004 Mustek WCam300 AN
182conex 0572:0041 Creative Notebook cx11646 186conex 0572:0041 Creative Notebook cx11646
@@ -195,14 +199,20 @@ gl860 05e3:0503 Genesys Logic PC Camera
195gl860 05e3:f191 Genesys Logic PC Camera 199gl860 05e3:f191 Genesys Logic PC Camera
196spca561 060b:a001 Maxell Compact Pc PM3 200spca561 060b:a001 Maxell Compact Pc PM3
197zc3xx 0698:2003 CTX M730V built in 201zc3xx 0698:2003 CTX M730V built in
202nw80x 06a5:0000 Typhoon Webcam 100 USB
203nw80x 06a5:d001 Divio based webcams
204nw80x 06a5:d800 Divio Chicony TwinkleCam, Trust SpaceCam
198spca500 06bd:0404 Agfa CL20 205spca500 06bd:0404 Agfa CL20
199spca500 06be:0800 Optimedia 206spca500 06be:0800 Optimedia
207nw80x 06be:d001 EZCam Pro p35u
200sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom 208sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
201spca506 06e1:a190 ADS Instant VCD 209spca506 06e1:a190 ADS Instant VCD
210ov534 06f8:3002 Hercules Blog Webcam
202ov534_9 06f8:3003 Hercules Dualpix HD Weblog 211ov534_9 06f8:3003 Hercules Dualpix HD Weblog
203sonixj 06f8:3004 Hercules Classic Silver 212sonixj 06f8:3004 Hercules Classic Silver
204sonixj 06f8:3008 Hercules Deluxe Optical Glass 213sonixj 06f8:3008 Hercules Deluxe Optical Glass
205pac7302 06f8:3009 Hercules Classic Link 214pac7302 06f8:3009 Hercules Classic Link
215nw80x 0728:d001 AVerMedia Camguard
206spca508 0733:0110 ViewQuest VQ110 216spca508 0733:0110 ViewQuest VQ110
207spca501 0733:0401 Intel Create and Share 217spca501 0733:0401 Intel Create and Share
208spca501 0733:0402 ViewQuest M318B 218spca501 0733:0402 ViewQuest M318B
diff --git a/Documentation/video4linux/omap3isp.txt b/Documentation/video4linux/omap3isp.txt
new file mode 100644
index 000000000000..69be2c782b98
--- /dev/null
+++ b/Documentation/video4linux/omap3isp.txt
@@ -0,0 +1,278 @@
1OMAP 3 Image Signal Processor (ISP) driver
2
3Copyright (C) 2010 Nokia Corporation
4Copyright (C) 2009 Texas Instruments, Inc.
5
6Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 Sakari Ailus <sakari.ailus@iki.fi>
8 David Cohen <dacohen@gmail.com>
9
10
11Introduction
12============
13
14This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
15driver located under drivers/media/video/omap3isp. The original driver was
16written by Texas Instruments but since that it has been rewritten (twice) at
17Nokia.
18
19The driver has been successfully used on the following versions of OMAP 3:
20
21 3430
22 3530
23 3630
24
25The driver implements V4L2, Media controller and v4l2_subdev interfaces.
26Sensor, lens and flash drivers using the v4l2_subdev interface in the kernel
27are supported.
28
29
30Split to subdevs
31================
32
33The OMAP 3 ISP is split into V4L2 subdevs, each of the blocks inside the ISP
34having one subdev to represent it. Each of the subdevs provide a V4L2 subdev
35interface to userspace.
36
37 OMAP3 ISP CCP2
38 OMAP3 ISP CSI2a
39 OMAP3 ISP CCDC
40 OMAP3 ISP preview
41 OMAP3 ISP resizer
42 OMAP3 ISP AEWB
43 OMAP3 ISP AF
44 OMAP3 ISP histogram
45
46Each possible link in the ISP is modelled by a link in the Media controller
47interface. For an example program see [2].
48
49
50Controlling the OMAP 3 ISP
51==========================
52
53In general, the settings given to the OMAP 3 ISP take effect at the beginning
54of the following frame. This is done when the module becomes idle during the
55vertical blanking period on the sensor. In memory-to-memory operation the pipe
56is run one frame at a time. Applying the settings is done between the frames.
57
58All the blocks in the ISP, excluding the CSI-2 and possibly the CCP2 receiver,
59insist on receiving complete frames. Sensors must thus never send the ISP
60partial frames.
61
62Autoidle does have issues with some ISP blocks on the 3430, at least.
63Autoidle is only enabled on 3630 when the omap3isp module parameter autoidle
64is non-zero.
65
66
67Events
68======
69
70The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and
71statistics (AEWB, AF and histogram) subdevs.
72
73The CCDC subdev produces V4L2_EVENT_OMAP3ISP_HS_VS type event on HS_VS
74interrupt which is used to signal frame start. The event is triggered exactly
75when the reception of the first line of the frame starts in the CCDC module.
76The event can be subscribed on the CCDC subdev.
77
78(When using parallel interface one must pay account to correct configuration
79of the VS signal polarity. This is automatically correct when using the serial
80receivers.)
81
82Each of the statistics subdevs is able to produce events. An event is
83generated whenever a statistics buffer can be dequeued by a user space
84application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available
85are:
86
87 V4L2_EVENT_OMAP3ISP_AEWB
88 V4L2_EVENT_OMAP3ISP_AF
89 V4L2_EVENT_OMAP3ISP_HIST
90
91The type of the event data is struct omap3isp_stat_event_status for these
92ioctls. If there is an error calculating the statistics, there will be an
93event as usual, but no related statistics buffer. In this case
94omap3isp_stat_event_status.buf_err is set to non-zero.
95
96
97Private IOCTLs
98==============
99
100The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where
101possible and practical. Much of the functions provided by the ISP, however,
102does not fall under the standard IOCTLs --- gamma tables and configuration of
103statistics collection are examples of such.
104
105In general, there is a private ioctl for configuring each of the blocks
106containing hardware-dependent functions.
107
108The following private IOCTLs are supported:
109
110 VIDIOC_OMAP3ISP_CCDC_CFG
111 VIDIOC_OMAP3ISP_PRV_CFG
112 VIDIOC_OMAP3ISP_AEWB_CFG
113 VIDIOC_OMAP3ISP_HIST_CFG
114 VIDIOC_OMAP3ISP_AF_CFG
115 VIDIOC_OMAP3ISP_STAT_REQ
116 VIDIOC_OMAP3ISP_STAT_EN
117
118The parameter structures used by these ioctls are described in
119include/linux/omap3isp.h. The detailed functions of the ISP itself related to
120a given ISP block is described in the Technical Reference Manuals (TRMs) ---
121see the end of the document for those.
122
123While it is possible to use the ISP driver without any use of these private
124IOCTLs it is not possible to obtain optimal image quality this way. The AEWB,
125AF and histogram modules cannot be used without configuring them using the
126appropriate private IOCTLs.
127
128
129CCDC and preview block IOCTLs
130=============================
131
132The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to
133configure, enable and disable functions in the CCDC and preview blocks,
134respectively. Both IOCTLs control several functions in the blocks they
135control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct
136omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG
137accepts a pointer to struct omap3isp_prev_update_config. The definition of
138both structures is available in [1].
139
140The update field in the structures tells whether to update the configuration
141for the specific function and the flag tells whether to enable or disable the
142function.
143
144The update and flag bit masks accept the following values. Each separate
145functions in the CCDC and preview blocks is associated with a flag (either
146disable or enable; part of the flag field in the structure) and a pointer to
147configuration data for the function.
148
149Valid values for the update and flag fields are listed here for
150VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one
151function in the same IOCTL call.
152
153 OMAP3ISP_CCDC_ALAW
154 OMAP3ISP_CCDC_LPF
155 OMAP3ISP_CCDC_BLCLAMP
156 OMAP3ISP_CCDC_BCOMP
157 OMAP3ISP_CCDC_FPC
158 OMAP3ISP_CCDC_CULL
159 OMAP3ISP_CCDC_CONFIG_LSC
160 OMAP3ISP_CCDC_TBL_LSC
161
162The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here:
163
164 OMAP3ISP_PREV_LUMAENH
165 OMAP3ISP_PREV_INVALAW
166 OMAP3ISP_PREV_HRZ_MED
167 OMAP3ISP_PREV_CFA
168 OMAP3ISP_PREV_CHROMA_SUPP
169 OMAP3ISP_PREV_WB
170 OMAP3ISP_PREV_BLKADJ
171 OMAP3ISP_PREV_RGB2RGB
172 OMAP3ISP_PREV_COLOR_CONV
173 OMAP3ISP_PREV_YC_LIMIT
174 OMAP3ISP_PREV_DEFECT_COR
175 OMAP3ISP_PREV_GAMMABYPASS
176 OMAP3ISP_PREV_DRK_FRM_CAPTURE
177 OMAP3ISP_PREV_DRK_FRM_SUBTRACT
178 OMAP3ISP_PREV_LENS_SHADING
179 OMAP3ISP_PREV_NF
180 OMAP3ISP_PREV_GAMMA
181
182The associated configuration pointer for the function may not be NULL when
183enabling the function. When disabling a function the configuration pointer is
184ignored.
185
186
187Statistic blocks IOCTLs
188=======================
189
190The statistics subdevs do offer more dynamic configuration options than the
191other subdevs. They can be enabled, disable and reconfigured when the pipeline
192is in streaming state.
193
194The statistics blocks always get the input image data from the CCDC (as the
195histogram memory read isn't implemented). The statistics are dequeueable by
196the user from the statistics subdev nodes using private IOCTLs.
197
198The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily
199reflected by the register level interface offered by the ISP hardware. There
200are aspects that are purely related to the driver implementation and these are
201discussed next.
202
203VIDIOC_OMAP3ISP_STAT_EN
204-----------------------
205
206This private IOCTL enables/disables a statistic module. If this request is
207done before streaming, it will take effect as soon as the pipeline starts to
208stream. If the pipeline is already streaming, it will take effect as soon as
209the CCDC becomes idle.
210
211VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG
212-----------------------------------------------------------------------------
213
214Those IOCTLs are used to configure the modules. They require user applications
215to have an in-depth knowledge of the hardware. Most of the fields explanation
216can be found on OMAP's TRMs. The two following fields common to all the above
217configure private IOCTLs require explanation for better understanding as they
218are not part of the TRM.
219
220omap3isp_[h3a_af/h3a_aewb/hist]_config.buf_size:
221
222The modules handle their buffers internally. The necessary buffer size for the
223module's data output depends on the requested configuration. Although the
224driver supports reconfiguration while streaming, it does not support a
225reconfiguration which requires bigger buffer size than what is already
226internally allocated if the module is enabled. It will return -EBUSY on this
227case. In order to avoid such condition, either disable/reconfigure/enable the
228module or request the necessary buffer size during the first configuration
229while the module is disabled.
230
231The internal buffer size allocation considers the requested configuration's
232minimum buffer size and the value set on buf_size field. If buf_size field is
233out of [minimum, maximum] buffer size range, it's clamped to fit in there.
234The driver then selects the biggest value. The corrected buf_size value is
235written back to user application.
236
237omap3isp_[h3a_af/h3a_aewb/hist]_config.config_counter:
238
239As the configuration doesn't take effect synchronously to the request, the
240driver must provide a way to track this information to provide more accurate
241data. After a configuration is requested, the config_counter returned to user
242space application will be an unique value associated to that request. When
243user application receives an event for buffer availability or when a new
244buffer is requested, this config_counter is used to match a buffer data and a
245configuration.
246
247VIDIOC_OMAP3ISP_STAT_REQ
248------------------------
249
250Send to user space the oldest data available in the internal buffer queue and
251discards such buffer afterwards. The field omap3isp_stat_data.frame_number
252matches with the video buffer's field_count.
253
254
255Technical reference manuals (TRMs) and other documentation
256==========================================================
257
258OMAP 3430 TRM:
259<URL:http://focus.ti.com/pdfs/wtbu/OMAP34xx_ES3.1.x_PUBLIC_TRM_vZM.zip>
260Referenced 2011-03-05.
261
262OMAP 35xx TRM:
263<URL:http://www.ti.com/litv/pdf/spruf98o> Referenced 2011-03-05.
264
265OMAP 3630 TRM:
266<URL:http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vQ.zip>
267Referenced 2011-03-05.
268
269DM 3730 TRM:
270<URL:http://www.ti.com/litv/pdf/sprugn4h> Referenced 2011-03-06.
271
272
273References
274==========
275
276[1] include/linux/omap3isp.h
277
278[2] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index f22f35c271f3..3b15608ee070 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -71,6 +71,10 @@ sub-device instances, the video_device struct stores V4L2 device node data
71and in the future a v4l2_fh struct will keep track of filehandle instances 71and in the future a v4l2_fh struct will keep track of filehandle instances
72(this is not yet implemented). 72(this is not yet implemented).
73 73
74The V4L2 framework also optionally integrates with the media framework. If a
75driver sets the struct v4l2_device mdev field, sub-devices and video nodes
76will automatically appear in the media framework as entities.
77
74 78
75struct v4l2_device 79struct v4l2_device
76------------------ 80------------------
@@ -83,11 +87,20 @@ You must register the device instance:
83 87
84 v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); 88 v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
85 89
86Registration will initialize the v4l2_device struct and link dev->driver_data 90Registration will initialize the v4l2_device struct. If the dev->driver_data
87to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived 91field is NULL, it will be linked to v4l2_dev.
88from dev (driver name followed by the bus_id, to be precise). If you set it 92
89up before calling v4l2_device_register then it will be untouched. If dev is 93Drivers that want integration with the media device framework need to set
90NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register. 94dev->driver_data manually to point to the driver-specific device structure
95that embed the struct v4l2_device instance. This is achieved by a
96dev_set_drvdata() call before registering the V4L2 device instance. They must
97also set the struct v4l2_device mdev field to point to a properly initialized
98and registered media_device instance.
99
100If v4l2_dev->name is empty then it will be set to a value derived from dev
101(driver name followed by the bus_id, to be precise). If you set it up before
102calling v4l2_device_register then it will be untouched. If dev is NULL, then
103you *must* setup v4l2_dev->name before calling v4l2_device_register.
91 104
92You can use v4l2_device_set_name() to set the name based on a driver name and 105You can use v4l2_device_set_name() to set the name based on a driver name and
93a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1, 106a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
@@ -108,6 +121,7 @@ You unregister with:
108 121
109 v4l2_device_unregister(struct v4l2_device *v4l2_dev); 122 v4l2_device_unregister(struct v4l2_device *v4l2_dev);
110 123
124If the dev->driver_data field points to v4l2_dev, it will be reset to NULL.
111Unregistering will also automatically unregister all subdevs from the device. 125Unregistering will also automatically unregister all subdevs from the device.
112 126
113If you have a hotpluggable device (e.g. a USB device), then when a disconnect 127If you have a hotpluggable device (e.g. a USB device), then when a disconnect
@@ -167,6 +181,21 @@ static int __devinit drv_probe(struct pci_dev *pdev,
167 state->instance = atomic_inc_return(&drv_instance) - 1; 181 state->instance = atomic_inc_return(&drv_instance) - 1;
168} 182}
169 183
184If you have multiple device nodes then it can be difficult to know when it is
185safe to unregister v4l2_device. For this purpose v4l2_device has refcounting
186support. The refcount is increased whenever video_register_device is called and
187it is decreased whenever that device node is released. When the refcount reaches
188zero, then the v4l2_device release() callback is called. You can do your final
189cleanup there.
190
191If other device nodes (e.g. ALSA) are created, then you can increase and
192decrease the refcount manually as well by calling:
193
194void v4l2_device_get(struct v4l2_device *v4l2_dev);
195
196or:
197
198int v4l2_device_put(struct v4l2_device *v4l2_dev);
170 199
171struct v4l2_subdev 200struct v4l2_subdev
172------------------ 201------------------
@@ -254,6 +283,26 @@ A sub-device driver initializes the v4l2_subdev struct using:
254Afterwards you need to initialize subdev->name with a unique name and set the 283Afterwards you need to initialize subdev->name with a unique name and set the
255module owner. This is done for you if you use the i2c helper functions. 284module owner. This is done for you if you use the i2c helper functions.
256 285
286If integration with the media framework is needed, you must initialize the
287media_entity struct embedded in the v4l2_subdev struct (entity field) by
288calling media_entity_init():
289
290 struct media_pad *pads = &my_sd->pads;
291 int err;
292
293 err = media_entity_init(&sd->entity, npads, pads, 0);
294
295The pads array must have been previously initialized. There is no need to
296manually set the struct media_entity type and name fields, but the revision
297field must be initialized if needed.
298
299A reference to the entity will be automatically acquired/released when the
300subdev device node (if any) is opened/closed.
301
302Don't forget to cleanup the media entity before the sub-device is destroyed:
303
304 media_entity_cleanup(&sd->entity);
305
257A device (bridge) driver needs to register the v4l2_subdev with the 306A device (bridge) driver needs to register the v4l2_subdev with the
258v4l2_device: 307v4l2_device:
259 308
@@ -263,6 +312,9 @@ This can fail if the subdev module disappeared before it could be registered.
263After this function was called successfully the subdev->dev field points to 312After this function was called successfully the subdev->dev field points to
264the v4l2_device. 313the v4l2_device.
265 314
315If the v4l2_device parent device has a non-NULL mdev field, the sub-device
316entity will be automatically registered with the media device.
317
266You can unregister a sub-device using: 318You can unregister a sub-device using:
267 319
268 v4l2_device_unregister_subdev(sd); 320 v4l2_device_unregister_subdev(sd);
@@ -319,6 +371,61 @@ controlled through GPIO pins. This distinction is only relevant when setting
319up the device, but once the subdev is registered it is completely transparent. 371up the device, but once the subdev is registered it is completely transparent.
320 372
321 373
374V4L2 sub-device userspace API
375-----------------------------
376
377Beside exposing a kernel API through the v4l2_subdev_ops structure, V4L2
378sub-devices can also be controlled directly by userspace applications.
379
380Device nodes named v4l-subdevX can be created in /dev to access sub-devices
381directly. If a sub-device supports direct userspace configuration it must set
382the V4L2_SUBDEV_FL_HAS_DEVNODE flag before being registered.
383
384After registering sub-devices, the v4l2_device driver can create device nodes
385for all registered sub-devices marked with V4L2_SUBDEV_FL_HAS_DEVNODE by calling
386v4l2_device_register_subdev_nodes(). Those device nodes will be automatically
387removed when sub-devices are unregistered.
388
389The device node handles a subset of the V4L2 API.
390
391VIDIOC_QUERYCTRL
392VIDIOC_QUERYMENU
393VIDIOC_G_CTRL
394VIDIOC_S_CTRL
395VIDIOC_G_EXT_CTRLS
396VIDIOC_S_EXT_CTRLS
397VIDIOC_TRY_EXT_CTRLS
398
399 The controls ioctls are identical to the ones defined in V4L2. They
400 behave identically, with the only exception that they deal only with
401 controls implemented in the sub-device. Depending on the driver, those
402 controls can be also be accessed through one (or several) V4L2 device
403 nodes.
404
405VIDIOC_DQEVENT
406VIDIOC_SUBSCRIBE_EVENT
407VIDIOC_UNSUBSCRIBE_EVENT
408
409 The events ioctls are identical to the ones defined in V4L2. They
410 behave identically, with the only exception that they deal only with
411 events generated by the sub-device. Depending on the driver, those
412 events can also be reported by one (or several) V4L2 device nodes.
413
414 Sub-device drivers that want to use events need to set the
415 V4L2_SUBDEV_USES_EVENTS v4l2_subdev::flags and initialize
416 v4l2_subdev::nevents to events queue depth before registering the
417 sub-device. After registration events can be queued as usual on the
418 v4l2_subdev::devnode device node.
419
420 To properly support events, the poll() file operation is also
421 implemented.
422
423Private ioctls
424
425 All ioctls not in the above list are passed directly to the sub-device
426 driver through the core::ioctl operation.
427
428
322I2C sub-device drivers 429I2C sub-device drivers
323---------------------- 430----------------------
324 431
@@ -457,6 +564,10 @@ You should also set these fields:
457 Otherwise you give it a pointer to a struct mutex_lock and before any 564 Otherwise you give it a pointer to a struct mutex_lock and before any
458 of the v4l2_file_operations is called this lock will be taken by the 565 of the v4l2_file_operations is called this lock will be taken by the
459 core and released afterwards. 566 core and released afterwards.
567- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY.
568 If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device.
569 If you want to have a separate priority state per (group of) device node(s),
570 then you can point it to your own struct v4l2_prio_state.
460- parent: you only set this if v4l2_device was registered with NULL as 571- parent: you only set this if v4l2_device was registered with NULL as
461 the parent device struct. This only happens in cases where one hardware 572 the parent device struct. This only happens in cases where one hardware
462 device has multiple PCI devices that all share the same v4l2_device core. 573 device has multiple PCI devices that all share the same v4l2_device core.
@@ -466,13 +577,34 @@ You should also set these fields:
466 (cx8802). Since the v4l2_device cannot be associated with a particular 577 (cx8802). Since the v4l2_device cannot be associated with a particular
467 PCI device it is setup without a parent device. But when the struct 578 PCI device it is setup without a parent device. But when the struct
468 video_device is setup you do know which parent PCI device to use. 579 video_device is setup you do know which parent PCI device to use.
580- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
581 handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
582 v4l2_fh. Eventually this flag will disappear once all drivers use the core
583 priority handling. But for now it has to be set explicitly.
469 584
470If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or 585If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
471.ioctl to video_ioctl2 in your v4l2_file_operations struct. 586in your v4l2_file_operations struct.
587
588Do not use .ioctl! This is deprecated and will go away in the future.
472 589
473The v4l2_file_operations struct is a subset of file_operations. The main 590The v4l2_file_operations struct is a subset of file_operations. The main
474difference is that the inode argument is omitted since it is never used. 591difference is that the inode argument is omitted since it is never used.
475 592
593If integration with the media framework is needed, you must initialize the
594media_entity struct embedded in the video_device struct (entity field) by
595calling media_entity_init():
596
597 struct media_pad *pad = &my_vdev->pad;
598 int err;
599
600 err = media_entity_init(&vdev->entity, 1, pad, 0);
601
602The pads array must have been previously initialized. There is no need to
603manually set the struct media_entity type and name fields.
604
605A reference to the entity will be automatically acquired/released when the
606video device is opened/closed.
607
476v4l2_file_operations and locking 608v4l2_file_operations and locking
477-------------------------------- 609--------------------------------
478 610
@@ -502,6 +634,9 @@ for you.
502 return err; 634 return err;
503 } 635 }
504 636
637If the v4l2_device parent device has a non-NULL mdev field, the video device
638entity will be automatically registered with the media device.
639
505Which device is registered depends on the type argument. The following 640Which device is registered depends on the type argument. The following
506types exist: 641types exist:
507 642
@@ -577,6 +712,13 @@ release, of course) will return an error as well.
577When the last user of the video device node exits, then the vdev->release() 712When the last user of the video device node exits, then the vdev->release()
578callback is called and you can do the final cleanup there. 713callback is called and you can do the final cleanup there.
579 714
715Don't forget to cleanup the media entity associated with the video device if
716it has been initialized:
717
718 media_entity_cleanup(&vdev->entity);
719
720This can be done from the release callback.
721
580 722
581video_device helper functions 723video_device helper functions
582----------------------------- 724-----------------------------
@@ -636,39 +778,25 @@ struct v4l2_fh
636-------------- 778--------------
637 779
638struct v4l2_fh provides a way to easily keep file handle specific data 780struct v4l2_fh provides a way to easily keep file handle specific data
639that is used by the V4L2 framework. Using v4l2_fh is optional for 781that is used by the V4L2 framework. New drivers must use struct v4l2_fh
640drivers. 782since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY)
783if the video_device flag V4L2_FL_USE_FH_PRIO is also set.
641 784
642The users of v4l2_fh (in the V4L2 framework, not the driver) know 785The users of v4l2_fh (in the V4L2 framework, not the driver) know
643whether a driver uses v4l2_fh as its file->private_data pointer by 786whether a driver uses v4l2_fh as its file->private_data pointer by
644testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. 787testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. This bit is
645 788set whenever v4l2_fh_init() is called.
646Useful functions:
647
648- v4l2_fh_init()
649
650 Initialise the file handle. This *MUST* be performed in the driver's
651 v4l2_file_operations->open() handler.
652
653- v4l2_fh_add()
654 789
655 Add a v4l2_fh to video_device file handle list. May be called after 790struct v4l2_fh is allocated as a part of the driver's own file handle
656 initialising the file handle. 791structure and file->private_data is set to it in the driver's open
657 792function by the driver.
658- v4l2_fh_del()
659
660 Unassociate the file handle from video_device(). The file handle
661 exit function may now be called.
662 793
663- v4l2_fh_exit() 794In many cases the struct v4l2_fh will be embedded in a larger structure.
795In that case you should call v4l2_fh_init+v4l2_fh_add in open() and
796v4l2_fh_del+v4l2_fh_exit in release().
664 797
665 Uninitialise the file handle. After uninitialisation the v4l2_fh 798Drivers can extract their own file handle structure by using the container_of
666 memory can be freed. 799macro. Example:
667
668struct v4l2_fh is allocated as a part of the driver's own file handle
669structure and is set to file->private_data in the driver's open
670function by the driver. Drivers can extract their own file handle
671structure by using the container_of macro. Example:
672 800
673struct my_fh { 801struct my_fh {
674 int blah; 802 int blah;
@@ -685,15 +813,21 @@ int my_open(struct file *file)
685 813
686 ... 814 ...
687 815
816 my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
817
818 ...
819
688 ret = v4l2_fh_init(&my_fh->fh, vfd); 820 ret = v4l2_fh_init(&my_fh->fh, vfd);
689 if (ret) 821 if (ret) {
822 kfree(my_fh);
690 return ret; 823 return ret;
824 }
691 825
692 v4l2_fh_add(&my_fh->fh); 826 ...
693 827
694 file->private_data = &my_fh->fh; 828 file->private_data = &my_fh->fh;
695 829 v4l2_fh_add(&my_fh->fh);
696 ... 830 return 0;
697} 831}
698 832
699int my_release(struct file *file) 833int my_release(struct file *file)
@@ -702,8 +836,65 @@ int my_release(struct file *file)
702 struct my_fh *my_fh = container_of(fh, struct my_fh, fh); 836 struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
703 837
704 ... 838 ...
839 v4l2_fh_del(&my_fh->fh);
840 v4l2_fh_exit(&my_fh->fh);
841 kfree(my_fh);
842 return 0;
705} 843}
706 844
845Below is a short description of the v4l2_fh functions used:
846
847int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
848
849 Initialise the file handle. This *MUST* be performed in the driver's
850 v4l2_file_operations->open() handler.
851
852void v4l2_fh_add(struct v4l2_fh *fh)
853
854 Add a v4l2_fh to video_device file handle list. Must be called once the
855 file handle is completely initialized.
856
857void v4l2_fh_del(struct v4l2_fh *fh)
858
859 Unassociate the file handle from video_device(). The file handle
860 exit function may now be called.
861
862void v4l2_fh_exit(struct v4l2_fh *fh)
863
864 Uninitialise the file handle. After uninitialisation the v4l2_fh
865 memory can be freed.
866
867
868If struct v4l2_fh is not embedded, then you can use these helper functions:
869
870int v4l2_fh_open(struct file *filp)
871
872 This allocates a struct v4l2_fh, initializes it and adds it to the struct
873 video_device associated with the file struct.
874
875int v4l2_fh_release(struct file *filp)
876
877 This deletes it from the struct video_device associated with the file
878 struct, uninitialised the v4l2_fh and frees it.
879
880These two functions can be plugged into the v4l2_file_operation's open() and
881release() ops.
882
883
884Several drivers need to do something when the first file handle is opened and
885when the last file handle closes. Two helper functions were added to check
886whether the v4l2_fh struct is the only open filehandle of the associated
887device node:
888
889int v4l2_fh_is_singular(struct v4l2_fh *fh)
890
891 Returns 1 if the file handle is the only open file handle, else 0.
892
893int v4l2_fh_is_singular_file(struct file *filp)
894
895 Same, but it calls v4l2_fh_is_singular with filp->private_data.
896
897
707V4L2 events 898V4L2 events
708----------- 899-----------
709 900
diff --git a/MAINTAINERS b/MAINTAINERS
index e11953dc8fa3..749f9cd38089 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2631,12 +2631,14 @@ F: drivers/net/wan/dlci.c
2631F: drivers/net/wan/sdla.c 2631F: drivers/net/wan/sdla.c
2632 2632
2633FRAMEBUFFER LAYER 2633FRAMEBUFFER LAYER
2634M: Paul Mundt <lethal@linux-sh.org>
2634L: linux-fbdev@vger.kernel.org 2635L: linux-fbdev@vger.kernel.org
2635W: http://linux-fbdev.sourceforge.net/ 2636W: http://linux-fbdev.sourceforge.net/
2636Q: http://patchwork.kernel.org/project/linux-fbdev/list/ 2637Q: http://patchwork.kernel.org/project/linux-fbdev/list/
2637T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git 2638T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git
2638S: Orphan 2639S: Maintained
2639F: Documentation/fb/ 2640F: Documentation/fb/
2641F: Documentation/devicetree/bindings/fb/
2640F: drivers/video/ 2642F: drivers/video/
2641F: include/video/ 2643F: include/video/
2642F: include/linux/fb.h 2644F: include/linux/fb.h
@@ -4535,14 +4537,14 @@ S: Maintained
4535F: sound/soc/omap/ 4537F: sound/soc/omap/
4536 4538
4537OMAP FRAMEBUFFER SUPPORT 4539OMAP FRAMEBUFFER SUPPORT
4538M: Tomi Valkeinen <tomi.valkeinen@nokia.com> 4540M: Tomi Valkeinen <tomi.valkeinen@ti.com>
4539L: linux-fbdev@vger.kernel.org 4541L: linux-fbdev@vger.kernel.org
4540L: linux-omap@vger.kernel.org 4542L: linux-omap@vger.kernel.org
4541S: Maintained 4543S: Maintained
4542F: drivers/video/omap/ 4544F: drivers/video/omap/
4543 4545
4544OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2) 4546OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
4545M: Tomi Valkeinen <tomi.valkeinen@nokia.com> 4547M: Tomi Valkeinen <tomi.valkeinen@ti.com>
4546L: linux-omap@vger.kernel.org 4548L: linux-omap@vger.kernel.org
4547L: linux-fbdev@vger.kernel.org 4549L: linux-fbdev@vger.kernel.org
4548S: Maintained 4550S: Maintained
@@ -4580,6 +4582,12 @@ L: linux-omap@vger.kernel.org
4580S: Maintained 4582S: Maintained
4581F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c 4583F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c
4582 4584
4585OMAP IMAGE SIGNAL PROCESSOR (ISP)
4586M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
4587L: linux-media@vger.kernel.org
4588S: Maintained
4589F: drivers/media/video/omap3isp/*
4590
4583OMAP USB SUPPORT 4591OMAP USB SUPPORT
4584M: Felipe Balbi <balbi@ti.com> 4592M: Felipe Balbi <balbi@ti.com>
4585M: David Brownell <dbrownell@users.sourceforge.net> 4593M: David Brownell <dbrownell@users.sourceforge.net>
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
index e6180af241f6..7453c8337b83 100644
--- a/arch/arm/boot/compressed/mmcif-sh7372.c
+++ b/arch/arm/boot/compressed/mmcif-sh7372.c
@@ -10,7 +10,8 @@
10 */ 10 */
11 11
12#include <linux/mmc/sh_mmcif.h> 12#include <linux/mmc/sh_mmcif.h>
13#include <mach/mmcif.h> 13#include <linux/mmc/boot.h>
14#include <mach/mmc.h>
14 15
15#define MMCIF_BASE (void __iomem *)0xe6bd0000 16#define MMCIF_BASE (void __iomem *)0xe6bd0000
16 17
@@ -41,8 +42,8 @@
41 */ 42 */
42asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len) 43asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
43{ 44{
44 mmcif_init_progress(); 45 mmc_init_progress();
45 mmcif_update_progress(MMCIF_PROGRESS_ENTER); 46 mmc_update_progress(MMC_PROGRESS_ENTER);
46 47
47 /* Initialise MMC 48 /* Initialise MMC
48 * registers: PORT84CR-PORT92CR 49 * registers: PORT84CR-PORT92CR
@@ -68,12 +69,12 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
68 /* Enable clock to MMC hardware block */ 69 /* Enable clock to MMC hardware block */
69 __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3); 70 __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
70 71
71 mmcif_update_progress(MMCIF_PROGRESS_INIT); 72 mmc_update_progress(MMC_PROGRESS_INIT);
72 73
73 /* setup MMCIF hardware */ 74 /* setup MMCIF hardware */
74 sh_mmcif_boot_init(MMCIF_BASE); 75 sh_mmcif_boot_init(MMCIF_BASE);
75 76
76 mmcif_update_progress(MMCIF_PROGRESS_LOAD); 77 mmc_update_progress(MMC_PROGRESS_LOAD);
77 78
78 /* load kernel via MMCIF interface */ 79 /* load kernel via MMCIF interface */
79 sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is at block 2 */ 80 sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is at block 2 */
@@ -83,5 +84,5 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
83 /* Disable clock to MMC hardware block */ 84 /* Disable clock to MMC hardware block */
84 __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3); 85 __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
85 86
86 mmcif_update_progress(MMCIF_PROGRESS_DONE); 87 mmc_update_progress(MMC_PROGRESS_DONE);
87} 88}
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 019fb7c67dc3..076db52ff672 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -193,6 +193,17 @@ CONFIG_FIRMWARE_EDID=y
193CONFIG_FB_MODE_HELPERS=y 193CONFIG_FB_MODE_HELPERS=y
194CONFIG_FB_TILEBLITTING=y 194CONFIG_FB_TILEBLITTING=y
195CONFIG_FB_OMAP_LCD_VGA=y 195CONFIG_FB_OMAP_LCD_VGA=y
196CONFIG_OMAP2_DSS=m
197CONFIG_OMAP2_DSS_RFBI=y
198CONFIG_OMAP2_DSS_SDI=y
199CONFIG_OMAP2_DSS_DSI=y
200CONFIG_FB_OMAP2=m
201CONFIG_PANEL_GENERIC_DPI=m
202CONFIG_PANEL_SHARP_LS037V7DW01=m
203CONFIG_PANEL_NEC_NL8048HL11_01B=m
204CONFIG_PANEL_TAAL=m
205CONFIG_PANEL_TPO_TD043MTEA1=m
206CONFIG_PANEL_ACX565AKM=m
196CONFIG_BACKLIGHT_LCD_SUPPORT=y 207CONFIG_BACKLIGHT_LCD_SUPPORT=y
197CONFIG_LCD_CLASS_DEVICE=y 208CONFIG_LCD_CLASS_DEVICE=y
198CONFIG_LCD_PLATFORM=y 209CONFIG_LCD_PLATFORM=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 7a9267e5da55..8845f1c9925d 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -21,6 +21,10 @@ CONFIG_MODULE_FORCE_UNLOAD=y
21# CONFIG_IOSCHED_CFQ is not set 21# CONFIG_IOSCHED_CFQ is not set
22CONFIG_ARCH_TEGRA=y 22CONFIG_ARCH_TEGRA=y
23CONFIG_MACH_HARMONY=y 23CONFIG_MACH_HARMONY=y
24CONFIG_MACH_KAEN=y
25CONFIG_MACH_PAZ00=y
26CONFIG_MACH_TRIMSLICE=y
27CONFIG_MACH_WARIO=y
24CONFIG_TEGRA_DEBUG_UARTD=y 28CONFIG_TEGRA_DEBUG_UARTD=y
25CONFIG_ARM_ERRATA_742230=y 29CONFIG_ARM_ERRATA_742230=y
26CONFIG_NO_HZ=y 30CONFIG_NO_HZ=y
@@ -40,6 +44,10 @@ CONFIG_PACKET=y
40CONFIG_UNIX=y 44CONFIG_UNIX=y
41CONFIG_NET_KEY=y 45CONFIG_NET_KEY=y
42CONFIG_INET=y 46CONFIG_INET=y
47CONFIG_IP_PNP=y
48CONFIG_IP_PNP_DHCP=y
49CONFIG_IP_PNP_BOOTP=y
50CONFIG_IP_PNP_RARP=y
43CONFIG_INET_ESP=y 51CONFIG_INET_ESP=y
44# CONFIG_INET_XFRM_MODE_TUNNEL is not set 52# CONFIG_INET_XFRM_MODE_TUNNEL is not set
45# CONFIG_INET_XFRM_MODE_BEET is not set 53# CONFIG_INET_XFRM_MODE_BEET is not set
@@ -66,7 +74,7 @@ CONFIG_APDS9802ALS=y
66CONFIG_ISL29003=y 74CONFIG_ISL29003=y
67CONFIG_NETDEVICES=y 75CONFIG_NETDEVICES=y
68CONFIG_DUMMY=y 76CONFIG_DUMMY=y
69# CONFIG_NETDEV_1000 is not set 77CONFIG_R8169=y
70# CONFIG_NETDEV_10000 is not set 78# CONFIG_NETDEV_10000 is not set
71# CONFIG_WLAN is not set 79# CONFIG_WLAN is not set
72# CONFIG_INPUT is not set 80# CONFIG_INPUT is not set
@@ -78,12 +86,23 @@ CONFIG_SERIAL_8250_CONSOLE=y
78# CONFIG_LEGACY_PTYS is not set 86# CONFIG_LEGACY_PTYS is not set
79# CONFIG_HW_RANDOM is not set 87# CONFIG_HW_RANDOM is not set
80CONFIG_I2C=y 88CONFIG_I2C=y
81# CONFIG_HWMON is not set 89# CONFIG_I2C_COMPAT is not set
82# CONFIG_MFD_SUPPORT is not set 90# CONFIG_I2C_HELPER_AUTO is not set
91CONFIG_I2C_TEGRA=y
92CONFIG_SENSORS_LM90=y
93CONFIG_MFD_TPS6586X=y
94CONFIG_REGULATOR=y
95CONFIG_REGULATOR_TPS6586X=y
83# CONFIG_USB_SUPPORT is not set 96# CONFIG_USB_SUPPORT is not set
84CONFIG_MMC=y 97CONFIG_MMC=y
85CONFIG_MMC_SDHCI=y 98CONFIG_MMC_SDHCI=y
86CONFIG_MMC_SDHCI_PLTFM=y 99CONFIG_MMC_SDHCI_PLTFM=y
100CONFIG_MMC_SDHCI_TEGRA=y
101CONFIG_STAGING=y
102# CONFIG_STAGING_EXCLUDE_BUILD is not set
103CONFIG_IIO=y
104CONFIG_SENSORS_ISL29018=y
105CONFIG_SENSORS_AK8975=y
87CONFIG_EXT2_FS=y 106CONFIG_EXT2_FS=y
88CONFIG_EXT2_FS_XATTR=y 107CONFIG_EXT2_FS_XATTR=y
89CONFIG_EXT2_FS_POSIX_ACL=y 108CONFIG_EXT2_FS_POSIX_ACL=y
@@ -95,6 +114,10 @@ CONFIG_EXT3_FS_SECURITY=y
95# CONFIG_DNOTIFY is not set 114# CONFIG_DNOTIFY is not set
96CONFIG_VFAT_FS=y 115CONFIG_VFAT_FS=y
97CONFIG_TMPFS=y 116CONFIG_TMPFS=y
117CONFIG_NFS_FS=y
118CONFIG_ROOT_NFS=y
119CONFIG_PARTITION_ADVANCED=y
120CONFIG_EFI_PARTITION=y
98CONFIG_NLS_CODEPAGE_437=y 121CONFIG_NLS_CODEPAGE_437=y
99CONFIG_NLS_ISO8859_1=y 122CONFIG_NLS_ISO8859_1=y
100CONFIG_PRINTK_TIME=y 123CONFIG_PRINTK_TIME=y
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index 614b3c00c4a0..6e1accf93f81 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -232,10 +232,13 @@ static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
232}; 232};
233 233
234/* MC13783 */ 234/* MC13783 */
235static struct mc13xxx_platform_data mc13783_pdata __initdata = { 235static struct mc13xxx_platform_data mc13783_pdata = {
236 .regulators = mx27_3ds_regulators, 236 .regulators = {
237 .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), 237 .regulators = mx27_3ds_regulators,
238 .flags = MC13XXX_USE_REGULATOR, 238 .num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
239
240 },
241 .flags = MC13783_USE_REGULATOR,
239}; 242};
240 243
241/* SPI */ 244/* SPI */
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index 38c77084b615..4cbce6d0fef1 100644
--- a/arch/arm/mach-imx/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -263,10 +263,12 @@ static struct mc13xxx_regulator_init_data pcm038_regulators[] = {
263}; 263};
264 264
265static struct mc13xxx_platform_data pcm038_pmic = { 265static struct mc13xxx_platform_data pcm038_pmic = {
266 .regulators = pcm038_regulators, 266 .regulators = {
267 .num_regulators = ARRAY_SIZE(pcm038_regulators), 267 .regulators = pcm038_regulators,
268 .flags = MC13XXX_USE_ADC | MC13XXX_USE_REGULATOR | 268 .num_regulators = ARRAY_SIZE(pcm038_regulators),
269 MC13XXX_USE_TOUCHSCREEN, 269 },
270 .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
271 MC13783_USE_TOUCHSCREEN,
270}; 272};
271 273
272static struct spi_board_info pcm038_spi_board_info[] __initdata = { 274static struct spi_board_info pcm038_spi_board_info[] __initdata = {
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index 544d3e414f58..034be624d35c 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -488,10 +488,12 @@ static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
488}; 488};
489 489
490/* MC13783 */ 490/* MC13783 */
491static struct mc13xxx_platform_data mc13783_pdata __initdata = { 491static struct mc13xxx_platform_data mc13783_pdata = {
492 .regulators = mx31_3ds_regulators, 492 .regulators = {
493 .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), 493 .regulators = mx31_3ds_regulators,
494 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_TOUCHSCREEN 494 .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
495 },
496 .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN,
495}; 497};
496 498
497/* SPI */ 499/* SPI */
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c
index 6f3692bccb8a..3a021b01161d 100644
--- a/arch/arm/mach-mx3/mach-mx31moboard.c
+++ b/arch/arm/mach-mx3/mach-mx31moboard.c
@@ -268,8 +268,10 @@ static struct mc13783_leds_platform_data moboard_leds = {
268}; 268};
269 269
270static struct mc13xxx_platform_data moboard_pmic = { 270static struct mc13xxx_platform_data moboard_pmic = {
271 .regulators = moboard_regulators, 271 .regulators = {
272 .num_regulators = ARRAY_SIZE(moboard_regulators), 272 .regulators = moboard_regulators,
273 .num_regulators = ARRAY_SIZE(moboard_regulators),
274 },
273 .leds = &moboard_leds, 275 .leds = &moboard_leds,
274 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC | 276 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC |
275 MC13XXX_USE_ADC | MC13XXX_USE_LED, 277 MC13XXX_USE_ADC | MC13XXX_USE_LED,
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index c06eb423c4e4..9afd087cc29c 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -307,9 +307,6 @@ static struct omap_dss_board_info sdp3430_dss_data = {
307 .default_device = &sdp3430_lcd_device, 307 .default_device = &sdp3430_lcd_device,
308}; 308};
309 309
310static struct regulator_consumer_supply sdp3430_vdda_dac_supply =
311 REGULATOR_SUPPLY("vdda_dac", "omapdss");
312
313static struct omap_board_config_kernel sdp3430_config[] __initdata = { 310static struct omap_board_config_kernel sdp3430_config[] __initdata = {
314}; 311};
315 312
@@ -398,12 +395,13 @@ static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = {
398}; 395};
399 396
400static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = { 397static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
401 REGULATOR_SUPPLY("vdda_dac", "omapdss"), 398 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
402}; 399};
403 400
404/* VPLL2 for digital video outputs */ 401/* VPLL2 for digital video outputs */
405static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { 402static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
406 REGULATOR_SUPPLY("vdds_dsi", "omapdss"), 403 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
404 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
407}; 405};
408 406
409static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = { 407static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 333ceb2c8fb0..56702c5e577f 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -36,6 +36,7 @@
36#include <plat/usb.h> 36#include <plat/usb.h>
37#include <plat/mmc.h> 37#include <plat/mmc.h>
38#include <plat/omap4-keypad.h> 38#include <plat/omap4-keypad.h>
39#include <plat/display.h>
39 40
40#include "mux.h" 41#include "mux.h"
41#include "hsmmc.h" 42#include "hsmmc.h"
@@ -47,6 +48,8 @@
47#define ETH_KS8851_QUART 138 48#define ETH_KS8851_QUART 138
48#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 49#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
49#define OMAP4_SFH7741_ENABLE_GPIO 188 50#define OMAP4_SFH7741_ENABLE_GPIO 188
51#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
52#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
50 53
51static const int sdp4430_keymap[] = { 54static const int sdp4430_keymap[] = {
52 KEY(0, 0, KEY_E), 55 KEY(0, 0, KEY_E),
@@ -547,6 +550,12 @@ static struct regulator_init_data sdp4430_vusb = {
547 }, 550 },
548}; 551};
549 552
553static struct regulator_init_data sdp4430_clk32kg = {
554 .constraints = {
555 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
556 },
557};
558
550static struct twl4030_platform_data sdp4430_twldata = { 559static struct twl4030_platform_data sdp4430_twldata = {
551 .irq_base = TWL6030_IRQ_BASE, 560 .irq_base = TWL6030_IRQ_BASE,
552 .irq_end = TWL6030_IRQ_END, 561 .irq_end = TWL6030_IRQ_END,
@@ -562,6 +571,7 @@ static struct twl4030_platform_data sdp4430_twldata = {
562 .vaux1 = &sdp4430_vaux1, 571 .vaux1 = &sdp4430_vaux1,
563 .vaux2 = &sdp4430_vaux2, 572 .vaux2 = &sdp4430_vaux2,
564 .vaux3 = &sdp4430_vaux3, 573 .vaux3 = &sdp4430_vaux3,
574 .clk32kg = &sdp4430_clk32kg,
565 .usb = &omap4_usbphy_data 575 .usb = &omap4_usbphy_data
566}; 576};
567 577
@@ -621,6 +631,76 @@ static void __init omap_sfh7741prox_init(void)
621 } 631 }
622} 632}
623 633
634static void sdp4430_hdmi_mux_init(void)
635{
636 /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
637 omap_mux_init_signal("hdmi_hpd",
638 OMAP_PIN_INPUT_PULLUP);
639 omap_mux_init_signal("hdmi_cec",
640 OMAP_PIN_INPUT_PULLUP);
641 /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
642 omap_mux_init_signal("hdmi_ddc_scl",
643 OMAP_PIN_INPUT_PULLUP);
644 omap_mux_init_signal("hdmi_ddc_sda",
645 OMAP_PIN_INPUT_PULLUP);
646}
647
648static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
649{
650 int status;
651
652 status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH,
653 "hdmi_gpio_hpd");
654 if (status) {
655 pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
656 return status;
657 }
658 status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH,
659 "hdmi_gpio_ls_oe");
660 if (status) {
661 pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
662 goto error1;
663 }
664
665 return 0;
666
667error1:
668 gpio_free(HDMI_GPIO_HPD);
669
670 return status;
671}
672
673static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
674{
675 gpio_free(HDMI_GPIO_LS_OE);
676 gpio_free(HDMI_GPIO_HPD);
677}
678
679static struct omap_dss_device sdp4430_hdmi_device = {
680 .name = "hdmi",
681 .driver_name = "hdmi_panel",
682 .type = OMAP_DISPLAY_TYPE_HDMI,
683 .platform_enable = sdp4430_panel_enable_hdmi,
684 .platform_disable = sdp4430_panel_disable_hdmi,
685 .channel = OMAP_DSS_CHANNEL_DIGIT,
686};
687
688static struct omap_dss_device *sdp4430_dss_devices[] = {
689 &sdp4430_hdmi_device,
690};
691
692static struct omap_dss_board_info sdp4430_dss_data = {
693 .num_devices = ARRAY_SIZE(sdp4430_dss_devices),
694 .devices = sdp4430_dss_devices,
695 .default_device = &sdp4430_hdmi_device,
696};
697
698void omap_4430sdp_display_init(void)
699{
700 sdp4430_hdmi_mux_init();
701 omap_display_init(&sdp4430_dss_data);
702}
703
624#ifdef CONFIG_OMAP_MUX 704#ifdef CONFIG_OMAP_MUX
625static struct omap_board_mux board_mux[] __initdata = { 705static struct omap_board_mux board_mux[] __initdata = {
626 OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), 706 OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
@@ -729,6 +809,8 @@ static void __init omap_4430sdp_init(void)
729 status = omap4_keyboard_init(&sdp4430_keypad_data); 809 status = omap4_keyboard_init(&sdp4430_keypad_data);
730 if (status) 810 if (status)
731 pr_err("Keypad initialization failed: %d\n", status); 811 pr_err("Keypad initialization failed: %d\n", status);
812
813 omap_4430sdp_display_init();
732} 814}
733 815
734static void __init omap_4430sdp_map_io(void) 816static void __init omap_4430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 7b5647954c13..02a12b41c0ff 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -488,7 +488,7 @@ static struct regulator_consumer_supply cm_t35_vsim_supply = {
488}; 488};
489 489
490static struct regulator_consumer_supply cm_t35_vdac_supply = 490static struct regulator_consumer_supply cm_t35_vdac_supply =
491 REGULATOR_SUPPLY("vdda_dac", "omapdss"); 491 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
492 492
493static struct regulator_consumer_supply cm_t35_vdvi_supply = 493static struct regulator_consumer_supply cm_t35_vdvi_supply =
494 REGULATOR_SUPPLY("vdvi", "omapdss"); 494 REGULATOR_SUPPLY("vdvi", "omapdss");
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index aa27483c493e..65f9fde2c567 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -196,7 +196,7 @@ static struct omap_dss_board_info devkit8000_dss_data = {
196}; 196};
197 197
198static struct regulator_consumer_supply devkit8000_vdda_dac_supply = 198static struct regulator_consumer_supply devkit8000_vdda_dac_supply =
199 REGULATOR_SUPPLY("vdda_dac", "omapdss"); 199 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
200 200
201static uint32_t board_keymap[] = { 201static uint32_t board_keymap[] = {
202 KEY(0, 0, KEY_1), 202 KEY(0, 0, KEY_1),
@@ -277,8 +277,10 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
277 .setup = devkit8000_twl_gpio_setup, 277 .setup = devkit8000_twl_gpio_setup,
278}; 278};
279 279
280static struct regulator_consumer_supply devkit8000_vpll1_supply = 280static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
281 REGULATOR_SUPPLY("vdds_dsi", "omapdss"); 281 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
282 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
283};
282 284
283/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ 285/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
284static struct regulator_init_data devkit8000_vmmc1 = { 286static struct regulator_init_data devkit8000_vmmc1 = {
@@ -319,8 +321,8 @@ static struct regulator_init_data devkit8000_vpll1 = {
319 .valid_ops_mask = REGULATOR_CHANGE_MODE 321 .valid_ops_mask = REGULATOR_CHANGE_MODE
320 | REGULATOR_CHANGE_STATUS, 322 | REGULATOR_CHANGE_STATUS,
321 }, 323 },
322 .num_consumer_supplies = 1, 324 .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies),
323 .consumer_supplies = &devkit8000_vpll1_supply, 325 .consumer_supplies = devkit8000_vpll1_supplies,
324}; 326};
325 327
326/* VAUX4 for ads7846 and nubs */ 328/* VAUX4 for ads7846 and nubs */
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index d3199b4ecdb6..5f8a2fd06337 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -485,8 +485,10 @@ static struct omap_dss_board_info igep2_dss_data = {
485 .default_device = &igep2_dvi_device, 485 .default_device = &igep2_dvi_device,
486}; 486};
487 487
488static struct regulator_consumer_supply igep2_vpll2_supply = 488static struct regulator_consumer_supply igep2_vpll2_supplies[] = {
489 REGULATOR_SUPPLY("vdds_dsi", "omapdss"); 489 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
490 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
491};
490 492
491static struct regulator_init_data igep2_vpll2 = { 493static struct regulator_init_data igep2_vpll2 = {
492 .constraints = { 494 .constraints = {
@@ -499,8 +501,8 @@ static struct regulator_init_data igep2_vpll2 = {
499 .valid_ops_mask = REGULATOR_CHANGE_MODE 501 .valid_ops_mask = REGULATOR_CHANGE_MODE
500 | REGULATOR_CHANGE_STATUS, 502 | REGULATOR_CHANGE_STATUS,
501 }, 503 },
502 .num_consumer_supplies = 1, 504 .num_consumer_supplies = ARRAY_SIZE(igep2_vpll2_supplies),
503 .consumer_supplies = &igep2_vpll2_supply, 505 .consumer_supplies = igep2_vpll2_supplies,
504}; 506};
505 507
506static void __init igep2_display_init(void) 508static void __init igep2_display_init(void)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 7640c054f43b..33007fd4a083 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -232,10 +232,12 @@ static struct omap_dss_board_info beagle_dss_data = {
232}; 232};
233 233
234static struct regulator_consumer_supply beagle_vdac_supply = 234static struct regulator_consumer_supply beagle_vdac_supply =
235 REGULATOR_SUPPLY("vdda_dac", "omapdss"); 235 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
236 236
237static struct regulator_consumer_supply beagle_vdvi_supply = 237static struct regulator_consumer_supply beagle_vdvi_supplies[] = {
238 REGULATOR_SUPPLY("vdds_dsi", "omapdss"); 238 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
239 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
240};
239 241
240static void __init beagle_display_init(void) 242static void __init beagle_display_init(void)
241{ 243{
@@ -422,8 +424,8 @@ static struct regulator_init_data beagle_vpll2 = {
422 .valid_ops_mask = REGULATOR_CHANGE_MODE 424 .valid_ops_mask = REGULATOR_CHANGE_MODE
423 | REGULATOR_CHANGE_STATUS, 425 | REGULATOR_CHANGE_STATUS,
424 }, 426 },
425 .num_consumer_supplies = 1, 427 .num_consumer_supplies = ARRAY_SIZE(beagle_vdvi_supplies),
426 .consumer_supplies = &beagle_vdvi_supply, 428 .consumer_supplies = beagle_vdvi_supplies,
427}; 429};
428 430
429static struct twl4030_usb_data beagle_usb_data = { 431static struct twl4030_usb_data beagle_usb_data = {
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 0fa2c7b208b1..5a1a916e5cc8 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -542,7 +542,7 @@ static struct twl4030_codec_data omap3evm_codec_data = {
542}; 542};
543 543
544static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = 544static struct regulator_consumer_supply omap3_evm_vdda_dac_supply =
545 REGULATOR_SUPPLY("vdda_dac", "omapdss"); 545 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
546 546
547/* VDAC for DSS driving S-Video */ 547/* VDAC for DSS driving S-Video */
548static struct regulator_init_data omap3_evm_vdac = { 548static struct regulator_init_data omap3_evm_vdac = {
@@ -560,8 +560,10 @@ static struct regulator_init_data omap3_evm_vdac = {
560}; 560};
561 561
562/* VPLL2 for digital video outputs */ 562/* VPLL2 for digital video outputs */
563static struct regulator_consumer_supply omap3_evm_vpll2_supply = 563static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = {
564 REGULATOR_SUPPLY("vdds_dsi", "omapdss"); 564 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
565 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
566};
565 567
566static struct regulator_init_data omap3_evm_vpll2 = { 568static struct regulator_init_data omap3_evm_vpll2 = {
567 .constraints = { 569 .constraints = {
@@ -573,8 +575,8 @@ static struct regulator_init_data omap3_evm_vpll2 = {
573 .valid_ops_mask = REGULATOR_CHANGE_MODE 575 .valid_ops_mask = REGULATOR_CHANGE_MODE
574 | REGULATOR_CHANGE_STATUS, 576 | REGULATOR_CHANGE_STATUS,
575 }, 577 },
576 .num_consumer_supplies = 1, 578 .num_consumer_supplies = ARRAY_SIZE(omap3_evm_vpll2_supplies),
577 .consumer_supplies = &omap3_evm_vpll2_supply, 579 .consumer_supplies = omap3_evm_vpll2_supplies,
578}; 580};
579 581
580/* ads7846 on SPI */ 582/* ads7846 on SPI */
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 2e5dc21e3477..07dba888f450 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -342,11 +342,12 @@ static struct regulator_consumer_supply pandora_vmmc3_supply =
342 REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"); 342 REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2");
343 343
344static struct regulator_consumer_supply pandora_vdda_dac_supply = 344static struct regulator_consumer_supply pandora_vdda_dac_supply =
345 REGULATOR_SUPPLY("vdda_dac", "omapdss"); 345 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
346 346
347static struct regulator_consumer_supply pandora_vdds_supplies[] = { 347static struct regulator_consumer_supply pandora_vdds_supplies[] = {
348 REGULATOR_SUPPLY("vdds_sdi", "omapdss"), 348 REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
349 REGULATOR_SUPPLY("vdds_dsi", "omapdss"), 349 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
350 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
350}; 351};
351 352
352static struct regulator_consumer_supply pandora_vcc_lcd_supply = 353static struct regulator_consumer_supply pandora_vcc_lcd_supply =
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 8ebdbc38b9de..a6e0b9161c99 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -439,7 +439,7 @@ static struct twl4030_codec_data omap3stalker_codec_data = {
439}; 439};
440 440
441static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = 441static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply =
442 REGULATOR_SUPPLY("vdda_dac", "omapdss"); 442 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
443 443
444/* VDAC for DSS driving S-Video */ 444/* VDAC for DSS driving S-Video */
445static struct regulator_init_data omap3_stalker_vdac = { 445static struct regulator_init_data omap3_stalker_vdac = {
@@ -457,8 +457,10 @@ static struct regulator_init_data omap3_stalker_vdac = {
457}; 457};
458 458
459/* VPLL2 for digital video outputs */ 459/* VPLL2 for digital video outputs */
460static struct regulator_consumer_supply omap3_stalker_vpll2_supply = 460static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = {
461 REGULATOR_SUPPLY("vdds_dsi", "omapdss"); 461 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
462 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
463};
462 464
463static struct regulator_init_data omap3_stalker_vpll2 = { 465static struct regulator_init_data omap3_stalker_vpll2 = {
464 .constraints = { 466 .constraints = {
@@ -471,8 +473,8 @@ static struct regulator_init_data omap3_stalker_vpll2 = {
471 .valid_ops_mask = REGULATOR_CHANGE_MODE 473 .valid_ops_mask = REGULATOR_CHANGE_MODE
472 | REGULATOR_CHANGE_STATUS, 474 | REGULATOR_CHANGE_STATUS,
473 }, 475 },
474 .num_consumer_supplies = 1, 476 .num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies),
475 .consumer_supplies = &omap3_stalker_vpll2_supply, 477 .consumer_supplies = omap3_stalker_vpll2_supplies,
476}; 478};
477 479
478static struct twl4030_platform_data omap3stalker_twldata = { 480static struct twl4030_platform_data omap3stalker_twldata = {
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 0f4d8a762a70..c936c6d7ded0 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -34,11 +34,13 @@
34#include <asm/mach-types.h> 34#include <asm/mach-types.h>
35#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
36#include <asm/mach/map.h> 36#include <asm/mach/map.h>
37#include <plat/display.h>
37 38
38#include <plat/board.h> 39#include <plat/board.h>
39#include <plat/common.h> 40#include <plat/common.h>
40#include <plat/usb.h> 41#include <plat/usb.h>
41#include <plat/mmc.h> 42#include <plat/mmc.h>
43#include <plat/panel-generic-dpi.h>
42#include "timer-gp.h" 44#include "timer-gp.h"
43 45
44#include "hsmmc.h" 46#include "hsmmc.h"
@@ -49,6 +51,8 @@
49#define GPIO_HUB_NRESET 62 51#define GPIO_HUB_NRESET 62
50#define GPIO_WIFI_PMENA 43 52#define GPIO_WIFI_PMENA 43
51#define GPIO_WIFI_IRQ 53 53#define GPIO_WIFI_IRQ 53
54#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
55#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
52 56
53/* wl127x BT, FM, GPS connectivity chip */ 57/* wl127x BT, FM, GPS connectivity chip */
54static int wl1271_gpios[] = {46, -1, -1}; 58static int wl1271_gpios[] = {46, -1, -1};
@@ -407,6 +411,12 @@ static struct regulator_init_data omap4_panda_vusb = {
407 }, 411 },
408}; 412};
409 413
414static struct regulator_init_data omap4_panda_clk32kg = {
415 .constraints = {
416 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
417 },
418};
419
410static struct twl4030_platform_data omap4_panda_twldata = { 420static struct twl4030_platform_data omap4_panda_twldata = {
411 .irq_base = TWL6030_IRQ_BASE, 421 .irq_base = TWL6030_IRQ_BASE,
412 .irq_end = TWL6030_IRQ_END, 422 .irq_end = TWL6030_IRQ_END,
@@ -422,6 +432,7 @@ static struct twl4030_platform_data omap4_panda_twldata = {
422 .vaux1 = &omap4_panda_vaux1, 432 .vaux1 = &omap4_panda_vaux1,
423 .vaux2 = &omap4_panda_vaux2, 433 .vaux2 = &omap4_panda_vaux2,
424 .vaux3 = &omap4_panda_vaux3, 434 .vaux3 = &omap4_panda_vaux3,
435 .clk32kg = &omap4_panda_clk32kg,
425 .usb = &omap4_usbphy_data, 436 .usb = &omap4_usbphy_data,
426}; 437};
427 438
@@ -433,6 +444,17 @@ static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
433 .platform_data = &omap4_panda_twldata, 444 .platform_data = &omap4_panda_twldata,
434 }, 445 },
435}; 446};
447
448/*
449 * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
450 * is connected as I2C slave device, and can be accessed at address 0x50
451 */
452static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
453 {
454 I2C_BOARD_INFO("eeprom", 0x50),
455 },
456};
457
436static int __init omap4_panda_i2c_init(void) 458static int __init omap4_panda_i2c_init(void)
437{ 459{
438 /* 460 /*
@@ -442,7 +464,12 @@ static int __init omap4_panda_i2c_init(void)
442 omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo, 464 omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
443 ARRAY_SIZE(omap4_panda_i2c_boardinfo)); 465 ARRAY_SIZE(omap4_panda_i2c_boardinfo));
444 omap_register_i2c_bus(2, 400, NULL, 0); 466 omap_register_i2c_bus(2, 400, NULL, 0);
445 omap_register_i2c_bus(3, 400, NULL, 0); 467 /*
468 * Bus 3 is attached to the DVI port where devices like the pico DLP
469 * projector don't work reliably with 400kHz
470 */
471 omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
472 ARRAY_SIZE(panda_i2c_eeprom));
446 omap_register_i2c_bus(4, 400, NULL, 0); 473 omap_register_i2c_bus(4, 400, NULL, 0);
447 return 0; 474 return 0;
448} 475}
@@ -462,6 +489,64 @@ static struct omap_board_mux board_mux[] __initdata = {
462 OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), 489 OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
463 OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), 490 OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
464 OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), 491 OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
492 /* gpio 0 - TFP410 PD */
493 OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
494 /* dispc2_data23 */
495 OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
496 /* dispc2_data22 */
497 OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
498 /* dispc2_data21 */
499 OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
500 /* dispc2_data20 */
501 OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
502 /* dispc2_data19 */
503 OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
504 /* dispc2_data18 */
505 OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
506 /* dispc2_data15 */
507 OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
508 /* dispc2_data14 */
509 OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
510 /* dispc2_data13 */
511 OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
512 /* dispc2_data12 */
513 OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
514 /* dispc2_data11 */
515 OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
516 /* dispc2_data10 */
517 OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
518 /* dispc2_data9 */
519 OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
520 /* dispc2_data16 */
521 OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
522 /* dispc2_data17 */
523 OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
524 /* dispc2_hsync */
525 OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
526 /* dispc2_pclk */
527 OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
528 /* dispc2_vsync */
529 OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
530 /* dispc2_de */
531 OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
532 /* dispc2_data8 */
533 OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
534 /* dispc2_data7 */
535 OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
536 /* dispc2_data6 */
537 OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
538 /* dispc2_data5 */
539 OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
540 /* dispc2_data4 */
541 OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
542 /* dispc2_data3 */
543 OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
544 /* dispc2_data2 */
545 OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
546 /* dispc2_data1 */
547 OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
548 /* dispc2_data0 */
549 OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
465 { .reg_offset = OMAP_MUX_TERMINATOR }, 550 { .reg_offset = OMAP_MUX_TERMINATOR },
466}; 551};
467 552
@@ -535,6 +620,128 @@ static inline void board_serial_init(void)
535} 620}
536#endif 621#endif
537 622
623/* Display DVI */
624#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
625
626static int omap4_panda_enable_dvi(struct omap_dss_device *dssdev)
627{
628 gpio_set_value(dssdev->reset_gpio, 1);
629 return 0;
630}
631
632static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
633{
634 gpio_set_value(dssdev->reset_gpio, 0);
635}
636
637/* Using generic display panel */
638static struct panel_generic_dpi_data omap4_dvi_panel = {
639 .name = "generic",
640 .platform_enable = omap4_panda_enable_dvi,
641 .platform_disable = omap4_panda_disable_dvi,
642};
643
644struct omap_dss_device omap4_panda_dvi_device = {
645 .type = OMAP_DISPLAY_TYPE_DPI,
646 .name = "dvi",
647 .driver_name = "generic_dpi_panel",
648 .data = &omap4_dvi_panel,
649 .phy.dpi.data_lines = 24,
650 .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
651 .channel = OMAP_DSS_CHANNEL_LCD2,
652};
653
654int __init omap4_panda_dvi_init(void)
655{
656 int r;
657
658 /* Requesting TFP410 DVI GPIO and disabling it, at bootup */
659 r = gpio_request_one(omap4_panda_dvi_device.reset_gpio,
660 GPIOF_OUT_INIT_LOW, "DVI PD");
661 if (r)
662 pr_err("Failed to get DVI powerdown GPIO\n");
663
664 return r;
665}
666
667
668static void omap4_panda_hdmi_mux_init(void)
669{
670 /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
671 omap_mux_init_signal("hdmi_hpd",
672 OMAP_PIN_INPUT_PULLUP);
673 omap_mux_init_signal("hdmi_cec",
674 OMAP_PIN_INPUT_PULLUP);
675 /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
676 omap_mux_init_signal("hdmi_ddc_scl",
677 OMAP_PIN_INPUT_PULLUP);
678 omap_mux_init_signal("hdmi_ddc_sda",
679 OMAP_PIN_INPUT_PULLUP);
680}
681
682static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
683{
684 int status;
685
686 status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH,
687 "hdmi_gpio_hpd");
688 if (status) {
689 pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
690 return status;
691 }
692 status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH,
693 "hdmi_gpio_ls_oe");
694 if (status) {
695 pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
696 goto error1;
697 }
698
699 return 0;
700
701error1:
702 gpio_free(HDMI_GPIO_HPD);
703
704 return status;
705}
706
707static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
708{
709 gpio_free(HDMI_GPIO_LS_OE);
710 gpio_free(HDMI_GPIO_HPD);
711}
712
713static struct omap_dss_device omap4_panda_hdmi_device = {
714 .name = "hdmi",
715 .driver_name = "hdmi_panel",
716 .type = OMAP_DISPLAY_TYPE_HDMI,
717 .platform_enable = omap4_panda_panel_enable_hdmi,
718 .platform_disable = omap4_panda_panel_disable_hdmi,
719 .channel = OMAP_DSS_CHANNEL_DIGIT,
720};
721
722static struct omap_dss_device *omap4_panda_dss_devices[] = {
723 &omap4_panda_dvi_device,
724 &omap4_panda_hdmi_device,
725};
726
727static struct omap_dss_board_info omap4_panda_dss_data = {
728 .num_devices = ARRAY_SIZE(omap4_panda_dss_devices),
729 .devices = omap4_panda_dss_devices,
730 .default_device = &omap4_panda_dvi_device,
731};
732
733void omap4_panda_display_init(void)
734{
735 int r;
736
737 r = omap4_panda_dvi_init();
738 if (r)
739 pr_err("error initializing panda DVI\n");
740
741 omap4_panda_hdmi_mux_init();
742 omap_display_init(&omap4_panda_dss_data);
743}
744
538static void __init omap4_panda_init(void) 745static void __init omap4_panda_init(void)
539{ 746{
540 int package = OMAP_PACKAGE_CBS; 747 int package = OMAP_PACKAGE_CBS;
@@ -553,6 +760,7 @@ static void __init omap4_panda_init(void)
553 omap4_twl6030_hsmmc_init(mmc); 760 omap4_twl6030_hsmmc_init(mmc);
554 omap4_ehci_init(); 761 omap4_ehci_init();
555 usb_musb_init(&musb_board_data); 762 usb_musb_init(&musb_board_data);
763 omap4_panda_display_init();
556} 764}
557 765
558static void __init omap4_panda_map_io(void) 766static void __init omap4_panda_map_io(void)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index d0961945c65a..59ca33326b8c 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -28,6 +28,8 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/i2c/twl.h> 29#include <linux/i2c/twl.h>
30#include <linux/regulator/machine.h> 30#include <linux/regulator/machine.h>
31#include <linux/regulator/fixed.h>
32#include <linux/spi/spi.h>
31 33
32#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
33#include <linux/mtd/nand.h> 35#include <linux/mtd/nand.h>
@@ -41,10 +43,14 @@
41 43
42#include <plat/board.h> 44#include <plat/board.h>
43#include <plat/common.h> 45#include <plat/common.h>
46#include <plat/display.h>
47#include <plat/panel-generic-dpi.h>
44#include <mach/gpio.h> 48#include <mach/gpio.h>
45#include <plat/gpmc.h> 49#include <plat/gpmc.h>
46#include <mach/hardware.h> 50#include <mach/hardware.h>
47#include <plat/nand.h> 51#include <plat/nand.h>
52#include <plat/mcspi.h>
53#include <plat/mux.h>
48#include <plat/usb.h> 54#include <plat/usb.h>
49 55
50#include "mux.h" 56#include "mux.h"
@@ -68,8 +74,6 @@
68#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ 74#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
69 defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) 75 defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
70 76
71#include <plat/mcspi.h>
72#include <linux/spi/spi.h>
73#include <linux/spi/ads7846.h> 77#include <linux/spi/ads7846.h>
74 78
75static struct omap2_mcspi_device_config ads7846_mcspi_config = { 79static struct omap2_mcspi_device_config ads7846_mcspi_config = {
@@ -94,16 +98,32 @@ static struct ads7846_platform_data ads7846_config = {
94 .keep_vref_on = 1, 98 .keep_vref_on = 1,
95}; 99};
96 100
97static struct spi_board_info overo_spi_board_info[] __initdata = { 101/* fixed regulator for ads7846 */
98 { 102static struct regulator_consumer_supply ads7846_supply =
99 .modalias = "ads7846", 103 REGULATOR_SUPPLY("vcc", "spi1.0");
100 .bus_num = 1, 104
101 .chip_select = 0, 105static struct regulator_init_data vads7846_regulator = {
102 .max_speed_hz = 1500000, 106 .constraints = {
103 .controller_data = &ads7846_mcspi_config, 107 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
104 .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), 108 },
105 .platform_data = &ads7846_config, 109 .num_consumer_supplies = 1,
106 } 110 .consumer_supplies = &ads7846_supply,
111};
112
113static struct fixed_voltage_config vads7846 = {
114 .supply_name = "vads7846",
115 .microvolts = 3300000, /* 3.3V */
116 .gpio = -EINVAL,
117 .startup_delay = 0,
118 .init_data = &vads7846_regulator,
119};
120
121static struct platform_device vads7846_device = {
122 .name = "reg-fixed-voltage",
123 .id = 1,
124 .dev = {
125 .platform_data = &vads7846,
126 },
107}; 127};
108 128
109static void __init overo_ads7846_init(void) 129static void __init overo_ads7846_init(void)
@@ -116,8 +136,7 @@ static void __init overo_ads7846_init(void)
116 return; 136 return;
117 } 137 }
118 138
119 spi_register_board_info(overo_spi_board_info, 139 platform_device_register(&vads7846_device);
120 ARRAY_SIZE(overo_spi_board_info));
121} 140}
122 141
123#else 142#else
@@ -233,6 +252,137 @@ static inline void __init overo_init_smsc911x(void)
233static inline void __init overo_init_smsc911x(void) { return; } 252static inline void __init overo_init_smsc911x(void) { return; }
234#endif 253#endif
235 254
255/* DSS */
256static int lcd_enabled;
257static int dvi_enabled;
258
259#define OVERO_GPIO_LCD_EN 144
260#define OVERO_GPIO_LCD_BL 145
261
262static void __init overo_display_init(void)
263{
264 if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) &&
265 (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0))
266 gpio_export(OVERO_GPIO_LCD_EN, 0);
267 else
268 printk(KERN_ERR "could not obtain gpio for "
269 "OVERO_GPIO_LCD_EN\n");
270
271 if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) &&
272 (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0))
273 gpio_export(OVERO_GPIO_LCD_BL, 0);
274 else
275 printk(KERN_ERR "could not obtain gpio for "
276 "OVERO_GPIO_LCD_BL\n");
277}
278
279static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
280{
281 if (lcd_enabled) {
282 printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
283 return -EINVAL;
284 }
285 dvi_enabled = 1;
286
287 return 0;
288}
289
290static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
291{
292 dvi_enabled = 0;
293}
294
295static struct panel_generic_dpi_data dvi_panel = {
296 .name = "generic",
297 .platform_enable = overo_panel_enable_dvi,
298 .platform_disable = overo_panel_disable_dvi,
299};
300
301static struct omap_dss_device overo_dvi_device = {
302 .name = "dvi",
303 .type = OMAP_DISPLAY_TYPE_DPI,
304 .driver_name = "generic_dpi_panel",
305 .data = &dvi_panel,
306 .phy.dpi.data_lines = 24,
307};
308
309static struct omap_dss_device overo_tv_device = {
310 .name = "tv",
311 .driver_name = "venc",
312 .type = OMAP_DISPLAY_TYPE_VENC,
313 .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
314};
315
316static int overo_panel_enable_lcd(struct omap_dss_device *dssdev)
317{
318 if (dvi_enabled) {
319 printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
320 return -EINVAL;
321 }
322
323 gpio_set_value(OVERO_GPIO_LCD_EN, 1);
324 gpio_set_value(OVERO_GPIO_LCD_BL, 1);
325 lcd_enabled = 1;
326 return 0;
327}
328
329static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
330{
331 gpio_set_value(OVERO_GPIO_LCD_EN, 0);
332 gpio_set_value(OVERO_GPIO_LCD_BL, 0);
333 lcd_enabled = 0;
334}
335
336static struct panel_generic_dpi_data lcd43_panel = {
337 .name = "samsung_lte430wq_f0c",
338 .platform_enable = overo_panel_enable_lcd,
339 .platform_disable = overo_panel_disable_lcd,
340};
341
342static struct omap_dss_device overo_lcd43_device = {
343 .name = "lcd43",
344 .type = OMAP_DISPLAY_TYPE_DPI,
345 .driver_name = "generic_dpi_panel",
346 .data = &lcd43_panel,
347 .phy.dpi.data_lines = 24,
348};
349
350#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
351 defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
352static struct omap_dss_device overo_lcd35_device = {
353 .type = OMAP_DISPLAY_TYPE_DPI,
354 .name = "lcd35",
355 .driver_name = "lgphilips_lb035q02_panel",
356 .phy.dpi.data_lines = 24,
357 .platform_enable = overo_panel_enable_lcd,
358 .platform_disable = overo_panel_disable_lcd,
359};
360#endif
361
362static struct omap_dss_device *overo_dss_devices[] = {
363 &overo_dvi_device,
364 &overo_tv_device,
365#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
366 defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
367 &overo_lcd35_device,
368#endif
369 &overo_lcd43_device,
370};
371
372static struct omap_dss_board_info overo_dss_data = {
373 .num_devices = ARRAY_SIZE(overo_dss_devices),
374 .devices = overo_dss_devices,
375 .default_device = &overo_dvi_device,
376};
377
378static struct regulator_consumer_supply overo_vdda_dac_supply =
379 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
380
381static struct regulator_consumer_supply overo_vdds_dsi_supply[] = {
382 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
383 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
384};
385
236static struct mtd_partition overo_nand_partitions[] = { 386static struct mtd_partition overo_nand_partitions[] = {
237 { 387 {
238 .name = "xloader", 388 .name = "xloader",
@@ -323,6 +473,93 @@ static struct regulator_consumer_supply overo_vmmc1_supply = {
323 .supply = "vmmc", 473 .supply = "vmmc",
324}; 474};
325 475
476#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
477#include <linux/leds.h>
478
479static struct gpio_led gpio_leds[] = {
480 {
481 .name = "overo:red:gpio21",
482 .default_trigger = "heartbeat",
483 .gpio = 21,
484 .active_low = true,
485 },
486 {
487 .name = "overo:blue:gpio22",
488 .default_trigger = "none",
489 .gpio = 22,
490 .active_low = true,
491 },
492 {
493 .name = "overo:blue:COM",
494 .default_trigger = "mmc0",
495 .gpio = -EINVAL, /* gets replaced */
496 .active_low = true,
497 },
498};
499
500static struct gpio_led_platform_data gpio_leds_pdata = {
501 .leds = gpio_leds,
502 .num_leds = ARRAY_SIZE(gpio_leds),
503};
504
505static struct platform_device gpio_leds_device = {
506 .name = "leds-gpio",
507 .id = -1,
508 .dev = {
509 .platform_data = &gpio_leds_pdata,
510 },
511};
512
513static void __init overo_init_led(void)
514{
515 platform_device_register(&gpio_leds_device);
516}
517
518#else
519static inline void __init overo_init_led(void) { return; }
520#endif
521
522#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
523#include <linux/input.h>
524#include <linux/gpio_keys.h>
525
526static struct gpio_keys_button gpio_buttons[] = {
527 {
528 .code = BTN_0,
529 .gpio = 23,
530 .desc = "button0",
531 .wakeup = 1,
532 },
533 {
534 .code = BTN_1,
535 .gpio = 14,
536 .desc = "button1",
537 .wakeup = 1,
538 },
539};
540
541static struct gpio_keys_platform_data gpio_keys_pdata = {
542 .buttons = gpio_buttons,
543 .nbuttons = ARRAY_SIZE(gpio_buttons),
544};
545
546static struct platform_device gpio_keys_device = {
547 .name = "gpio-keys",
548 .id = -1,
549 .dev = {
550 .platform_data = &gpio_keys_pdata,
551 },
552};
553
554static void __init overo_init_keys(void)
555{
556 platform_device_register(&gpio_keys_device);
557}
558
559#else
560static inline void __init overo_init_keys(void) { return; }
561#endif
562
326static int overo_twl_gpio_setup(struct device *dev, 563static int overo_twl_gpio_setup(struct device *dev,
327 unsigned gpio, unsigned ngpio) 564 unsigned gpio, unsigned ngpio)
328{ 565{
@@ -330,6 +567,11 @@ static int overo_twl_gpio_setup(struct device *dev,
330 567
331 overo_vmmc1_supply.dev = mmc[0].dev; 568 overo_vmmc1_supply.dev = mmc[0].dev;
332 569
570#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
571 /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
572 gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
573#endif
574
333 return 0; 575 return 0;
334} 576}
335 577
@@ -337,6 +579,7 @@ static struct twl4030_gpio_platform_data overo_gpio_data = {
337 .gpio_base = OMAP_MAX_GPIO_LINES, 579 .gpio_base = OMAP_MAX_GPIO_LINES,
338 .irq_base = TWL4030_GPIO_IRQ_BASE, 580 .irq_base = TWL4030_GPIO_IRQ_BASE,
339 .irq_end = TWL4030_GPIO_IRQ_END, 581 .irq_end = TWL4030_GPIO_IRQ_END,
582 .use_leds = true,
340 .setup = overo_twl_gpio_setup, 583 .setup = overo_twl_gpio_setup,
341}; 584};
342 585
@@ -358,6 +601,35 @@ static struct regulator_init_data overo_vmmc1 = {
358 .consumer_supplies = &overo_vmmc1_supply, 601 .consumer_supplies = &overo_vmmc1_supply,
359}; 602};
360 603
604/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
605static struct regulator_init_data overo_vdac = {
606 .constraints = {
607 .min_uV = 1800000,
608 .max_uV = 1800000,
609 .valid_modes_mask = REGULATOR_MODE_NORMAL
610 | REGULATOR_MODE_STANDBY,
611 .valid_ops_mask = REGULATOR_CHANGE_MODE
612 | REGULATOR_CHANGE_STATUS,
613 },
614 .num_consumer_supplies = 1,
615 .consumer_supplies = &overo_vdda_dac_supply,
616};
617
618/* VPLL2 for digital video outputs */
619static struct regulator_init_data overo_vpll2 = {
620 .constraints = {
621 .name = "VDVI",
622 .min_uV = 1800000,
623 .max_uV = 1800000,
624 .valid_modes_mask = REGULATOR_MODE_NORMAL
625 | REGULATOR_MODE_STANDBY,
626 .valid_ops_mask = REGULATOR_CHANGE_MODE
627 | REGULATOR_CHANGE_STATUS,
628 },
629 .num_consumer_supplies = ARRAY_SIZE(overo_vdds_dsi_supply),
630 .consumer_supplies = overo_vdds_dsi_supply,
631};
632
361static struct twl4030_codec_audio_data overo_audio_data; 633static struct twl4030_codec_audio_data overo_audio_data;
362 634
363static struct twl4030_codec_data overo_codec_data = { 635static struct twl4030_codec_data overo_codec_data = {
@@ -365,8 +637,6 @@ static struct twl4030_codec_data overo_codec_data = {
365 .audio = &overo_audio_data, 637 .audio = &overo_audio_data,
366}; 638};
367 639
368/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
369
370static struct twl4030_platform_data overo_twldata = { 640static struct twl4030_platform_data overo_twldata = {
371 .irq_base = TWL4030_IRQ_BASE, 641 .irq_base = TWL4030_IRQ_BASE,
372 .irq_end = TWL4030_IRQ_END, 642 .irq_end = TWL4030_IRQ_END,
@@ -374,6 +644,8 @@ static struct twl4030_platform_data overo_twldata = {
374 .usb = &overo_usb_data, 644 .usb = &overo_usb_data,
375 .codec = &overo_codec_data, 645 .codec = &overo_codec_data,
376 .vmmc1 = &overo_vmmc1, 646 .vmmc1 = &overo_vmmc1,
647 .vdac = &overo_vdac,
648 .vpll2 = &overo_vpll2,
377}; 649};
378 650
379static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { 651static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
@@ -394,18 +666,38 @@ static int __init overo_i2c_init(void)
394 return 0; 666 return 0;
395} 667}
396 668
397static struct platform_device overo_lcd_device = { 669static struct spi_board_info overo_spi_board_info[] __initdata = {
398 .name = "overo_lcd", 670#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
399 .id = -1, 671 defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
400}; 672 {
401 673 .modalias = "ads7846",
402static struct omap_lcd_config overo_lcd_config __initdata = { 674 .bus_num = 1,
403 .ctrl_name = "internal", 675 .chip_select = 0,
676 .max_speed_hz = 1500000,
677 .controller_data = &ads7846_mcspi_config,
678 .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
679 .platform_data = &ads7846_config,
680 },
681#endif
682#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
683 defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
684 {
685 .modalias = "lgphilips_lb035q02_panel-spi",
686 .bus_num = 1,
687 .chip_select = 1,
688 .max_speed_hz = 500000,
689 .mode = SPI_MODE_3,
690 },
691#endif
404}; 692};
405 693
406static struct omap_board_config_kernel overo_config[] __initdata = { 694static int __init overo_spi_init(void)
407 { OMAP_TAG_LCD, &overo_lcd_config }, 695{
408}; 696 overo_ads7846_init();
697 spi_register_board_info(overo_spi_board_info,
698 ARRAY_SIZE(overo_spi_board_info));
699 return 0;
700}
409 701
410static void __init overo_init_early(void) 702static void __init overo_init_early(void)
411{ 703{
@@ -414,15 +706,10 @@ static void __init overo_init_early(void)
414 mt46h32m32lf6_sdrc_params); 706 mt46h32m32lf6_sdrc_params);
415} 707}
416 708
417static struct platform_device *overo_devices[] __initdata = {
418 &overo_lcd_device,
419};
420
421static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 709static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
422 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 710 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
423 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 711 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
424 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 712 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
425
426 .phy_reset = true, 713 .phy_reset = true,
427 .reset_gpio_port[0] = -EINVAL, 714 .reset_gpio_port[0] = -EINVAL,
428 .reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET, 715 .reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET,
@@ -444,16 +731,18 @@ static struct omap_musb_board_data musb_board_data = {
444static void __init overo_init(void) 731static void __init overo_init(void)
445{ 732{
446 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); 733 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
447 omap_board_config = overo_config;
448 omap_board_config_size = ARRAY_SIZE(overo_config);
449 overo_i2c_init(); 734 overo_i2c_init();
450 platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); 735 omap_display_init(&overo_dss_data);
451 omap_serial_init(); 736 omap_serial_init();
452 overo_flash_init(); 737 overo_flash_init();
453 usb_musb_init(&musb_board_data); 738 usb_musb_init(&musb_board_data);
454 usbhs_init(&usbhs_bdata); 739 usbhs_init(&usbhs_bdata);
740 overo_spi_init();
455 overo_ads7846_init(); 741 overo_ads7846_init();
456 overo_init_smsc911x(); 742 overo_init_smsc911x();
743 overo_display_init();
744 overo_init_led();
745 overo_init_keys();
457 746
458 /* Ensure SDRC pins are mux'd for self-refresh */ 747 /* Ensure SDRC pins are mux'd for self-refresh */
459 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); 748 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 5f1900c532ec..bbcb6775a6a3 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -372,7 +372,7 @@ static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
372}; 372};
373 373
374static struct regulator_consumer_supply rx51_vdac_supply[] = { 374static struct regulator_consumer_supply rx51_vdac_supply[] = {
375 REGULATOR_SUPPLY("vdda_dac", "omapdss"), 375 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
376}; 376};
377 377
378static struct regulator_init_data rx51_vaux1 = { 378static struct regulator_init_data rx51_vaux1 = {
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 448ab60195d5..8dee7549fbdf 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -226,11 +226,13 @@ static struct omap2_hsmmc_info mmc[] = {
226 {} /* Terminator */ 226 {} /* Terminator */
227}; 227};
228 228
229static struct regulator_consumer_supply zoom_vpll2_supply = 229static struct regulator_consumer_supply zoom_vpll2_supplies[] = {
230 REGULATOR_SUPPLY("vdds_dsi", "omapdss"); 230 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
231 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
232};
231 233
232static struct regulator_consumer_supply zoom_vdda_dac_supply = 234static struct regulator_consumer_supply zoom_vdda_dac_supply =
233 REGULATOR_SUPPLY("vdda_dac", "omapdss"); 235 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
234 236
235static struct regulator_init_data zoom_vpll2 = { 237static struct regulator_init_data zoom_vpll2 = {
236 .constraints = { 238 .constraints = {
@@ -241,8 +243,8 @@ static struct regulator_init_data zoom_vpll2 = {
241 .valid_ops_mask = REGULATOR_CHANGE_MODE 243 .valid_ops_mask = REGULATOR_CHANGE_MODE
242 | REGULATOR_CHANGE_STATUS, 244 | REGULATOR_CHANGE_STATUS,
243 }, 245 },
244 .num_consumer_supplies = 1, 246 .num_consumer_supplies = ARRAY_SIZE(zoom_vpll2_supplies),
245 .consumer_supplies = &zoom_vpll2_supply, 247 .consumer_supplies = zoom_vpll2_supplies,
246}; 248};
247 249
248static struct regulator_init_data zoom_vdac = { 250static struct regulator_init_data zoom_vdac = {
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index b6f65d4ac97d..2926d028b6e9 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1804,10 +1804,10 @@ static struct omap_clk omap2420_clks[] = {
1804 CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X), 1804 CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X),
1805 CLK(NULL, "gfx_ick", &gfx_ick, CK_242X), 1805 CLK(NULL, "gfx_ick", &gfx_ick, CK_242X),
1806 /* DSS domain clocks */ 1806 /* DSS domain clocks */
1807 CLK("omapdss", "ick", &dss_ick, CK_242X), 1807 CLK("omapdss_dss", "ick", &dss_ick, CK_242X),
1808 CLK("omapdss", "dss1_fck", &dss1_fck, CK_242X), 1808 CLK("omapdss_dss", "fck", &dss1_fck, CK_242X),
1809 CLK("omapdss", "dss2_fck", &dss2_fck, CK_242X), 1809 CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_242X),
1810 CLK("omapdss", "tv_fck", &dss_54m_fck, CK_242X), 1810 CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_242X),
1811 /* L3 domain clocks */ 1811 /* L3 domain clocks */
1812 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X), 1812 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X),
1813 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X), 1813 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index bba018331a71..0c79d39e3021 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1894,10 +1894,10 @@ static struct omap_clk omap2430_clks[] = {
1894 CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), 1894 CLK(NULL, "mdm_ick", &mdm_ick, CK_243X),
1895 CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), 1895 CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
1896 /* DSS domain clocks */ 1896 /* DSS domain clocks */
1897 CLK("omapdss", "ick", &dss_ick, CK_243X), 1897 CLK("omapdss_dss", "ick", &dss_ick, CK_243X),
1898 CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X), 1898 CLK("omapdss_dss", "fck", &dss1_fck, CK_243X),
1899 CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X), 1899 CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_243X),
1900 CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X), 1900 CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_243X),
1901 /* L3 domain clocks */ 1901 /* L3 domain clocks */
1902 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X), 1902 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X),
1903 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X), 1903 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index fcb321a64f13..75b119bd9cda 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3356,13 +3356,13 @@ static struct omap_clk omap3xxx_clks[] = {
3356 CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX), 3356 CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX),
3357 CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX), 3357 CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX),
3358 CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX), 3358 CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX),
3359 CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), 3359 CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
3360 CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3360 CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3361 CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX), 3361 CLK("omapdss_dss", "tv_clk", &dss_tv_fck, CK_3XXX),
3362 CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX), 3362 CLK("omapdss_dss", "video_clk", &dss_96m_fck, CK_3XXX),
3363 CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX), 3363 CLK("omapdss_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX),
3364 CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1), 3364 CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1),
3365 CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3365 CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3366 CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX), 3366 CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
3367 CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), 3367 CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
3368 CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), 3368 CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index d32ed979a8da..276992d3b7fb 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3114,11 +3114,16 @@ static struct omap_clk omap44xx_clks[] = {
3114 CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X), 3114 CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X),
3115 CLK(NULL, "dmic_fck", &dmic_fck, CK_443X), 3115 CLK(NULL, "dmic_fck", &dmic_fck, CK_443X),
3116 CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), 3116 CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
3117 CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X), 3117 CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X),
3118 CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X), 3118 CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X),
3119 CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X), 3119 CLK("omapdss_dss", "dss_clk", &dss_dss_clk, CK_443X),
3120 CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X), 3120 CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X),
3121 CLK(NULL, "dss_fck", &dss_fck, CK_443X), 3121 CLK("omapdss_dss", "fck", &dss_fck, CK_443X),
3122 /*
3123 * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility
3124 * with OMAP2/3.
3125 */
3126 CLK("omapdss_dss", "ick", &dummy_ck, CK_443X),
3122 CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), 3127 CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
3123 CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), 3128 CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
3124 CLK(NULL, "emif2_fck", &emif2_fck, CK_443X), 3129 CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 0d2d6a9c303c..e97851492847 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -35,6 +35,7 @@
35 35
36#include "mux.h" 36#include "mux.h"
37#include "control.h" 37#include "control.h"
38#include "devices.h"
38 39
39#define L3_MODULES_MAX_LEN 12 40#define L3_MODULES_MAX_LEN 12
40#define L3_MODULES 3 41#define L3_MODULES 3
@@ -102,7 +103,7 @@ postcore_initcall(omap4_l3_init);
102 103
103#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) 104#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
104 105
105static struct resource cam_resources[] = { 106static struct resource omap2cam_resources[] = {
106 { 107 {
107 .start = OMAP24XX_CAMERA_BASE, 108 .start = OMAP24XX_CAMERA_BASE,
108 .end = OMAP24XX_CAMERA_BASE + 0xfff, 109 .end = OMAP24XX_CAMERA_BASE + 0xfff,
@@ -114,19 +115,13 @@ static struct resource cam_resources[] = {
114 } 115 }
115}; 116};
116 117
117static struct platform_device omap_cam_device = { 118static struct platform_device omap2cam_device = {
118 .name = "omap24xxcam", 119 .name = "omap24xxcam",
119 .id = -1, 120 .id = -1,
120 .num_resources = ARRAY_SIZE(cam_resources), 121 .num_resources = ARRAY_SIZE(omap2cam_resources),
121 .resource = cam_resources, 122 .resource = omap2cam_resources,
122}; 123};
123 124#endif
124static inline void omap_init_camera(void)
125{
126 platform_device_register(&omap_cam_device);
127}
128
129#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
130 125
131static struct resource omap3isp_resources[] = { 126static struct resource omap3isp_resources[] = {
132 { 127 {
@@ -135,11 +130,6 @@ static struct resource omap3isp_resources[] = {
135 .flags = IORESOURCE_MEM, 130 .flags = IORESOURCE_MEM,
136 }, 131 },
137 { 132 {
138 .start = OMAP3430_ISP_CBUFF_BASE,
139 .end = OMAP3430_ISP_CBUFF_END,
140 .flags = IORESOURCE_MEM,
141 },
142 {
143 .start = OMAP3430_ISP_CCP2_BASE, 133 .start = OMAP3430_ISP_CCP2_BASE,
144 .end = OMAP3430_ISP_CCP2_END, 134 .end = OMAP3430_ISP_CCP2_END,
145 .flags = IORESOURCE_MEM, 135 .flags = IORESOURCE_MEM,
@@ -175,13 +165,33 @@ static struct resource omap3isp_resources[] = {
175 .flags = IORESOURCE_MEM, 165 .flags = IORESOURCE_MEM,
176 }, 166 },
177 { 167 {
178 .start = OMAP3430_ISP_CSI2A_BASE, 168 .start = OMAP3430_ISP_CSI2A_REGS1_BASE,
179 .end = OMAP3430_ISP_CSI2A_END, 169 .end = OMAP3430_ISP_CSI2A_REGS1_END,
170 .flags = IORESOURCE_MEM,
171 },
172 {
173 .start = OMAP3430_ISP_CSIPHY2_BASE,
174 .end = OMAP3430_ISP_CSIPHY2_END,
175 .flags = IORESOURCE_MEM,
176 },
177 {
178 .start = OMAP3630_ISP_CSI2A_REGS2_BASE,
179 .end = OMAP3630_ISP_CSI2A_REGS2_END,
180 .flags = IORESOURCE_MEM,
181 },
182 {
183 .start = OMAP3630_ISP_CSI2C_REGS1_BASE,
184 .end = OMAP3630_ISP_CSI2C_REGS1_END,
185 .flags = IORESOURCE_MEM,
186 },
187 {
188 .start = OMAP3630_ISP_CSIPHY1_BASE,
189 .end = OMAP3630_ISP_CSIPHY1_END,
180 .flags = IORESOURCE_MEM, 190 .flags = IORESOURCE_MEM,
181 }, 191 },
182 { 192 {
183 .start = OMAP3430_ISP_CSI2PHY_BASE, 193 .start = OMAP3630_ISP_CSI2C_REGS2_BASE,
184 .end = OMAP3430_ISP_CSI2PHY_END, 194 .end = OMAP3630_ISP_CSI2C_REGS2_END,
185 .flags = IORESOURCE_MEM, 195 .flags = IORESOURCE_MEM,
186 }, 196 },
187 { 197 {
@@ -197,15 +207,19 @@ static struct platform_device omap3isp_device = {
197 .resource = omap3isp_resources, 207 .resource = omap3isp_resources,
198}; 208};
199 209
200static inline void omap_init_camera(void) 210int omap3_init_camera(struct isp_platform_data *pdata)
201{ 211{
202 platform_device_register(&omap3isp_device); 212 omap3isp_device.dev.platform_data = pdata;
213 return platform_device_register(&omap3isp_device);
203} 214}
204#else 215
205static inline void omap_init_camera(void) 216static inline void omap_init_camera(void)
206{ 217{
207} 218#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
219 if (cpu_is_omap24xx())
220 platform_device_register(&omap2cam_device);
208#endif 221#endif
222}
209 223
210struct omap_device_pm_latency omap_keyboard_latency[] = { 224struct omap_device_pm_latency omap_keyboard_latency[] = {
211 { 225 {
diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h
new file mode 100644
index 000000000000..f61eb6e5d136
--- /dev/null
+++ b/arch/arm/mach-omap2/devices.h
@@ -0,0 +1,19 @@
1/*
2 * arch/arm/mach-omap2/devices.h
3 *
4 * OMAP2 platform device setup/initialization
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef __ARCH_ARM_MACH_OMAP_DEVICES_H
13#define __ARCH_ARM_MACH_OMAP_DEVICES_H
14
15struct isp_platform_data;
16
17int omap3_init_camera(struct isp_platform_data *pdata);
18
19#endif
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index b18db84b0349..256d23fb79ab 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -23,6 +23,8 @@
23#include <linux/err.h> 23#include <linux/err.h>
24 24
25#include <plat/display.h> 25#include <plat/display.h>
26#include <plat/omap_hwmod.h>
27#include <plat/omap_device.h>
26 28
27static struct platform_device omap_display_device = { 29static struct platform_device omap_display_device = {
28 .name = "omapdss", 30 .name = "omapdss",
@@ -32,9 +34,87 @@ static struct platform_device omap_display_device = {
32 }, 34 },
33}; 35};
34 36
37static struct omap_device_pm_latency omap_dss_latency[] = {
38 [0] = {
39 .deactivate_func = omap_device_idle_hwmods,
40 .activate_func = omap_device_enable_hwmods,
41 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
42 },
43};
44
45/* oh_core is used for getting opt-clocks */
46static struct omap_hwmod *oh_core;
47
48static bool opt_clock_available(const char *clk_role)
49{
50 int i;
51
52 for (i = 0; i < oh_core->opt_clks_cnt; i++) {
53 if (!strcmp(oh_core->opt_clks[i].role, clk_role))
54 return true;
55 }
56 return false;
57}
58
35int __init omap_display_init(struct omap_dss_board_info *board_data) 59int __init omap_display_init(struct omap_dss_board_info *board_data)
36{ 60{
37 int r = 0; 61 int r = 0;
62 struct omap_hwmod *oh;
63 struct omap_device *od;
64 int i;
65 struct omap_display_platform_data pdata;
66
67 /*
68 * omap: valid DSS hwmod names
69 * omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc
70 * omap3,4: dss_dsi1
71 * omap4: dss_dsi2, dss_hdmi
72 */
73 char *oh_name[] = { "dss_core", "dss_dispc", "dss_rfbi", "dss_venc",
74 "dss_dsi1", "dss_dsi2", "dss_hdmi" };
75 char *dev_name[] = { "omapdss_dss", "omapdss_dispc", "omapdss_rfbi",
76 "omapdss_venc", "omapdss_dsi1", "omapdss_dsi2",
77 "omapdss_hdmi" };
78 int oh_count;
79
80 memset(&pdata, 0, sizeof(pdata));
81
82 if (cpu_is_omap24xx())
83 oh_count = ARRAY_SIZE(oh_name) - 3;
84 /* last 3 hwmod dev in oh_name are not available for omap2 */
85 else if (cpu_is_omap44xx())
86 oh_count = ARRAY_SIZE(oh_name);
87 else
88 oh_count = ARRAY_SIZE(oh_name) - 2;
89 /* last 2 hwmod dev in oh_name are not available for omap3 */
90
91 /* opt_clks are always associated with dss hwmod */
92 oh_core = omap_hwmod_lookup("dss_core");
93 if (!oh_core) {
94 pr_err("Could not look up dss_core.\n");
95 return -ENODEV;
96 }
97
98 pdata.board_data = board_data;
99 pdata.board_data->get_last_off_on_transaction_id = NULL;
100 pdata.opt_clock_available = opt_clock_available;
101
102 for (i = 0; i < oh_count; i++) {
103 oh = omap_hwmod_lookup(oh_name[i]);
104 if (!oh) {
105 pr_err("Could not look up %s\n", oh_name[i]);
106 return -ENODEV;
107 }
108
109 od = omap_device_build(dev_name[i], -1, oh, &pdata,
110 sizeof(struct omap_display_platform_data),
111 omap_dss_latency,
112 ARRAY_SIZE(omap_dss_latency), 0);
113
114 if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
115 oh_name[i]))
116 return -ENODEV;
117 }
38 omap_display_device.dev.platform_data = board_data; 118 omap_display_device.dev.platform_data = board_data;
39 119
40 r = platform_device_register(&omap_display_device); 120 r = platform_device_register(&omap_display_device);
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 62823467163b..8eb3ce1bbfbe 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -1168,11 +1168,6 @@ static struct omap_hwmod_class omap2420_dss_hwmod_class = {
1168 .sysc = &omap2420_dss_sysc, 1168 .sysc = &omap2420_dss_sysc,
1169}; 1169};
1170 1170
1171/* dss */
1172static struct omap_hwmod_irq_info omap2420_dss_irqs[] = {
1173 { .irq = 25 },
1174};
1175
1176static struct omap_hwmod_dma_info omap2420_dss_sdma_chs[] = { 1171static struct omap_hwmod_dma_info omap2420_dss_sdma_chs[] = {
1177 { .name = "dispc", .dma_req = 5 }, 1172 { .name = "dispc", .dma_req = 5 },
1178}; 1173};
@@ -1221,8 +1216,6 @@ static struct omap_hwmod omap2420_dss_core_hwmod = {
1221 .name = "dss_core", 1216 .name = "dss_core",
1222 .class = &omap2420_dss_hwmod_class, 1217 .class = &omap2420_dss_hwmod_class,
1223 .main_clk = "dss1_fck", /* instead of dss_fck */ 1218 .main_clk = "dss1_fck", /* instead of dss_fck */
1224 .mpu_irqs = omap2420_dss_irqs,
1225 .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dss_irqs),
1226 .sdma_reqs = omap2420_dss_sdma_chs, 1219 .sdma_reqs = omap2420_dss_sdma_chs,
1227 .sdma_reqs_cnt = ARRAY_SIZE(omap2420_dss_sdma_chs), 1220 .sdma_reqs_cnt = ARRAY_SIZE(omap2420_dss_sdma_chs),
1228 .prcm = { 1221 .prcm = {
@@ -1265,6 +1258,10 @@ static struct omap_hwmod_class omap2420_dispc_hwmod_class = {
1265 .sysc = &omap2420_dispc_sysc, 1258 .sysc = &omap2420_dispc_sysc,
1266}; 1259};
1267 1260
1261static struct omap_hwmod_irq_info omap2420_dispc_irqs[] = {
1262 { .irq = 25 },
1263};
1264
1268static struct omap_hwmod_addr_space omap2420_dss_dispc_addrs[] = { 1265static struct omap_hwmod_addr_space omap2420_dss_dispc_addrs[] = {
1269 { 1266 {
1270 .pa_start = 0x48050400, 1267 .pa_start = 0x48050400,
@@ -1297,6 +1294,8 @@ static struct omap_hwmod_ocp_if *omap2420_dss_dispc_slaves[] = {
1297static struct omap_hwmod omap2420_dss_dispc_hwmod = { 1294static struct omap_hwmod omap2420_dss_dispc_hwmod = {
1298 .name = "dss_dispc", 1295 .name = "dss_dispc",
1299 .class = &omap2420_dispc_hwmod_class, 1296 .class = &omap2420_dispc_hwmod_class,
1297 .mpu_irqs = omap2420_dispc_irqs,
1298 .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dispc_irqs),
1300 .main_clk = "dss1_fck", 1299 .main_clk = "dss1_fck",
1301 .prcm = { 1300 .prcm = {
1302 .omap2 = { 1301 .omap2 = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 0fdf2cabfb12..a860fb5024c2 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -1268,10 +1268,6 @@ static struct omap_hwmod_class omap2430_dss_hwmod_class = {
1268 .sysc = &omap2430_dss_sysc, 1268 .sysc = &omap2430_dss_sysc,
1269}; 1269};
1270 1270
1271/* dss */
1272static struct omap_hwmod_irq_info omap2430_dss_irqs[] = {
1273 { .irq = 25 },
1274};
1275static struct omap_hwmod_dma_info omap2430_dss_sdma_chs[] = { 1271static struct omap_hwmod_dma_info omap2430_dss_sdma_chs[] = {
1276 { .name = "dispc", .dma_req = 5 }, 1272 { .name = "dispc", .dma_req = 5 },
1277}; 1273};
@@ -1314,8 +1310,6 @@ static struct omap_hwmod omap2430_dss_core_hwmod = {
1314 .name = "dss_core", 1310 .name = "dss_core",
1315 .class = &omap2430_dss_hwmod_class, 1311 .class = &omap2430_dss_hwmod_class,
1316 .main_clk = "dss1_fck", /* instead of dss_fck */ 1312 .main_clk = "dss1_fck", /* instead of dss_fck */
1317 .mpu_irqs = omap2430_dss_irqs,
1318 .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dss_irqs),
1319 .sdma_reqs = omap2430_dss_sdma_chs, 1313 .sdma_reqs = omap2430_dss_sdma_chs,
1320 .sdma_reqs_cnt = ARRAY_SIZE(omap2430_dss_sdma_chs), 1314 .sdma_reqs_cnt = ARRAY_SIZE(omap2430_dss_sdma_chs),
1321 .prcm = { 1315 .prcm = {
@@ -1358,6 +1352,10 @@ static struct omap_hwmod_class omap2430_dispc_hwmod_class = {
1358 .sysc = &omap2430_dispc_sysc, 1352 .sysc = &omap2430_dispc_sysc,
1359}; 1353};
1360 1354
1355static struct omap_hwmod_irq_info omap2430_dispc_irqs[] = {
1356 { .irq = 25 },
1357};
1358
1361static struct omap_hwmod_addr_space omap2430_dss_dispc_addrs[] = { 1359static struct omap_hwmod_addr_space omap2430_dss_dispc_addrs[] = {
1362 { 1360 {
1363 .pa_start = 0x48050400, 1361 .pa_start = 0x48050400,
@@ -1384,6 +1382,8 @@ static struct omap_hwmod_ocp_if *omap2430_dss_dispc_slaves[] = {
1384static struct omap_hwmod omap2430_dss_dispc_hwmod = { 1382static struct omap_hwmod omap2430_dss_dispc_hwmod = {
1385 .name = "dss_dispc", 1383 .name = "dss_dispc",
1386 .class = &omap2430_dispc_hwmod_class, 1384 .class = &omap2430_dispc_hwmod_class,
1385 .mpu_irqs = omap2430_dispc_irqs,
1386 .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dispc_irqs),
1387 .main_clk = "dss1_fck", 1387 .main_clk = "dss1_fck",
1388 .prcm = { 1388 .prcm = {
1389 .omap2 = { 1389 .omap2 = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index c819c306693a..b98e2dfcba28 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1480,11 +1480,6 @@ static struct omap_hwmod_class omap3xxx_dss_hwmod_class = {
1480 .sysc = &omap3xxx_dss_sysc, 1480 .sysc = &omap3xxx_dss_sysc,
1481}; 1481};
1482 1482
1483/* dss */
1484static struct omap_hwmod_irq_info omap3xxx_dss_irqs[] = {
1485 { .irq = 25 },
1486};
1487
1488static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = { 1483static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = {
1489 { .name = "dispc", .dma_req = 5 }, 1484 { .name = "dispc", .dma_req = 5 },
1490 { .name = "dsi1", .dma_req = 74 }, 1485 { .name = "dsi1", .dma_req = 74 },
@@ -1548,7 +1543,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = {
1548 1543
1549static struct omap_hwmod_opt_clk dss_opt_clks[] = { 1544static struct omap_hwmod_opt_clk dss_opt_clks[] = {
1550 { .role = "tv_clk", .clk = "dss_tv_fck" }, 1545 { .role = "tv_clk", .clk = "dss_tv_fck" },
1551 { .role = "dssclk", .clk = "dss_96m_fck" }, 1546 { .role = "video_clk", .clk = "dss_96m_fck" },
1552 { .role = "sys_clk", .clk = "dss2_alwon_fck" }, 1547 { .role = "sys_clk", .clk = "dss2_alwon_fck" },
1553}; 1548};
1554 1549
@@ -1556,8 +1551,6 @@ static struct omap_hwmod omap3430es1_dss_core_hwmod = {
1556 .name = "dss_core", 1551 .name = "dss_core",
1557 .class = &omap3xxx_dss_hwmod_class, 1552 .class = &omap3xxx_dss_hwmod_class,
1558 .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ 1553 .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
1559 .mpu_irqs = omap3xxx_dss_irqs,
1560 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs),
1561 .sdma_reqs = omap3xxx_dss_sdma_chs, 1554 .sdma_reqs = omap3xxx_dss_sdma_chs,
1562 .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs), 1555 .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
1563 1556
@@ -1584,8 +1577,6 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = {
1584 .name = "dss_core", 1577 .name = "dss_core",
1585 .class = &omap3xxx_dss_hwmod_class, 1578 .class = &omap3xxx_dss_hwmod_class,
1586 .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ 1579 .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
1587 .mpu_irqs = omap3xxx_dss_irqs,
1588 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs),
1589 .sdma_reqs = omap3xxx_dss_sdma_chs, 1580 .sdma_reqs = omap3xxx_dss_sdma_chs,
1590 .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs), 1581 .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
1591 1582
@@ -1631,6 +1622,10 @@ static struct omap_hwmod_class omap3xxx_dispc_hwmod_class = {
1631 .sysc = &omap3xxx_dispc_sysc, 1622 .sysc = &omap3xxx_dispc_sysc,
1632}; 1623};
1633 1624
1625static struct omap_hwmod_irq_info omap3xxx_dispc_irqs[] = {
1626 { .irq = 25 },
1627};
1628
1634static struct omap_hwmod_addr_space omap3xxx_dss_dispc_addrs[] = { 1629static struct omap_hwmod_addr_space omap3xxx_dss_dispc_addrs[] = {
1635 { 1630 {
1636 .pa_start = 0x48050400, 1631 .pa_start = 0x48050400,
@@ -1664,6 +1659,8 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
1664static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { 1659static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
1665 .name = "dss_dispc", 1660 .name = "dss_dispc",
1666 .class = &omap3xxx_dispc_hwmod_class, 1661 .class = &omap3xxx_dispc_hwmod_class,
1662 .mpu_irqs = omap3xxx_dispc_irqs,
1663 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dispc_irqs),
1667 .main_clk = "dss1_alwon_fck", 1664 .main_clk = "dss1_alwon_fck",
1668 .prcm = { 1665 .prcm = {
1669 .omap2 = { 1666 .omap2 = {
@@ -1689,6 +1686,10 @@ static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
1689 .name = "dsi", 1686 .name = "dsi",
1690}; 1687};
1691 1688
1689static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = {
1690 { .irq = 25 },
1691};
1692
1692/* dss_dsi1 */ 1693/* dss_dsi1 */
1693static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = { 1694static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = {
1694 { 1695 {
@@ -1722,6 +1723,8 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = {
1722static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = { 1723static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
1723 .name = "dss_dsi1", 1724 .name = "dss_dsi1",
1724 .class = &omap3xxx_dsi_hwmod_class, 1725 .class = &omap3xxx_dsi_hwmod_class,
1726 .mpu_irqs = omap3xxx_dsi1_irqs,
1727 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dsi1_irqs),
1725 .main_clk = "dss1_alwon_fck", 1728 .main_clk = "dss1_alwon_fck",
1726 .prcm = { 1729 .prcm = {
1727 .omap2 = { 1730 .omap2 = {
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 1a8118c929be..a94f29da5d30 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -923,7 +923,8 @@ static struct platform_device ceu_device = {
923 .num_resources = ARRAY_SIZE(ceu_resources), 923 .num_resources = ARRAY_SIZE(ceu_resources),
924 .resource = ceu_resources, 924 .resource = ceu_resources,
925 .dev = { 925 .dev = {
926 .platform_data = &sh_mobile_ceu_info, 926 .platform_data = &sh_mobile_ceu_info,
927 .coherent_dma_mask = 0xffffffff,
927 }, 928 },
928}; 929};
929 930
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 1a63c213e45d..49bc07482179 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -295,6 +295,18 @@ static struct fb_videomode mackerel_lcdc_modes[] = {
295 }, 295 },
296}; 296};
297 297
298static int mackerel_set_brightness(void *board_data, int brightness)
299{
300 gpio_set_value(GPIO_PORT31, brightness);
301
302 return 0;
303}
304
305static int mackerel_get_brightness(void *board_data)
306{
307 return gpio_get_value(GPIO_PORT31);
308}
309
298static struct sh_mobile_lcdc_info lcdc_info = { 310static struct sh_mobile_lcdc_info lcdc_info = {
299 .clock_source = LCDC_CLK_BUS, 311 .clock_source = LCDC_CLK_BUS,
300 .ch[0] = { 312 .ch[0] = {
@@ -307,6 +319,14 @@ static struct sh_mobile_lcdc_info lcdc_info = {
307 .flags = 0, 319 .flags = 0,
308 .lcd_size_cfg.width = 152, 320 .lcd_size_cfg.width = 152,
309 .lcd_size_cfg.height = 91, 321 .lcd_size_cfg.height = 91,
322 .board_cfg = {
323 .set_brightness = mackerel_set_brightness,
324 .get_brightness = mackerel_get_brightness,
325 },
326 .bl_info = {
327 .name = "sh_mobile_lcdc_bl",
328 .max_brightness = 1,
329 },
310 } 330 }
311}; 331};
312 332
@@ -901,7 +921,8 @@ static struct platform_device ceu_device = {
901 .num_resources = ARRAY_SIZE(ceu_resources), 921 .num_resources = ARRAY_SIZE(ceu_resources),
902 .resource = ceu_resources, 922 .resource = ceu_resources,
903 .dev = { 923 .dev = {
904 .platform_data = &sh_mobile_ceu_info, 924 .platform_data = &sh_mobile_ceu_info,
925 .coherent_dma_mask = 0xffffffff,
905 }, 926 },
906}; 927};
907 928
@@ -1059,7 +1080,7 @@ static void __init mackerel_init(void)
1059 gpio_request(GPIO_FN_LCDDCK, NULL); 1080 gpio_request(GPIO_FN_LCDDCK, NULL);
1060 1081
1061 gpio_request(GPIO_PORT31, NULL); /* backlight */ 1082 gpio_request(GPIO_PORT31, NULL); /* backlight */
1062 gpio_direction_output(GPIO_PORT31, 1); 1083 gpio_direction_output(GPIO_PORT31, 0); /* off by default */
1063 1084
1064 gpio_request(GPIO_PORT151, NULL); /* LCDDON */ 1085 gpio_request(GPIO_PORT151, NULL); /* LCDDON */
1065 gpio_direction_output(GPIO_PORT151, 1); 1086 gpio_direction_output(GPIO_PORT151, 1);
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h
index a8d02be8d2b6..db59fdbda860 100644
--- a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
+++ b/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h
@@ -1,5 +1,5 @@
1#ifndef MMCIF_AP4EB_H 1#ifndef MMC_AP4EB_H
2#define MMCIF_AP4EB_H 2#define MMC_AP4EB_H
3 3
4#define PORT185CR (void __iomem *)0xe60520b9 4#define PORT185CR (void __iomem *)0xe60520b9
5#define PORT186CR (void __iomem *)0xe60520ba 5#define PORT186CR (void __iomem *)0xe60520ba
@@ -8,7 +8,7 @@
8 8
9#define PORTR191_160DR (void __iomem *)0xe6056014 9#define PORTR191_160DR (void __iomem *)0xe6056014
10 10
11static inline void mmcif_init_progress(void) 11static inline void mmc_init_progress(void)
12{ 12{
13 /* Initialise LEDS1-4 13 /* Initialise LEDS1-4
14 * registers: PORT185CR-PORT188CR (LED1-LED4 Control) 14 * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
@@ -20,10 +20,10 @@ static inline void mmcif_init_progress(void)
20 __raw_writeb(0x10, PORT188CR); 20 __raw_writeb(0x10, PORT188CR);
21} 21}
22 22
23static inline void mmcif_update_progress(int n) 23static inline void mmc_update_progress(int n)
24{ 24{
25 __raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) | 25 __raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
26 (1 << (25 + n)), PORTR191_160DR); 26 (1 << (25 + n)), PORTR191_160DR);
27} 27}
28 28
29#endif /* MMCIF_AP4EB_H */ 29#endif /* MMC_AP4EB_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h b/arch/arm/mach-shmobile/include/mach/mmc-mackerel.h
index 4b4f6949a868..15d3a9efdec2 100644
--- a/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h
+++ b/arch/arm/mach-shmobile/include/mach/mmc-mackerel.h
@@ -1,5 +1,5 @@
1#ifndef MMCIF_MACKEREL_H 1#ifndef MMC_MACKEREL_H
2#define MMCIF_MACKEREL_H 2#define MMC_MACKEREL_H
3 3
4#define PORT0CR (void __iomem *)0xe6051000 4#define PORT0CR (void __iomem *)0xe6051000
5#define PORT1CR (void __iomem *)0xe6051001 5#define PORT1CR (void __iomem *)0xe6051001
@@ -9,7 +9,7 @@
9#define PORTR031_000DR (void __iomem *)0xe6055000 9#define PORTR031_000DR (void __iomem *)0xe6055000
10#define PORTL159_128DR (void __iomem *)0xe6054010 10#define PORTL159_128DR (void __iomem *)0xe6054010
11 11
12static inline void mmcif_init_progress(void) 12static inline void mmc_init_progress(void)
13{ 13{
14 /* Initialise LEDS0-3 14 /* Initialise LEDS0-3
15 * registers: PORT0CR-PORT2CR,PORT159CR (LED0-LED3 Control) 15 * registers: PORT0CR-PORT2CR,PORT159CR (LED0-LED3 Control)
@@ -21,7 +21,7 @@ static inline void mmcif_init_progress(void)
21 __raw_writeb(0x10, PORT159CR); 21 __raw_writeb(0x10, PORT159CR);
22} 22}
23 23
24static inline void mmcif_update_progress(int n) 24static inline void mmc_update_progress(int n)
25{ 25{
26 unsigned a = 0, b = 0; 26 unsigned a = 0, b = 0;
27 27
@@ -35,5 +35,4 @@ static inline void mmcif_update_progress(int n)
35 __raw_writel((__raw_readl(PORTL159_128DR) & ~(1 << 31)) | b, 35 __raw_writel((__raw_readl(PORTL159_128DR) & ~(1 << 31)) | b,
36 PORTL159_128DR); 36 PORTL159_128DR);
37} 37}
38 38#endif /* MMC_MACKEREL_H */
39#endif /* MMCIF_MACKEREL_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif.h b/arch/arm/mach-shmobile/include/mach/mmc.h
index f4dc3279cf03..e11560a525a1 100644
--- a/arch/arm/mach-shmobile/include/mach/mmcif.h
+++ b/arch/arm/mach-shmobile/include/mach/mmc.h
@@ -1,5 +1,5 @@
1#ifndef MMCIF_H 1#ifndef MMC_H
2#define MMCIF_H 2#define MMC_H
3 3
4/************************************************** 4/**************************************************
5 * 5 *
@@ -8,11 +8,11 @@
8 **************************************************/ 8 **************************************************/
9 9
10#ifdef CONFIG_MACH_AP4EVB 10#ifdef CONFIG_MACH_AP4EVB
11#include "mach/mmcif-ap4eb.h" 11#include "mach/mmc-ap4eb.h"
12#elif CONFIG_MACH_MACKEREL 12#elif CONFIG_MACH_MACKEREL
13#include "mach/mmcif-mackerel.h" 13#include "mach/mmc-mackerel.h"
14#else 14#else
15#error "unsupported board." 15#error "unsupported board."
16#endif 16#endif
17 17
18#endif /* MMCIF_H */ 18#endif /* MMC_H */
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 622a9ec1ff08..3cdeffc97b44 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -36,6 +36,11 @@ config MACH_KAEN
36 help 36 help
37 Support for the Kaen version of Seaboard 37 Support for the Kaen version of Seaboard
38 38
39config MACH_PAZ00
40 bool "Paz00 board"
41 help
42 Support for the Toshiba AC100/Dynabook AZ netbook
43
39config MACH_SEABOARD 44config MACH_SEABOARD
40 bool "Seaboard board" 45 bool "Seaboard board"
41 help 46 help
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 9f7a7e1e0c38..1afe05038c27 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -22,6 +22,10 @@ obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
22obj-${CONFIG_MACH_HARMONY} += board-harmony.o 22obj-${CONFIG_MACH_HARMONY} += board-harmony.o
23obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o 23obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o
24obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o 24obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o
25obj-${CONFIG_MACH_HARMONY} += board-harmony-power.o
26
27obj-${CONFIG_MACH_PAZ00} += board-paz00.o
28obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o
25 29
26obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o 30obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o
27obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o 31obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
index f7e7d4514b6a..9c27b95b8d86 100644
--- a/arch/arm/mach-tegra/board-harmony-pcie.c
+++ b/arch/arm/mach-tegra/board-harmony-pcie.c
@@ -27,13 +27,29 @@
27 27
28#ifdef CONFIG_TEGRA_PCI 28#ifdef CONFIG_TEGRA_PCI
29 29
30/* GPIO 3 of the PMIC */
31#define EN_VDD_1V05_GPIO (TEGRA_NR_GPIOS + 2)
32
30static int __init harmony_pcie_init(void) 33static int __init harmony_pcie_init(void)
31{ 34{
35 struct regulator *regulator = NULL;
32 int err; 36 int err;
33 37
34 if (!machine_is_harmony()) 38 if (!machine_is_harmony())
35 return 0; 39 return 0;
36 40
41 err = gpio_request(EN_VDD_1V05_GPIO, "EN_VDD_1V05");
42 if (err)
43 return err;
44
45 gpio_direction_output(EN_VDD_1V05_GPIO, 1);
46
47 regulator = regulator_get(NULL, "pex_clk");
48 if (IS_ERR_OR_NULL(regulator))
49 goto err_reg;
50
51 regulator_enable(regulator);
52
37 tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_NORMAL); 53 tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_NORMAL);
38 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_NORMAL); 54 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_NORMAL);
39 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_NORMAL); 55 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_NORMAL);
@@ -49,9 +65,15 @@ err_pcie:
49 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE); 65 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE);
50 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE); 66 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE);
51 67
68 regulator_disable(regulator);
69 regulator_put(regulator);
70err_reg:
71 gpio_free(EN_VDD_1V05_GPIO);
72
52 return err; 73 return err;
53} 74}
54 75
55subsys_initcall(harmony_pcie_init); 76/* PCI should be initialized after I2C, mfd and regulators */
77subsys_initcall_sync(harmony_pcie_init);
56 78
57#endif 79#endif
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
index 98368d947be3..4d63e2e97a8d 100644
--- a/arch/arm/mach-tegra/board-harmony-pinmux.c
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -27,11 +27,11 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
27 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 27 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
28 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 28 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
29 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 29 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
30 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 30 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
31 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 31 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
32 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 32 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
33 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 33 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
34 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 34 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
35 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 35 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
36 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 36 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
37 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 37 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
@@ -114,13 +114,13 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
114 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 114 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 115 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 116 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
117 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 117 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
118 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 118 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
119 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 119 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
120 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 120 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 121 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 122 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
123 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 123 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
124 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 124 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 125 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
126 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 126 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
@@ -141,12 +141,16 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
141}; 141};
142 142
143static struct tegra_gpio_table gpio_table[] = { 143static struct tegra_gpio_table gpio_table[] = {
144 { .gpio = TEGRA_GPIO_PI5, .enable = true }, /* mmc2 cd */ 144 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
145 { .gpio = TEGRA_GPIO_PH1, .enable = true }, /* mmc2 wp */ 145 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
146 { .gpio = TEGRA_GPIO_PT3, .enable = true }, /* mmc2 pwr */ 146 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
147 { .gpio = TEGRA_GPIO_PH2, .enable = true }, /* mmc4 cd */ 147 { .gpio = TEGRA_GPIO_SD4_CD, .enable = true },
148 { .gpio = TEGRA_GPIO_PH3, .enable = true }, /* mmc4 wp */ 148 { .gpio = TEGRA_GPIO_SD4_WP, .enable = true },
149 { .gpio = TEGRA_GPIO_PI6, .enable = true }, /* mmc4 pwr */ 149 { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true },
150 { .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
151 { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
152 { .gpio = TEGRA_GPIO_INT_MIC_EN, .enable = true },
153 { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true },
150}; 154};
151 155
152void harmony_pinmux_init(void) 156void harmony_pinmux_init(void)
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c
new file mode 100644
index 000000000000..c84442cabe07
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-power.c
@@ -0,0 +1,117 @@
1/*
2 * Copyright (C) 2010 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21
22#include <linux/regulator/machine.h>
23#include <linux/mfd/tps6586x.h>
24
25#include <mach/irqs.h>
26
27#define PMC_CTRL 0x0
28#define PMC_CTRL_INTR_LOW (1 << 17)
29
30static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
31 REGULATOR_SUPPLY("pex_clk", NULL),
32};
33
34static struct regulator_init_data ldo0_data = {
35 .constraints = {
36 .min_uV = 1250 * 1000,
37 .max_uV = 3300 * 1000,
38 .valid_modes_mask = (REGULATOR_MODE_NORMAL |
39 REGULATOR_MODE_STANDBY),
40 .valid_ops_mask = (REGULATOR_CHANGE_MODE |
41 REGULATOR_CHANGE_STATUS |
42 REGULATOR_CHANGE_VOLTAGE),
43 },
44 .num_consumer_supplies = ARRAY_SIZE(tps658621_ldo0_supply),
45 .consumer_supplies = tps658621_ldo0_supply,
46};
47
48#define HARMONY_REGULATOR_INIT(_id, _minmv, _maxmv) \
49 static struct regulator_init_data _id##_data = { \
50 .constraints = { \
51 .min_uV = (_minmv)*1000, \
52 .max_uV = (_maxmv)*1000, \
53 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
54 REGULATOR_MODE_STANDBY), \
55 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
56 REGULATOR_CHANGE_STATUS | \
57 REGULATOR_CHANGE_VOLTAGE), \
58 }, \
59 }
60
61HARMONY_REGULATOR_INIT(sm0, 725, 1500);
62HARMONY_REGULATOR_INIT(sm1, 725, 1500);
63HARMONY_REGULATOR_INIT(sm2, 3000, 4550);
64HARMONY_REGULATOR_INIT(ldo1, 725, 1500);
65HARMONY_REGULATOR_INIT(ldo2, 725, 1500);
66HARMONY_REGULATOR_INIT(ldo3, 1250, 3300);
67HARMONY_REGULATOR_INIT(ldo4, 1700, 2475);
68HARMONY_REGULATOR_INIT(ldo5, 1250, 3300);
69HARMONY_REGULATOR_INIT(ldo6, 1250, 3300);
70HARMONY_REGULATOR_INIT(ldo7, 1250, 3300);
71HARMONY_REGULATOR_INIT(ldo8, 1250, 3300);
72HARMONY_REGULATOR_INIT(ldo9, 1250, 3300);
73
74#define TPS_REG(_id, _data) \
75 { \
76 .id = TPS6586X_ID_##_id, \
77 .name = "tps6586x-regulator", \
78 .platform_data = _data, \
79 }
80
81static struct tps6586x_subdev_info tps_devs[] = {
82 TPS_REG(SM_0, &sm0_data),
83 TPS_REG(SM_1, &sm1_data),
84 TPS_REG(SM_2, &sm2_data),
85 TPS_REG(LDO_0, &ldo0_data),
86 TPS_REG(LDO_1, &ldo1_data),
87 TPS_REG(LDO_2, &ldo2_data),
88 TPS_REG(LDO_3, &ldo3_data),
89 TPS_REG(LDO_4, &ldo4_data),
90 TPS_REG(LDO_5, &ldo5_data),
91 TPS_REG(LDO_6, &ldo6_data),
92 TPS_REG(LDO_7, &ldo7_data),
93 TPS_REG(LDO_8, &ldo8_data),
94 TPS_REG(LDO_9, &ldo9_data),
95};
96
97static struct tps6586x_platform_data tps_platform = {
98 .irq_base = TEGRA_NR_IRQS,
99 .num_subdevs = ARRAY_SIZE(tps_devs),
100 .subdevs = tps_devs,
101 .gpio_base = TEGRA_NR_GPIOS,
102};
103
104static struct i2c_board_info __initdata harmony_regulators[] = {
105 {
106 I2C_BOARD_INFO("tps6586x", 0x34),
107 .irq = INT_EXTERNAL_PMU,
108 .platform_data = &tps_platform,
109 },
110};
111
112int __init harmony_regulator_init(void)
113{
114 i2c_register_board_info(3, harmony_regulators, 1);
115
116 return 0;
117}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 49224e936eb4..75c918a86a31 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -2,6 +2,7 @@
2 * arch/arm/mach-tegra/board-harmony.c 2 * arch/arm/mach-tegra/board-harmony.c
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA, Inc.
5 * 6 *
6 * This software is licensed under the terms of the GNU General Public 7 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 8 * License version 2, as published by the Free Software Foundation, and
@@ -22,12 +23,18 @@
22#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
23#include <linux/pda_power.h> 24#include <linux/pda_power.h>
24#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/gpio.h>
27#include <linux/i2c.h>
28#include <linux/i2c-tegra.h>
29
30#include <sound/wm8903.h>
25 31
26#include <asm/mach-types.h> 32#include <asm/mach-types.h>
27#include <asm/mach/arch.h> 33#include <asm/mach/arch.h>
28#include <asm/mach/time.h> 34#include <asm/mach/time.h>
29#include <asm/setup.h> 35#include <asm/setup.h>
30 36
37#include <mach/harmony_audio.h>
31#include <mach/iomap.h> 38#include <mach/iomap.h>
32#include <mach/irqs.h> 39#include <mach/irqs.h>
33#include <mach/sdhci.h> 40#include <mach/sdhci.h>
@@ -60,11 +67,81 @@ static struct platform_device debug_uart = {
60 }, 67 },
61}; 68};
62 69
70static struct harmony_audio_platform_data harmony_audio_pdata = {
71 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
72 .gpio_hp_det = TEGRA_GPIO_HP_DET,
73 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
74 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
75};
76
77static struct platform_device harmony_audio_device = {
78 .name = "tegra-snd-harmony",
79 .id = 0,
80 .dev = {
81 .platform_data = &harmony_audio_pdata,
82 },
83};
84
85static struct tegra_i2c_platform_data harmony_i2c1_platform_data = {
86 .bus_clk_rate = 400000,
87};
88
89static struct tegra_i2c_platform_data harmony_i2c2_platform_data = {
90 .bus_clk_rate = 400000,
91};
92
93static struct tegra_i2c_platform_data harmony_i2c3_platform_data = {
94 .bus_clk_rate = 400000,
95};
96
97static struct tegra_i2c_platform_data harmony_dvc_platform_data = {
98 .bus_clk_rate = 400000,
99};
100
101static struct wm8903_platform_data harmony_wm8903_pdata = {
102 .irq_active_low = 0,
103 .micdet_cfg = 0,
104 .micdet_delay = 100,
105 .gpio_base = HARMONY_GPIO_WM8903(0),
106 .gpio_cfg = {
107 WM8903_GPIO_NO_CONFIG,
108 WM8903_GPIO_NO_CONFIG,
109 0,
110 WM8903_GPIO_NO_CONFIG,
111 WM8903_GPIO_NO_CONFIG,
112 },
113};
114
115static struct i2c_board_info __initdata wm8903_board_info = {
116 I2C_BOARD_INFO("wm8903", 0x1a),
117 .platform_data = &harmony_wm8903_pdata,
118 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
119};
120
121static void __init harmony_i2c_init(void)
122{
123 tegra_i2c_device1.dev.platform_data = &harmony_i2c1_platform_data;
124 tegra_i2c_device2.dev.platform_data = &harmony_i2c2_platform_data;
125 tegra_i2c_device3.dev.platform_data = &harmony_i2c3_platform_data;
126 tegra_i2c_device4.dev.platform_data = &harmony_dvc_platform_data;
127
128 platform_device_register(&tegra_i2c_device1);
129 platform_device_register(&tegra_i2c_device2);
130 platform_device_register(&tegra_i2c_device3);
131 platform_device_register(&tegra_i2c_device4);
132
133 i2c_register_board_info(0, &wm8903_board_info, 1);
134}
135
63static struct platform_device *harmony_devices[] __initdata = { 136static struct platform_device *harmony_devices[] __initdata = {
64 &debug_uart, 137 &debug_uart,
65 &tegra_sdhci_device1, 138 &tegra_sdhci_device1,
66 &tegra_sdhci_device2, 139 &tegra_sdhci_device2,
67 &tegra_sdhci_device4, 140 &tegra_sdhci_device4,
141 &tegra_i2s_device1,
142 &tegra_das_device,
143 &tegra_pcm_device,
144 &harmony_audio_device,
68}; 145};
69 146
70static void __init tegra_harmony_fixup(struct machine_desc *desc, 147static void __init tegra_harmony_fixup(struct machine_desc *desc,
@@ -80,6 +157,10 @@ static void __init tegra_harmony_fixup(struct machine_desc *desc,
80static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = { 157static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
81 /* name parent rate enabled */ 158 /* name parent rate enabled */
82 { "uartd", "pll_p", 216000000, true }, 159 { "uartd", "pll_p", 216000000, true },
160 { "pll_a", "pll_p_out1", 56448000, true },
161 { "pll_a_out0", "pll_a", 11289600, true },
162 { "cdev1", NULL, 0, true },
163 { "i2s1", "pll_a_out0", 11289600, false},
83 { NULL, NULL, 0, 0}, 164 { NULL, NULL, 0, 0},
84}; 165};
85 166
@@ -91,15 +172,15 @@ static struct tegra_sdhci_platform_data sdhci_pdata1 = {
91}; 172};
92 173
93static struct tegra_sdhci_platform_data sdhci_pdata2 = { 174static struct tegra_sdhci_platform_data sdhci_pdata2 = {
94 .cd_gpio = TEGRA_GPIO_PI5, 175 .cd_gpio = TEGRA_GPIO_SD2_CD,
95 .wp_gpio = TEGRA_GPIO_PH1, 176 .wp_gpio = TEGRA_GPIO_SD2_WP,
96 .power_gpio = TEGRA_GPIO_PT3, 177 .power_gpio = TEGRA_GPIO_SD2_POWER,
97}; 178};
98 179
99static struct tegra_sdhci_platform_data sdhci_pdata4 = { 180static struct tegra_sdhci_platform_data sdhci_pdata4 = {
100 .cd_gpio = TEGRA_GPIO_PH2, 181 .cd_gpio = TEGRA_GPIO_SD4_CD,
101 .wp_gpio = TEGRA_GPIO_PH3, 182 .wp_gpio = TEGRA_GPIO_SD4_WP,
102 .power_gpio = TEGRA_GPIO_PI6, 183 .power_gpio = TEGRA_GPIO_SD4_POWER,
103 .is_8bit = 1, 184 .is_8bit = 1,
104}; 185};
105 186
@@ -114,6 +195,8 @@ static void __init tegra_harmony_init(void)
114 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; 195 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
115 196
116 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); 197 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
198 harmony_i2c_init();
199 harmony_regulator_init();
117} 200}
118 201
119MACHINE_START(HARMONY, "harmony") 202MACHINE_START(HARMONY, "harmony")
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
index 09ca7755dd55..1e57b071f52d 100644
--- a/arch/arm/mach-tegra/board-harmony.h
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -17,6 +17,21 @@
17#ifndef _MACH_TEGRA_BOARD_HARMONY_H 17#ifndef _MACH_TEGRA_BOARD_HARMONY_H
18#define _MACH_TEGRA_BOARD_HARMONY_H 18#define _MACH_TEGRA_BOARD_HARMONY_H
19 19
20#define HARMONY_GPIO_WM8903(_x_) (TEGRA_NR_GPIOS + (_x_))
21
22#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
23#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
24#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PT3
25#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2
26#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3
27#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6
28#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PX3
29#define TEGRA_GPIO_SPKR_EN HARMONY_GPIO_WM8903(2)
30#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
31#define TEGRA_GPIO_INT_MIC_EN TEGRA_GPIO_PX0
32#define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PX1
33
20void harmony_pinmux_init(void); 34void harmony_pinmux_init(void);
35int harmony_regulator_init(void);
21 36
22#endif 37#endif
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c
new file mode 100644
index 000000000000..2643d1bd568b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00-pinmux.c
@@ -0,0 +1,157 @@
1/*
2 * arch/arm/mach-tegra/board-paz00-pinmux.c
3 *
4 * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/gpio.h>
19#include <mach/pinmux.h>
20
21#include "gpio-names.h"
22#include "board-paz00.h"
23
24static struct tegra_pingroup_config paz00_pinmux[] = {
25 {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
26 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
27 {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
28 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
29 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
30 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
31 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
32 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
33 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_PLLC_OUT1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
34 {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
35 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
36 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
37 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
38 {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
39 {TEGRA_PINGROUP_DTA, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
40 {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
41 {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
42 {TEGRA_PINGROUP_DTD, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
43 {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
44 {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
45 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
46 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_GMC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
48 {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
49 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
50 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
51 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
52 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
53 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
55 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_KBCB, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
59 {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
60 {TEGRA_PINGROUP_KBCD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
61 {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
62 {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
63 {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
64 {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
65 {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
67 {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
72 {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
73 {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
74 {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
75 {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
76 {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
77 {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
78 {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
79 {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
80 {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
81 {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
82 {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
83 {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
84 {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
85 {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
86 {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
87 {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
88 {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
89 {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
90 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
91 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
92 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
93 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
94 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
95 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
96 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
97 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
98 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
99 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
100 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
101 {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
102 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
103 {TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
104 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
105 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
106 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
107 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
108 {TEGRA_PINGROUP_SDC, TEGRA_MUX_TWC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
109 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
110 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
112 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
115 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
117 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_SPID, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
122 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_RSVD4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
123 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
124 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
125 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_UAD, TEGRA_MUX_SPDIF, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
129 {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
130 {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
131 {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
132 {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
133 {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
138 {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
139 {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
141};
142
143static struct tegra_gpio_table gpio_table[] = {
144 { .gpio = TEGRA_GPIO_SD1_CD, .enable = true },
145 { .gpio = TEGRA_GPIO_SD1_WP, .enable = true },
146 { .gpio = TEGRA_GPIO_SD1_POWER, .enable = true },
147 { .gpio = TEGRA_GPIO_SD4_CD, .enable = true },
148 { .gpio = TEGRA_GPIO_SD4_WP, .enable = true },
149 { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true },
150};
151
152void paz00_pinmux_init(void)
153{
154 tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
155
156 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
157}
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
new file mode 100644
index 000000000000..57e50a823eec
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -0,0 +1,128 @@
1/*
2 * arch/arm/mach-tegra/board-paz00.c
3 *
4 * Copyright (C) 2011 Marc Dietrich <marvin24@gmx.de>
5 *
6 * Based on board-harmony.c
7 * Copyright (C) 2010 Google, Inc.
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/serial_8250.h>
24#include <linux/clk.h>
25#include <linux/dma-mapping.h>
26#include <linux/pda_power.h>
27#include <linux/io.h>
28
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/time.h>
32#include <asm/setup.h>
33
34#include <mach/iomap.h>
35#include <mach/irqs.h>
36#include <mach/sdhci.h>
37
38#include "board.h"
39#include "board-paz00.h"
40#include "clock.h"
41#include "devices.h"
42#include "gpio-names.h"
43
44static struct plat_serial8250_port debug_uart_platform_data[] = {
45 {
46 .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
47 .mapbase = TEGRA_UARTD_BASE,
48 .irq = INT_UARTD,
49 .flags = UPF_BOOT_AUTOCONF,
50 .iotype = UPIO_MEM,
51 .regshift = 2,
52 .uartclk = 216000000,
53 }, {
54 .flags = 0
55 }
56};
57
58static struct platform_device debug_uart = {
59 .name = "serial8250",
60 .id = PLAT8250_DEV_PLATFORM,
61 .dev = {
62 .platform_data = debug_uart_platform_data,
63 },
64};
65
66static struct platform_device *paz00_devices[] __initdata = {
67 &debug_uart,
68 &tegra_sdhci_device1,
69 &tegra_sdhci_device2,
70 &tegra_sdhci_device4,
71};
72
73static void __init tegra_paz00_fixup(struct machine_desc *desc,
74 struct tag *tags, char **cmdline, struct meminfo *mi)
75{
76 mi->nr_banks = 1;
77 mi->bank[0].start = PHYS_OFFSET;
78 mi->bank[0].size = 448 * SZ_1M;
79}
80
81static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = {
82 /* name parent rate enabled */
83 { "uartd", "pll_p", 216000000, true },
84 { NULL, NULL, 0, 0},
85};
86
87
88static struct tegra_sdhci_platform_data sdhci_pdata1 = {
89 .cd_gpio = TEGRA_GPIO_SD1_CD,
90 .wp_gpio = TEGRA_GPIO_SD1_WP,
91 .power_gpio = TEGRA_GPIO_SD1_POWER,
92};
93
94static struct tegra_sdhci_platform_data sdhci_pdata2 = {
95 .cd_gpio = -1,
96 .wp_gpio = -1,
97 .power_gpio = -1,
98};
99
100static struct tegra_sdhci_platform_data sdhci_pdata4 = {
101 .cd_gpio = TEGRA_GPIO_SD4_CD,
102 .wp_gpio = TEGRA_GPIO_SD4_WP,
103 .power_gpio = TEGRA_GPIO_SD4_POWER,
104 .is_8bit = 1,
105};
106
107static void __init tegra_paz00_init(void)
108{
109 tegra_clk_init_from_table(paz00_clk_init_table);
110
111 paz00_pinmux_init();
112
113 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
114 tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
115 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
116
117 platform_add_devices(paz00_devices, ARRAY_SIZE(paz00_devices));
118}
119
120MACHINE_START(PAZ00, "paz00")
121 .boot_params = 0x00000100,
122 .fixup = tegra_paz00_fixup,
123 .map_io = tegra_map_common_io,
124 .init_early = tegra_init_early,
125 .init_irq = tegra_init_irq,
126 .timer = &tegra_timer,
127 .init_machine = tegra_paz00_init,
128MACHINE_END
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h
new file mode 100644
index 000000000000..da193ca76d3b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00.h
@@ -0,0 +1,29 @@
1/*
2 * arch/arm/mach-tegra/board-paz00.h
3 *
4 * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _MACH_TEGRA_BOARD_PAZ00_H
18#define _MACH_TEGRA_BOARD_PAZ00_H
19
20#define TEGRA_GPIO_SD1_CD TEGRA_GPIO_PV5
21#define TEGRA_GPIO_SD1_WP TEGRA_GPIO_PH1
22#define TEGRA_GPIO_SD1_POWER TEGRA_GPIO_PT3
23#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2
24#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3
25#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6
26
27void paz00_pinmux_init(void);
28
29#endif
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
index 2d6ad83ed4b2..0bda495e9742 100644
--- a/arch/arm/mach-tegra/board-seaboard-pinmux.c
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
@@ -161,11 +161,12 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
161 161
162 162
163static struct tegra_gpio_table gpio_table[] = { 163static struct tegra_gpio_table gpio_table[] = {
164 { .gpio = TEGRA_GPIO_PI5, .enable = true }, /* mmc2 cd */ 164 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
165 { .gpio = TEGRA_GPIO_PH1, .enable = true }, /* mmc2 wp */ 165 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
166 { .gpio = TEGRA_GPIO_PI6, .enable = true }, /* mmc2 pwr */ 166 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
167 { .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true }, /* lid switch */ 167 { .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true },
168 { .gpio = TEGRA_GPIO_POWERKEY, .enable = true }, /* power key */ 168 { .gpio = TEGRA_GPIO_POWERKEY, .enable = true },
169 { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true },
169}; 170};
170 171
171void __init seaboard_pinmux_init(void) 172void __init seaboard_pinmux_init(void)
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index 6ca9e61f6cd0..a8d7ace9f958 100644
--- a/arch/arm/mach-tegra/board-seaboard.c
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -18,9 +18,12 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/serial_8250.h> 20#include <linux/serial_8250.h>
21#include <linux/i2c.h>
22#include <linux/i2c-tegra.h>
21#include <linux/delay.h> 23#include <linux/delay.h>
22#include <linux/input.h> 24#include <linux/input.h>
23#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/gpio.h>
24#include <linux/gpio_keys.h> 27#include <linux/gpio_keys.h>
25 28
26#include <mach/iomap.h> 29#include <mach/iomap.h>
@@ -63,6 +66,22 @@ static __initdata struct tegra_clk_init_table seaboard_clk_init_table[] = {
63 { NULL, NULL, 0, 0}, 66 { NULL, NULL, 0, 0},
64}; 67};
65 68
69static struct tegra_i2c_platform_data seaboard_i2c1_platform_data = {
70 .bus_clk_rate = 400000.
71};
72
73static struct tegra_i2c_platform_data seaboard_i2c2_platform_data = {
74 .bus_clk_rate = 400000,
75};
76
77static struct tegra_i2c_platform_data seaboard_i2c3_platform_data = {
78 .bus_clk_rate = 400000,
79};
80
81static struct tegra_i2c_platform_data seaboard_dvc_platform_data = {
82 .bus_clk_rate = 400000,
83};
84
66static struct gpio_keys_button seaboard_gpio_keys_buttons[] = { 85static struct gpio_keys_button seaboard_gpio_keys_buttons[] = {
67 { 86 {
68 .code = SW_LID, 87 .code = SW_LID,
@@ -103,9 +122,9 @@ static struct tegra_sdhci_platform_data sdhci_pdata1 = {
103}; 122};
104 123
105static struct tegra_sdhci_platform_data sdhci_pdata3 = { 124static struct tegra_sdhci_platform_data sdhci_pdata3 = {
106 .cd_gpio = TEGRA_GPIO_PI5, 125 .cd_gpio = TEGRA_GPIO_SD2_CD,
107 .wp_gpio = TEGRA_GPIO_PH1, 126 .wp_gpio = TEGRA_GPIO_SD2_WP,
108 .power_gpio = TEGRA_GPIO_PI6, 127 .power_gpio = TEGRA_GPIO_SD2_POWER,
109}; 128};
110 129
111static struct tegra_sdhci_platform_data sdhci_pdata4 = { 130static struct tegra_sdhci_platform_data sdhci_pdata4 = {
@@ -124,7 +143,36 @@ static struct platform_device *seaboard_devices[] __initdata = {
124 &seaboard_gpio_keys_device, 143 &seaboard_gpio_keys_device,
125}; 144};
126 145
127static void __init __tegra_seaboard_init(void) 146static struct i2c_board_info __initdata isl29018_device = {
147 I2C_BOARD_INFO("isl29018", 0x44),
148 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ),
149};
150
151static struct i2c_board_info __initdata adt7461_device = {
152 I2C_BOARD_INFO("adt7461", 0x4c),
153};
154
155static void __init seaboard_i2c_init(void)
156{
157 gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018");
158 gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ);
159
160 i2c_register_board_info(0, &isl29018_device, 1);
161
162 i2c_register_board_info(4, &adt7461_device, 1);
163
164 tegra_i2c_device1.dev.platform_data = &seaboard_i2c1_platform_data;
165 tegra_i2c_device2.dev.platform_data = &seaboard_i2c2_platform_data;
166 tegra_i2c_device3.dev.platform_data = &seaboard_i2c3_platform_data;
167 tegra_i2c_device4.dev.platform_data = &seaboard_dvc_platform_data;
168
169 platform_device_register(&tegra_i2c_device1);
170 platform_device_register(&tegra_i2c_device2);
171 platform_device_register(&tegra_i2c_device3);
172 platform_device_register(&tegra_i2c_device4);
173}
174
175static void __init seaboard_common_init(void)
128{ 176{
129 seaboard_pinmux_init(); 177 seaboard_pinmux_init();
130 178
@@ -144,7 +192,9 @@ static void __init tegra_seaboard_init(void)
144 debug_uart_platform_data[0].mapbase = TEGRA_UARTD_BASE; 192 debug_uart_platform_data[0].mapbase = TEGRA_UARTD_BASE;
145 debug_uart_platform_data[0].irq = INT_UARTD; 193 debug_uart_platform_data[0].irq = INT_UARTD;
146 194
147 __tegra_seaboard_init(); 195 seaboard_common_init();
196
197 seaboard_i2c_init();
148} 198}
149 199
150static void __init tegra_kaen_init(void) 200static void __init tegra_kaen_init(void)
@@ -154,7 +204,9 @@ static void __init tegra_kaen_init(void)
154 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE; 204 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
155 debug_uart_platform_data[0].irq = INT_UARTB; 205 debug_uart_platform_data[0].irq = INT_UARTB;
156 206
157 __tegra_seaboard_init(); 207 seaboard_common_init();
208
209 seaboard_i2c_init();
158} 210}
159 211
160static void __init tegra_wario_init(void) 212static void __init tegra_wario_init(void)
@@ -164,7 +216,9 @@ static void __init tegra_wario_init(void)
164 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE; 216 debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
165 debug_uart_platform_data[0].irq = INT_UARTB; 217 debug_uart_platform_data[0].irq = INT_UARTB;
166 218
167 __tegra_seaboard_init(); 219 seaboard_common_init();
220
221 seaboard_i2c_init();
168} 222}
169 223
170 224
diff --git a/arch/arm/mach-tegra/board-seaboard.h b/arch/arm/mach-tegra/board-seaboard.h
index a098e3599731..d8415e1a8434 100644
--- a/arch/arm/mach-tegra/board-seaboard.h
+++ b/arch/arm/mach-tegra/board-seaboard.h
@@ -17,6 +17,9 @@
17#ifndef _MACH_TEGRA_BOARD_SEABOARD_H 17#ifndef _MACH_TEGRA_BOARD_SEABOARD_H
18#define _MACH_TEGRA_BOARD_SEABOARD_H 18#define _MACH_TEGRA_BOARD_SEABOARD_H
19 19
20#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
21#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
22#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PI6
20#define TEGRA_GPIO_LIDSWITCH TEGRA_GPIO_PC7 23#define TEGRA_GPIO_LIDSWITCH TEGRA_GPIO_PC7
21#define TEGRA_GPIO_USB1 TEGRA_GPIO_PD0 24#define TEGRA_GPIO_USB1 TEGRA_GPIO_PD0
22#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PV2 25#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PV2
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c
index 6d4fc9f7f1fb..13534fa08abf 100644
--- a/arch/arm/mach-tegra/board-trimslice-pinmux.c
+++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c
@@ -16,8 +16,11 @@
16 16
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19
19#include <mach/pinmux.h> 20#include <mach/pinmux.h>
21#include <mach/gpio.h>
20 22
23#include "gpio-names.h"
21#include "board-trimslice.h" 24#include "board-trimslice.h"
22 25
23static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { 26static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
@@ -139,7 +142,13 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
139 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 142 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
140}; 143};
141 144
145static struct tegra_gpio_table gpio_table[] = {
146 { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */
147 { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */
148};
149
142void __init trimslice_pinmux_init(void) 150void __init trimslice_pinmux_init(void)
143{ 151{
144 tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux)); 152 tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
153 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
145} 154}
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
index 7be7d4acd02f..cda4cfd78e84 100644
--- a/arch/arm/mach-tegra/board-trimslice.c
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -29,9 +29,12 @@
29#include <asm/setup.h> 29#include <asm/setup.h>
30 30
31#include <mach/iomap.h> 31#include <mach/iomap.h>
32#include <mach/sdhci.h>
32 33
33#include "board.h" 34#include "board.h"
34#include "clock.h" 35#include "clock.h"
36#include "devices.h"
37#include "gpio-names.h"
35 38
36#include "board-trimslice.h" 39#include "board-trimslice.h"
37 40
@@ -56,9 +59,22 @@ static struct platform_device debug_uart = {
56 .platform_data = debug_uart_platform_data, 59 .platform_data = debug_uart_platform_data,
57 }, 60 },
58}; 61};
62static struct tegra_sdhci_platform_data sdhci_pdata1 = {
63 .cd_gpio = -1,
64 .wp_gpio = -1,
65 .power_gpio = -1,
66};
67
68static struct tegra_sdhci_platform_data sdhci_pdata4 = {
69 .cd_gpio = TRIMSLICE_GPIO_SD4_CD,
70 .wp_gpio = TRIMSLICE_GPIO_SD4_WP,
71 .power_gpio = -1,
72};
59 73
60static struct platform_device *trimslice_devices[] __initdata = { 74static struct platform_device *trimslice_devices[] __initdata = {
61 &debug_uart, 75 &debug_uart,
76 &tegra_sdhci_device1,
77 &tegra_sdhci_device4,
62}; 78};
63 79
64static void __init tegra_trimslice_fixup(struct machine_desc *desc, 80static void __init tegra_trimslice_fixup(struct machine_desc *desc,
@@ -92,6 +108,9 @@ static void __init tegra_trimslice_init(void)
92 108
93 trimslice_pinmux_init(); 109 trimslice_pinmux_init();
94 110
111 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
112 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
113
95 platform_add_devices(trimslice_devices, ARRAY_SIZE(trimslice_devices)); 114 platform_add_devices(trimslice_devices, ARRAY_SIZE(trimslice_devices));
96} 115}
97 116
diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h
index 16ec0f0d3bb1..e8ef6291c6f1 100644
--- a/arch/arm/mach-tegra/board-trimslice.h
+++ b/arch/arm/mach-tegra/board-trimslice.h
@@ -17,6 +17,9 @@
17#ifndef _MACH_TEGRA_BOARD_TRIMSLICE_H 17#ifndef _MACH_TEGRA_BOARD_TRIMSLICE_H
18#define _MACH_TEGRA_BOARD_TRIMSLICE_H 18#define _MACH_TEGRA_BOARD_TRIMSLICE_H
19 19
20#define TRIMSLICE_GPIO_SD4_CD TEGRA_GPIO_PP1 /* mmc4 cd */
21#define TRIMSLICE_GPIO_SD4_WP TEGRA_GPIO_PP2 /* mmc4 wp */
22
20void trimslice_pinmux_init(void); 23void trimslice_pinmux_init(void);
21 24
22#endif 25#endif
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 682e6d33108c..1528f9daef1f 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -503,3 +503,73 @@ struct platform_device tegra_uarte_device = {
503 .coherent_dma_mask = DMA_BIT_MASK(32), 503 .coherent_dma_mask = DMA_BIT_MASK(32),
504 }, 504 },
505}; 505};
506
507static struct resource i2s_resource1[] = {
508 [0] = {
509 .start = INT_I2S1,
510 .end = INT_I2S1,
511 .flags = IORESOURCE_IRQ
512 },
513 [1] = {
514 .start = TEGRA_DMA_REQ_SEL_I2S_1,
515 .end = TEGRA_DMA_REQ_SEL_I2S_1,
516 .flags = IORESOURCE_DMA
517 },
518 [2] = {
519 .start = TEGRA_I2S1_BASE,
520 .end = TEGRA_I2S1_BASE + TEGRA_I2S1_SIZE - 1,
521 .flags = IORESOURCE_MEM
522 }
523};
524
525static struct resource i2s_resource2[] = {
526 [0] = {
527 .start = INT_I2S2,
528 .end = INT_I2S2,
529 .flags = IORESOURCE_IRQ
530 },
531 [1] = {
532 .start = TEGRA_DMA_REQ_SEL_I2S2_1,
533 .end = TEGRA_DMA_REQ_SEL_I2S2_1,
534 .flags = IORESOURCE_DMA
535 },
536 [2] = {
537 .start = TEGRA_I2S2_BASE,
538 .end = TEGRA_I2S2_BASE + TEGRA_I2S2_SIZE - 1,
539 .flags = IORESOURCE_MEM
540 }
541};
542
543struct platform_device tegra_i2s_device1 = {
544 .name = "tegra-i2s",
545 .id = 0,
546 .resource = i2s_resource1,
547 .num_resources = ARRAY_SIZE(i2s_resource1),
548};
549
550struct platform_device tegra_i2s_device2 = {
551 .name = "tegra-i2s",
552 .id = 1,
553 .resource = i2s_resource2,
554 .num_resources = ARRAY_SIZE(i2s_resource2),
555};
556
557static struct resource tegra_das_resources[] = {
558 [0] = {
559 .start = TEGRA_APB_MISC_DAS_BASE,
560 .end = TEGRA_APB_MISC_DAS_BASE + TEGRA_APB_MISC_DAS_SIZE - 1,
561 .flags = IORESOURCE_MEM,
562 },
563};
564
565struct platform_device tegra_das_device = {
566 .name = "tegra-das",
567 .id = -1,
568 .num_resources = ARRAY_SIZE(tegra_das_resources),
569 .resource = tegra_das_resources,
570};
571
572struct platform_device tegra_pcm_device = {
573 .name = "tegra-pcm-audio",
574 .id = -1,
575};
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index 888810c37ee9..4a7dc0a097d6 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -42,5 +42,9 @@ extern struct platform_device tegra_uartc_device;
42extern struct platform_device tegra_uartd_device; 42extern struct platform_device tegra_uartd_device;
43extern struct platform_device tegra_uarte_device; 43extern struct platform_device tegra_uarte_device;
44extern struct platform_device tegra_pmu_device; 44extern struct platform_device tegra_pmu_device;
45extern struct platform_device tegra_i2s_device1;
46extern struct platform_device tegra_i2s_device2;
47extern struct platform_device tegra_das_device;
48extern struct platform_device tegra_pcm_device;
45 49
46#endif 50#endif
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 691cdabd69cf..19dec3ac0854 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -122,6 +122,9 @@
122#define TEGRA_APB_MISC_BASE 0x70000000 122#define TEGRA_APB_MISC_BASE 0x70000000
123#define TEGRA_APB_MISC_SIZE SZ_4K 123#define TEGRA_APB_MISC_SIZE SZ_4K
124 124
125#define TEGRA_APB_MISC_DAS_BASE 0x70000c00
126#define TEGRA_APB_MISC_DAS_SIZE SZ_128
127
125#define TEGRA_AC97_BASE 0x70002000 128#define TEGRA_AC97_BASE 0x70002000
126#define TEGRA_AC97_SIZE SZ_512 129#define TEGRA_AC97_SIZE SZ_512
127 130
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index b3b0f0f5053d..e5f6fc428348 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -78,7 +78,7 @@ __tagtable(ATAG_INITRD2, parse_tag_initrd2);
78 */ 78 */
79struct meminfo meminfo; 79struct meminfo meminfo;
80 80
81void show_mem(void) 81void show_mem(unsigned int filter)
82{ 82{
83 int free = 0, total = 0, reserved = 0; 83 int free = 0, total = 0, reserved = 0;
84 int shared = 0, cached = 0, slab = 0, i; 84 int shared = 0, cached = 0, slab = 0, i;
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 0f140ecedb01..5e04ddc18fa8 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -58,6 +58,7 @@ enum omap_display_type {
58 OMAP_DISPLAY_TYPE_SDI = 1 << 2, 58 OMAP_DISPLAY_TYPE_SDI = 1 << 2,
59 OMAP_DISPLAY_TYPE_DSI = 1 << 3, 59 OMAP_DISPLAY_TYPE_DSI = 1 << 3,
60 OMAP_DISPLAY_TYPE_VENC = 1 << 4, 60 OMAP_DISPLAY_TYPE_VENC = 1 << 4,
61 OMAP_DISPLAY_TYPE_HDMI = 1 << 5,
61}; 62};
62 63
63enum omap_plane { 64enum omap_plane {
@@ -237,6 +238,13 @@ static inline int omap_display_init(struct omap_dss_board_info *board_data)
237} 238}
238#endif 239#endif
239 240
241struct omap_display_platform_data {
242 struct omap_dss_board_info *board_data;
243 /* TODO: Additional members to be added when PM is considered */
244
245 bool (*opt_clock_available)(const char *clk_role);
246};
247
240struct omap_video_timings { 248struct omap_video_timings {
241 /* Unit: pixels */ 249 /* Unit: pixels */
242 u16 x_res; 250 u16 x_res;
@@ -396,8 +404,8 @@ struct omap_dss_device {
396 struct { 404 struct {
397 u16 regn; 405 u16 regn;
398 u16 regm; 406 u16 regm;
399 u16 regm3; 407 u16 regm_dispc;
400 u16 regm4; 408 u16 regm_dsi;
401 409
402 u16 lp_clk_div; 410 u16 lp_clk_div;
403 411
@@ -555,6 +563,9 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
555 int channel, 563 int channel,
556 u16 x, u16 y, u16 w, u16 h, 564 u16 x, u16 y, u16 w, u16 h,
557 void (*callback)(int, void *), void *data); 565 void (*callback)(int, void *), void *data);
566int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
567int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
568void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
558 569
559int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); 570int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
560void omapdss_dsi_display_disable(struct omap_dss_device *dssdev); 571void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
index 98fc8b4a4cc4..b9e85886b9d6 100644
--- a/arch/arm/plat-omap/include/plat/omap34xx.h
+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
@@ -56,8 +56,12 @@
56#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000) 56#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000)
57#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200) 57#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200)
58#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400) 58#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
59#define OMAP3430_ISP_CSI2A_BASE (OMAP3430_ISP_BASE + 0x1800) 59#define OMAP3430_ISP_CSI2A_REGS1_BASE (OMAP3430_ISP_BASE + 0x1800)
60#define OMAP3430_ISP_CSI2PHY_BASE (OMAP3430_ISP_BASE + 0x1970) 60#define OMAP3430_ISP_CSIPHY2_BASE (OMAP3430_ISP_BASE + 0x1970)
61#define OMAP3630_ISP_CSI2A_REGS2_BASE (OMAP3430_ISP_BASE + 0x19C0)
62#define OMAP3630_ISP_CSI2C_REGS1_BASE (OMAP3430_ISP_BASE + 0x1C00)
63#define OMAP3630_ISP_CSIPHY1_BASE (OMAP3430_ISP_BASE + 0x1D70)
64#define OMAP3630_ISP_CSI2C_REGS2_BASE (OMAP3430_ISP_BASE + 0x1DC0)
61 65
62#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F) 66#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F)
63#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077) 67#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077)
@@ -69,8 +73,12 @@
69#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB) 73#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB)
70#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB) 74#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB)
71#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F) 75#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F)
72#define OMAP3430_ISP_CSI2A_END (OMAP3430_ISP_CSI2A_BASE + 0x16F) 76#define OMAP3430_ISP_CSI2A_REGS1_END (OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F)
73#define OMAP3430_ISP_CSI2PHY_END (OMAP3430_ISP_CSI2PHY_BASE + 0x007) 77#define OMAP3430_ISP_CSIPHY2_END (OMAP3430_ISP_CSIPHY2_BASE + 0x00B)
78#define OMAP3630_ISP_CSI2A_REGS2_END (OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F)
79#define OMAP3630_ISP_CSI2C_REGS1_END (OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F)
80#define OMAP3630_ISP_CSIPHY1_END (OMAP3630_ISP_CSIPHY1_BASE + 0x00B)
81#define OMAP3630_ISP_CSI2C_REGS2_END (OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F)
74 82
75#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000) 83#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
76#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000) 84#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000)
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 01615d4f57d6..672c21632f2f 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -31,6 +31,7 @@ config BLACKFIN
31 select HAVE_OPROFILE 31 select HAVE_OPROFILE
32 select ARCH_WANT_OPTIONAL_GPIOLIB 32 select ARCH_WANT_OPTIONAL_GPIOLIB
33 select HAVE_GENERIC_HARDIRQS 33 select HAVE_GENERIC_HARDIRQS
34 select GENERIC_ATOMIC64
34 select GENERIC_IRQ_PROBE 35 select GENERIC_IRQ_PROBE
35 select IRQ_PER_CPU if SMP 36 select IRQ_PER_CPU if SMP
36 select GENERIC_HARDIRQS_NO_DEPRECATED 37 select GENERIC_HARDIRQS_NO_DEPRECATED
diff --git a/arch/blackfin/include/asm/atomic.h b/arch/blackfin/include/asm/atomic.h
index d27c6274247d..e48508957160 100644
--- a/arch/blackfin/include/asm/atomic.h
+++ b/arch/blackfin/include/asm/atomic.h
@@ -121,4 +121,6 @@ static inline int atomic_test_mask(int mask, atomic_t *v)
121 121
122#endif 122#endif
123 123
124#include <asm-generic/atomic64.h>
125
124#endif 126#endif
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index c97497dd0d19..ff9a9f35d50b 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -396,8 +396,9 @@
396#define __NR_name_to_handle_at 375 396#define __NR_name_to_handle_at 375
397#define __NR_open_by_handle_at 376 397#define __NR_open_by_handle_at 376
398#define __NR_clock_adjtime 377 398#define __NR_clock_adjtime 377
399#define __NR_syncfs 378
399 400
400#define __NR_syscall 378 401#define __NR_syscall 379
401#define NR_syscalls __NR_syscall 402#define NR_syscalls __NR_syscall
402 403
403/* Old optional stuff no one actually uses */ 404/* Old optional stuff no one actually uses */
diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h
index 4070079e2c00..ffd0537295ac 100644
--- a/arch/blackfin/mach-bf548/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h
@@ -81,7 +81,11 @@
81/* PLL Status Register Is Inaccurate */ 81/* PLL Status Register Is Inaccurate */
82#define ANOMALY_05000351 (__SILICON_REVISION__ < 1) 82#define ANOMALY_05000351 (__SILICON_REVISION__ < 1)
83/* bfrom_SysControl() Firmware Function Performs Improper System Reset */ 83/* bfrom_SysControl() Firmware Function Performs Improper System Reset */
84#define ANOMALY_05000353 (__SILICON_REVISION__ < 2) 84/*
85 * Note: anomaly sheet says this is fixed with bf54x-0.2+, but testing
86 * shows that the fix itself does not cover all cases.
87 */
88#define ANOMALY_05000353 (1)
85/* Regulator Programming Blocked when Hibernate Wakeup Source Remains Active */ 89/* Regulator Programming Blocked when Hibernate Wakeup Source Remains Active */
86#define ANOMALY_05000355 (__SILICON_REVISION__ < 1) 90#define ANOMALY_05000355 (__SILICON_REVISION__ < 1)
87/* System Stalled During A Core Access To AMC While A Core Access To NFC FIFO Is Required */ 91/* System Stalled During A Core Access To AMC While A Core Access To NFC FIFO Is Required */
diff --git a/arch/blackfin/mach-bf561/hotplug.c b/arch/blackfin/mach-bf561/hotplug.c
index 42fc085629c7..0123117b8ff2 100644
--- a/arch/blackfin/mach-bf561/hotplug.c
+++ b/arch/blackfin/mach-bf561/hotplug.c
@@ -7,6 +7,7 @@
7 7
8#include <linux/smp.h> 8#include <linux/smp.h>
9#include <asm/blackfin.h> 9#include <asm/blackfin.h>
10#include <asm/cacheflush.h>
10#include <mach/pll.h> 11#include <mach/pll.h>
11 12
12int hotplug_coreb; 13int hotplug_coreb;
@@ -14,8 +15,16 @@ int hotplug_coreb;
14void platform_cpu_die(void) 15void platform_cpu_die(void)
15{ 16{
16 unsigned long iwr; 17 unsigned long iwr;
18
17 hotplug_coreb = 1; 19 hotplug_coreb = 1;
18 20
21 /*
22 * When CoreB wakes up, the code in _coreb_trampoline_start cannot
23 * turn off the data cache. This causes the CoreB failed to boot.
24 * As a workaround, we invalidate all the data cache before sleep.
25 */
26 blackfin_invalidate_entire_dcache();
27
19 /* disable core timer */ 28 /* disable core timer */
20 bfin_write_TCNTL(0); 29 bfin_write_TCNTL(0);
21 30
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 757943f620e7..46ab45704c89 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1752,6 +1752,7 @@ ENTRY(_sys_call_table)
1752 .long _sys_name_to_handle_at /* 375 */ 1752 .long _sys_name_to_handle_at /* 375 */
1753 .long _sys_open_by_handle_at 1753 .long _sys_open_by_handle_at
1754 .long _sys_clock_adjtime 1754 .long _sys_clock_adjtime
1755 .long _sys_syncfs
1755 1756
1756 .rept NR_syscalls-(.-_sys_call_table)/4 1757 .rept NR_syscalls-(.-_sys_call_table)/4
1757 .long _sys_ni_syscall 1758 .long _sys_ni_syscall
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
index 837dc82a013e..a06dfb13d518 100644
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -128,9 +128,9 @@ static inline const char *acpi_get_sysname (void)
128int acpi_request_vector (u32 int_type); 128int acpi_request_vector (u32 int_type);
129int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); 129int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
130 130
131/* routines for saving/restoring kernel state */ 131/* Low-level suspend routine. */
132extern int acpi_save_state_mem(void); 132extern int acpi_suspend_lowlevel(void);
133extern void acpi_restore_state_mem(void); 133
134extern unsigned long acpi_wakeup_address; 134extern unsigned long acpi_wakeup_address;
135 135
136/* 136/*
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index 954d398a54b4..404d037c5e10 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -315,11 +315,15 @@
315#define __NR_fanotify_init 1323 315#define __NR_fanotify_init 1323
316#define __NR_fanotify_mark 1324 316#define __NR_fanotify_mark 1324
317#define __NR_prlimit64 1325 317#define __NR_prlimit64 1325
318#define __NR_name_to_handle_at 1326
319#define __NR_open_by_handle_at 1327
320#define __NR_clock_adjtime 1328
321#define __NR_syncfs 1329
318 322
319#ifdef __KERNEL__ 323#ifdef __KERNEL__
320 324
321 325
322#define NR_syscalls 302 /* length of syscall table */ 326#define NR_syscalls 306 /* length of syscall table */
323 327
324/* 328/*
325 * The following defines stop scripts/checksyscalls.sh from complaining about 329 * The following defines stop scripts/checksyscalls.sh from complaining about
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 90ebceb899a0..3be485a300b1 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -803,7 +803,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
803 * ACPI based hotplug CPU support 803 * ACPI based hotplug CPU support
804 */ 804 */
805#ifdef CONFIG_ACPI_HOTPLUG_CPU 805#ifdef CONFIG_ACPI_HOTPLUG_CPU
806static 806static __cpuinit
807int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) 807int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
808{ 808{
809#ifdef CONFIG_ACPI_NUMA 809#ifdef CONFIG_ACPI_NUMA
@@ -878,7 +878,7 @@ __init void prefill_possible_map(void)
878 set_cpu_possible(i, true); 878 set_cpu_possible(i, true);
879} 879}
880 880
881int acpi_map_lsapic(acpi_handle handle, int *pcpu) 881static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
882{ 882{
883 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 883 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
884 union acpi_object *obj; 884 union acpi_object *obj;
@@ -929,6 +929,11 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu)
929 return (0); 929 return (0);
930} 930}
931 931
932/* wrapper to silence section mismatch warning */
933int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu)
934{
935 return _acpi_map_lsapic(handle, pcpu);
936}
932EXPORT_SYMBOL(acpi_map_lsapic); 937EXPORT_SYMBOL(acpi_map_lsapic);
933 938
934int acpi_unmap_lsapic(int cpu) 939int acpi_unmap_lsapic(int cpu)
@@ -1034,18 +1039,8 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
1034EXPORT_SYMBOL(acpi_unregister_ioapic); 1039EXPORT_SYMBOL(acpi_unregister_ioapic);
1035 1040
1036/* 1041/*
1037 * acpi_save_state_mem() - save kernel state 1042 * acpi_suspend_lowlevel() - save kernel state and suspend.
1038 * 1043 *
1039 * TBD when when IA64 starts to support suspend... 1044 * TBD when when IA64 starts to support suspend...
1040 */ 1045 */
1041int acpi_save_state_mem(void) { return 0; } 1046int acpi_suspend_lowlevel(void) { return 0; }
1042
1043/*
1044 * acpi_restore_state()
1045 */
1046void acpi_restore_state_mem(void) {}
1047
1048/*
1049 * do_suspend_lowlevel()
1050 */
1051void do_suspend_lowlevel(void) {}
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 244704a174de..6de2e23b3636 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1771,6 +1771,10 @@ sys_call_table:
1771 data8 sys_fanotify_init 1771 data8 sys_fanotify_init
1772 data8 sys_fanotify_mark 1772 data8 sys_fanotify_mark
1773 data8 sys_prlimit64 // 1325 1773 data8 sys_prlimit64 // 1325
1774 data8 sys_name_to_handle_at
1775 data8 sys_open_by_handle_at
1776 data8 sys_clock_adjtime
1777 data8 sys_syncfs
1774 1778
1775 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1779 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
1776#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ 1780#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index 54bf54059811..9a018cde5d84 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -36,7 +36,7 @@ static unsigned long max_gap;
36 * Shows a simple page count of reserved and used pages in the system. 36 * Shows a simple page count of reserved and used pages in the system.
37 * For discontig machines, it does this on a per-pgdat basis. 37 * For discontig machines, it does this on a per-pgdat basis.
38 */ 38 */
39void show_mem(void) 39void show_mem(unsigned int filter)
40{ 40{
41 int i, total_reserved = 0; 41 int i, total_reserved = 0;
42 int total_shared = 0, total_cached = 0; 42 int total_shared = 0, total_cached = 0;
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 61620323bb60..82ab1bc6afb1 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -614,7 +614,7 @@ void __cpuinit *per_cpu_init(void)
614 * Shows a simple page count of reserved and used pages in the system. 614 * Shows a simple page count of reserved and used pages in the system.
615 * For discontig machines, it does this on a per-pgdat basis. 615 * For discontig machines, it does this on a per-pgdat basis.
616 */ 616 */
617void show_mem(void) 617void show_mem(unsigned int filter)
618{ 618{
619 int i, total_reserved = 0; 619 int i, total_reserved = 0;
620 int total_shared = 0, total_cached = 0; 620 int total_shared = 0, total_cached = 0;
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 10971be43061..d8ab97a73db2 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -3,6 +3,8 @@ config MN10300
3 select HAVE_OPROFILE 3 select HAVE_OPROFILE
4 select HAVE_GENERIC_HARDIRQS 4 select HAVE_GENERIC_HARDIRQS
5 select GENERIC_HARDIRQS_NO_DEPRECATED 5 select GENERIC_HARDIRQS_NO_DEPRECATED
6 select HAVE_ARCH_TRACEHOOK
7 select HAVE_ARCH_KGDB
6 8
7config AM33_2 9config AM33_2
8 def_bool n 10 def_bool n
@@ -401,9 +403,9 @@ comment "[!] NOTE: A lower number/level indicates a higher priority (0 is highes
401comment "____Non-maskable interrupt levels____" 403comment "____Non-maskable interrupt levels____"
402comment "The following must be set to a higher priority than local_irq_disable() and on-chip serial" 404comment "The following must be set to a higher priority than local_irq_disable() and on-chip serial"
403 405
404config GDBSTUB_IRQ_LEVEL 406config DEBUGGER_IRQ_LEVEL
405 int "GDBSTUB interrupt priority" 407 int "DEBUGGER interrupt priority"
406 depends on GDBSTUB 408 depends on KERNEL_DEBUGGER
407 range 0 1 if LINUX_CLI_LEVEL = 2 409 range 0 1 if LINUX_CLI_LEVEL = 2
408 range 0 2 if LINUX_CLI_LEVEL = 3 410 range 0 2 if LINUX_CLI_LEVEL = 3
409 range 0 3 if LINUX_CLI_LEVEL = 4 411 range 0 3 if LINUX_CLI_LEVEL = 4
@@ -437,7 +439,7 @@ config LINUX_CLI_LEVEL
437 EPSW.IM from 7. Any interrupt is permitted for which the level is 439 EPSW.IM from 7. Any interrupt is permitted for which the level is
438 lower than EPSW.IM. 440 lower than EPSW.IM.
439 441
440 Certain interrupts, such as GDBSTUB and virtual MN10300 on-chip 442 Certain interrupts, such as DEBUGGER and virtual MN10300 on-chip
441 serial DMA interrupts are allowed to interrupt normal disabled 443 serial DMA interrupts are allowed to interrupt normal disabled
442 sections. 444 sections.
443 445
diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug
index ce83c74b3fd7..bdbfd444a9ff 100644
--- a/arch/mn10300/Kconfig.debug
+++ b/arch/mn10300/Kconfig.debug
@@ -36,7 +36,7 @@ config KPROBES
36 36
37config GDBSTUB 37config GDBSTUB
38 bool "Remote GDB kernel debugging" 38 bool "Remote GDB kernel debugging"
39 depends on DEBUG_KERNEL 39 depends on DEBUG_KERNEL && DEPRECATED
40 select DEBUG_INFO 40 select DEBUG_INFO
41 select FRAME_POINTER 41 select FRAME_POINTER
42 help 42 help
@@ -46,6 +46,9 @@ config GDBSTUB
46 RAM to avoid excessive linking time. This is only useful for kernel 46 RAM to avoid excessive linking time. This is only useful for kernel
47 hackers. If unsure, say N. 47 hackers. If unsure, say N.
48 48
49 This is deprecated in favour of KGDB and will be removed in a later
50 version.
51
49config GDBSTUB_IMMEDIATE 52config GDBSTUB_IMMEDIATE
50 bool "Break into GDB stub immediately" 53 bool "Break into GDB stub immediately"
51 depends on GDBSTUB 54 depends on GDBSTUB
@@ -54,6 +57,14 @@ config GDBSTUB_IMMEDIATE
54 possible, leaving the program counter at the beginning of 57 possible, leaving the program counter at the beginning of
55 start_kernel() in init/main.c. 58 start_kernel() in init/main.c.
56 59
60config GDBSTUB_ALLOW_SINGLE_STEP
61 bool "Allow software single-stepping in GDB stub"
62 depends on GDBSTUB && !SMP && !PREEMPT
63 help
64 Allow GDB stub to perform software single-stepping through the
65 kernel. This doesn't work very well on SMP or preemptible kernels as
66 it uses temporary breakpoints to emulate single-stepping.
67
57config GDB_CONSOLE 68config GDB_CONSOLE
58 bool "Console output to GDB" 69 bool "Console output to GDB"
59 depends on GDBSTUB 70 depends on GDBSTUB
@@ -142,3 +153,7 @@ config GDBSTUB_ON_TTYSx
142 default y 153 default y
143 154
144endmenu 155endmenu
156
157config KERNEL_DEBUGGER
158 def_bool y
159 depends on GDBSTUB || KGDB
diff --git a/arch/mn10300/include/asm/debugger.h b/arch/mn10300/include/asm/debugger.h
new file mode 100644
index 000000000000..e1d3b083696c
--- /dev/null
+++ b/arch/mn10300/include/asm/debugger.h
@@ -0,0 +1,43 @@
1/* Kernel debugger for MN10300
2 *
3 * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _ASM_DEBUGGER_H
13#define _ASM_DEBUGGER_H
14
15#if defined(CONFIG_KERNEL_DEBUGGER)
16
17extern int debugger_intercept(enum exception_code, int, int, struct pt_regs *);
18extern int at_debugger_breakpoint(struct pt_regs *);
19
20#ifndef CONFIG_MN10300_DEBUGGER_CACHE_NO_FLUSH
21extern void debugger_local_cache_flushinv(void);
22extern void debugger_local_cache_flushinv_one(u8 *);
23#else
24static inline void debugger_local_cache_flushinv(void) {}
25static inline void debugger_local_cache_flushinv_one(u8 *addr) {}
26#endif
27
28#else /* CONFIG_KERNEL_DEBUGGER */
29
30static inline int debugger_intercept(enum exception_code excep,
31 int signo, int si_code,
32 struct pt_regs *regs)
33{
34 return 0;
35}
36
37static inline int at_debugger_breakpoint(struct pt_regs *regs)
38{
39 return 0;
40}
41
42#endif /* CONFIG_KERNEL_DEBUGGER */
43#endif /* _ASM_DEBUGGER_H */
diff --git a/arch/mn10300/include/asm/div64.h b/arch/mn10300/include/asm/div64.h
index 34dcb8e68309..503efab2a516 100644
--- a/arch/mn10300/include/asm/div64.h
+++ b/arch/mn10300/include/asm/div64.h
@@ -16,6 +16,19 @@
16extern void ____unhandled_size_in_do_div___(void); 16extern void ____unhandled_size_in_do_div___(void);
17 17
18/* 18/*
19 * Beginning with gcc 4.6, the MDR register is represented explicitly. We
20 * must, therefore, at least explicitly clobber the register when we make
21 * changes to it. The following assembly fragments *could* be rearranged in
22 * order to leave the moves to/from the MDR register to the compiler, but the
23 * gains would be minimal at best.
24 */
25#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
26# define CLOBBER_MDR_CC "mdr", "cc"
27#else
28# define CLOBBER_MDR_CC "cc"
29#endif
30
31/*
19 * divide n by base, leaving the result in n and returning the remainder 32 * divide n by base, leaving the result in n and returning the remainder
20 * - we can do this quite efficiently on the MN10300 by cascading the divides 33 * - we can do this quite efficiently on the MN10300 by cascading the divides
21 * through the MDR register 34 * through the MDR register
@@ -29,7 +42,7 @@ extern void ____unhandled_size_in_do_div___(void);
29 "mov mdr,%1 \n" \ 42 "mov mdr,%1 \n" \
30 : "+r"(n), "=d"(__rem) \ 43 : "+r"(n), "=d"(__rem) \
31 : "r"(base), "1"(__rem) \ 44 : "r"(base), "1"(__rem) \
32 : "cc" \ 45 : CLOBBER_MDR_CC \
33 ); \ 46 ); \
34 } else if (sizeof(n) <= 8) { \ 47 } else if (sizeof(n) <= 8) { \
35 union { \ 48 union { \
@@ -48,7 +61,7 @@ extern void ____unhandled_size_in_do_div___(void);
48 : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \ 61 : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \
49 : "r"(base), "0"(__rem), "1"(__quot.w[1]), \ 62 : "r"(base), "0"(__rem), "1"(__quot.w[1]), \
50 "2"(__quot.w[0]) \ 63 "2"(__quot.w[0]) \
51 : "cc" \ 64 : CLOBBER_MDR_CC \
52 ); \ 65 ); \
53 n = __quot.l; \ 66 n = __quot.l; \
54 } else { \ 67 } else { \
@@ -72,7 +85,7 @@ unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div)
72 * MDR = MDR:val%div */ 85 * MDR = MDR:val%div */
73 : "=r"(result) 86 : "=r"(result)
74 : "0"(val), "ir"(mult), "r"(div) 87 : "0"(val), "ir"(mult), "r"(div)
75 : "cc" 88 : CLOBBER_MDR_CC
76 ); 89 );
77 90
78 return result; 91 return result;
@@ -93,7 +106,7 @@ signed __muldiv64s(signed val, signed mult, signed div)
93 * MDR = MDR:val%div */ 106 * MDR = MDR:val%div */
94 : "=r"(result) 107 : "=r"(result)
95 : "0"(val), "ir"(mult), "r"(div) 108 : "0"(val), "ir"(mult), "r"(div)
96 : "cc" 109 : CLOBBER_MDR_CC
97 ); 110 );
98 111
99 return result; 112 return result;
diff --git a/arch/mn10300/include/asm/fpu.h b/arch/mn10300/include/asm/fpu.h
index b7625de8eade..738ff72659d5 100644
--- a/arch/mn10300/include/asm/fpu.h
+++ b/arch/mn10300/include/asm/fpu.h
@@ -55,7 +55,6 @@ static inline void clear_using_fpu(struct task_struct *tsk)
55 55
56extern asmlinkage void fpu_kill_state(struct task_struct *); 56extern asmlinkage void fpu_kill_state(struct task_struct *);
57extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code); 57extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code);
58extern asmlinkage void fpu_invalid_op(struct pt_regs *, enum exception_code);
59extern asmlinkage void fpu_init_state(void); 58extern asmlinkage void fpu_init_state(void);
60extern asmlinkage void fpu_save(struct fpu_state_struct *); 59extern asmlinkage void fpu_save(struct fpu_state_struct *);
61extern int fpu_setup_sigcontext(struct fpucontext *buf); 60extern int fpu_setup_sigcontext(struct fpucontext *buf);
@@ -113,7 +112,6 @@ static inline void flush_fpu(void)
113 112
114extern asmlinkage 113extern asmlinkage
115void unexpected_fpu_exception(struct pt_regs *, enum exception_code); 114void unexpected_fpu_exception(struct pt_regs *, enum exception_code);
116#define fpu_invalid_op unexpected_fpu_exception
117#define fpu_exception unexpected_fpu_exception 115#define fpu_exception unexpected_fpu_exception
118 116
119struct task_struct; 117struct task_struct;
diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h
index 7a7ae12c7119..678f68d5f37b 100644
--- a/arch/mn10300/include/asm/irqflags.h
+++ b/arch/mn10300/include/asm/irqflags.h
@@ -20,7 +20,7 @@
20/* 20/*
21 * interrupt control 21 * interrupt control
22 * - "disabled": run in IM1/2 22 * - "disabled": run in IM1/2
23 * - level 0 - GDB stub 23 * - level 0 - kernel debugger
24 * - level 1 - virtual serial DMA (if present) 24 * - level 1 - virtual serial DMA (if present)
25 * - level 5 - normal interrupt priority 25 * - level 5 - normal interrupt priority
26 * - level 6 - timer interrupt 26 * - level 6 - timer interrupt
diff --git a/arch/mn10300/include/asm/kgdb.h b/arch/mn10300/include/asm/kgdb.h
new file mode 100644
index 000000000000..eb245f18a708
--- /dev/null
+++ b/arch/mn10300/include/asm/kgdb.h
@@ -0,0 +1,81 @@
1/* Kernel debugger for MN10300
2 *
3 * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _ASM_KGDB_H
13#define _ASM_KGDB_H
14
15/*
16 * BUFMAX defines the maximum number of characters in inbound/outbound
17 * buffers at least NUMREGBYTES*2 are needed for register packets
18 * Longer buffer is needed to list all threads
19 */
20#define BUFMAX 1024
21
22/*
23 * Note that this register image is in a different order than the register
24 * image that Linux produces at interrupt time.
25 */
26enum regnames {
27 GDB_FR_D0 = 0,
28 GDB_FR_D1 = 1,
29 GDB_FR_D2 = 2,
30 GDB_FR_D3 = 3,
31 GDB_FR_A0 = 4,
32 GDB_FR_A1 = 5,
33 GDB_FR_A2 = 6,
34 GDB_FR_A3 = 7,
35
36 GDB_FR_SP = 8,
37 GDB_FR_PC = 9,
38 GDB_FR_MDR = 10,
39 GDB_FR_EPSW = 11,
40 GDB_FR_LIR = 12,
41 GDB_FR_LAR = 13,
42 GDB_FR_MDRQ = 14,
43
44 GDB_FR_E0 = 15,
45 GDB_FR_E1 = 16,
46 GDB_FR_E2 = 17,
47 GDB_FR_E3 = 18,
48 GDB_FR_E4 = 19,
49 GDB_FR_E5 = 20,
50 GDB_FR_E6 = 21,
51 GDB_FR_E7 = 22,
52
53 GDB_FR_SSP = 23,
54 GDB_FR_MSP = 24,
55 GDB_FR_USP = 25,
56 GDB_FR_MCRH = 26,
57 GDB_FR_MCRL = 27,
58 GDB_FR_MCVF = 28,
59
60 GDB_FR_FPCR = 29,
61 GDB_FR_DUMMY0 = 30,
62 GDB_FR_DUMMY1 = 31,
63
64 GDB_FR_FS0 = 32,
65
66 GDB_FR_SIZE = 64,
67};
68
69#define GDB_ORIG_D0 41
70#define NUMREGBYTES (GDB_FR_SIZE*4)
71
72static inline void arch_kgdb_breakpoint(void)
73{
74 asm(".globl __arch_kgdb_breakpoint; __arch_kgdb_breakpoint: break");
75}
76extern u8 __arch_kgdb_breakpoint;
77
78#define BREAK_INSTR_SIZE 1
79#define CACHE_FLUSH_IS_SAFE 1
80
81#endif /* _ASM_KGDB_H */
diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h
index a3930e43a958..6745dbe64944 100644
--- a/arch/mn10300/include/asm/smp.h
+++ b/arch/mn10300/include/asm/smp.h
@@ -34,7 +34,7 @@
34#define LOCAL_TIMER_IPI 193 34#define LOCAL_TIMER_IPI 193
35#define FLUSH_CACHE_IPI 194 35#define FLUSH_CACHE_IPI 194
36#define CALL_FUNCTION_NMI_IPI 195 36#define CALL_FUNCTION_NMI_IPI 195
37#define GDB_NMI_IPI 196 37#define DEBUGGER_NMI_IPI 196
38 38
39#define SMP_BOOT_IRQ 195 39#define SMP_BOOT_IRQ 195
40 40
@@ -43,6 +43,7 @@
43#define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4 43#define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4
44#define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0 44#define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0
45#define SMP_BOOT_GxICR_LV GxICR_LEVEL_0 45#define SMP_BOOT_GxICR_LV GxICR_LEVEL_0
46#define DEBUGGER_GxICR_LV CONFIG_DEBUGGER_IRQ_LEVEL
46 47
47#define TIME_OUT_COUNT_BOOT_IPI 100 48#define TIME_OUT_COUNT_BOOT_IPI 100
48#define DELAY_TIME_BOOT_IPI 75000 49#define DELAY_TIME_BOOT_IPI 75000
@@ -61,8 +62,9 @@
61 * An alternate way of dealing with this could be to use the EPSW.S bits to 62 * An alternate way of dealing with this could be to use the EPSW.S bits to
62 * cache this information for systems with up to four CPUs. 63 * cache this information for systems with up to four CPUs.
63 */ 64 */
65#define arch_smp_processor_id() (CPUID)
64#if 0 66#if 0
65#define raw_smp_processor_id() (CPUID) 67#define raw_smp_processor_id() (arch_smp_processor_id())
66#else 68#else
67#define raw_smp_processor_id() (current_thread_info()->cpu) 69#define raw_smp_processor_id() (current_thread_info()->cpu)
68#endif 70#endif
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index 8d53f09c878d..87c213002d4c 100644
--- a/arch/mn10300/include/asm/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
@@ -131,7 +131,11 @@ static inline unsigned long current_stack_pointer(void)
131 kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) 131 kmalloc_node(THREAD_SIZE, GFP_KERNEL, node)
132#endif 132#endif
133 133
134#ifndef CONFIG_KGDB
134#define free_thread_info(ti) kfree((ti)) 135#define free_thread_info(ti) kfree((ti))
136#else
137extern void free_thread_info(struct thread_info *);
138#endif
135#define get_thread_info(ti) get_task_struct((ti)->task) 139#define get_thread_info(ti) get_task_struct((ti)->task)
136#define put_thread_info(ti) put_task_struct((ti)->task) 140#define put_thread_info(ti) put_task_struct((ti)->task)
137 141
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
index a06a2e10051d..47ed30fe8178 100644
--- a/arch/mn10300/kernel/Makefile
+++ b/arch/mn10300/kernel/Makefile
@@ -21,11 +21,8 @@ obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-low.o
21obj-$(CONFIG_GDBSTUB_ON_TTYSx) += gdb-io-serial.o gdb-io-serial-low.o 21obj-$(CONFIG_GDBSTUB_ON_TTYSx) += gdb-io-serial.o gdb-io-serial-low.o
22obj-$(CONFIG_GDBSTUB_ON_TTYSMx) += gdb-io-ttysm.o gdb-io-ttysm-low.o 22obj-$(CONFIG_GDBSTUB_ON_TTYSMx) += gdb-io-ttysm.o gdb-io-ttysm-low.o
23 23
24ifeq ($(CONFIG_MN10300_CACHE_ENABLED),y)
25obj-$(CONFIG_GDBSTUB) += gdb-cache.o
26endif
27
28obj-$(CONFIG_MN10300_RTC) += rtc.o 24obj-$(CONFIG_MN10300_RTC) += rtc.o
29obj-$(CONFIG_PROFILE) += profile.o profile-low.o 25obj-$(CONFIG_PROFILE) += profile.o profile-low.o
30obj-$(CONFIG_MODULES) += module.o 26obj-$(CONFIG_MODULES) += module.o
31obj-$(CONFIG_KPROBES) += kprobes.o 27obj-$(CONFIG_KPROBES) += kprobes.o
28obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index f00b9bafcd3e..fb93ad720b82 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -266,7 +266,11 @@ ENTRY(raw_bus_error)
266 266
267############################################################################### 267###############################################################################
268# 268#
269# Miscellaneous exception entry points 269# NMI exception entry points
270#
271# This is used by ordinary interrupt channels that have the GxICR_NMI bit set
272# in addition to the main NMI and Watchdog channels. SMP NMI IPIs use this
273# facility.
270# 274#
271############################################################################### 275###############################################################################
272ENTRY(nmi_handler) 276ENTRY(nmi_handler)
@@ -281,7 +285,7 @@ ENTRY(nmi_handler)
281 and NMIAGR_GN,d0 285 and NMIAGR_GN,d0
282 lsr 0x2,d0 286 lsr 0x2,d0
283 cmp CALL_FUNCTION_NMI_IPI,d0 287 cmp CALL_FUNCTION_NMI_IPI,d0
284 bne 5f # if not call function, jump 288 bne nmi_not_smp_callfunc # if not call function, jump
285 289
286 # function call nmi ipi 290 # function call nmi ipi
287 add 4,sp # no need to store TBR 291 add 4,sp # no need to store TBR
@@ -295,59 +299,38 @@ ENTRY(nmi_handler)
295 call smp_nmi_call_function_interrupt[],0 299 call smp_nmi_call_function_interrupt[],0
296 RESTORE_ALL 300 RESTORE_ALL
297 301
2985: 302nmi_not_smp_callfunc:
299#ifdef CONFIG_GDBSTUB 303#ifdef CONFIG_KERNEL_DEBUGGER
300 cmp GDB_NMI_IPI,d0 304 cmp DEBUGGER_NMI_IPI,d0
301 bne 3f # if not gdb nmi ipi, jump 305 bne nmi_not_debugger # if not kernel debugger NMI IPI, jump
302 306
303 # gdb nmi ipi 307 # kernel debugger NMI IPI
304 add 4,sp # no need to store TBR 308 add 4,sp # no need to store TBR
305 mov GxICR_DETECT,d0 # clear NMI 309 mov GxICR_DETECT,d0 # clear NMI
306 movbu d0,(GxICR(GDB_NMI_IPI)) 310 movbu d0,(GxICR(DEBUGGER_NMI_IPI))
307 movhu (GxICR(GDB_NMI_IPI)),d0 311 movhu (GxICR(DEBUGGER_NMI_IPI)),d0
308 and ~EPSW_NMID,epsw # enable NMI 312 and ~EPSW_NMID,epsw # enable NMI
309#ifdef CONFIG_MN10300_CACHE_ENABLED 313
310 mov (gdbstub_nmi_opr_type),d0
311 cmp GDBSTUB_NMI_CACHE_PURGE,d0
312 bne 4f # if not gdb cache purge, jump
313
314 # gdb cache purge nmi ipi
315 add -20,sp
316 mov d1,(4,sp)
317 mov a0,(8,sp)
318 mov a1,(12,sp)
319 mov mdr,d0
320 mov d0,(16,sp)
321 call gdbstub_local_purge_cache[],0
322 mov 0x1,d0
323 mov (CPUID),d1
324 asl d1,d0
325 mov gdbstub_nmi_cpumask,a0
326 bclr d0,(a0)
327 mov (4,sp),d1
328 mov (8,sp),a0
329 mov (12,sp),a1
330 mov (16,sp),d0
331 mov d0,mdr
332 add 20,sp
333 mov (sp),d0
334 add 4,sp
335 rti
3364:
337#endif /* CONFIG_MN10300_CACHE_ENABLED */
338 # gdb wait nmi ipi
339 mov (sp),d0 314 mov (sp),d0
340 SAVE_ALL 315 SAVE_ALL
341 call gdbstub_nmi_wait[],0 316 mov fp,d0 # arg 0: stacked register file
317 mov a2,d1 # arg 1: exception number
318 call debugger_nmi_interrupt[],0
342 RESTORE_ALL 319 RESTORE_ALL
3433: 320
344#endif /* CONFIG_GDBSTUB */ 321nmi_not_debugger:
322#endif /* CONFIG_KERNEL_DEBUGGER */
345 mov (sp),d0 # restore TBR to d0 323 mov (sp),d0 # restore TBR to d0
346 add 4,sp 324 add 4,sp
347#endif /* CONFIG_SMP */ 325#endif /* CONFIG_SMP */
348 326
349 bra __common_exception_nonmi 327 bra __common_exception_nonmi
350 328
329###############################################################################
330#
331# General exception entry point
332#
333###############################################################################
351ENTRY(__common_exception) 334ENTRY(__common_exception)
352 add -4,sp 335 add -4,sp
353 mov d0,(sp) 336 mov d0,(sp)
diff --git a/arch/mn10300/kernel/fpu.c b/arch/mn10300/kernel/fpu.c
index 5f9c3fa19a85..bb5fa7df6c44 100644
--- a/arch/mn10300/kernel/fpu.c
+++ b/arch/mn10300/kernel/fpu.c
@@ -70,24 +70,6 @@ asmlinkage void fpu_exception(struct pt_regs *regs, enum exception_code code)
70} 70}
71 71
72/* 72/*
73 * handle an FPU invalid_op exception
74 * - Derived from DO_EINFO() macro in arch/mn10300/kernel/traps.c
75 */
76asmlinkage void fpu_invalid_op(struct pt_regs *regs, enum exception_code code)
77{
78 siginfo_t info;
79
80 if (!user_mode(regs))
81 die_if_no_fixup("FPU invalid opcode", regs, code);
82
83 info.si_signo = SIGILL;
84 info.si_errno = 0;
85 info.si_code = ILL_COPROC;
86 info.si_addr = (void *) regs->pc;
87 force_sig_info(info.si_signo, &info, current);
88}
89
90/*
91 * save the FPU state to a signal context 73 * save the FPU state to a signal context
92 */ 74 */
93int fpu_setup_sigcontext(struct fpucontext *fpucontext) 75int fpu_setup_sigcontext(struct fpucontext *fpucontext)
diff --git a/arch/mn10300/kernel/gdb-cache.S b/arch/mn10300/kernel/gdb-cache.S
deleted file mode 100644
index 1108badc3d32..000000000000
--- a/arch/mn10300/kernel/gdb-cache.S
+++ /dev/null
@@ -1,105 +0,0 @@
1###############################################################################
2#
3# MN10300 Low-level cache purging routines for gdbstub
4#
5# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
6# Written by David Howells (dhowells@redhat.com)
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public Licence
10# as published by the Free Software Foundation; either version
11# 2 of the Licence, or (at your option) any later version.
12#
13###############################################################################
14#include <linux/sys.h>
15#include <linux/linkage.h>
16#include <asm/smp.h>
17#include <asm/cache.h>
18#include <asm/cpu-regs.h>
19#include <asm/exceptions.h>
20#include <asm/frame.inc>
21#include <asm/serial-regs.h>
22
23 .text
24
25###############################################################################
26#
27# GDB stub cache purge
28#
29###############################################################################
30 .type gdbstub_purge_cache,@function
31ENTRY(gdbstub_purge_cache)
32 #######################################################################
33 # read the addresses tagged in the cache's tag RAM and attempt to flush
34 # those addresses specifically
35 # - we rely on the hardware to filter out invalid tag entry addresses
36 mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address
37 mov DCACHE_PURGE(0,0),a1 # dcache purge request address
38 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
39
40mn10300_dcache_flush_loop:
41 mov (a0),d0
42 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
43 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
44 # cache
45 mov d0,(a1) # conditional purge
46
47mn10300_dcache_flush_skip:
48 add L1_CACHE_BYTES,a0
49 add L1_CACHE_BYTES,a1
50 add -1,d1
51 bne mn10300_dcache_flush_loop
52
53;; # unconditionally flush and invalidate the dcache
54;; mov DCACHE_PURGE(0,0),a1 # dcache purge request address
55;; mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of
56;; # entries
57;;
58;; gdbstub_purge_cache__dcache_loop:
59;; mov (a1),d0 # unconditional purge
60;;
61;; add L1_CACHE_BYTES,a1
62;; add -1,d1
63;; bne gdbstub_purge_cache__dcache_loop
64
65 #######################################################################
66 # now invalidate the icache
67 mov CHCTR,a0
68 movhu (a0),a1
69
70 mov epsw,d1
71 and ~EPSW_IE,epsw
72 nop
73 nop
74
75 # disable the icache
76 and ~CHCTR_ICEN,d0
77 movhu d0,(a0)
78
79 # and wait for it to calm down
80 setlb
81 movhu (a0),d0
82 btst CHCTR_ICBUSY,d0
83 lne
84
85 # invalidate
86 or CHCTR_ICINV,d0
87 movhu d0,(a0)
88
89 # wait for the cache to finish
90 mov CHCTR,a0
91 setlb
92 movhu (a0),d0
93 btst CHCTR_ICBUSY,d0
94 lne
95
96 # and reenable it
97 movhu a1,(a0)
98 movhu (a0),d0 # read back to flush
99 # (SIGILLs all over without this)
100
101 mov d1,epsw
102
103 ret [],0
104
105 .size gdbstub_purge_cache,.-gdbstub_purge_cache
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
index abdeea153c89..c859cacbb9c3 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ b/arch/mn10300/kernel/gdb-io-ttysm.c
@@ -59,10 +59,10 @@ void __init gdbstub_io_init(void)
59 59
60 /* we want to get serial receive interrupts */ 60 /* we want to get serial receive interrupts */
61 set_intr_level(gdbstub_port->rx_irq, 61 set_intr_level(gdbstub_port->rx_irq,
62 NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL)); 62 NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
63 set_intr_level(gdbstub_port->tx_irq, 63 set_intr_level(gdbstub_port->tx_irq,
64 NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL)); 64 NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
65 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL), 65 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL),
66 gdbstub_io_rx_handler); 66 gdbstub_io_rx_handler);
67 67
68 *gdbstub_port->rx_icr |= GxICR_ENABLE; 68 *gdbstub_port->rx_icr |= GxICR_ENABLE;
@@ -88,7 +88,7 @@ void __init gdbstub_io_init(void)
88 88
89 /* permit level 0 IRQs only */ 89 /* permit level 0 IRQs only */
90 arch_local_change_intr_mask_level( 90 arch_local_change_intr_mask_level(
91 NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); 91 NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
92} 92}
93 93
94/* 94/*
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
index b169d99d9f20..538266b2c9bc 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -133,7 +133,7 @@
133#include <asm/system.h> 133#include <asm/system.h>
134#include <asm/gdb-stub.h> 134#include <asm/gdb-stub.h>
135#include <asm/exceptions.h> 135#include <asm/exceptions.h>
136#include <asm/cacheflush.h> 136#include <asm/debugger.h>
137#include <asm/serial-regs.h> 137#include <asm/serial-regs.h>
138#include <asm/busctl-regs.h> 138#include <asm/busctl-regs.h>
139#include <unit/leds.h> 139#include <unit/leds.h>
@@ -405,6 +405,7 @@ static int hexToInt(char **ptr, int *intValue)
405 return (numChars); 405 return (numChars);
406} 406}
407 407
408#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
408/* 409/*
409 * We single-step by setting breakpoints. When an exception 410 * We single-step by setting breakpoints. When an exception
410 * is handled, we need to restore the instructions hoisted 411 * is handled, we need to restore the instructions hoisted
@@ -729,6 +730,7 @@ static int gdbstub_single_step(struct pt_regs *regs)
729 __gdbstub_restore_bp(); 730 __gdbstub_restore_bp();
730 return -EFAULT; 731 return -EFAULT;
731} 732}
733#endif /* CONFIG_GDBSTUB_ALLOW_SINGLE_STEP */
732 734
733#ifdef CONFIG_GDBSTUB_CONSOLE 735#ifdef CONFIG_GDBSTUB_CONSOLE
734 736
@@ -1171,7 +1173,7 @@ int gdbstub_clear_breakpoint(u8 *addr, int len)
1171 1173
1172/* 1174/*
1173 * This function does all command processing for interfacing to gdb 1175 * This function does all command processing for interfacing to gdb
1174 * - returns 1 if the exception should be skipped, 0 otherwise. 1176 * - returns 0 if the exception should be skipped, -ERROR otherwise.
1175 */ 1177 */
1176static int gdbstub(struct pt_regs *regs, enum exception_code excep) 1178static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1177{ 1179{
@@ -1186,7 +1188,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1186 int loop; 1188 int loop;
1187 1189
1188 if (excep == EXCEP_FPU_DISABLED) 1190 if (excep == EXCEP_FPU_DISABLED)
1189 return 0; 1191 return -ENOTSUPP;
1190 1192
1191 gdbstub_flush_caches = 0; 1193 gdbstub_flush_caches = 0;
1192 1194
@@ -1195,7 +1197,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1195 asm volatile("mov mdr,%0" : "=d"(mdr)); 1197 asm volatile("mov mdr,%0" : "=d"(mdr));
1196 local_save_flags(epsw); 1198 local_save_flags(epsw);
1197 arch_local_change_intr_mask_level( 1199 arch_local_change_intr_mask_level(
1198 NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); 1200 NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
1199 1201
1200 gdbstub_store_fpu(); 1202 gdbstub_store_fpu();
1201 1203
@@ -1208,11 +1210,13 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1208 /* if we were single stepping, restore the opcodes hoisted for the 1210 /* if we were single stepping, restore the opcodes hoisted for the
1209 * breakpoint[s] */ 1211 * breakpoint[s] */
1210 broke = 0; 1212 broke = 0;
1213#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
1211 if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) || 1214 if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) ||
1212 (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc)) 1215 (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc))
1213 broke = 1; 1216 broke = 1;
1214 1217
1215 __gdbstub_restore_bp(); 1218 __gdbstub_restore_bp();
1219#endif
1216 1220
1217 if (gdbstub_rx_unget) { 1221 if (gdbstub_rx_unget) {
1218 sigval = SIGINT; 1222 sigval = SIGINT;
@@ -1548,17 +1552,21 @@ packet_waiting:
1548 * Step to next instruction 1552 * Step to next instruction
1549 */ 1553 */
1550 case 's': 1554 case 's':
1551 /* 1555 /* Using the T flag doesn't seem to perform single
1552 * using the T flag doesn't seem to perform single
1553 * stepping (it seems to wind up being caught by the 1556 * stepping (it seems to wind up being caught by the
1554 * JTAG unit), so we have to use breakpoints and 1557 * JTAG unit), so we have to use breakpoints and
1555 * continue instead. 1558 * continue instead.
1556 */ 1559 */
1560#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
1557 if (gdbstub_single_step(regs) < 0) 1561 if (gdbstub_single_step(regs) < 0)
1558 /* ignore any fault error for now */ 1562 /* ignore any fault error for now */
1559 gdbstub_printk("unable to set single-step" 1563 gdbstub_printk("unable to set single-step"
1560 " bp\n"); 1564 " bp\n");
1561 goto done; 1565 goto done;
1566#else
1567 gdbstub_strcpy(output_buffer, "E01");
1568 break;
1569#endif
1562 1570
1563 /* 1571 /*
1564 * Set baud rate (bBB) 1572 * Set baud rate (bBB)
@@ -1657,7 +1665,7 @@ done:
1657 * NB: We flush both caches, just to be sure... 1665 * NB: We flush both caches, just to be sure...
1658 */ 1666 */
1659 if (gdbstub_flush_caches) 1667 if (gdbstub_flush_caches)
1660 gdbstub_purge_cache(); 1668 debugger_local_cache_flushinv();
1661 1669
1662 gdbstub_load_fpu(); 1670 gdbstub_load_fpu();
1663 mn10300_set_gdbleds(0); 1671 mn10300_set_gdbleds(0);
@@ -1667,14 +1675,23 @@ done:
1667 touch_softlockup_watchdog(); 1675 touch_softlockup_watchdog();
1668 1676
1669 local_irq_restore(epsw); 1677 local_irq_restore(epsw);
1670 return 1; 1678 return 0;
1679}
1680
1681/*
1682 * Determine if we hit a debugger special breakpoint that needs skipping over
1683 * automatically.
1684 */
1685int at_debugger_breakpoint(struct pt_regs *regs)
1686{
1687 return 0;
1671} 1688}
1672 1689
1673/* 1690/*
1674 * handle event interception 1691 * handle event interception
1675 */ 1692 */
1676asmlinkage int gdbstub_intercept(struct pt_regs *regs, 1693asmlinkage int debugger_intercept(enum exception_code excep,
1677 enum exception_code excep) 1694 int signo, int si_code, struct pt_regs *regs)
1678{ 1695{
1679 static u8 notfirst = 1; 1696 static u8 notfirst = 1;
1680 int ret; 1697 int ret;
@@ -1688,7 +1705,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
1688 asm("mov mdr,%0" : "=d"(mdr)); 1705 asm("mov mdr,%0" : "=d"(mdr));
1689 1706
1690 gdbstub_entry( 1707 gdbstub_entry(
1691 "--> gdbstub_intercept(%p,%04x) [MDR=%lx PC=%lx]\n", 1708 "--> debugger_intercept(%p,%04x) [MDR=%lx PC=%lx]\n",
1692 regs, excep, mdr, regs->pc); 1709 regs, excep, mdr, regs->pc);
1693 1710
1694 gdbstub_entry( 1711 gdbstub_entry(
@@ -1722,7 +1739,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
1722 1739
1723 ret = gdbstub(regs, excep); 1740 ret = gdbstub(regs, excep);
1724 1741
1725 gdbstub_entry("<-- gdbstub_intercept()\n"); 1742 gdbstub_entry("<-- debugger_intercept()\n");
1726 gdbstub_busy = 0; 1743 gdbstub_busy = 0;
1727 return ret; 1744 return ret;
1728} 1745}
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
index ea946613f46d..a5ac755dd69f 100644
--- a/arch/mn10300/kernel/internal.h
+++ b/arch/mn10300/kernel/internal.h
@@ -30,6 +30,13 @@ extern void mn10300_low_ipi_handler(void);
30#endif 30#endif
31 31
32/* 32/*
33 * smp.c
34 */
35#ifdef CONFIG_SMP
36extern void smp_jump_to_debugger(void);
37#endif
38
39/*
33 * time.c 40 * time.c
34 */ 41 */
35extern irqreturn_t local_timer_interrupt(void); 42extern irqreturn_t local_timer_interrupt(void);
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index f09fed5e6afc..5f7fc3eb45e6 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -153,7 +153,7 @@ mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask,
153 case LOCAL_TIMER_IPI: 153 case LOCAL_TIMER_IPI:
154 case FLUSH_CACHE_IPI: 154 case FLUSH_CACHE_IPI:
155 case CALL_FUNCTION_NMI_IPI: 155 case CALL_FUNCTION_NMI_IPI:
156 case GDB_NMI_IPI: 156 case DEBUGGER_NMI_IPI:
157#ifdef CONFIG_MN10300_TTYSM0 157#ifdef CONFIG_MN10300_TTYSM0
158 case SC0RXIRQ: 158 case SC0RXIRQ:
159 case SC0TXIRQ: 159 case SC0TXIRQ:
diff --git a/arch/mn10300/kernel/kgdb.c b/arch/mn10300/kernel/kgdb.c
new file mode 100644
index 000000000000..f6c981db2a36
--- /dev/null
+++ b/arch/mn10300/kernel/kgdb.c
@@ -0,0 +1,502 @@
1/* kgdb support for MN10300
2 *
3 * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/slab.h>
13#include <linux/ptrace.h>
14#include <linux/kgdb.h>
15#include <linux/uaccess.h>
16#include <unit/leds.h>
17#include <unit/serial.h>
18#include <asm/debugger.h>
19#include <asm/serial-regs.h>
20#include "internal.h"
21
22/*
23 * Software single-stepping breakpoint save (used by __switch_to())
24 */
25static struct thread_info *kgdb_sstep_thread;
26u8 *kgdb_sstep_bp_addr[2];
27u8 kgdb_sstep_bp[2];
28
29/*
30 * Copy kernel exception frame registers to the GDB register file
31 */
32void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
33{
34 unsigned long ssp = (unsigned long) (regs + 1);
35
36 gdb_regs[GDB_FR_D0] = regs->d0;
37 gdb_regs[GDB_FR_D1] = regs->d1;
38 gdb_regs[GDB_FR_D2] = regs->d2;
39 gdb_regs[GDB_FR_D3] = regs->d3;
40 gdb_regs[GDB_FR_A0] = regs->a0;
41 gdb_regs[GDB_FR_A1] = regs->a1;
42 gdb_regs[GDB_FR_A2] = regs->a2;
43 gdb_regs[GDB_FR_A3] = regs->a3;
44 gdb_regs[GDB_FR_SP] = (regs->epsw & EPSW_nSL) ? regs->sp : ssp;
45 gdb_regs[GDB_FR_PC] = regs->pc;
46 gdb_regs[GDB_FR_MDR] = regs->mdr;
47 gdb_regs[GDB_FR_EPSW] = regs->epsw;
48 gdb_regs[GDB_FR_LIR] = regs->lir;
49 gdb_regs[GDB_FR_LAR] = regs->lar;
50 gdb_regs[GDB_FR_MDRQ] = regs->mdrq;
51 gdb_regs[GDB_FR_E0] = regs->e0;
52 gdb_regs[GDB_FR_E1] = regs->e1;
53 gdb_regs[GDB_FR_E2] = regs->e2;
54 gdb_regs[GDB_FR_E3] = regs->e3;
55 gdb_regs[GDB_FR_E4] = regs->e4;
56 gdb_regs[GDB_FR_E5] = regs->e5;
57 gdb_regs[GDB_FR_E6] = regs->e6;
58 gdb_regs[GDB_FR_E7] = regs->e7;
59 gdb_regs[GDB_FR_SSP] = ssp;
60 gdb_regs[GDB_FR_MSP] = 0;
61 gdb_regs[GDB_FR_USP] = regs->sp;
62 gdb_regs[GDB_FR_MCRH] = regs->mcrh;
63 gdb_regs[GDB_FR_MCRL] = regs->mcrl;
64 gdb_regs[GDB_FR_MCVF] = regs->mcvf;
65 gdb_regs[GDB_FR_DUMMY0] = 0;
66 gdb_regs[GDB_FR_DUMMY1] = 0;
67 gdb_regs[GDB_FR_FS0] = 0;
68}
69
70/*
71 * Extracts kernel SP/PC values understandable by gdb from the values
72 * saved by switch_to().
73 */
74void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
75{
76 gdb_regs[GDB_FR_SSP] = p->thread.sp;
77 gdb_regs[GDB_FR_PC] = p->thread.pc;
78 gdb_regs[GDB_FR_A3] = p->thread.a3;
79 gdb_regs[GDB_FR_USP] = p->thread.usp;
80 gdb_regs[GDB_FR_FPCR] = p->thread.fpu_state.fpcr;
81}
82
83/*
84 * Fill kernel exception frame registers from the GDB register file
85 */
86void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
87{
88 regs->d0 = gdb_regs[GDB_FR_D0];
89 regs->d1 = gdb_regs[GDB_FR_D1];
90 regs->d2 = gdb_regs[GDB_FR_D2];
91 regs->d3 = gdb_regs[GDB_FR_D3];
92 regs->a0 = gdb_regs[GDB_FR_A0];
93 regs->a1 = gdb_regs[GDB_FR_A1];
94 regs->a2 = gdb_regs[GDB_FR_A2];
95 regs->a3 = gdb_regs[GDB_FR_A3];
96 regs->sp = gdb_regs[GDB_FR_SP];
97 regs->pc = gdb_regs[GDB_FR_PC];
98 regs->mdr = gdb_regs[GDB_FR_MDR];
99 regs->epsw = gdb_regs[GDB_FR_EPSW];
100 regs->lir = gdb_regs[GDB_FR_LIR];
101 regs->lar = gdb_regs[GDB_FR_LAR];
102 regs->mdrq = gdb_regs[GDB_FR_MDRQ];
103 regs->e0 = gdb_regs[GDB_FR_E0];
104 regs->e1 = gdb_regs[GDB_FR_E1];
105 regs->e2 = gdb_regs[GDB_FR_E2];
106 regs->e3 = gdb_regs[GDB_FR_E3];
107 regs->e4 = gdb_regs[GDB_FR_E4];
108 regs->e5 = gdb_regs[GDB_FR_E5];
109 regs->e6 = gdb_regs[GDB_FR_E6];
110 regs->e7 = gdb_regs[GDB_FR_E7];
111 regs->sp = gdb_regs[GDB_FR_SSP];
112 /* gdb_regs[GDB_FR_MSP]; */
113 // regs->usp = gdb_regs[GDB_FR_USP];
114 regs->mcrh = gdb_regs[GDB_FR_MCRH];
115 regs->mcrl = gdb_regs[GDB_FR_MCRL];
116 regs->mcvf = gdb_regs[GDB_FR_MCVF];
117 /* gdb_regs[GDB_FR_DUMMY0]; */
118 /* gdb_regs[GDB_FR_DUMMY1]; */
119
120 // regs->fpcr = gdb_regs[GDB_FR_FPCR];
121 // regs->fs0 = gdb_regs[GDB_FR_FS0];
122}
123
124struct kgdb_arch arch_kgdb_ops = {
125 .gdb_bpt_instr = { 0xff },
126 .flags = KGDB_HW_BREAKPOINT,
127};
128
129static const unsigned char mn10300_kgdb_insn_sizes[256] =
130{
131 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
132 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, /* 0 */
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
134 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */
135 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */
136 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */
137 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */
138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
140 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */
141 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */
142 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */
143 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */
144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
146 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
147 0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1 /* f */
148};
149
150/*
151 * Attempt to emulate single stepping by means of breakpoint instructions.
152 * Although there is a single-step trace flag in EPSW, its use is not
153 * sufficiently documented and is only intended for use with the JTAG debugger.
154 */
155static int kgdb_arch_do_singlestep(struct pt_regs *regs)
156{
157 unsigned long arg;
158 unsigned size;
159 u8 *pc = (u8 *)regs->pc, *sp = (u8 *)(regs + 1), cur;
160 u8 *x = NULL, *y = NULL;
161 int ret;
162
163 ret = probe_kernel_read(&cur, pc, 1);
164 if (ret < 0)
165 return ret;
166
167 size = mn10300_kgdb_insn_sizes[cur];
168 if (size > 0) {
169 x = pc + size;
170 goto set_x;
171 }
172
173 switch (cur) {
174 /* Bxx (d8,PC) */
175 case 0xc0 ... 0xca:
176 ret = probe_kernel_read(&arg, pc + 1, 1);
177 if (ret < 0)
178 return ret;
179 x = pc + 2;
180 if (arg >= 0 && arg <= 2)
181 goto set_x;
182 y = pc + (s8)arg;
183 goto set_x_and_y;
184
185 /* LXX (d8,PC) */
186 case 0xd0 ... 0xda:
187 x = pc + 1;
188 if (regs->pc == regs->lar)
189 goto set_x;
190 y = (u8 *)regs->lar;
191 goto set_x_and_y;
192
193 /* SETLB - loads the next four bytes into the LIR register
194 * (which mustn't include a breakpoint instruction) */
195 case 0xdb:
196 x = pc + 5;
197 goto set_x;
198
199 /* JMP (d16,PC) or CALL (d16,PC) */
200 case 0xcc:
201 case 0xcd:
202 ret = probe_kernel_read(&arg, pc + 1, 2);
203 if (ret < 0)
204 return ret;
205 x = pc + (s16)arg;
206 goto set_x;
207
208 /* JMP (d32,PC) or CALL (d32,PC) */
209 case 0xdc:
210 case 0xdd:
211 ret = probe_kernel_read(&arg, pc + 1, 4);
212 if (ret < 0)
213 return ret;
214 x = pc + (s32)arg;
215 goto set_x;
216
217 /* RETF */
218 case 0xde:
219 x = (u8 *)regs->mdr;
220 goto set_x;
221
222 /* RET */
223 case 0xdf:
224 ret = probe_kernel_read(&arg, pc + 2, 1);
225 if (ret < 0)
226 return ret;
227 ret = probe_kernel_read(&x, sp + (s8)arg, 4);
228 if (ret < 0)
229 return ret;
230 goto set_x;
231
232 case 0xf0:
233 ret = probe_kernel_read(&cur, pc + 1, 1);
234 if (ret < 0)
235 return ret;
236
237 if (cur >= 0xf0 && cur <= 0xf7) {
238 /* JMP (An) / CALLS (An) */
239 switch (cur & 3) {
240 case 0: x = (u8 *)regs->a0; break;
241 case 1: x = (u8 *)regs->a1; break;
242 case 2: x = (u8 *)regs->a2; break;
243 case 3: x = (u8 *)regs->a3; break;
244 }
245 goto set_x;
246 } else if (cur == 0xfc) {
247 /* RETS */
248 ret = probe_kernel_read(&x, sp, 4);
249 if (ret < 0)
250 return ret;
251 goto set_x;
252 } else if (cur == 0xfd) {
253 /* RTI */
254 ret = probe_kernel_read(&x, sp + 4, 4);
255 if (ret < 0)
256 return ret;
257 goto set_x;
258 } else {
259 x = pc + 2;
260 goto set_x;
261 }
262 break;
263
264 /* potential 3-byte conditional branches */
265 case 0xf8:
266 ret = probe_kernel_read(&cur, pc + 1, 1);
267 if (ret < 0)
268 return ret;
269 x = pc + 3;
270
271 if (cur >= 0xe8 && cur <= 0xeb) {
272 ret = probe_kernel_read(&arg, pc + 2, 1);
273 if (ret < 0)
274 return ret;
275 if (arg >= 0 && arg <= 3)
276 goto set_x;
277 y = pc + (s8)arg;
278 goto set_x_and_y;
279 }
280 goto set_x;
281
282 case 0xfa:
283 ret = probe_kernel_read(&cur, pc + 1, 1);
284 if (ret < 0)
285 return ret;
286
287 if (cur == 0xff) {
288 /* CALLS (d16,PC) */
289 ret = probe_kernel_read(&arg, pc + 2, 2);
290 if (ret < 0)
291 return ret;
292 x = pc + (s16)arg;
293 goto set_x;
294 }
295
296 x = pc + 4;
297 goto set_x;
298
299 case 0xfc:
300 ret = probe_kernel_read(&cur, pc + 1, 1);
301 if (ret < 0)
302 return ret;
303
304 if (cur == 0xff) {
305 /* CALLS (d32,PC) */
306 ret = probe_kernel_read(&arg, pc + 2, 4);
307 if (ret < 0)
308 return ret;
309 x = pc + (s32)arg;
310 goto set_x;
311 }
312
313 x = pc + 6;
314 goto set_x;
315 }
316
317 return 0;
318
319set_x:
320 kgdb_sstep_bp_addr[0] = x;
321 kgdb_sstep_bp_addr[1] = NULL;
322 ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
323 if (ret < 0)
324 return ret;
325 ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
326 if (ret < 0)
327 return ret;
328 kgdb_sstep_thread = current_thread_info();
329 debugger_local_cache_flushinv_one(x);
330 return ret;
331
332set_x_and_y:
333 kgdb_sstep_bp_addr[0] = x;
334 kgdb_sstep_bp_addr[1] = y;
335 ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
336 if (ret < 0)
337 return ret;
338 ret = probe_kernel_read(&kgdb_sstep_bp[1], y, 1);
339 if (ret < 0)
340 return ret;
341 ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
342 if (ret < 0)
343 return ret;
344 ret = probe_kernel_write(y, &arch_kgdb_ops.gdb_bpt_instr, 1);
345 if (ret < 0) {
346 probe_kernel_write(kgdb_sstep_bp_addr[0],
347 &kgdb_sstep_bp[0], 1);
348 } else {
349 kgdb_sstep_thread = current_thread_info();
350 }
351 debugger_local_cache_flushinv_one(x);
352 debugger_local_cache_flushinv_one(y);
353 return ret;
354}
355
356/*
357 * Remove emplaced single-step breakpoints, returning true if we hit one of
358 * them.
359 */
360static bool kgdb_arch_undo_singlestep(struct pt_regs *regs)
361{
362 bool hit = false;
363 u8 *x = kgdb_sstep_bp_addr[0], *y = kgdb_sstep_bp_addr[1];
364 u8 opcode;
365
366 if (kgdb_sstep_thread == current_thread_info()) {
367 if (x) {
368 if (x == (u8 *)regs->pc)
369 hit = true;
370 if (probe_kernel_read(&opcode, x,
371 1) < 0 ||
372 opcode != 0xff)
373 BUG();
374 probe_kernel_write(x, &kgdb_sstep_bp[0], 1);
375 debugger_local_cache_flushinv_one(x);
376 }
377 if (y) {
378 if (y == (u8 *)regs->pc)
379 hit = true;
380 if (probe_kernel_read(&opcode, y,
381 1) < 0 ||
382 opcode != 0xff)
383 BUG();
384 probe_kernel_write(y, &kgdb_sstep_bp[1], 1);
385 debugger_local_cache_flushinv_one(y);
386 }
387 }
388
389 kgdb_sstep_bp_addr[0] = NULL;
390 kgdb_sstep_bp_addr[1] = NULL;
391 kgdb_sstep_thread = NULL;
392 return hit;
393}
394
395/*
396 * Catch a single-step-pending thread being deleted and make sure the global
397 * single-step state is cleared. At this point the breakpoints should have
398 * been removed by __switch_to().
399 */
400void free_thread_info(struct thread_info *ti)
401{
402 if (kgdb_sstep_thread == ti) {
403 kgdb_sstep_thread = NULL;
404
405 /* However, we may now be running in degraded mode, with most
406 * of the CPUs disabled until such a time as KGDB is reentered,
407 * so force immediate reentry */
408 kgdb_breakpoint();
409 }
410 kfree(ti);
411}
412
413/*
414 * Handle unknown packets and [CcsDk] packets
415 * - at this point breakpoints have been installed
416 */
417int kgdb_arch_handle_exception(int vector, int signo, int err_code,
418 char *remcom_in_buffer, char *remcom_out_buffer,
419 struct pt_regs *regs)
420{
421 long addr;
422 char *ptr;
423
424 switch (remcom_in_buffer[0]) {
425 case 'c':
426 case 's':
427 /* try to read optional parameter, pc unchanged if no parm */
428 ptr = &remcom_in_buffer[1];
429 if (kgdb_hex2long(&ptr, &addr))
430 regs->pc = addr;
431 case 'D':
432 case 'k':
433 atomic_set(&kgdb_cpu_doing_single_step, -1);
434
435 if (remcom_in_buffer[0] == 's') {
436 kgdb_arch_do_singlestep(regs);
437 kgdb_single_step = 1;
438 atomic_set(&kgdb_cpu_doing_single_step,
439 raw_smp_processor_id());
440 }
441 return 0;
442 }
443 return -1; /* this means that we do not want to exit from the handler */
444}
445
446/*
447 * Handle event interception
448 * - returns 0 if the exception should be skipped, -ERROR otherwise.
449 */
450int debugger_intercept(enum exception_code excep, int signo, int si_code,
451 struct pt_regs *regs)
452{
453 int ret;
454
455 if (kgdb_arch_undo_singlestep(regs)) {
456 excep = EXCEP_TRAP;
457 signo = SIGTRAP;
458 si_code = TRAP_TRACE;
459 }
460
461 ret = kgdb_handle_exception(excep, signo, si_code, regs);
462
463 debugger_local_cache_flushinv();
464
465 return ret;
466}
467
468/*
469 * Determine if we've hit a debugger special breakpoint
470 */
471int at_debugger_breakpoint(struct pt_regs *regs)
472{
473 return regs->pc == (unsigned long)&__arch_kgdb_breakpoint;
474}
475
476/*
477 * Initialise kgdb
478 */
479int kgdb_arch_init(void)
480{
481 return 0;
482}
483
484/*
485 * Do something, perhaps, but don't know what.
486 */
487void kgdb_arch_exit(void)
488{
489}
490
491#ifdef CONFIG_SMP
492void debugger_nmi_interrupt(struct pt_regs *regs, enum exception_code code)
493{
494 kgdb_nmicallback(arch_smp_processor_id(), regs);
495 debugger_local_cache_flushinv();
496}
497
498void kgdb_roundup_cpus(unsigned long flags)
499{
500 smp_jump_to_debugger();
501}
502#endif
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index 93c53739cfc9..efca426a2ed4 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -119,6 +119,10 @@ static int mn10300_serial_request_port(struct uart_port *);
119static void mn10300_serial_config_port(struct uart_port *, int); 119static void mn10300_serial_config_port(struct uart_port *, int);
120static int mn10300_serial_verify_port(struct uart_port *, 120static int mn10300_serial_verify_port(struct uart_port *,
121 struct serial_struct *); 121 struct serial_struct *);
122#ifdef CONFIG_CONSOLE_POLL
123static void mn10300_serial_poll_put_char(struct uart_port *, unsigned char);
124static int mn10300_serial_poll_get_char(struct uart_port *);
125#endif
122 126
123static const struct uart_ops mn10300_serial_ops = { 127static const struct uart_ops mn10300_serial_ops = {
124 .tx_empty = mn10300_serial_tx_empty, 128 .tx_empty = mn10300_serial_tx_empty,
@@ -138,6 +142,10 @@ static const struct uart_ops mn10300_serial_ops = {
138 .request_port = mn10300_serial_request_port, 142 .request_port = mn10300_serial_request_port,
139 .config_port = mn10300_serial_config_port, 143 .config_port = mn10300_serial_config_port,
140 .verify_port = mn10300_serial_verify_port, 144 .verify_port = mn10300_serial_verify_port,
145#ifdef CONFIG_CONSOLE_POLL
146 .poll_put_char = mn10300_serial_poll_put_char,
147 .poll_get_char = mn10300_serial_poll_get_char,
148#endif
141}; 149};
142 150
143static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id); 151static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id);
@@ -1634,3 +1642,70 @@ static int __init mn10300_serial_console_init(void)
1634 1642
1635console_initcall(mn10300_serial_console_init); 1643console_initcall(mn10300_serial_console_init);
1636#endif 1644#endif
1645
1646#ifdef CONFIG_CONSOLE_POLL
1647/*
1648 * Polled character reception for the kernel debugger
1649 */
1650static int mn10300_serial_poll_get_char(struct uart_port *_port)
1651{
1652 struct mn10300_serial_port *port =
1653 container_of(_port, struct mn10300_serial_port, uart);
1654 unsigned ix;
1655 u8 st, ch;
1656
1657 _enter("%s", port->name);
1658
1659 do {
1660 /* pull chars out of the hat */
1661 ix = port->rx_outp;
1662 if (ix == port->rx_inp)
1663 return NO_POLL_CHAR;
1664
1665 ch = port->rx_buffer[ix++];
1666 st = port->rx_buffer[ix++];
1667 smp_rmb();
1668 port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
1669
1670 } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));
1671
1672 return ch;
1673}
1674
1675
1676/*
1677 * Polled character transmission for the kernel debugger
1678 */
1679static void mn10300_serial_poll_put_char(struct uart_port *_port,
1680 unsigned char ch)
1681{
1682 struct mn10300_serial_port *port =
1683 container_of(_port, struct mn10300_serial_port, uart);
1684 u8 intr, tmp;
1685
1686 /* wait for the transmitter to finish anything it might be doing (and
1687 * this includes the virtual DMA handler, so it might take a while) */
1688 while (*port->_status & (SC01STR_TBF | SC01STR_TXF))
1689 continue;
1690
1691 /* disable the Tx ready interrupt */
1692 intr = *port->_intr;
1693 *port->_intr = intr & ~SC01ICR_TI;
1694 tmp = *port->_intr;
1695
1696 if (ch == 0x0a) {
1697 *(u8 *) port->_txb = 0x0d;
1698 while (*port->_status & SC01STR_TBF)
1699 continue;
1700 }
1701
1702 *(u8 *) port->_txb = ch;
1703 while (*port->_status & SC01STR_TBF)
1704 continue;
1705
1706 /* restore the Tx interrupt flag */
1707 *port->_intr = intr;
1708 tmp = *port->_intr;
1709}
1710
1711#endif /* CONFIG_CONSOLE_POLL */
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index e1b14a6ed544..28eec3102535 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -135,7 +135,7 @@ void release_segments(struct mm_struct *mm)
135 135
136void machine_restart(char *cmd) 136void machine_restart(char *cmd)
137{ 137{
138#ifdef CONFIG_GDBSTUB 138#ifdef CONFIG_KERNEL_DEBUGGER
139 gdbstub_exit(0); 139 gdbstub_exit(0);
140#endif 140#endif
141 141
@@ -148,14 +148,14 @@ void machine_restart(char *cmd)
148 148
149void machine_halt(void) 149void machine_halt(void)
150{ 150{
151#ifdef CONFIG_GDBSTUB 151#ifdef CONFIG_KERNEL_DEBUGGER
152 gdbstub_exit(0); 152 gdbstub_exit(0);
153#endif 153#endif
154} 154}
155 155
156void machine_power_off(void) 156void machine_power_off(void)
157{ 157{
158#ifdef CONFIG_GDBSTUB 158#ifdef CONFIG_KERNEL_DEBUGGER
159 gdbstub_exit(0); 159 gdbstub_exit(0);
160#endif 160#endif
161} 161}
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
index 1ebb79f1650d..51c02f97dcea 100644
--- a/arch/mn10300/kernel/smp.c
+++ b/arch/mn10300/kernel/smp.c
@@ -440,6 +440,22 @@ int smp_nmi_call_function(smp_call_func_t func, void *info, int wait)
440} 440}
441 441
442/** 442/**
443 * smp_jump_to_debugger - Make other CPUs enter the debugger by sending an IPI
444 *
445 * Send a non-maskable request to all other CPUs in the system, instructing
446 * them to jump into the debugger. The caller is responsible for checking that
447 * the other CPUs responded to the instruction.
448 *
449 * The caller should make sure that this CPU's debugger IPI is disabled.
450 */
451void smp_jump_to_debugger(void)
452{
453 if (num_online_cpus() > 1)
454 /* Send a message to all other CPUs */
455 send_IPI_allbutself(DEBUGGER_NMI_IPI);
456}
457
458/**
443 * stop_this_cpu - Callback to stop a CPU. 459 * stop_this_cpu - Callback to stop a CPU.
444 * @unused: Callback context (ignored). 460 * @unused: Callback context (ignored).
445 */ 461 */
@@ -603,7 +619,7 @@ static void __init smp_cpu_init(void)
603/** 619/**
604 * smp_prepare_cpu_init - Initialise CPU in startup_secondary 620 * smp_prepare_cpu_init - Initialise CPU in startup_secondary
605 * 621 *
606 * Set interrupt level 0-6 setting and init ICR of gdbstub. 622 * Set interrupt level 0-6 setting and init ICR of the kernel debugger.
607 */ 623 */
608void smp_prepare_cpu_init(void) 624void smp_prepare_cpu_init(void)
609{ 625{
@@ -622,15 +638,15 @@ void smp_prepare_cpu_init(void)
622 for (loop = 0; loop < GxICR_NUM_IRQS; loop++) 638 for (loop = 0; loop < GxICR_NUM_IRQS; loop++)
623 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT; 639 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
624 640
625#ifdef CONFIG_GDBSTUB 641#ifdef CONFIG_KERNEL_DEBUGGER
626 /* initialise GDB-stub */ 642 /* initialise the kernel debugger interrupt */
627 do { 643 do {
628 unsigned long flags; 644 unsigned long flags;
629 u16 tmp16; 645 u16 tmp16;
630 646
631 flags = arch_local_cli_save(); 647 flags = arch_local_cli_save();
632 GxICR(GDB_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; 648 GxICR(DEBUGGER_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
633 tmp16 = GxICR(GDB_NMI_IPI); 649 tmp16 = GxICR(DEBUGGER_NMI_IPI);
634 arch_local_irq_restore(flags); 650 arch_local_irq_restore(flags);
635 } while (0); 651 } while (0);
636#endif 652#endif
diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S
index 9074d0fb8788..de3e74fc9ea0 100644
--- a/arch/mn10300/kernel/switch_to.S
+++ b/arch/mn10300/kernel/switch_to.S
@@ -39,11 +39,17 @@ ENTRY(__switch_to)
39 39
40 # save prev context 40 # save prev context
41 mov __switch_back,d0 41 mov __switch_back,d0
42 mov d0,(THREAD_PC,a0)
43 mov sp,a2 42 mov sp,a2
44 mov a2,(THREAD_SP,a0) 43 mov a2,(THREAD_SP,a0)
45 mov a3,(THREAD_A3,a0) 44 mov a3,(THREAD_A3,a0)
46 45
46#ifdef CONFIG_KGDB
47 btst 0xff,(kgdb_single_step)
48 bne __switch_to__lift_sstep_bp
49__switch_to__continue:
50#endif
51 mov d0,(THREAD_PC,a0)
52
47 mov (THREAD_A3,a1),a3 53 mov (THREAD_A3,a1),a3
48 mov (THREAD_SP,a1),a2 54 mov (THREAD_SP,a1),a2
49 55
@@ -68,3 +74,106 @@ ENTRY(__switch_to)
68__switch_back: 74__switch_back:
69 and ~EPSW_NMID,epsw 75 and ~EPSW_NMID,epsw
70 ret [d2,d3,a2,a3,exreg1],32 76 ret [d2,d3,a2,a3,exreg1],32
77
78#ifdef CONFIG_KGDB
79###############################################################################
80#
81# Lift the single-step breakpoints when the task being traced is switched out
82# A0 = prev
83# A1 = next
84#
85###############################################################################
86__switch_to__lift_sstep_bp:
87 add -12,sp
88 mov a0,e4
89 mov a1,e5
90
91 # Clear the single-step flag to prevent us coming this way until we get
92 # switched back in
93 bclr 0xff,(kgdb_single_step)
94
95 # Remove first breakpoint
96 mov (kgdb_sstep_bp_addr),a2
97 cmp 0,a2
98 beq 1f
99 movbu (kgdb_sstep_bp),d0
100 movbu d0,(a2)
101#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
102 mov a2,d0
103 mov a2,d1
104 add 1,d1
105 calls flush_icache_range
106#endif
1071:
108
109 # Remove second breakpoint
110 mov (kgdb_sstep_bp_addr+4),a2
111 cmp 0,a2
112 beq 2f
113 movbu (kgdb_sstep_bp+1),d0
114 movbu d0,(a2)
115#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
116 mov a2,d0
117 mov a2,d1
118 add 1,d1
119 calls flush_icache_range
120#endif
1212:
122
123 # Change the resumption address and return
124 mov __switch_back__reinstall_sstep_bp,d0
125 mov e4,a0
126 mov e5,a1
127 add 12,sp
128 bra __switch_to__continue
129
130###############################################################################
131#
132# Reinstall the single-step breakpoints when the task being traced is switched
133# back in (A1 points to the new thread_struct).
134#
135###############################################################################
136__switch_back__reinstall_sstep_bp:
137 add -12,sp
138 mov a0,e4 # save the return value
139 mov 0xff,d3
140
141 # Reinstall first breakpoint
142 mov (kgdb_sstep_bp_addr),a2
143 cmp 0,a2
144 beq 1f
145 movbu (a2),d0
146 movbu d0,(kgdb_sstep_bp)
147 movbu d3,(a2)
148#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
149 mov a2,d0
150 mov a2,d1
151 add 1,d1
152 calls flush_icache_range
153#endif
1541:
155
156 # Reinstall second breakpoint
157 mov (kgdb_sstep_bp_addr+4),a2
158 cmp 0,a2
159 beq 2f
160 movbu (a2),d0
161 movbu d0,(kgdb_sstep_bp+1)
162 movbu d3,(a2)
163#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
164 mov a2,d0
165 mov a2,d1
166 add 1,d1
167 calls flush_icache_range
168#endif
1692:
170
171 mov d3,(kgdb_single_step)
172
173 # Restore the return value (the previous thread_struct pointer)
174 mov e4,a0
175 mov a0,d0
176 add 12,sp
177 bra __switch_back
178
179#endif /* CONFIG_KGDB */
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index b90c3f160c77..f03cb278828f 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -38,8 +38,9 @@
38#include <asm/busctl-regs.h> 38#include <asm/busctl-regs.h>
39#include <unit/leds.h> 39#include <unit/leds.h>
40#include <asm/fpu.h> 40#include <asm/fpu.h>
41#include <asm/gdb-stub.h>
42#include <asm/sections.h> 41#include <asm/sections.h>
42#include <asm/debugger.h>
43#include "internal.h"
43 44
44#if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff) 45#if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff)
45#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" 46#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!"
@@ -49,63 +50,169 @@ int kstack_depth_to_print = 24;
49 50
50spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); 51spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock);
51 52
52ATOMIC_NOTIFIER_HEAD(mn10300_die_chain); 53struct exception_to_signal_map {
54 u8 signo;
55 u32 si_code;
56};
57
58static const struct exception_to_signal_map exception_to_signal_map[256] = {
59 /* MMU exceptions */
60 [EXCEP_ITLBMISS >> 3] = { 0, 0 },
61 [EXCEP_DTLBMISS >> 3] = { 0, 0 },
62 [EXCEP_IAERROR >> 3] = { 0, 0 },
63 [EXCEP_DAERROR >> 3] = { 0, 0 },
64
65 /* system exceptions */
66 [EXCEP_TRAP >> 3] = { SIGTRAP, TRAP_BRKPT },
67 [EXCEP_ISTEP >> 3] = { SIGTRAP, TRAP_TRACE }, /* Monitor */
68 [EXCEP_IBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */
69 [EXCEP_OBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */
70 [EXCEP_PRIVINS >> 3] = { SIGILL, ILL_PRVOPC },
71 [EXCEP_UNIMPINS >> 3] = { SIGILL, ILL_ILLOPC },
72 [EXCEP_UNIMPEXINS >> 3] = { SIGILL, ILL_ILLOPC },
73 [EXCEP_MEMERR >> 3] = { SIGSEGV, SEGV_ACCERR },
74 [EXCEP_MISALIGN >> 3] = { SIGBUS, BUS_ADRALN },
75 [EXCEP_BUSERROR >> 3] = { SIGBUS, BUS_ADRERR },
76 [EXCEP_ILLINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
77 [EXCEP_ILLDATACC >> 3] = { SIGSEGV, SEGV_ACCERR },
78 [EXCEP_IOINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
79 [EXCEP_PRIVINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */
80 [EXCEP_PRIVDATACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */
81 [EXCEP_DATINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
82 [EXCEP_DOUBLE_FAULT >> 3] = { SIGILL, ILL_BADSTK },
83
84 /* FPU exceptions */
85 [EXCEP_FPU_DISABLED >> 3] = { SIGILL, ILL_COPROC },
86 [EXCEP_FPU_UNIMPINS >> 3] = { SIGILL, ILL_COPROC },
87 [EXCEP_FPU_OPERATION >> 3] = { SIGFPE, FPE_INTDIV },
88
89 /* interrupts */
90 [EXCEP_WDT >> 3] = { SIGALRM, 0 },
91 [EXCEP_NMI >> 3] = { SIGQUIT, 0 },
92 [EXCEP_IRQ_LEVEL0 >> 3] = { SIGINT, 0 },
93 [EXCEP_IRQ_LEVEL1 >> 3] = { 0, 0 },
94 [EXCEP_IRQ_LEVEL2 >> 3] = { 0, 0 },
95 [EXCEP_IRQ_LEVEL3 >> 3] = { 0, 0 },
96 [EXCEP_IRQ_LEVEL4 >> 3] = { 0, 0 },
97 [EXCEP_IRQ_LEVEL5 >> 3] = { 0, 0 },
98 [EXCEP_IRQ_LEVEL6 >> 3] = { 0, 0 },
99
100 /* system calls */
101 [EXCEP_SYSCALL0 >> 3] = { 0, 0 },
102 [EXCEP_SYSCALL1 >> 3] = { SIGILL, ILL_ILLTRP },
103 [EXCEP_SYSCALL2 >> 3] = { SIGILL, ILL_ILLTRP },
104 [EXCEP_SYSCALL3 >> 3] = { SIGILL, ILL_ILLTRP },
105 [EXCEP_SYSCALL4 >> 3] = { SIGILL, ILL_ILLTRP },
106 [EXCEP_SYSCALL5 >> 3] = { SIGILL, ILL_ILLTRP },
107 [EXCEP_SYSCALL6 >> 3] = { SIGILL, ILL_ILLTRP },
108 [EXCEP_SYSCALL7 >> 3] = { SIGILL, ILL_ILLTRP },
109 [EXCEP_SYSCALL8 >> 3] = { SIGILL, ILL_ILLTRP },
110 [EXCEP_SYSCALL9 >> 3] = { SIGILL, ILL_ILLTRP },
111 [EXCEP_SYSCALL10 >> 3] = { SIGILL, ILL_ILLTRP },
112 [EXCEP_SYSCALL11 >> 3] = { SIGILL, ILL_ILLTRP },
113 [EXCEP_SYSCALL12 >> 3] = { SIGILL, ILL_ILLTRP },
114 [EXCEP_SYSCALL13 >> 3] = { SIGILL, ILL_ILLTRP },
115 [EXCEP_SYSCALL14 >> 3] = { SIGILL, ILL_ILLTRP },
116 [EXCEP_SYSCALL15 >> 3] = { SIGABRT, 0 },
117};
53 118
54/* 119/*
55 * These constants are for searching for possible module text 120 * Handle kernel exceptions.
56 * segments. MODULE_RANGE is a guess of how much space is likely 121 *
57 * to be vmalloced. 122 * See if there's a fixup handler we can force a jump to when an exception
123 * happens due to something kernel code did
58 */ 124 */
59#define MODULE_RANGE (8 * 1024 * 1024) 125int die_if_no_fixup(const char *str, struct pt_regs *regs,
60 126 enum exception_code code)
61#define DO_ERROR(signr, prologue, str, name) \ 127{
62asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 128 u8 opcode;
63{ \ 129 int signo, si_code;
64 prologue; \ 130
65 if (die_if_no_fixup(str, regs, intcode)) \ 131 if (user_mode(regs))
66 return; \ 132 return 0;
67 force_sig(signr, current); \ 133
68} 134 peripheral_leds_display_exception(code);
135
136 signo = exception_to_signal_map[code >> 3].signo;
137 si_code = exception_to_signal_map[code >> 3].si_code;
138
139 switch (code) {
140 /* see if we can fixup the kernel accessing memory */
141 case EXCEP_ITLBMISS:
142 case EXCEP_DTLBMISS:
143 case EXCEP_IAERROR:
144 case EXCEP_DAERROR:
145 case EXCEP_MEMERR:
146 case EXCEP_MISALIGN:
147 case EXCEP_BUSERROR:
148 case EXCEP_ILLDATACC:
149 case EXCEP_IOINSACC:
150 case EXCEP_PRIVINSACC:
151 case EXCEP_PRIVDATACC:
152 case EXCEP_DATINSACC:
153 if (fixup_exception(regs))
154 return 1;
155 break;
69 156
70#define DO_EINFO(signr, prologue, str, name, sicode) \ 157 case EXCEP_TRAP:
71asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 158 case EXCEP_UNIMPINS:
72{ \ 159 if (get_user(opcode, (uint8_t __user *)regs->pc) != 0)
73 siginfo_t info; \ 160 break;
74 prologue; \ 161 if (opcode == 0xff) {
75 if (die_if_no_fixup(str, regs, intcode)) \ 162 if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
76 return; \ 163 return 1;
77 info.si_signo = signr; \ 164 if (at_debugger_breakpoint(regs))
78 if (signr == SIGILL && sicode == ILL_ILLOPC) { \ 165 regs->pc++;
79 uint8_t opcode; \ 166 signo = SIGTRAP;
80 if (get_user(opcode, (uint8_t __user *)regs->pc) == 0) \ 167 si_code = TRAP_BRKPT;
81 if (opcode == 0xff) \ 168 }
82 info.si_signo = SIGTRAP; \ 169 break;
83 } \ 170
84 info.si_errno = 0; \ 171 case EXCEP_SYSCALL1 ... EXCEP_SYSCALL14:
85 info.si_code = sicode; \ 172 /* syscall return addr is _after_ the instruction */
86 info.si_addr = (void *) regs->pc; \ 173 regs->pc -= 2;
87 force_sig_info(info.si_signo, &info, current); \ 174 break;
175
176 case EXCEP_SYSCALL15:
177 if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_WARN)
178 return 1;
179
180 /* syscall return addr is _after_ the instruction */
181 regs->pc -= 2;
182 break;
183
184 default:
185 break;
186 }
187
188 if (debugger_intercept(code, signo, si_code, regs) == 0)
189 return 1;
190
191 if (notify_die(DIE_GPF, str, regs, code, 0, 0))
192 return 1;
193
194 /* make the process die as the last resort */
195 die(str, regs, code);
88} 196}
89 197
90DO_ERROR(SIGTRAP, {}, "trap", trap); 198/*
91DO_ERROR(SIGSEGV, {}, "ibreak", ibreak); 199 * General exception handler
92DO_ERROR(SIGSEGV, {}, "obreak", obreak); 200 */
93DO_EINFO(SIGSEGV, {}, "access error", access_error, SEGV_ACCERR); 201asmlinkage void handle_exception(struct pt_regs *regs, u32 intcode)
94DO_EINFO(SIGSEGV, {}, "insn access error", insn_acc_error, SEGV_ACCERR); 202{
95DO_EINFO(SIGSEGV, {}, "data access error", data_acc_error, SEGV_ACCERR); 203 siginfo_t info;
96DO_EINFO(SIGILL, {}, "privileged opcode", priv_op, ILL_PRVOPC); 204
97DO_EINFO(SIGILL, {}, "invalid opcode", invalid_op, ILL_ILLOPC); 205 /* deal with kernel exceptions here */
98DO_EINFO(SIGILL, {}, "invalid ex opcode", invalid_exop, ILL_ILLOPC); 206 if (die_if_no_fixup(NULL, regs, intcode))
99DO_EINFO(SIGBUS, {}, "invalid address", mem_error, BUS_ADRERR); 207 return;
100DO_EINFO(SIGBUS, {}, "bus error", bus_error, BUS_ADRERR); 208
101 209 /* otherwise it's a userspace exception */
102DO_ERROR(SIGTRAP, 210 info.si_signo = exception_to_signal_map[intcode >> 3].signo;
103#ifndef CONFIG_MN10300_USING_JTAG 211 info.si_code = exception_to_signal_map[intcode >> 3].si_code;
104 DCR &= ~0x0001, 212 info.si_errno = 0;
105#else 213 info.si_addr = (void *) regs->pc;
106 {}, 214 force_sig_info(info.si_signo, &info, current);
107#endif 215}
108 "single step", istep);
109 216
110/* 217/*
111 * handle NMI 218 * handle NMI
@@ -113,10 +220,8 @@ DO_ERROR(SIGTRAP,
113asmlinkage void nmi(struct pt_regs *regs, enum exception_code code) 220asmlinkage void nmi(struct pt_regs *regs, enum exception_code code)
114{ 221{
115 /* see if gdbstub wants to deal with it */ 222 /* see if gdbstub wants to deal with it */
116#ifdef CONFIG_GDBSTUB 223 if (debugger_intercept(code, SIGQUIT, 0, regs))
117 if (gdbstub_intercept(regs, code))
118 return; 224 return;
119#endif
120 225
121 printk(KERN_WARNING "--- Register Dump ---\n"); 226 printk(KERN_WARNING "--- Register Dump ---\n");
122 show_registers(regs); 227 show_registers(regs);
@@ -128,29 +233,36 @@ asmlinkage void nmi(struct pt_regs *regs, enum exception_code code)
128 */ 233 */
129void show_trace(unsigned long *sp) 234void show_trace(unsigned long *sp)
130{ 235{
131 unsigned long *stack, addr, module_start, module_end; 236 unsigned long bottom, stack, addr, fp, raslot;
132 int i; 237
133 238 printk(KERN_EMERG "\nCall Trace:\n");
134 printk(KERN_EMERG "\nCall Trace:"); 239
135 240 //stack = (unsigned long)sp;
136 stack = sp; 241 asm("mov sp,%0" : "=a"(stack));
137 i = 0; 242 asm("mov a3,%0" : "=r"(fp));
138 module_start = VMALLOC_START; 243
139 module_end = VMALLOC_END; 244 raslot = ULONG_MAX;
245 bottom = (stack + THREAD_SIZE) & ~(THREAD_SIZE - 1);
246 for (; stack < bottom; stack += sizeof(addr)) {
247 addr = *(unsigned long *)stack;
248 if (stack == fp) {
249 if (addr > stack && addr < bottom) {
250 fp = addr;
251 raslot = stack + sizeof(addr);
252 continue;
253 }
254 fp = 0;
255 raslot = ULONG_MAX;
256 }
140 257
141 while (((long) stack & (THREAD_SIZE - 1)) != 0) {
142 addr = *stack++;
143 if (__kernel_text_address(addr)) { 258 if (__kernel_text_address(addr)) {
144#if 1
145 printk(" [<%08lx>]", addr); 259 printk(" [<%08lx>]", addr);
260 if (stack >= raslot)
261 raslot = ULONG_MAX;
262 else
263 printk(" ?");
146 print_symbol(" %s", addr); 264 print_symbol(" %s", addr);
147 printk("\n"); 265 printk("\n");
148#else
149 if ((i % 6) == 0)
150 printk(KERN_EMERG " ");
151 printk("[<%08lx>] ", addr);
152 i++;
153#endif
154 } 266 }
155 } 267 }
156 268
@@ -323,86 +435,6 @@ void die(const char *str, struct pt_regs *regs, enum exception_code code)
323} 435}
324 436
325/* 437/*
326 * see if there's a fixup handler we can force a jump to when an exception
327 * happens due to something kernel code did
328 */
329int die_if_no_fixup(const char *str, struct pt_regs *regs,
330 enum exception_code code)
331{
332 if (user_mode(regs))
333 return 0;
334
335 peripheral_leds_display_exception(code);
336
337 switch (code) {
338 /* see if we can fixup the kernel accessing memory */
339 case EXCEP_ITLBMISS:
340 case EXCEP_DTLBMISS:
341 case EXCEP_IAERROR:
342 case EXCEP_DAERROR:
343 case EXCEP_MEMERR:
344 case EXCEP_MISALIGN:
345 case EXCEP_BUSERROR:
346 case EXCEP_ILLDATACC:
347 case EXCEP_IOINSACC:
348 case EXCEP_PRIVINSACC:
349 case EXCEP_PRIVDATACC:
350 case EXCEP_DATINSACC:
351 if (fixup_exception(regs))
352 return 1;
353 case EXCEP_UNIMPINS:
354 if (regs->pc && *(uint8_t *)regs->pc == 0xff)
355 if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
356 return 1;
357 break;
358 default:
359 break;
360 }
361
362 /* see if gdbstub wants to deal with it */
363#ifdef CONFIG_GDBSTUB
364 if (gdbstub_intercept(regs, code))
365 return 1;
366#endif
367
368 if (notify_die(DIE_GPF, str, regs, code, 0, 0))
369 return 1;
370
371 /* make the process die as the last resort */
372 die(str, regs, code);
373}
374
375/*
376 * handle unsupported syscall instructions (syscall 1-15)
377 */
378static asmlinkage void unsupported_syscall(struct pt_regs *regs,
379 enum exception_code code)
380{
381 struct task_struct *tsk = current;
382 siginfo_t info;
383
384 /* catch a kernel BUG() */
385 if (code == EXCEP_SYSCALL15 && !user_mode(regs)) {
386 if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_BUG) {
387#ifdef CONFIG_GDBSTUB
388 gdbstub_intercept(regs, code);
389#endif
390 }
391 }
392
393 regs->pc -= 2; /* syscall return addr is _after_ the instruction */
394
395 die_if_no_fixup("An unsupported syscall insn was used by the kernel\n",
396 regs, code);
397
398 info.si_signo = SIGILL;
399 info.si_errno = ENOSYS;
400 info.si_code = ILL_ILLTRP;
401 info.si_addr = (void *) regs->pc;
402 force_sig_info(SIGILL, &info, tsk);
403}
404
405/*
406 * display the register file when the stack pointer gets clobbered 438 * display the register file when the stack pointer gets clobbered
407 */ 439 */
408asmlinkage void do_double_fault(struct pt_regs *regs) 440asmlinkage void do_double_fault(struct pt_regs *regs)
@@ -481,10 +513,8 @@ asmlinkage void uninitialised_exception(struct pt_regs *regs,
481{ 513{
482 514
483 /* see if gdbstub wants to deal with it */ 515 /* see if gdbstub wants to deal with it */
484#ifdef CONFIG_GDBSTUB 516 if (debugger_intercept(code, SIGSYS, 0, regs) == 0)
485 if (gdbstub_intercept(regs, code))
486 return; 517 return;
487#endif
488 518
489 peripheral_leds_display_exception(code); 519 peripheral_leds_display_exception(code);
490 printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF); 520 printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF);
@@ -549,43 +579,43 @@ void __init set_intr_stub(enum exception_code code, void *handler)
549 */ 579 */
550void __init trap_init(void) 580void __init trap_init(void)
551{ 581{
552 set_excp_vector(EXCEP_TRAP, trap); 582 set_excp_vector(EXCEP_TRAP, handle_exception);
553 set_excp_vector(EXCEP_ISTEP, istep); 583 set_excp_vector(EXCEP_ISTEP, handle_exception);
554 set_excp_vector(EXCEP_IBREAK, ibreak); 584 set_excp_vector(EXCEP_IBREAK, handle_exception);
555 set_excp_vector(EXCEP_OBREAK, obreak); 585 set_excp_vector(EXCEP_OBREAK, handle_exception);
556 586
557 set_excp_vector(EXCEP_PRIVINS, priv_op); 587 set_excp_vector(EXCEP_PRIVINS, handle_exception);
558 set_excp_vector(EXCEP_UNIMPINS, invalid_op); 588 set_excp_vector(EXCEP_UNIMPINS, handle_exception);
559 set_excp_vector(EXCEP_UNIMPEXINS, invalid_exop); 589 set_excp_vector(EXCEP_UNIMPEXINS, handle_exception);
560 set_excp_vector(EXCEP_MEMERR, mem_error); 590 set_excp_vector(EXCEP_MEMERR, handle_exception);
561 set_excp_vector(EXCEP_MISALIGN, misalignment); 591 set_excp_vector(EXCEP_MISALIGN, misalignment);
562 set_excp_vector(EXCEP_BUSERROR, bus_error); 592 set_excp_vector(EXCEP_BUSERROR, handle_exception);
563 set_excp_vector(EXCEP_ILLINSACC, insn_acc_error); 593 set_excp_vector(EXCEP_ILLINSACC, handle_exception);
564 set_excp_vector(EXCEP_ILLDATACC, data_acc_error); 594 set_excp_vector(EXCEP_ILLDATACC, handle_exception);
565 set_excp_vector(EXCEP_IOINSACC, insn_acc_error); 595 set_excp_vector(EXCEP_IOINSACC, handle_exception);
566 set_excp_vector(EXCEP_PRIVINSACC, insn_acc_error); 596 set_excp_vector(EXCEP_PRIVINSACC, handle_exception);
567 set_excp_vector(EXCEP_PRIVDATACC, data_acc_error); 597 set_excp_vector(EXCEP_PRIVDATACC, handle_exception);
568 set_excp_vector(EXCEP_DATINSACC, insn_acc_error); 598 set_excp_vector(EXCEP_DATINSACC, handle_exception);
569 set_excp_vector(EXCEP_FPU_UNIMPINS, fpu_invalid_op); 599 set_excp_vector(EXCEP_FPU_UNIMPINS, handle_exception);
570 set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception); 600 set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception);
571 601
572 set_excp_vector(EXCEP_NMI, nmi); 602 set_excp_vector(EXCEP_NMI, nmi);
573 603
574 set_excp_vector(EXCEP_SYSCALL1, unsupported_syscall); 604 set_excp_vector(EXCEP_SYSCALL1, handle_exception);
575 set_excp_vector(EXCEP_SYSCALL2, unsupported_syscall); 605 set_excp_vector(EXCEP_SYSCALL2, handle_exception);
576 set_excp_vector(EXCEP_SYSCALL3, unsupported_syscall); 606 set_excp_vector(EXCEP_SYSCALL3, handle_exception);
577 set_excp_vector(EXCEP_SYSCALL4, unsupported_syscall); 607 set_excp_vector(EXCEP_SYSCALL4, handle_exception);
578 set_excp_vector(EXCEP_SYSCALL5, unsupported_syscall); 608 set_excp_vector(EXCEP_SYSCALL5, handle_exception);
579 set_excp_vector(EXCEP_SYSCALL6, unsupported_syscall); 609 set_excp_vector(EXCEP_SYSCALL6, handle_exception);
580 set_excp_vector(EXCEP_SYSCALL7, unsupported_syscall); 610 set_excp_vector(EXCEP_SYSCALL7, handle_exception);
581 set_excp_vector(EXCEP_SYSCALL8, unsupported_syscall); 611 set_excp_vector(EXCEP_SYSCALL8, handle_exception);
582 set_excp_vector(EXCEP_SYSCALL9, unsupported_syscall); 612 set_excp_vector(EXCEP_SYSCALL9, handle_exception);
583 set_excp_vector(EXCEP_SYSCALL10, unsupported_syscall); 613 set_excp_vector(EXCEP_SYSCALL10, handle_exception);
584 set_excp_vector(EXCEP_SYSCALL11, unsupported_syscall); 614 set_excp_vector(EXCEP_SYSCALL11, handle_exception);
585 set_excp_vector(EXCEP_SYSCALL12, unsupported_syscall); 615 set_excp_vector(EXCEP_SYSCALL12, handle_exception);
586 set_excp_vector(EXCEP_SYSCALL13, unsupported_syscall); 616 set_excp_vector(EXCEP_SYSCALL13, handle_exception);
587 set_excp_vector(EXCEP_SYSCALL14, unsupported_syscall); 617 set_excp_vector(EXCEP_SYSCALL14, handle_exception);
588 set_excp_vector(EXCEP_SYSCALL15, unsupported_syscall); 618 set_excp_vector(EXCEP_SYSCALL15, handle_exception);
589} 619}
590 620
591/* 621/*
diff --git a/arch/mn10300/mm/Kconfig.cache b/arch/mn10300/mm/Kconfig.cache
index c4fd923a55a0..bfbe52691f2c 100644
--- a/arch/mn10300/mm/Kconfig.cache
+++ b/arch/mn10300/mm/Kconfig.cache
@@ -99,3 +99,49 @@ config MN10300_CACHE_INV_ICACHE
99 help 99 help
100 Set if we need the icache to be invalidated, even if the dcache is in 100 Set if we need the icache to be invalidated, even if the dcache is in
101 write-through mode and doesn't need flushing. 101 write-through mode and doesn't need flushing.
102
103#
104# The kernel debugger gets its own separate cache flushing functions
105#
106config MN10300_DEBUGGER_CACHE_FLUSH_BY_TAG
107 def_bool y if KERNEL_DEBUGGER && \
108 MN10300_CACHE_WBACK && \
109 !MN10300_CACHE_SNOOP && \
110 MN10300_CACHE_MANAGE_BY_TAG
111 help
112 Set if the debugger needs to flush the dcache and invalidate the
113 icache using the cache tag registers to make breakpoints work.
114
115config MN10300_DEBUGGER_CACHE_FLUSH_BY_REG
116 def_bool y if KERNEL_DEBUGGER && \
117 MN10300_CACHE_WBACK && \
118 !MN10300_CACHE_SNOOP && \
119 MN10300_CACHE_MANAGE_BY_REG
120 help
121 Set if the debugger needs to flush the dcache and invalidate the
122 icache using automatic purge registers to make breakpoints work.
123
124config MN10300_DEBUGGER_CACHE_INV_BY_TAG
125 def_bool y if KERNEL_DEBUGGER && \
126 MN10300_CACHE_WTHRU && \
127 !MN10300_CACHE_SNOOP && \
128 MN10300_CACHE_MANAGE_BY_TAG
129 help
130 Set if the debugger needs to invalidate the icache using the cache
131 tag registers to make breakpoints work.
132
133config MN10300_DEBUGGER_CACHE_INV_BY_REG
134 def_bool y if KERNEL_DEBUGGER && \
135 MN10300_CACHE_WTHRU && \
136 !MN10300_CACHE_SNOOP && \
137 MN10300_CACHE_MANAGE_BY_REG
138 help
139 Set if the debugger needs to invalidate the icache using automatic
140 purge registers to make breakpoints work.
141
142config MN10300_DEBUGGER_CACHE_NO_FLUSH
143 def_bool y if KERNEL_DEBUGGER && \
144 (MN10300_CACHE_DISABLED || MN10300_CACHE_SNOOP)
145 help
146 Set if the debugger does not need to flush the dcache and/or
147 invalidate the icache to make breakpoints work.
diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile
index 203fee23f7d7..11f38466ac28 100644
--- a/arch/mn10300/mm/Makefile
+++ b/arch/mn10300/mm/Makefile
@@ -13,6 +13,15 @@ cacheflush-$(CONFIG_MN10300_CACHE_INV_BY_REG) += cache-inv-by-reg.o
13cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o 13cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o
14cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_REG) += cache-flush-by-reg.o 14cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_REG) += cache-flush-by-reg.o
15 15
16cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_FLUSH_BY_TAG) += \
17 cache-dbg-flush-by-tag.o cache-dbg-inv-by-tag.o
18cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_FLUSH_BY_REG) += \
19 cache-dbg-flush-by-reg.o
20cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_TAG) += \
21 cache-dbg-inv-by-tag.o cache-dbg-inv.o
22cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_REG) += \
23 cache-dbg-inv-by-reg.o cache-dbg-inv.o
24
16cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o 25cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o
17 26
18obj-y := \ 27obj-y := \
diff --git a/arch/mn10300/mm/cache-dbg-flush-by-reg.S b/arch/mn10300/mm/cache-dbg-flush-by-reg.S
new file mode 100644
index 000000000000..665919f2ab62
--- /dev/null
+++ b/arch/mn10300/mm/cache-dbg-flush-by-reg.S
@@ -0,0 +1,160 @@
1/* MN10300 CPU cache invalidation routines, using automatic purge registers
2 *
3 * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/sys.h>
12#include <linux/linkage.h>
13#include <asm/smp.h>
14#include <asm/page.h>
15#include <asm/cache.h>
16#include <asm/irqflags.h>
17#include <asm/cacheflush.h>
18#include "cache.inc"
19
20 .am33_2
21
22###############################################################################
23#
24# void debugger_local_cache_flushinv(void)
25# Flush the entire data cache back to RAM and invalidate the icache
26#
27###############################################################################
28 ALIGN
29 .globl debugger_local_cache_flushinv
30 .type debugger_local_cache_flushinv,@function
31debugger_local_cache_flushinv:
32 #
33 # firstly flush the dcache
34 #
35 movhu (CHCTR),d0
36 btst CHCTR_DCEN|CHCTR_ICEN,d0
37 beq debugger_local_cache_flushinv_end
38
39 mov DCPGCR,a0
40
41 mov epsw,d1
42 and ~EPSW_IE,epsw
43 or EPSW_NMID,epsw
44 nop
45
46 btst CHCTR_DCEN,d0
47 beq debugger_local_cache_flushinv_no_dcache
48
49 # wait for busy bit of area purge
50 setlb
51 mov (a0),d0
52 btst DCPGCR_DCPGBSY,d0
53 lne
54
55 # set mask
56 clr d0
57 mov d0,(DCPGMR)
58
59 # area purge
60 #
61 # DCPGCR = DCPGCR_DCP
62 #
63 mov DCPGCR_DCP,d0
64 mov d0,(a0)
65
66 # wait for busy bit of area purge
67 setlb
68 mov (a0),d0
69 btst DCPGCR_DCPGBSY,d0
70 lne
71
72debugger_local_cache_flushinv_no_dcache:
73 #
74 # secondly, invalidate the icache if it is enabled
75 #
76 mov CHCTR,a0
77 movhu (a0),d0
78 btst CHCTR_ICEN,d0
79 beq debugger_local_cache_flushinv_done
80
81 invalidate_icache 0
82
83debugger_local_cache_flushinv_done:
84 mov d1,epsw
85
86debugger_local_cache_flushinv_end:
87 ret [],0
88 .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv
89
90###############################################################################
91#
92# void debugger_local_cache_flushinv_one(u8 *addr)
93#
94# Invalidate one particular cacheline if it's in the icache
95#
96###############################################################################
97 ALIGN
98 .globl debugger_local_cache_flushinv_one
99 .type debugger_local_cache_flushinv_one,@function
100debugger_local_cache_flushinv_one:
101 movhu (CHCTR),d1
102 btst CHCTR_DCEN|CHCTR_ICEN,d1
103 beq debugger_local_cache_flushinv_one_end
104 btst CHCTR_DCEN,d1
105 beq debugger_local_cache_flushinv_one_no_dcache
106
107 # round cacheline addr down
108 and L1_CACHE_TAG_MASK,d0
109 mov d0,a1
110 mov d0,d1
111
112 # determine the dcache purge control reg address
113 mov DCACHE_PURGE(0,0),a0
114 and L1_CACHE_TAG_ENTRY,d0
115 add d0,a0
116
117 # retain valid entries in the cache
118 or L1_CACHE_TAG_VALID,d1
119
120 # conditionally purge this line in all ways
121 mov d1,(L1_CACHE_WAYDISP*0,a0)
122
123debugger_local_cache_flushinv_no_dcache:
124 #
125 # now try to flush the icache
126 #
127 mov CHCTR,a0
128 movhu (a0),d0
129 btst CHCTR_ICEN,d0
130 beq mn10300_local_icache_inv_range_reg_end
131
132 LOCAL_CLI_SAVE(d1)
133
134 mov ICIVCR,a0
135
136 # wait for the invalidator to quiesce
137 setlb
138 mov (a0),d0
139 btst ICIVCR_ICIVBSY,d0
140 lne
141
142 # set the mask
143 mov L1_CACHE_TAG_MASK,d0
144 mov d0,(ICIVMR)
145
146 # invalidate the cache line at the given address
147 or ICIVCR_ICI,a1
148 mov a1,(a0)
149
150 # wait for the invalidator to quiesce again
151 setlb
152 mov (a0),d0
153 btst ICIVCR_ICIVBSY,d0
154 lne
155
156 LOCAL_IRQ_RESTORE(d1)
157
158debugger_local_cache_flushinv_one_end:
159 ret [],0
160 .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one
diff --git a/arch/mn10300/mm/cache-dbg-flush-by-tag.S b/arch/mn10300/mm/cache-dbg-flush-by-tag.S
new file mode 100644
index 000000000000..bf56930e6e70
--- /dev/null
+++ b/arch/mn10300/mm/cache-dbg-flush-by-tag.S
@@ -0,0 +1,114 @@
1/* MN10300 CPU cache invalidation routines, using direct tag flushing
2 *
3 * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/sys.h>
12#include <linux/linkage.h>
13#include <asm/smp.h>
14#include <asm/page.h>
15#include <asm/cache.h>
16#include <asm/irqflags.h>
17#include <asm/cacheflush.h>
18#include "cache.inc"
19
20 .am33_2
21
22###############################################################################
23#
24# void debugger_local_cache_flushinv(void)
25#
26# Flush the entire data cache back to RAM and invalidate the icache
27#
28###############################################################################
29 ALIGN
30 .globl debugger_local_cache_flushinv
31 .type debugger_local_cache_flushinv,@function
32debugger_local_cache_flushinv:
33 #
34 # firstly flush the dcache
35 #
36 movhu (CHCTR),d0
37 btst CHCTR_DCEN|CHCTR_ICEN,d0
38 beq debugger_local_cache_flushinv_end
39
40 btst CHCTR_DCEN,d0
41 beq debugger_local_cache_flushinv_no_dcache
42
43 # read the addresses tagged in the cache's tag RAM and attempt to flush
44 # those addresses specifically
45 # - we rely on the hardware to filter out invalid tag entry addresses
46 mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address
47 mov DCACHE_PURGE(0,0),a1 # dcache purge request address
48 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,e0 # total number of entries
49
50mn10300_local_dcache_flush_loop:
51 mov (a0),d0
52 and L1_CACHE_TAG_MASK,d0
53 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
54 # cache
55 mov d0,(a1) # conditional purge
56
57 add L1_CACHE_BYTES,a0
58 add L1_CACHE_BYTES,a1
59 add -1,e0
60 bne mn10300_local_dcache_flush_loop
61
62debugger_local_cache_flushinv_no_dcache:
63 #
64 # secondly, invalidate the icache if it is enabled
65 #
66 mov CHCTR,a0
67 movhu (a0),d0
68 btst CHCTR_ICEN,d0
69 beq debugger_local_cache_flushinv_end
70
71 invalidate_icache 1
72
73debugger_local_cache_flushinv_end:
74 ret [],0
75 .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv
76
77###############################################################################
78#
79# void debugger_local_cache_flushinv_one(u8 *addr)
80#
81# Invalidate one particular cacheline if it's in the icache
82#
83###############################################################################
84 ALIGN
85 .globl debugger_local_cache_flushinv_one
86 .type debugger_local_cache_flushinv_one,@function
87debugger_local_cache_flushinv_one:
88 movhu (CHCTR),d1
89 btst CHCTR_DCEN|CHCTR_ICEN,d1
90 beq debugger_local_cache_flushinv_one_end
91 btst CHCTR_DCEN,d1
92 beq debugger_local_cache_flushinv_one_icache
93
94 # round cacheline addr down
95 and L1_CACHE_TAG_MASK,d0
96 mov d0,a1
97
98 # determine the dcache purge control reg address
99 mov DCACHE_PURGE(0,0),a0
100 and L1_CACHE_TAG_ENTRY,d0
101 add d0,a0
102
103 # retain valid entries in the cache
104 or L1_CACHE_TAG_VALID,a1
105
106 # conditionally purge this line in all ways
107 mov a1,(L1_CACHE_WAYDISP*0,a0)
108
109 # now go and do the icache
110 bra debugger_local_cache_flushinv_one_icache
111
112debugger_local_cache_flushinv_one_end:
113 ret [],0
114 .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one
diff --git a/arch/mn10300/mm/cache-dbg-inv-by-reg.S b/arch/mn10300/mm/cache-dbg-inv-by-reg.S
new file mode 100644
index 000000000000..c4e6252941b1
--- /dev/null
+++ b/arch/mn10300/mm/cache-dbg-inv-by-reg.S
@@ -0,0 +1,69 @@
1/* MN10300 CPU cache invalidation routines, using automatic purge registers
2 *
3 * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/sys.h>
12#include <linux/linkage.h>
13#include <asm/cache.h>
14#include <asm/irqflags.h>
15#include <asm/cacheflush.h>
16#include "cache.inc"
17
18 .am33_2
19
20 .globl debugger_local_cache_flushinv_one
21
22###############################################################################
23#
24# void debugger_local_cache_flushinv_one(u8 *addr)
25#
26# Invalidate one particular cacheline if it's in the icache
27#
28###############################################################################
29 ALIGN
30 .globl debugger_local_cache_flushinv_one
31 .type debugger_local_cache_flushinv_one,@function
32debugger_local_cache_flushinv_one:
33 mov d0,a1
34
35 mov CHCTR,a0
36 movhu (a0),d0
37 btst CHCTR_ICEN,d0
38 beq mn10300_local_icache_inv_range_reg_end
39
40 LOCAL_CLI_SAVE(d1)
41
42 mov ICIVCR,a0
43
44 # wait for the invalidator to quiesce
45 setlb
46 mov (a0),d0
47 btst ICIVCR_ICIVBSY,d0
48 lne
49
50 # set the mask
51 mov ~L1_CACHE_TAG_MASK,d0
52 mov d0,(ICIVMR)
53
54 # invalidate the cache line at the given address
55 and ~L1_CACHE_TAG_MASK,a1
56 or ICIVCR_ICI,a1
57 mov a1,(a0)
58
59 # wait for the invalidator to quiesce again
60 setlb
61 mov (a0),d0
62 btst ICIVCR_ICIVBSY,d0
63 lne
64
65 LOCAL_IRQ_RESTORE(d1)
66
67mn10300_local_icache_inv_range_reg_end:
68 ret [],0
69 .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one
diff --git a/arch/mn10300/mm/cache-dbg-inv-by-tag.S b/arch/mn10300/mm/cache-dbg-inv-by-tag.S
new file mode 100644
index 000000000000..d8ec821e5f88
--- /dev/null
+++ b/arch/mn10300/mm/cache-dbg-inv-by-tag.S
@@ -0,0 +1,120 @@
1/* MN10300 CPU cache invalidation routines, using direct tag flushing
2 *
3 * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/sys.h>
12#include <linux/linkage.h>
13#include <asm/smp.h>
14#include <asm/page.h>
15#include <asm/cache.h>
16#include <asm/irqflags.h>
17#include <asm/cacheflush.h>
18#include "cache.inc"
19
20 .am33_2
21
22 .globl debugger_local_cache_flushinv_one_icache
23
24###############################################################################
25#
26# void debugger_local_cache_flushinv_one(u8 *addr)
27#
28# Invalidate one particular cacheline if it's in the icache
29#
30###############################################################################
31 ALIGN
32 .globl debugger_local_cache_flushinv_one_icache
33 .type debugger_local_cache_flushinv_one_icache,@function
34debugger_local_cache_flushinv_one_icache:
35 movm [d3,a2],(sp)
36
37 mov CHCTR,a2
38 movhu (a2),d0
39 btst CHCTR_ICEN,d0
40 beq debugger_local_cache_flushinv_one_icache_end
41
42 mov d0,a1
43 and L1_CACHE_TAG_MASK,a1
44
45 # read the tags from the tag RAM, and if they indicate a matching valid
46 # cache line then we invalidate that line
47 mov ICACHE_TAG(0,0),a0
48 mov a1,d0
49 and L1_CACHE_TAG_ENTRY,d0
50 add d0,a0 # starting icache tag RAM
51 # access address
52
53 and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base
54 or L1_CACHE_TAG_VALID,a1
55 mov L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_VALID,d1
56
57 LOCAL_CLI_SAVE(d3)
58
59 # disable the icache
60 movhu (a2),d0
61 and ~CHCTR_ICEN,d0
62 movhu d0,(a2)
63
64 # and wait for it to calm down
65 setlb
66 movhu (a2),d0
67 btst CHCTR_ICBUSY,d0
68 lne
69
70 # check all the way tags for this cache entry
71 mov (a0),d0 # read the tag in the way 0 slot
72 xor a1,d0
73 and d1,d0
74 beq debugger_local_icache_kill # jump if matched
75
76 add L1_CACHE_WAYDISP,a0
77 mov (a0),d0 # read the tag in the way 1 slot
78 xor a1,d0
79 and d1,d0
80 beq debugger_local_icache_kill # jump if matched
81
82 add L1_CACHE_WAYDISP,a0
83 mov (a0),d0 # read the tag in the way 2 slot
84 xor a1,d0
85 and d1,d0
86 beq debugger_local_icache_kill # jump if matched
87
88 add L1_CACHE_WAYDISP,a0
89 mov (a0),d0 # read the tag in the way 3 slot
90 xor a1,d0
91 and d1,d0
92 bne debugger_local_icache_finish # jump if not matched
93
94debugger_local_icache_kill:
95 mov d0,(a0) # kill the tag (D0 is 0 at this point)
96
97debugger_local_icache_finish:
98 # wait for the cache to finish what it's doing
99 setlb
100 movhu (a2),d0
101 btst CHCTR_ICBUSY,d0
102 lne
103
104 # and reenable it
105 or CHCTR_ICEN,d0
106 movhu d0,(a2)
107 movhu (a2),d0
108
109 # re-enable interrupts
110 LOCAL_IRQ_RESTORE(d3)
111
112debugger_local_cache_flushinv_one_icache_end:
113 ret [d3,a2],8
114 .size debugger_local_cache_flushinv_one_icache,.-debugger_local_cache_flushinv_one_icache
115
116#ifdef CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_TAG
117 .globl debugger_local_cache_flushinv_one
118 .type debugger_local_cache_flushinv_one,@function
119debugger_local_cache_flushinv_one = debugger_local_cache_flushinv_one_icache
120#endif
diff --git a/arch/mn10300/mm/cache-dbg-inv.S b/arch/mn10300/mm/cache-dbg-inv.S
new file mode 100644
index 000000000000..eba2d6dca066
--- /dev/null
+++ b/arch/mn10300/mm/cache-dbg-inv.S
@@ -0,0 +1,47 @@
1/* MN10300 CPU cache invalidation routines
2 *
3 * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/sys.h>
12#include <linux/linkage.h>
13#include <asm/smp.h>
14#include <asm/page.h>
15#include <asm/cache.h>
16#include <asm/irqflags.h>
17#include <asm/cacheflush.h>
18#include "cache.inc"
19
20 .am33_2
21
22 .globl debugger_local_cache_flushinv
23
24###############################################################################
25#
26# void debugger_local_cache_flushinv(void)
27#
28# Invalidate the entire icache
29#
30###############################################################################
31 ALIGN
32 .globl debugger_local_cache_flushinv
33 .type debugger_local_cache_flushinv,@function
34debugger_local_cache_flushinv:
35 #
36 # we only need to invalidate the icache in this cache mode
37 #
38 mov CHCTR,a0
39 movhu (a0),d0
40 btst CHCTR_ICEN,d0
41 beq debugger_local_cache_flushinv_end
42
43 invalidate_icache 1
44
45debugger_local_cache_flushinv_end:
46 ret [],0
47 .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv
diff --git a/arch/mn10300/mm/cache-flush-by-tag.S b/arch/mn10300/mm/cache-flush-by-tag.S
index 5cd6a27dd63e..1ddc06849242 100644
--- a/arch/mn10300/mm/cache-flush-by-tag.S
+++ b/arch/mn10300/mm/cache-flush-by-tag.S
@@ -62,7 +62,7 @@ mn10300_local_dcache_flush:
62 62
63mn10300_local_dcache_flush_loop: 63mn10300_local_dcache_flush_loop:
64 mov (a0),d0 64 mov (a0),d0
65 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 65 and L1_CACHE_TAG_MASK,d0
66 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the 66 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
67 # cache 67 # cache
68 mov d0,(a1) # conditional purge 68 mov d0,(a1) # conditional purge
@@ -112,11 +112,11 @@ mn10300_local_dcache_flush_range:
1121: 1121:
113 113
114 # round start addr down 114 # round start addr down
115 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 115 and L1_CACHE_TAG_MASK,d0
116 mov d0,a1 116 mov d0,a1
117 117
118 add L1_CACHE_BYTES,d1 # round end addr up 118 add L1_CACHE_BYTES,d1 # round end addr up
119 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 119 and L1_CACHE_TAG_MASK,d1
120 120
121 # write a request to flush all instances of an address from the cache 121 # write a request to flush all instances of an address from the cache
122 mov DCACHE_PURGE(0,0),a0 122 mov DCACHE_PURGE(0,0),a0
@@ -215,12 +215,11 @@ mn10300_local_dcache_flush_inv_range:
215 bra mn10300_local_dcache_flush_inv 215 bra mn10300_local_dcache_flush_inv
2161: 2161:
217 217
218 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 218 and L1_CACHE_TAG_MASK,d0 # round start addr down
219 # addr down
220 mov d0,a1 219 mov d0,a1
221 220
222 add L1_CACHE_BYTES,d1 # round end addr up 221 add L1_CACHE_BYTES,d1 # round end addr up
223 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 222 and L1_CACHE_TAG_MASK,d1
224 223
225 # write a request to flush and invalidate all instances of an address 224 # write a request to flush and invalidate all instances of an address
226 # from the cache 225 # from the cache
diff --git a/arch/mn10300/mm/cache-inv-by-reg.S b/arch/mn10300/mm/cache-inv-by-reg.S
index c8950861ed77..a60825b91e77 100644
--- a/arch/mn10300/mm/cache-inv-by-reg.S
+++ b/arch/mn10300/mm/cache-inv-by-reg.S
@@ -15,6 +15,7 @@
15#include <asm/cache.h> 15#include <asm/cache.h>
16#include <asm/irqflags.h> 16#include <asm/irqflags.h>
17#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
18#include "cache.inc"
18 19
19#define mn10300_local_dcache_inv_range_intr_interval \ 20#define mn10300_local_dcache_inv_range_intr_interval \
20 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) 21 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1)
@@ -62,10 +63,7 @@ mn10300_local_icache_inv:
62 btst CHCTR_ICEN,d0 63 btst CHCTR_ICEN,d0
63 beq mn10300_local_icache_inv_end 64 beq mn10300_local_icache_inv_end
64 65
65 # invalidate 66 invalidate_icache 1
66 or CHCTR_ICINV,d0
67 movhu d0,(a0)
68 movhu (a0),d0
69 67
70mn10300_local_icache_inv_end: 68mn10300_local_icache_inv_end:
71 ret [],0 69 ret [],0
@@ -87,11 +85,8 @@ mn10300_local_dcache_inv:
87 btst CHCTR_DCEN,d0 85 btst CHCTR_DCEN,d0
88 beq mn10300_local_dcache_inv_end 86 beq mn10300_local_dcache_inv_end
89 87
90 # invalidate 88 invalidate_dcache 1
91 or CHCTR_DCINV,d0 89
92 movhu d0,(a0)
93 movhu (a0),d0
94
95mn10300_local_dcache_inv_end: 90mn10300_local_dcache_inv_end:
96 ret [],0 91 ret [],0
97 .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv 92 .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv
@@ -121,9 +116,9 @@ mn10300_local_dcache_inv_range:
121 # and if they're not cacheline-aligned, we must flush any bits outside 116 # and if they're not cacheline-aligned, we must flush any bits outside
122 # the range that share cachelines with stuff inside the range 117 # the range that share cachelines with stuff inside the range
123#ifdef CONFIG_MN10300_CACHE_WBACK 118#ifdef CONFIG_MN10300_CACHE_WBACK
124 btst ~(L1_CACHE_BYTES-1),d0 119 btst ~L1_CACHE_TAG_MASK,d0
125 bne 1f 120 bne 1f
126 btst ~(L1_CACHE_BYTES-1),d1 121 btst ~L1_CACHE_TAG_MASK,d1
127 beq 2f 122 beq 2f
1281: 1231:
129 bra mn10300_local_dcache_flush_inv_range 124 bra mn10300_local_dcache_flush_inv_range
@@ -141,12 +136,11 @@ mn10300_local_dcache_inv_range:
141 # writeback mode, in which case we would be in flush and invalidate by 136 # writeback mode, in which case we would be in flush and invalidate by
142 # now 137 # now
143#ifndef CONFIG_MN10300_CACHE_WBACK 138#ifndef CONFIG_MN10300_CACHE_WBACK
144 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 139 and L1_CACHE_TAG_MASK,d0 # round start addr down
145 # addr down
146 140
147 mov L1_CACHE_BYTES-1,d2 141 mov L1_CACHE_BYTES-1,d2
148 add d2,d1 142 add d2,d1
149 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 # round end addr up 143 and L1_CACHE_TAG_MASK,d1 # round end addr up
150#endif /* !CONFIG_MN10300_CACHE_WBACK */ 144#endif /* !CONFIG_MN10300_CACHE_WBACK */
151 145
152 sub d0,d1,d2 # calculate the total size 146 sub d0,d1,d2 # calculate the total size
diff --git a/arch/mn10300/mm/cache-inv-by-tag.S b/arch/mn10300/mm/cache-inv-by-tag.S
index e9713b40c0ff..ccedce9c144d 100644
--- a/arch/mn10300/mm/cache-inv-by-tag.S
+++ b/arch/mn10300/mm/cache-inv-by-tag.S
@@ -15,6 +15,7 @@
15#include <asm/cache.h> 15#include <asm/cache.h>
16#include <asm/irqflags.h> 16#include <asm/irqflags.h>
17#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
18#include "cache.inc"
18 19
19#define mn10300_local_dcache_inv_range_intr_interval \ 20#define mn10300_local_dcache_inv_range_intr_interval \
20 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) 21 +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1)
@@ -70,43 +71,7 @@ mn10300_local_icache_inv:
70 btst CHCTR_ICEN,d0 71 btst CHCTR_ICEN,d0
71 beq mn10300_local_icache_inv_end 72 beq mn10300_local_icache_inv_end
72 73
73#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) 74 invalidate_icache 1
74 LOCAL_CLI_SAVE(d1)
75
76 # disable the icache
77 and ~CHCTR_ICEN,d0
78 movhu d0,(a0)
79
80 # and wait for it to calm down
81 setlb
82 movhu (a0),d0
83 btst CHCTR_ICBUSY,d0
84 lne
85
86 # invalidate
87 or CHCTR_ICINV,d0
88 movhu d0,(a0)
89
90 # wait for the cache to finish
91 mov CHCTR,a0
92 setlb
93 movhu (a0),d0
94 btst CHCTR_ICBUSY,d0
95 lne
96
97 # and reenable it
98 and ~CHCTR_ICINV,d0
99 or CHCTR_ICEN,d0
100 movhu d0,(a0)
101 movhu (a0),d0
102
103 LOCAL_IRQ_RESTORE(d1)
104#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
105 # invalidate
106 or CHCTR_ICINV,d0
107 movhu d0,(a0)
108 movhu (a0),d0
109#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
110 75
111mn10300_local_icache_inv_end: 76mn10300_local_icache_inv_end:
112 ret [],0 77 ret [],0
@@ -128,43 +93,7 @@ mn10300_local_dcache_inv:
128 btst CHCTR_DCEN,d0 93 btst CHCTR_DCEN,d0
129 beq mn10300_local_dcache_inv_end 94 beq mn10300_local_dcache_inv_end
130 95
131#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) 96 invalidate_dcache 1
132 LOCAL_CLI_SAVE(d1)
133
134 # disable the dcache
135 and ~CHCTR_DCEN,d0
136 movhu d0,(a0)
137
138 # and wait for it to calm down
139 setlb
140 movhu (a0),d0
141 btst CHCTR_DCBUSY,d0
142 lne
143
144 # invalidate
145 or CHCTR_DCINV,d0
146 movhu d0,(a0)
147
148 # wait for the cache to finish
149 mov CHCTR,a0
150 setlb
151 movhu (a0),d0
152 btst CHCTR_DCBUSY,d0
153 lne
154
155 # and reenable it
156 and ~CHCTR_DCINV,d0
157 or CHCTR_DCEN,d0
158 movhu d0,(a0)
159 movhu (a0),d0
160
161 LOCAL_IRQ_RESTORE(d1)
162#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
163 # invalidate
164 or CHCTR_DCINV,d0
165 movhu d0,(a0)
166 movhu (a0),d0
167#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
168 97
169mn10300_local_dcache_inv_end: 98mn10300_local_dcache_inv_end:
170 ret [],0 99 ret [],0
@@ -195,9 +124,9 @@ mn10300_local_dcache_inv_range:
195 # and if they're not cacheline-aligned, we must flush any bits outside 124 # and if they're not cacheline-aligned, we must flush any bits outside
196 # the range that share cachelines with stuff inside the range 125 # the range that share cachelines with stuff inside the range
197#ifdef CONFIG_MN10300_CACHE_WBACK 126#ifdef CONFIG_MN10300_CACHE_WBACK
198 btst ~(L1_CACHE_BYTES-1),d0 127 btst ~L1_CACHE_TAG_MASK,d0
199 bne 1f 128 bne 1f
200 btst ~(L1_CACHE_BYTES-1),d1 129 btst ~L1_CACHE_TAG_MASK,d1
201 beq 2f 130 beq 2f
2021: 1311:
203 bra mn10300_local_dcache_flush_inv_range 132 bra mn10300_local_dcache_flush_inv_range
@@ -212,11 +141,10 @@ mn10300_local_dcache_inv_range:
212 beq mn10300_local_dcache_inv_range_end 141 beq mn10300_local_dcache_inv_range_end
213 142
214#ifndef CONFIG_MN10300_CACHE_WBACK 143#ifndef CONFIG_MN10300_CACHE_WBACK
215 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 144 and L1_CACHE_TAG_MASK,d0 # round start addr down
216 # addr down
217 145
218 add L1_CACHE_BYTES,d1 # round end addr up 146 add L1_CACHE_BYTES,d1 # round end addr up
219 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 147 and L1_CACHE_TAG_MASK,d1
220#endif /* !CONFIG_MN10300_CACHE_WBACK */ 148#endif /* !CONFIG_MN10300_CACHE_WBACK */
221 mov d0,a1 149 mov d0,a1
222 150
diff --git a/arch/mn10300/mm/cache.inc b/arch/mn10300/mm/cache.inc
new file mode 100644
index 000000000000..394a119b9c73
--- /dev/null
+++ b/arch/mn10300/mm/cache.inc
@@ -0,0 +1,133 @@
1/* MN10300 CPU core caching macros -*- asm -*-
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12
13###############################################################################
14#
15# Invalidate the instruction cache.
16# A0: Should hold CHCTR
17# D0: Should have been read from CHCTR
18# D1: Will be clobbered
19#
20# On some cores it is necessary to disable the icache whilst we do this.
21#
22###############################################################################
23 .macro invalidate_icache,disable_irq
24
25#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
26 .if \disable_irq
27 # don't want an interrupt routine seeing a disabled cache
28 mov epsw,d1
29 and ~EPSW_IE,epsw
30 or EPSW_NMID,epsw
31 nop
32 nop
33 .endif
34
35 # disable the icache
36 and ~CHCTR_ICEN,d0
37 movhu d0,(a0)
38
39 # and wait for it to calm down
40 setlb
41 movhu (a0),d0
42 btst CHCTR_ICBUSY,d0
43 lne
44
45 # invalidate
46 or CHCTR_ICINV,d0
47 movhu d0,(a0)
48
49 # wait for the cache to finish
50 setlb
51 movhu (a0),d0
52 btst CHCTR_ICBUSY,d0
53 lne
54
55 # and reenable it
56 or CHCTR_ICEN,d0
57 movhu d0,(a0)
58 movhu (a0),d0
59
60 .if \disable_irq
61 LOCAL_IRQ_RESTORE(d1)
62 .endif
63
64#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
65
66 # invalidate
67 or CHCTR_ICINV,d0
68 movhu d0,(a0)
69 movhu (a0),d0
70
71#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
72 .endm
73
74###############################################################################
75#
76# Invalidate the data cache.
77# A0: Should hold CHCTR
78# D0: Should have been read from CHCTR
79# D1: Will be clobbered
80#
81# On some cores it is necessary to disable the dcache whilst we do this.
82#
83###############################################################################
84 .macro invalidate_dcache,disable_irq
85
86#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
87 .if \disable_irq
88 # don't want an interrupt routine seeing a disabled cache
89 mov epsw,d1
90 and ~EPSW_IE,epsw
91 or EPSW_NMID,epsw
92 nop
93 nop
94 .endif
95
96 # disable the dcache
97 and ~CHCTR_DCEN,d0
98 movhu d0,(a0)
99
100 # and wait for it to calm down
101 setlb
102 movhu (a0),d0
103 btst CHCTR_DCBUSY,d0
104 lne
105
106 # invalidate
107 or CHCTR_DCINV,d0
108 movhu d0,(a0)
109
110 # wait for the cache to finish
111 setlb
112 movhu (a0),d0
113 btst CHCTR_DCBUSY,d0
114 lne
115
116 # and reenable it
117 or CHCTR_DCEN,d0
118 movhu d0,(a0)
119 movhu (a0),d0
120
121 .if \disable_irq
122 LOCAL_IRQ_RESTORE(d1)
123 .endif
124
125#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
126
127 # invalidate
128 or CHCTR_DCINV,d0
129 movhu d0,(a0)
130 movhu (a0),d0
131
132#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
133 .endm
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c
index 59c3da49d9d9..0945409a8022 100644
--- a/arch/mn10300/mm/fault.c
+++ b/arch/mn10300/mm/fault.c
@@ -28,8 +28,9 @@
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <asm/pgalloc.h> 29#include <asm/pgalloc.h>
30#include <asm/hardirq.h> 30#include <asm/hardirq.h>
31#include <asm/gdb-stub.h>
32#include <asm/cpu-regs.h> 31#include <asm/cpu-regs.h>
32#include <asm/debugger.h>
33#include <asm/gdb-stub.h>
33 34
34/* 35/*
35 * Unlock any spinlocks which will prevent us from getting the 36 * Unlock any spinlocks which will prevent us from getting the
@@ -306,10 +307,8 @@ no_context:
306 printk(" printing pc:\n"); 307 printk(" printing pc:\n");
307 printk(KERN_ALERT "%08lx\n", regs->pc); 308 printk(KERN_ALERT "%08lx\n", regs->pc);
308 309
309#ifdef CONFIG_GDBSTUB 310 debugger_intercept(fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR,
310 gdbstub_intercept( 311 SIGSEGV, SEGV_ACCERR, regs);
311 regs, fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR);
312#endif
313 312
314 page = PTBR; 313 page = PTBR;
315 page = ((unsigned long *) __va(page))[address >> 22]; 314 page = ((unsigned long *) __va(page))[address >> 22];
diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
index c1528004163c..967d144f307e 100644
--- a/arch/mn10300/proc-mn103e010/include/proc/cache.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
@@ -23,6 +23,7 @@
23#define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */ 23#define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */
24#define L1_CACHE_TAG_ENTRY 0x00000ff0 /* cache tag entry address mask */ 24#define L1_CACHE_TAG_ENTRY 0x00000ff0 /* cache tag entry address mask */
25#define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */ 25#define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */
26#define L1_CACHE_TAG_MASK +(L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY)
26 27
27/* 28/*
28 * specification of the interval between interrupt checking intervals whilst 29 * specification of the interval between interrupt checking intervals whilst
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
index cafd7b5b55b4..bcb5df2d892f 100644
--- a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
@@ -29,6 +29,7 @@
29#define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */ 29#define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */
30#define L1_CACHE_TAG_ENTRY 0x00000fe0 /* cache tag entry address mask */ 30#define L1_CACHE_TAG_ENTRY 0x00000fe0 /* cache tag entry address mask */
31#define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */ 31#define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */
32#define L1_CACHE_TAG_MASK +(L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY)
32 33
33/* 34/*
34 * specification of the interval between interrupt checking intervals whilst 35 * specification of the interval between interrupt checking intervals whilst
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index f4f4d700833a..b7ed8d7a9b33 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -544,7 +544,7 @@ void __init mem_init(void)
544unsigned long *empty_zero_page __read_mostly; 544unsigned long *empty_zero_page __read_mostly;
545EXPORT_SYMBOL(empty_zero_page); 545EXPORT_SYMBOL(empty_zero_page);
546 546
547void show_mem(void) 547void show_mem(unsigned int filter)
548{ 548{
549 int i,free = 0,total = 0,reserved = 0; 549 int i,free = 0,total = 0,reserved = 0;
550 int shared = 0, cached = 0; 550 int shared = 0, cached = 0;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index d17d04cfb2cd..33794c1d92c3 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -821,7 +821,7 @@ cmds(struct pt_regs *excp)
821 memzcan(); 821 memzcan();
822 break; 822 break;
823 case 'i': 823 case 'i':
824 show_mem(); 824 show_mem(0);
825 break; 825 break;
826 default: 826 default:
827 termch = cmd; 827 termch = cmd;
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 1fbf0c7583d0..9af3c8d0776b 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -23,8 +23,7 @@ config SUPERH
23 select HAVE_SPARSE_IRQ 23 select HAVE_SPARSE_IRQ
24 select RTC_LIB 24 select RTC_LIB
25 select GENERIC_ATOMIC64 25 select GENERIC_ATOMIC64
26 # Support the deprecated APIs until MFD and GPIOLIB catch up. 26 select GENERIC_HARDIRQS_NO_DEPRECATED
27 select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB
28 select GENERIC_IRQ_SHOW 27 select GENERIC_IRQ_SHOW
29 help 28 help
30 The SuperH is a RISC processor targeted for use in embedded systems 29 The SuperH is a RISC processor targeted for use in embedded systems
diff --git a/arch/sh/boards/board-edosk7760.c b/arch/sh/boards/board-edosk7760.c
index f47ac82da876..e9656a2cc4cc 100644
--- a/arch/sh/boards/board-edosk7760.c
+++ b/arch/sh/boards/board-edosk7760.c
@@ -56,7 +56,7 @@ static struct mtd_partition edosk7760_nor_flash_partitions[] = {
56 }, { 56 }, {
57 .name = "fs", 57 .name = "fs",
58 .offset = MTDPART_OFS_APPEND, 58 .offset = MTDPART_OFS_APPEND,
59 .size = SZ_26M, 59 .size = (26 << 20),
60 }, { 60 }, {
61 .name = "other", 61 .name = "other",
62 .offset = MTDPART_OFS_APPEND, 62 .offset = MTDPART_OFS_APPEND,
diff --git a/arch/sh/boot/romimage/mmcif-sh7724.c b/arch/sh/boot/romimage/mmcif-sh7724.c
index c84e7831018d..16b122510c84 100644
--- a/arch/sh/boot/romimage/mmcif-sh7724.c
+++ b/arch/sh/boot/romimage/mmcif-sh7724.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/mmc/sh_mmcif.h> 11#include <linux/mmc/sh_mmcif.h>
12#include <linux/mmc/boot.h>
12#include <mach/romimage.h> 13#include <mach/romimage.h>
13 14
14#define MMCIF_BASE (void __iomem *)0xa4ca0000 15#define MMCIF_BASE (void __iomem *)0xa4ca0000
@@ -29,7 +30,7 @@
29 */ 30 */
30asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) 31asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes)
31{ 32{
32 mmcif_update_progress(MMCIF_PROGRESS_ENTER); 33 mmcif_update_progress(MMC_PROGRESS_ENTER);
33 34
34 /* enable clock to the MMCIF hardware block */ 35 /* enable clock to the MMCIF hardware block */
35 __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2); 36 __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2);
@@ -52,12 +53,12 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes)
52 /* high drive capability for MMC pins */ 53 /* high drive capability for MMC pins */
53 __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA); 54 __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA);
54 55
55 mmcif_update_progress(MMCIF_PROGRESS_INIT); 56 mmcif_update_progress(MMC_PROGRESS_INIT);
56 57
57 /* setup MMCIF hardware */ 58 /* setup MMCIF hardware */
58 sh_mmcif_boot_init(MMCIF_BASE); 59 sh_mmcif_boot_init(MMCIF_BASE);
59 60
60 mmcif_update_progress(MMCIF_PROGRESS_LOAD); 61 mmcif_update_progress(MMC_PROGRESS_LOAD);
61 62
62 /* load kernel via MMCIF interface */ 63 /* load kernel via MMCIF interface */
63 sh_mmcif_boot_do_read(MMCIF_BASE, 512, 64 sh_mmcif_boot_do_read(MMCIF_BASE, 512,
@@ -67,5 +68,5 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes)
67 /* disable clock to the MMCIF hardware block */ 68 /* disable clock to the MMCIF hardware block */
68 __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); 69 __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2);
69 70
70 mmcif_update_progress(MMCIF_PROGRESS_DONE); 71 mmcif_update_progress(MMC_PROGRESS_DONE);
71} 72}
diff --git a/arch/sh/include/asm/sizes.h b/arch/sh/include/asm/sizes.h
index 0b9fe2d5c36d..dd248c2e1085 100644
--- a/arch/sh/include/asm/sizes.h
+++ b/arch/sh/include/asm/sizes.h
@@ -1,62 +1 @@
1/* #include <asm-generic/sizes.h>
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16/* DO NOT EDIT!! - this file automatically generated
17 * from .s file by awk -f s2h.awk
18 */
19/* Size definitions
20 * Copyright (C) ARM Limited 1998. All rights reserved.
21 */
22
23#ifndef __sizes_h
24#define __sizes_h 1
25
26/* handy sizes */
27#define SZ_16 0x00000010
28#define SZ_32 0x00000020
29#define SZ_64 0x00000040
30#define SZ_128 0x00000080
31#define SZ_256 0x00000100
32#define SZ_512 0x00000200
33
34#define SZ_1K 0x00000400
35#define SZ_2K 0x00000800
36#define SZ_4K 0x00001000
37#define SZ_8K 0x00002000
38#define SZ_16K 0x00004000
39#define SZ_32K 0x00008000
40#define SZ_64K 0x00010000
41#define SZ_128K 0x00020000
42#define SZ_256K 0x00040000
43#define SZ_512K 0x00080000
44
45#define SZ_1M 0x00100000
46#define SZ_2M 0x00200000
47#define SZ_4M 0x00400000
48#define SZ_8M 0x00800000
49#define SZ_16M 0x01000000
50#define SZ_26M 0x01a00000
51#define SZ_32M 0x02000000
52#define SZ_64M 0x04000000
53#define SZ_128M 0x08000000
54#define SZ_256M 0x10000000
55#define SZ_512M 0x20000000
56
57#define SZ_1G 0x40000000
58#define SZ_2G 0x80000000
59
60#endif
61
62/* END */
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index b5a74e88028d..ca7765e5f967 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -372,8 +372,9 @@
372#define __NR_name_to_handle_at 359 372#define __NR_name_to_handle_at 359
373#define __NR_open_by_handle_at 360 373#define __NR_open_by_handle_at 360
374#define __NR_clock_adjtime 361 374#define __NR_clock_adjtime 361
375#define __NR_syncfs 362
375 376
376#define NR_syscalls 362 377#define NR_syscalls 363
377 378
378#ifdef __KERNEL__ 379#ifdef __KERNEL__
379 380
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index 953da4a52199..a694009bb816 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -393,10 +393,11 @@
393#define __NR_name_to_handle_at 370 393#define __NR_name_to_handle_at 370
394#define __NR_open_by_handle_at 371 394#define __NR_open_by_handle_at 371
395#define __NR_clock_adjtime 372 395#define __NR_clock_adjtime 372
396#define __NR_syncfs 373
396 397
397#ifdef __KERNEL__ 398#ifdef __KERNEL__
398 399
399#define NR_syscalls 373 400#define NR_syscalls 374
400 401
401#define __ARCH_WANT_IPC_PARSE_VERSION 402#define __ARCH_WANT_IPC_PARSE_VERSION
402#define __ARCH_WANT_OLD_READDIR 403#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index f39ad57296b7..325f98b1736d 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -32,7 +32,7 @@ void free_thread_xstate(struct task_struct *tsk)
32#if THREAD_SHIFT < PAGE_SHIFT 32#if THREAD_SHIFT < PAGE_SHIFT
33static struct kmem_cache *thread_info_cache; 33static struct kmem_cache *thread_info_cache;
34 34
35struct thread_info *alloc_thread_info(struct task_struct *tsk, int node) 35struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node)
36{ 36{
37 struct thread_info *ti; 37 struct thread_info *ti;
38#ifdef CONFIG_DEBUG_STACK_USAGE 38#ifdef CONFIG_DEBUG_STACK_USAGE
@@ -57,7 +57,7 @@ void thread_info_cache_init(void)
57 THREAD_SIZE, SLAB_PANIC, NULL); 57 THREAD_SIZE, SLAB_PANIC, NULL);
58} 58}
59#else 59#else
60struct thread_info *alloc_thread_info(struct task_struct *tsk) 60struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node)
61{ 61{
62#ifdef CONFIG_DEBUG_STACK_USAGE 62#ifdef CONFIG_DEBUG_STACK_USAGE
63 gfp_t mask = GFP_KERNEL | __GFP_ZERO; 63 gfp_t mask = GFP_KERNEL | __GFP_ZERO;
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 90a15d29feeb..2130ca674e9b 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -101,6 +101,8 @@ static int set_single_step(struct task_struct *tsk, unsigned long addr)
101 101
102 attr = bp->attr; 102 attr = bp->attr;
103 attr.bp_addr = addr; 103 attr.bp_addr = addr;
104 /* reenable breakpoint */
105 attr.disabled = false;
104 err = modify_user_hw_breakpoint(bp, &attr); 106 err = modify_user_hw_breakpoint(bp, &attr);
105 if (unlikely(err)) 107 if (unlikely(err))
106 return err; 108 return err;
@@ -392,6 +394,9 @@ long arch_ptrace(struct task_struct *child, long request,
392 tmp = 0; 394 tmp = 0;
393 } else { 395 } else {
394 unsigned long index; 396 unsigned long index;
397 ret = init_fpu(child);
398 if (ret)
399 break;
395 index = addr - offsetof(struct user, fpu); 400 index = addr - offsetof(struct user, fpu);
396 tmp = ((unsigned long *)child->thread.xstate) 401 tmp = ((unsigned long *)child->thread.xstate)
397 [index >> 2]; 402 [index >> 2];
@@ -423,6 +428,9 @@ long arch_ptrace(struct task_struct *child, long request,
423 else if (addr >= offsetof(struct user, fpu) && 428 else if (addr >= offsetof(struct user, fpu) &&
424 addr < offsetof(struct user, u_fpvalid)) { 429 addr < offsetof(struct user, u_fpvalid)) {
425 unsigned long index; 430 unsigned long index;
431 ret = init_fpu(child);
432 if (ret)
433 break;
426 index = addr - offsetof(struct user, fpu); 434 index = addr - offsetof(struct user, fpu);
427 set_stopped_child_used_math(child); 435 set_stopped_child_used_math(child);
428 ((unsigned long *)child->thread.xstate) 436 ((unsigned long *)child->thread.xstate)
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 4436eacddb15..c8f97649f354 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -403,6 +403,9 @@ long arch_ptrace(struct task_struct *child, long request,
403 else if ((addr >= offsetof(struct user, fpu)) && 403 else if ((addr >= offsetof(struct user, fpu)) &&
404 (addr < offsetof(struct user, u_fpvalid))) { 404 (addr < offsetof(struct user, u_fpvalid))) {
405 unsigned long index; 405 unsigned long index;
406 ret = init_fpu(child);
407 if (ret)
408 break;
406 index = addr - offsetof(struct user, fpu); 409 index = addr - offsetof(struct user, fpu);
407 tmp = get_fpu_long(child, index); 410 tmp = get_fpu_long(child, index);
408 } else if (addr == offsetof(struct user, u_fpvalid)) { 411 } else if (addr == offsetof(struct user, u_fpvalid)) {
@@ -442,6 +445,9 @@ long arch_ptrace(struct task_struct *child, long request,
442 else if ((addr >= offsetof(struct user, fpu)) && 445 else if ((addr >= offsetof(struct user, fpu)) &&
443 (addr < offsetof(struct user, u_fpvalid))) { 446 (addr < offsetof(struct user, u_fpvalid))) {
444 unsigned long index; 447 unsigned long index;
448 ret = init_fpu(child);
449 if (ret)
450 break;
445 index = addr - offsetof(struct user, fpu); 451 index = addr - offsetof(struct user, fpu);
446 ret = put_fpu_long(child, index, data); 452 ret = put_fpu_long(child, index, data);
447 } 453 }
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index 768fb33fdd35..030966a9305c 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -379,3 +379,4 @@ ENTRY(sys_call_table)
379 .long sys_name_to_handle_at 379 .long sys_name_to_handle_at
380 .long sys_open_by_handle_at /* 360 */ 380 .long sys_open_by_handle_at /* 360 */
381 .long sys_clock_adjtime 381 .long sys_clock_adjtime
382 .long sys_syncfs
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S
index 44e7b00c8067..ca0a6142ab63 100644
--- a/arch/sh/kernel/syscalls_64.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -399,3 +399,4 @@ sys_call_table:
399 .long sys_name_to_handle_at /* 370 */ 399 .long sys_name_to_handle_at /* 370 */
400 .long sys_open_by_handle_at 400 .long sys_open_by_handle_at
401 .long sys_clock_adjtime 401 .long sys_clock_adjtime
402 .long sys_syncfs
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index b20b1b3eee4b..fad52f1f6812 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Privileged Space Mapping Buffer (PMB) Support. 4 * Privileged Space Mapping Buffer (PMB) Support.
5 * 5 *
6 * Copyright (C) 2005 - 2010 Paul Mundt 6 * Copyright (C) 2005 - 2011 Paul Mundt
7 * Copyright (C) 2010 Matt Fleming 7 * Copyright (C) 2010 Matt Fleming
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
@@ -12,7 +12,7 @@
12 */ 12 */
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/sysdev.h> 15#include <linux/syscore_ops.h>
16#include <linux/cpu.h> 16#include <linux/cpu.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/bitops.h> 18#include <linux/bitops.h>
@@ -874,46 +874,31 @@ static int __init pmb_debugfs_init(void)
874subsys_initcall(pmb_debugfs_init); 874subsys_initcall(pmb_debugfs_init);
875 875
876#ifdef CONFIG_PM 876#ifdef CONFIG_PM
877static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state) 877static void pmb_syscore_resume(void)
878{ 878{
879 static pm_message_t prev_state; 879 struct pmb_entry *pmbe;
880 int i; 880 int i;
881 881
882 /* Restore the PMB after a resume from hibernation */ 882 read_lock(&pmb_rwlock);
883 if (state.event == PM_EVENT_ON &&
884 prev_state.event == PM_EVENT_FREEZE) {
885 struct pmb_entry *pmbe;
886
887 read_lock(&pmb_rwlock);
888 883
889 for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { 884 for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
890 if (test_bit(i, pmb_map)) { 885 if (test_bit(i, pmb_map)) {
891 pmbe = &pmb_entry_list[i]; 886 pmbe = &pmb_entry_list[i];
892 set_pmb_entry(pmbe); 887 set_pmb_entry(pmbe);
893 }
894 } 888 }
895
896 read_unlock(&pmb_rwlock);
897 } 889 }
898 890
899 prev_state = state; 891 read_unlock(&pmb_rwlock);
900
901 return 0;
902}
903
904static int pmb_sysdev_resume(struct sys_device *dev)
905{
906 return pmb_sysdev_suspend(dev, PMSG_ON);
907} 892}
908 893
909static struct sysdev_driver pmb_sysdev_driver = { 894static struct syscore_ops pmb_syscore_ops = {
910 .suspend = pmb_sysdev_suspend, 895 .resume = pmb_syscore_resume,
911 .resume = pmb_sysdev_resume,
912}; 896};
913 897
914static int __init pmb_sysdev_init(void) 898static int __init pmb_sysdev_init(void)
915{ 899{
916 return sysdev_driver_register(&cpu_sysdev_class, &pmb_sysdev_driver); 900 register_syscore_ops(&pmb_syscore_ops);
901 return 0;
917} 902}
918subsys_initcall(pmb_sysdev_init); 903subsys_initcall(pmb_sysdev_init);
919#endif 904#endif
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 6d0e02c4fe09..4c31e2b6e71b 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -75,7 +75,7 @@ void __init kmap_init(void)
75 kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); 75 kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE);
76} 76}
77 77
78void show_mem(void) 78void show_mem(unsigned int filter)
79{ 79{
80 printk("Mem-info:\n"); 80 printk("Mem-info:\n");
81 show_free_areas(); 81 show_free_areas();
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c
index 1a2b36f8866d..de7d8e21e01d 100644
--- a/arch/tile/mm/pgtable.c
+++ b/arch/tile/mm/pgtable.c
@@ -41,7 +41,7 @@
41 * The normal show_free_areas() is too verbose on Tile, with dozens 41 * The normal show_free_areas() is too verbose on Tile, with dozens
42 * of processors and often four NUMA zones each with high and lowmem. 42 * of processors and often four NUMA zones each with high and lowmem.
43 */ 43 */
44void show_mem(void) 44void show_mem(unsigned int filter)
45{ 45{
46 struct zone *zone; 46 struct zone *zone;
47 47
diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c
index 3dbe3709b69d..1fc02633f700 100644
--- a/arch/unicore32/mm/init.c
+++ b/arch/unicore32/mm/init.c
@@ -55,7 +55,7 @@ early_param("initrd", early_initrd);
55 */ 55 */
56struct meminfo meminfo; 56struct meminfo meminfo;
57 57
58void show_mem(void) 58void show_mem(unsigned int filter)
59{ 59{
60 int free = 0, total = 0, reserved = 0; 60 int free = 0, total = 0, reserved = 0;
61 int shared = 0, cached = 0, slab = 0, i; 61 int shared = 0, cached = 0, slab = 0, i;
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 448d73a371ba..12e0e7dd869c 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -114,9 +114,8 @@ static inline void acpi_disable_pci(void)
114 acpi_noirq_set(); 114 acpi_noirq_set();
115} 115}
116 116
117/* routines for saving/restoring kernel state */ 117/* Low-level suspend routine. */
118extern int acpi_save_state_mem(void); 118extern int acpi_suspend_lowlevel(void);
119extern void acpi_restore_state_mem(void);
120 119
121extern const unsigned char acpi_wakeup_code[]; 120extern const unsigned char acpi_wakeup_code[];
122#define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code))) 121#define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code)))
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 4572c58e66d5..ff93bc1b09c3 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -25,12 +25,12 @@ static char temp_stack[4096];
25#endif 25#endif
26 26
27/** 27/**
28 * acpi_save_state_mem - save kernel state 28 * acpi_suspend_lowlevel - save kernel state
29 * 29 *
30 * Create an identity mapped page table and copy the wakeup routine to 30 * Create an identity mapped page table and copy the wakeup routine to
31 * low memory. 31 * low memory.
32 */ 32 */
33int acpi_save_state_mem(void) 33int acpi_suspend_lowlevel(void)
34{ 34{
35 struct wakeup_header *header; 35 struct wakeup_header *header;
36 /* address in low memory of the wakeup routine. */ 36 /* address in low memory of the wakeup routine. */
@@ -96,16 +96,10 @@ int acpi_save_state_mem(void)
96 saved_magic = 0x123456789abcdef0L; 96 saved_magic = 0x123456789abcdef0L;
97#endif /* CONFIG_64BIT */ 97#endif /* CONFIG_64BIT */
98 98
99 do_suspend_lowlevel();
99 return 0; 100 return 0;
100} 101}
101 102
102/*
103 * acpi_restore_state - undo effects of acpi_save_state_mem
104 */
105void acpi_restore_state_mem(void)
106{
107}
108
109static int __init acpi_sleep_setup(char *str) 103static int __init acpi_sleep_setup(char *str)
110{ 104{
111 while ((str != NULL) && (*str != '\0')) { 105 while ((str != NULL) && (*str != '\0')) {
diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h
index 86ba1c87165b..416d4be13fef 100644
--- a/arch/x86/kernel/acpi/sleep.h
+++ b/arch/x86/kernel/acpi/sleep.h
@@ -11,3 +11,5 @@ extern int wakeup_pmode_return;
11 11
12extern unsigned long acpi_copy_wakeup_routine(unsigned long); 12extern unsigned long acpi_copy_wakeup_routine(unsigned long);
13extern void wakeup_long64(void); 13extern void wakeup_long64(void);
14
15extern void do_suspend_lowlevel(void);
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c
index 8209472b27a5..83930deec3c6 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-apei.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c
@@ -106,24 +106,34 @@ int apei_write_mce(struct mce *m)
106ssize_t apei_read_mce(struct mce *m, u64 *record_id) 106ssize_t apei_read_mce(struct mce *m, u64 *record_id)
107{ 107{
108 struct cper_mce_record rcd; 108 struct cper_mce_record rcd;
109 ssize_t len; 109 int rc, pos;
110 110
111 len = erst_read_next(&rcd.hdr, sizeof(rcd)); 111 rc = erst_get_record_id_begin(&pos);
112 if (len <= 0) 112 if (rc)
113 return len; 113 return rc;
114 /* Can not skip other records in storage via ERST unless clear them */ 114retry:
115 else if (len != sizeof(rcd) || 115 rc = erst_get_record_id_next(&pos, record_id);
116 uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE)) { 116 if (rc)
117 if (printk_ratelimit()) 117 goto out;
118 pr_warning( 118 /* no more record */
119 "MCE-APEI: Can not skip the unknown record in ERST"); 119 if (*record_id == APEI_ERST_INVALID_RECORD_ID)
120 return -EIO; 120 goto out;
121 } 121 rc = erst_read(*record_id, &rcd.hdr, sizeof(rcd));
122 122 /* someone else has cleared the record, try next one */
123 if (rc == -ENOENT)
124 goto retry;
125 else if (rc < 0)
126 goto out;
127 /* try to skip other type records in storage */
128 else if (rc != sizeof(rcd) ||
129 uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE))
130 goto retry;
123 memcpy(m, &rcd.mce, sizeof(*m)); 131 memcpy(m, &rcd.mce, sizeof(*m));
124 *record_id = rcd.hdr.record_id; 132 rc = sizeof(*m);
133out:
134 erst_get_record_id_end();
125 135
126 return sizeof(*m); 136 return rc;
127} 137}
128 138
129/* Check whether there is record in ERST */ 139/* Check whether there is record in ERST */
diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c
index 127775696d6c..99513642a0e6 100644
--- a/arch/x86/platform/olpc/olpc-xo1.c
+++ b/arch/x86/platform/olpc/olpc-xo1.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/mfd/core.h>
18 19
19#include <asm/io.h> 20#include <asm/io.h>
20#include <asm/olpc.h> 21#include <asm/olpc.h>
@@ -56,25 +57,24 @@ static void xo1_power_off(void)
56static int __devinit olpc_xo1_probe(struct platform_device *pdev) 57static int __devinit olpc_xo1_probe(struct platform_device *pdev)
57{ 58{
58 struct resource *res; 59 struct resource *res;
60 int err;
59 61
60 /* don't run on non-XOs */ 62 /* don't run on non-XOs */
61 if (!machine_is_olpc()) 63 if (!machine_is_olpc())
62 return -ENODEV; 64 return -ENODEV;
63 65
66 err = mfd_cell_enable(pdev);
67 if (err)
68 return err;
69
64 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 70 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
65 if (!res) { 71 if (!res) {
66 dev_err(&pdev->dev, "can't fetch device resource info\n"); 72 dev_err(&pdev->dev, "can't fetch device resource info\n");
67 return -EIO; 73 return -EIO;
68 } 74 }
69 75 if (strcmp(pdev->name, "olpc-xo1-pms") == 0)
70 if (!request_region(res->start, resource_size(res), DRV_NAME)) {
71 dev_err(&pdev->dev, "can't request region\n");
72 return -EIO;
73 }
74
75 if (strcmp(pdev->name, "cs5535-pms") == 0)
76 pms_base = res->start; 76 pms_base = res->start;
77 else if (strcmp(pdev->name, "cs5535-acpi") == 0) 77 else if (strcmp(pdev->name, "olpc-xo1-ac-acpi") == 0)
78 acpi_base = res->start; 78 acpi_base = res->start;
79 79
80 /* If we have both addresses, we can override the poweroff hook */ 80 /* If we have both addresses, we can override the poweroff hook */
@@ -88,14 +88,11 @@ static int __devinit olpc_xo1_probe(struct platform_device *pdev)
88 88
89static int __devexit olpc_xo1_remove(struct platform_device *pdev) 89static int __devexit olpc_xo1_remove(struct platform_device *pdev)
90{ 90{
91 struct resource *r; 91 mfd_cell_disable(pdev);
92
93 r = platform_get_resource(pdev, IORESOURCE_IO, 0);
94 release_region(r->start, resource_size(r));
95 92
96 if (strcmp(pdev->name, "cs5535-pms") == 0) 93 if (strcmp(pdev->name, "olpc-xo1-pms") == 0)
97 pms_base = 0; 94 pms_base = 0;
98 else if (strcmp(pdev->name, "cs5535-acpi") == 0) 95 else if (strcmp(pdev->name, "olpc-xo1-acpi") == 0)
99 acpi_base = 0; 96 acpi_base = 0;
100 97
101 pm_power_off = NULL; 98 pm_power_off = NULL;
@@ -104,7 +101,7 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev)
104 101
105static struct platform_driver cs5535_pms_drv = { 102static struct platform_driver cs5535_pms_drv = {
106 .driver = { 103 .driver = {
107 .name = "cs5535-pms", 104 .name = "olpc-xo1-pms",
108 .owner = THIS_MODULE, 105 .owner = THIS_MODULE,
109 }, 106 },
110 .probe = olpc_xo1_probe, 107 .probe = olpc_xo1_probe,
@@ -113,7 +110,7 @@ static struct platform_driver cs5535_pms_drv = {
113 110
114static struct platform_driver cs5535_acpi_drv = { 111static struct platform_driver cs5535_acpi_drv = {
115 .driver = { 112 .driver = {
116 .name = "cs5535-acpi", 113 .name = "olpc-xo1-acpi",
117 .owner = THIS_MODULE, 114 .owner = THIS_MODULE,
118 }, 115 },
119 .probe = olpc_xo1_probe, 116 .probe = olpc_xo1_probe,
@@ -124,26 +121,27 @@ static int __init olpc_xo1_init(void)
124{ 121{
125 int r; 122 int r;
126 123
127 r = platform_driver_register(&cs5535_pms_drv); 124 r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms");
128 if (r) 125 if (r)
129 return r; 126 return r;
130 127
131 r = platform_driver_register(&cs5535_acpi_drv); 128 r = mfd_shared_platform_driver_register(&cs5535_acpi_drv,
129 "cs5535-acpi");
132 if (r) 130 if (r)
133 platform_driver_unregister(&cs5535_pms_drv); 131 mfd_shared_platform_driver_unregister(&cs5535_pms_drv);
134 132
135 return r; 133 return r;
136} 134}
137 135
138static void __exit olpc_xo1_exit(void) 136static void __exit olpc_xo1_exit(void)
139{ 137{
140 platform_driver_unregister(&cs5535_acpi_drv); 138 mfd_shared_platform_driver_unregister(&cs5535_acpi_drv);
141 platform_driver_unregister(&cs5535_pms_drv); 139 mfd_shared_platform_driver_unregister(&cs5535_pms_drv);
142} 140}
143 141
144MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); 142MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
145MODULE_LICENSE("GPL"); 143MODULE_LICENSE("GPL");
146MODULE_ALIAS("platform:olpc-xo1"); 144MODULE_ALIAS("platform:cs5535-pms");
147 145
148module_init(olpc_xo1_init); 146module_init(olpc_xo1_init);
149module_exit(olpc_xo1_exit); 147module_exit(olpc_xo1_exit);
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 455768a3eb9e..2bef5705ce24 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -371,12 +371,14 @@ void blkiocg_update_io_remove_stats(struct blkio_group *blkg,
371} 371}
372EXPORT_SYMBOL_GPL(blkiocg_update_io_remove_stats); 372EXPORT_SYMBOL_GPL(blkiocg_update_io_remove_stats);
373 373
374void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time) 374void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time,
375 unsigned long unaccounted_time)
375{ 376{
376 unsigned long flags; 377 unsigned long flags;
377 378
378 spin_lock_irqsave(&blkg->stats_lock, flags); 379 spin_lock_irqsave(&blkg->stats_lock, flags);
379 blkg->stats.time += time; 380 blkg->stats.time += time;
381 blkg->stats.unaccounted_time += unaccounted_time;
380 spin_unlock_irqrestore(&blkg->stats_lock, flags); 382 spin_unlock_irqrestore(&blkg->stats_lock, flags);
381} 383}
382EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used); 384EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used);
@@ -604,6 +606,9 @@ static uint64_t blkio_get_stat(struct blkio_group *blkg,
604 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, 606 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
605 blkg->stats.sectors, cb, dev); 607 blkg->stats.sectors, cb, dev);
606#ifdef CONFIG_DEBUG_BLK_CGROUP 608#ifdef CONFIG_DEBUG_BLK_CGROUP
609 if (type == BLKIO_STAT_UNACCOUNTED_TIME)
610 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
611 blkg->stats.unaccounted_time, cb, dev);
607 if (type == BLKIO_STAT_AVG_QUEUE_SIZE) { 612 if (type == BLKIO_STAT_AVG_QUEUE_SIZE) {
608 uint64_t sum = blkg->stats.avg_queue_size_sum; 613 uint64_t sum = blkg->stats.avg_queue_size_sum;
609 uint64_t samples = blkg->stats.avg_queue_size_samples; 614 uint64_t samples = blkg->stats.avg_queue_size_samples;
@@ -1125,6 +1130,9 @@ static int blkiocg_file_read_map(struct cgroup *cgrp, struct cftype *cft,
1125 return blkio_read_blkg_stats(blkcg, cft, cb, 1130 return blkio_read_blkg_stats(blkcg, cft, cb,
1126 BLKIO_STAT_QUEUED, 1); 1131 BLKIO_STAT_QUEUED, 1);
1127#ifdef CONFIG_DEBUG_BLK_CGROUP 1132#ifdef CONFIG_DEBUG_BLK_CGROUP
1133 case BLKIO_PROP_unaccounted_time:
1134 return blkio_read_blkg_stats(blkcg, cft, cb,
1135 BLKIO_STAT_UNACCOUNTED_TIME, 0);
1128 case BLKIO_PROP_dequeue: 1136 case BLKIO_PROP_dequeue:
1129 return blkio_read_blkg_stats(blkcg, cft, cb, 1137 return blkio_read_blkg_stats(blkcg, cft, cb,
1130 BLKIO_STAT_DEQUEUE, 0); 1138 BLKIO_STAT_DEQUEUE, 0);
@@ -1382,6 +1390,12 @@ struct cftype blkio_files[] = {
1382 BLKIO_PROP_dequeue), 1390 BLKIO_PROP_dequeue),
1383 .read_map = blkiocg_file_read_map, 1391 .read_map = blkiocg_file_read_map,
1384 }, 1392 },
1393 {
1394 .name = "unaccounted_time",
1395 .private = BLKIOFILE_PRIVATE(BLKIO_POLICY_PROP,
1396 BLKIO_PROP_unaccounted_time),
1397 .read_map = blkiocg_file_read_map,
1398 },
1385#endif 1399#endif
1386}; 1400};
1387 1401
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
index ea4861bdd549..10919fae2d3a 100644
--- a/block/blk-cgroup.h
+++ b/block/blk-cgroup.h
@@ -49,6 +49,8 @@ enum stat_type {
49 /* All the single valued stats go below this */ 49 /* All the single valued stats go below this */
50 BLKIO_STAT_TIME, 50 BLKIO_STAT_TIME,
51 BLKIO_STAT_SECTORS, 51 BLKIO_STAT_SECTORS,
52 /* Time not charged to this cgroup */
53 BLKIO_STAT_UNACCOUNTED_TIME,
52#ifdef CONFIG_DEBUG_BLK_CGROUP 54#ifdef CONFIG_DEBUG_BLK_CGROUP
53 BLKIO_STAT_AVG_QUEUE_SIZE, 55 BLKIO_STAT_AVG_QUEUE_SIZE,
54 BLKIO_STAT_IDLE_TIME, 56 BLKIO_STAT_IDLE_TIME,
@@ -81,6 +83,7 @@ enum blkcg_file_name_prop {
81 BLKIO_PROP_io_serviced, 83 BLKIO_PROP_io_serviced,
82 BLKIO_PROP_time, 84 BLKIO_PROP_time,
83 BLKIO_PROP_sectors, 85 BLKIO_PROP_sectors,
86 BLKIO_PROP_unaccounted_time,
84 BLKIO_PROP_io_service_time, 87 BLKIO_PROP_io_service_time,
85 BLKIO_PROP_io_wait_time, 88 BLKIO_PROP_io_wait_time,
86 BLKIO_PROP_io_merged, 89 BLKIO_PROP_io_merged,
@@ -114,6 +117,8 @@ struct blkio_group_stats {
114 /* total disk time and nr sectors dispatched by this group */ 117 /* total disk time and nr sectors dispatched by this group */
115 uint64_t time; 118 uint64_t time;
116 uint64_t sectors; 119 uint64_t sectors;
120 /* Time not charged to this cgroup */
121 uint64_t unaccounted_time;
117 uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL]; 122 uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL];
118#ifdef CONFIG_DEBUG_BLK_CGROUP 123#ifdef CONFIG_DEBUG_BLK_CGROUP
119 /* Sum of number of IOs queued across all samples */ 124 /* Sum of number of IOs queued across all samples */
@@ -240,7 +245,7 @@ static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }
240 245
241#endif 246#endif
242 247
243#define BLKIO_WEIGHT_MIN 100 248#define BLKIO_WEIGHT_MIN 10
244#define BLKIO_WEIGHT_MAX 1000 249#define BLKIO_WEIGHT_MAX 1000
245#define BLKIO_WEIGHT_DEFAULT 500 250#define BLKIO_WEIGHT_DEFAULT 500
246 251
@@ -293,7 +298,8 @@ extern int blkiocg_del_blkio_group(struct blkio_group *blkg);
293extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg, 298extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg,
294 void *key); 299 void *key);
295void blkiocg_update_timeslice_used(struct blkio_group *blkg, 300void blkiocg_update_timeslice_used(struct blkio_group *blkg,
296 unsigned long time); 301 unsigned long time,
302 unsigned long unaccounted_time);
297void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes, 303void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes,
298 bool direction, bool sync); 304 bool direction, bool sync);
299void blkiocg_update_completion_stats(struct blkio_group *blkg, 305void blkiocg_update_completion_stats(struct blkio_group *blkg,
@@ -319,7 +325,9 @@ blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; }
319static inline struct blkio_group * 325static inline struct blkio_group *
320blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) { return NULL; } 326blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) { return NULL; }
321static inline void blkiocg_update_timeslice_used(struct blkio_group *blkg, 327static inline void blkiocg_update_timeslice_used(struct blkio_group *blkg,
322 unsigned long time) {} 328 unsigned long time,
329 unsigned long unaccounted_time)
330{}
323static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg, 331static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
324 uint64_t bytes, bool direction, bool sync) {} 332 uint64_t bytes, bool direction, bool sync) {}
325static inline void blkiocg_update_completion_stats(struct blkio_group *blkg, 333static inline void blkiocg_update_completion_stats(struct blkio_group *blkg,
diff --git a/block/blk-core.c b/block/blk-core.c
index a63336d49f30..59b5c00c0126 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -27,6 +27,7 @@
27#include <linux/writeback.h> 27#include <linux/writeback.h>
28#include <linux/task_io_accounting_ops.h> 28#include <linux/task_io_accounting_ops.h>
29#include <linux/fault-inject.h> 29#include <linux/fault-inject.h>
30#include <linux/list_sort.h>
30 31
31#define CREATE_TRACE_POINTS 32#define CREATE_TRACE_POINTS
32#include <trace/events/block.h> 33#include <trace/events/block.h>
@@ -149,39 +150,29 @@ EXPORT_SYMBOL(blk_rq_init);
149static void req_bio_endio(struct request *rq, struct bio *bio, 150static void req_bio_endio(struct request *rq, struct bio *bio,
150 unsigned int nbytes, int error) 151 unsigned int nbytes, int error)
151{ 152{
152 struct request_queue *q = rq->q; 153 if (error)
153 154 clear_bit(BIO_UPTODATE, &bio->bi_flags);
154 if (&q->flush_rq != rq) { 155 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
155 if (error) 156 error = -EIO;
156 clear_bit(BIO_UPTODATE, &bio->bi_flags);
157 else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
158 error = -EIO;
159 157
160 if (unlikely(nbytes > bio->bi_size)) { 158 if (unlikely(nbytes > bio->bi_size)) {
161 printk(KERN_ERR "%s: want %u bytes done, %u left\n", 159 printk(KERN_ERR "%s: want %u bytes done, %u left\n",
162 __func__, nbytes, bio->bi_size); 160 __func__, nbytes, bio->bi_size);
163 nbytes = bio->bi_size; 161 nbytes = bio->bi_size;
164 } 162 }
165 163
166 if (unlikely(rq->cmd_flags & REQ_QUIET)) 164 if (unlikely(rq->cmd_flags & REQ_QUIET))
167 set_bit(BIO_QUIET, &bio->bi_flags); 165 set_bit(BIO_QUIET, &bio->bi_flags);
168 166
169 bio->bi_size -= nbytes; 167 bio->bi_size -= nbytes;
170 bio->bi_sector += (nbytes >> 9); 168 bio->bi_sector += (nbytes >> 9);
171 169
172 if (bio_integrity(bio)) 170 if (bio_integrity(bio))
173 bio_integrity_advance(bio, nbytes); 171 bio_integrity_advance(bio, nbytes);
174 172
175 if (bio->bi_size == 0) 173 /* don't actually finish bio if it's part of flush sequence */
176 bio_endio(bio, error); 174 if (bio->bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
177 } else { 175 bio_endio(bio, error);
178 /*
179 * Okay, this is the sequenced flush request in
180 * progress, just record the error;
181 */
182 if (error && !q->flush_err)
183 q->flush_err = error;
184 }
185} 176}
186 177
187void blk_dump_rq_flags(struct request *rq, char *msg) 178void blk_dump_rq_flags(struct request *rq, char *msg)
@@ -208,135 +199,43 @@ void blk_dump_rq_flags(struct request *rq, char *msg)
208EXPORT_SYMBOL(blk_dump_rq_flags); 199EXPORT_SYMBOL(blk_dump_rq_flags);
209 200
210/* 201/*
211 * "plug" the device if there are no outstanding requests: this will 202 * Make sure that plugs that were pending when this function was entered,
212 * force the transfer to start only after we have put all the requests 203 * are now complete and requests pushed to the queue.
213 * on the list. 204*/
214 * 205static inline void queue_sync_plugs(struct request_queue *q)
215 * This is called with interrupts off and no requests on the queue and
216 * with the queue lock held.
217 */
218void blk_plug_device(struct request_queue *q)
219{ 206{
220 WARN_ON(!irqs_disabled());
221
222 /* 207 /*
223 * don't plug a stopped queue, it must be paired with blk_start_queue() 208 * If the current process is plugged and has barriers submitted,
224 * which will restart the queueing 209 * we will livelock if we don't unplug first.
225 */ 210 */
226 if (blk_queue_stopped(q)) 211 blk_flush_plug(current);
227 return;
228
229 if (!queue_flag_test_and_set(QUEUE_FLAG_PLUGGED, q)) {
230 mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
231 trace_block_plug(q);
232 }
233}
234EXPORT_SYMBOL(blk_plug_device);
235
236/**
237 * blk_plug_device_unlocked - plug a device without queue lock held
238 * @q: The &struct request_queue to plug
239 *
240 * Description:
241 * Like @blk_plug_device(), but grabs the queue lock and disables
242 * interrupts.
243 **/
244void blk_plug_device_unlocked(struct request_queue *q)
245{
246 unsigned long flags;
247
248 spin_lock_irqsave(q->queue_lock, flags);
249 blk_plug_device(q);
250 spin_unlock_irqrestore(q->queue_lock, flags);
251}
252EXPORT_SYMBOL(blk_plug_device_unlocked);
253
254/*
255 * remove the queue from the plugged list, if present. called with
256 * queue lock held and interrupts disabled.
257 */
258int blk_remove_plug(struct request_queue *q)
259{
260 WARN_ON(!irqs_disabled());
261
262 if (!queue_flag_test_and_clear(QUEUE_FLAG_PLUGGED, q))
263 return 0;
264
265 del_timer(&q->unplug_timer);
266 return 1;
267} 212}
268EXPORT_SYMBOL(blk_remove_plug);
269 213
270/* 214static void blk_delay_work(struct work_struct *work)
271 * remove the plug and let it rip..
272 */
273void __generic_unplug_device(struct request_queue *q)
274{ 215{
275 if (unlikely(blk_queue_stopped(q))) 216 struct request_queue *q;
276 return;
277 if (!blk_remove_plug(q) && !blk_queue_nonrot(q))
278 return;
279 217
280 q->request_fn(q); 218 q = container_of(work, struct request_queue, delay_work.work);
219 spin_lock_irq(q->queue_lock);
220 __blk_run_queue(q, false);
221 spin_unlock_irq(q->queue_lock);
281} 222}
282 223
283/** 224/**
284 * generic_unplug_device - fire a request queue 225 * blk_delay_queue - restart queueing after defined interval
285 * @q: The &struct request_queue in question 226 * @q: The &struct request_queue in question
227 * @msecs: Delay in msecs
286 * 228 *
287 * Description: 229 * Description:
288 * Linux uses plugging to build bigger requests queues before letting 230 * Sometimes queueing needs to be postponed for a little while, to allow
289 * the device have at them. If a queue is plugged, the I/O scheduler 231 * resources to come back. This function will make sure that queueing is
290 * is still adding and merging requests on the queue. Once the queue 232 * restarted around the specified time.
291 * gets unplugged, the request_fn defined for the queue is invoked and 233 */
292 * transfers started. 234void blk_delay_queue(struct request_queue *q, unsigned long msecs)
293 **/
294void generic_unplug_device(struct request_queue *q)
295{
296 if (blk_queue_plugged(q)) {
297 spin_lock_irq(q->queue_lock);
298 __generic_unplug_device(q);
299 spin_unlock_irq(q->queue_lock);
300 }
301}
302EXPORT_SYMBOL(generic_unplug_device);
303
304static void blk_backing_dev_unplug(struct backing_dev_info *bdi,
305 struct page *page)
306{
307 struct request_queue *q = bdi->unplug_io_data;
308
309 blk_unplug(q);
310}
311
312void blk_unplug_work(struct work_struct *work)
313{
314 struct request_queue *q =
315 container_of(work, struct request_queue, unplug_work);
316
317 trace_block_unplug_io(q);
318 q->unplug_fn(q);
319}
320
321void blk_unplug_timeout(unsigned long data)
322{
323 struct request_queue *q = (struct request_queue *)data;
324
325 trace_block_unplug_timer(q);
326 kblockd_schedule_work(q, &q->unplug_work);
327}
328
329void blk_unplug(struct request_queue *q)
330{ 235{
331 /* 236 schedule_delayed_work(&q->delay_work, msecs_to_jiffies(msecs));
332 * devices don't necessarily have an ->unplug_fn defined
333 */
334 if (q->unplug_fn) {
335 trace_block_unplug_io(q);
336 q->unplug_fn(q);
337 }
338} 237}
339EXPORT_SYMBOL(blk_unplug); 238EXPORT_SYMBOL(blk_delay_queue);
340 239
341/** 240/**
342 * blk_start_queue - restart a previously stopped queue 241 * blk_start_queue - restart a previously stopped queue
@@ -372,7 +271,7 @@ EXPORT_SYMBOL(blk_start_queue);
372 **/ 271 **/
373void blk_stop_queue(struct request_queue *q) 272void blk_stop_queue(struct request_queue *q)
374{ 273{
375 blk_remove_plug(q); 274 cancel_delayed_work(&q->delay_work);
376 queue_flag_set(QUEUE_FLAG_STOPPED, q); 275 queue_flag_set(QUEUE_FLAG_STOPPED, q);
377} 276}
378EXPORT_SYMBOL(blk_stop_queue); 277EXPORT_SYMBOL(blk_stop_queue);
@@ -390,13 +289,16 @@ EXPORT_SYMBOL(blk_stop_queue);
390 * that its ->make_request_fn will not re-add plugging prior to calling 289 * that its ->make_request_fn will not re-add plugging prior to calling
391 * this function. 290 * this function.
392 * 291 *
292 * This function does not cancel any asynchronous activity arising
293 * out of elevator or throttling code. That would require elevaotor_exit()
294 * and blk_throtl_exit() to be called with queue lock initialized.
295 *
393 */ 296 */
394void blk_sync_queue(struct request_queue *q) 297void blk_sync_queue(struct request_queue *q)
395{ 298{
396 del_timer_sync(&q->unplug_timer);
397 del_timer_sync(&q->timeout); 299 del_timer_sync(&q->timeout);
398 cancel_work_sync(&q->unplug_work); 300 cancel_delayed_work_sync(&q->delay_work);
399 throtl_shutdown_timer_wq(q); 301 queue_sync_plugs(q);
400} 302}
401EXPORT_SYMBOL(blk_sync_queue); 303EXPORT_SYMBOL(blk_sync_queue);
402 304
@@ -412,14 +314,9 @@ EXPORT_SYMBOL(blk_sync_queue);
412 */ 314 */
413void __blk_run_queue(struct request_queue *q, bool force_kblockd) 315void __blk_run_queue(struct request_queue *q, bool force_kblockd)
414{ 316{
415 blk_remove_plug(q);
416
417 if (unlikely(blk_queue_stopped(q))) 317 if (unlikely(blk_queue_stopped(q)))
418 return; 318 return;
419 319
420 if (elv_queue_empty(q))
421 return;
422
423 /* 320 /*
424 * Only recurse once to avoid overrunning the stack, let the unplug 321 * Only recurse once to avoid overrunning the stack, let the unplug
425 * handling reinvoke the handler shortly if we already got there. 322 * handling reinvoke the handler shortly if we already got there.
@@ -427,10 +324,8 @@ void __blk_run_queue(struct request_queue *q, bool force_kblockd)
427 if (!force_kblockd && !queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { 324 if (!force_kblockd && !queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
428 q->request_fn(q); 325 q->request_fn(q);
429 queue_flag_clear(QUEUE_FLAG_REENTER, q); 326 queue_flag_clear(QUEUE_FLAG_REENTER, q);
430 } else { 327 } else
431 queue_flag_set(QUEUE_FLAG_PLUGGED, q); 328 queue_delayed_work(kblockd_workqueue, &q->delay_work, 0);
432 kblockd_schedule_work(q, &q->unplug_work);
433 }
434} 329}
435EXPORT_SYMBOL(__blk_run_queue); 330EXPORT_SYMBOL(__blk_run_queue);
436 331
@@ -457,6 +352,11 @@ void blk_put_queue(struct request_queue *q)
457 kobject_put(&q->kobj); 352 kobject_put(&q->kobj);
458} 353}
459 354
355/*
356 * Note: If a driver supplied the queue lock, it should not zap that lock
357 * unexpectedly as some queue cleanup components like elevator_exit() and
358 * blk_throtl_exit() need queue lock.
359 */
460void blk_cleanup_queue(struct request_queue *q) 360void blk_cleanup_queue(struct request_queue *q)
461{ 361{
462 /* 362 /*
@@ -475,6 +375,8 @@ void blk_cleanup_queue(struct request_queue *q)
475 if (q->elevator) 375 if (q->elevator)
476 elevator_exit(q->elevator); 376 elevator_exit(q->elevator);
477 377
378 blk_throtl_exit(q);
379
478 blk_put_queue(q); 380 blk_put_queue(q);
479} 381}
480EXPORT_SYMBOL(blk_cleanup_queue); 382EXPORT_SYMBOL(blk_cleanup_queue);
@@ -517,8 +419,6 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
517 if (!q) 419 if (!q)
518 return NULL; 420 return NULL;
519 421
520 q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug;
521 q->backing_dev_info.unplug_io_data = q;
522 q->backing_dev_info.ra_pages = 422 q->backing_dev_info.ra_pages =
523 (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 423 (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
524 q->backing_dev_info.state = 0; 424 q->backing_dev_info.state = 0;
@@ -538,17 +438,24 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
538 438
539 setup_timer(&q->backing_dev_info.laptop_mode_wb_timer, 439 setup_timer(&q->backing_dev_info.laptop_mode_wb_timer,
540 laptop_mode_timer_fn, (unsigned long) q); 440 laptop_mode_timer_fn, (unsigned long) q);
541 init_timer(&q->unplug_timer);
542 setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q); 441 setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
543 INIT_LIST_HEAD(&q->timeout_list); 442 INIT_LIST_HEAD(&q->timeout_list);
544 INIT_LIST_HEAD(&q->pending_flushes); 443 INIT_LIST_HEAD(&q->flush_queue[0]);
545 INIT_WORK(&q->unplug_work, blk_unplug_work); 444 INIT_LIST_HEAD(&q->flush_queue[1]);
445 INIT_LIST_HEAD(&q->flush_data_in_flight);
446 INIT_DELAYED_WORK(&q->delay_work, blk_delay_work);
546 447
547 kobject_init(&q->kobj, &blk_queue_ktype); 448 kobject_init(&q->kobj, &blk_queue_ktype);
548 449
549 mutex_init(&q->sysfs_lock); 450 mutex_init(&q->sysfs_lock);
550 spin_lock_init(&q->__queue_lock); 451 spin_lock_init(&q->__queue_lock);
551 452
453 /*
454 * By default initialize queue_lock to internal lock and driver can
455 * override it later if need be.
456 */
457 q->queue_lock = &q->__queue_lock;
458
552 return q; 459 return q;
553} 460}
554EXPORT_SYMBOL(blk_alloc_queue_node); 461EXPORT_SYMBOL(blk_alloc_queue_node);
@@ -631,9 +538,11 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
631 q->request_fn = rfn; 538 q->request_fn = rfn;
632 q->prep_rq_fn = NULL; 539 q->prep_rq_fn = NULL;
633 q->unprep_rq_fn = NULL; 540 q->unprep_rq_fn = NULL;
634 q->unplug_fn = generic_unplug_device;
635 q->queue_flags = QUEUE_FLAG_DEFAULT; 541 q->queue_flags = QUEUE_FLAG_DEFAULT;
636 q->queue_lock = lock; 542
543 /* Override internal queue lock with supplied lock pointer */
544 if (lock)
545 q->queue_lock = lock;
637 546
638 /* 547 /*
639 * This also sets hw/phys segments, boundary and size 548 * This also sets hw/phys segments, boundary and size
@@ -666,6 +575,8 @@ int blk_get_queue(struct request_queue *q)
666 575
667static inline void blk_free_request(struct request_queue *q, struct request *rq) 576static inline void blk_free_request(struct request_queue *q, struct request *rq)
668{ 577{
578 BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
579
669 if (rq->cmd_flags & REQ_ELVPRIV) 580 if (rq->cmd_flags & REQ_ELVPRIV)
670 elv_put_request(q, rq); 581 elv_put_request(q, rq);
671 mempool_free(rq, q->rq.rq_pool); 582 mempool_free(rq, q->rq.rq_pool);
@@ -762,6 +673,25 @@ static void freed_request(struct request_queue *q, int sync, int priv)
762} 673}
763 674
764/* 675/*
676 * Determine if elevator data should be initialized when allocating the
677 * request associated with @bio.
678 */
679static bool blk_rq_should_init_elevator(struct bio *bio)
680{
681 if (!bio)
682 return true;
683
684 /*
685 * Flush requests do not use the elevator so skip initialization.
686 * This allows a request to share the flush and elevator data.
687 */
688 if (bio->bi_rw & (REQ_FLUSH | REQ_FUA))
689 return false;
690
691 return true;
692}
693
694/*
765 * Get a free request, queue_lock must be held. 695 * Get a free request, queue_lock must be held.
766 * Returns NULL on failure, with queue_lock held. 696 * Returns NULL on failure, with queue_lock held.
767 * Returns !NULL on success, with queue_lock *not held*. 697 * Returns !NULL on success, with queue_lock *not held*.
@@ -773,7 +703,7 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
773 struct request_list *rl = &q->rq; 703 struct request_list *rl = &q->rq;
774 struct io_context *ioc = NULL; 704 struct io_context *ioc = NULL;
775 const bool is_sync = rw_is_sync(rw_flags) != 0; 705 const bool is_sync = rw_is_sync(rw_flags) != 0;
776 int may_queue, priv; 706 int may_queue, priv = 0;
777 707
778 may_queue = elv_may_queue(q, rw_flags); 708 may_queue = elv_may_queue(q, rw_flags);
779 if (may_queue == ELV_MQUEUE_NO) 709 if (may_queue == ELV_MQUEUE_NO)
@@ -817,9 +747,11 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
817 rl->count[is_sync]++; 747 rl->count[is_sync]++;
818 rl->starved[is_sync] = 0; 748 rl->starved[is_sync] = 0;
819 749
820 priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); 750 if (blk_rq_should_init_elevator(bio)) {
821 if (priv) 751 priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
822 rl->elvpriv++; 752 if (priv)
753 rl->elvpriv++;
754 }
823 755
824 if (blk_queue_io_stat(q)) 756 if (blk_queue_io_stat(q))
825 rw_flags |= REQ_IO_STAT; 757 rw_flags |= REQ_IO_STAT;
@@ -866,8 +798,8 @@ out:
866} 798}
867 799
868/* 800/*
869 * No available requests for this queue, unplug the device and wait for some 801 * No available requests for this queue, wait for some requests to become
870 * requests to become available. 802 * available.
871 * 803 *
872 * Called with q->queue_lock held, and returns with it unlocked. 804 * Called with q->queue_lock held, and returns with it unlocked.
873 */ 805 */
@@ -888,7 +820,6 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
888 820
889 trace_block_sleeprq(q, bio, rw_flags & 1); 821 trace_block_sleeprq(q, bio, rw_flags & 1);
890 822
891 __generic_unplug_device(q);
892 spin_unlock_irq(q->queue_lock); 823 spin_unlock_irq(q->queue_lock);
893 io_schedule(); 824 io_schedule();
894 825
@@ -1010,6 +941,13 @@ void blk_requeue_request(struct request_queue *q, struct request *rq)
1010} 941}
1011EXPORT_SYMBOL(blk_requeue_request); 942EXPORT_SYMBOL(blk_requeue_request);
1012 943
944static void add_acct_request(struct request_queue *q, struct request *rq,
945 int where)
946{
947 drive_stat_acct(rq, 1);
948 __elv_add_request(q, rq, where);
949}
950
1013/** 951/**
1014 * blk_insert_request - insert a special request into a request queue 952 * blk_insert_request - insert a special request into a request queue
1015 * @q: request queue where request should be inserted 953 * @q: request queue where request should be inserted
@@ -1052,8 +990,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq,
1052 if (blk_rq_tagged(rq)) 990 if (blk_rq_tagged(rq))
1053 blk_queue_end_tag(q, rq); 991 blk_queue_end_tag(q, rq);
1054 992
1055 drive_stat_acct(rq, 1); 993 add_acct_request(q, rq, where);
1056 __elv_add_request(q, rq, where, 0);
1057 __blk_run_queue(q, false); 994 __blk_run_queue(q, false);
1058 spin_unlock_irqrestore(q->queue_lock, flags); 995 spin_unlock_irqrestore(q->queue_lock, flags);
1059} 996}
@@ -1174,6 +1111,113 @@ void blk_add_request_payload(struct request *rq, struct page *page,
1174} 1111}
1175EXPORT_SYMBOL_GPL(blk_add_request_payload); 1112EXPORT_SYMBOL_GPL(blk_add_request_payload);
1176 1113
1114static bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
1115 struct bio *bio)
1116{
1117 const int ff = bio->bi_rw & REQ_FAILFAST_MASK;
1118
1119 /*
1120 * Debug stuff, kill later
1121 */
1122 if (!rq_mergeable(req)) {
1123 blk_dump_rq_flags(req, "back");
1124 return false;
1125 }
1126
1127 if (!ll_back_merge_fn(q, req, bio))
1128 return false;
1129
1130 trace_block_bio_backmerge(q, bio);
1131
1132 if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
1133 blk_rq_set_mixed_merge(req);
1134
1135 req->biotail->bi_next = bio;
1136 req->biotail = bio;
1137 req->__data_len += bio->bi_size;
1138 req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
1139
1140 drive_stat_acct(req, 0);
1141 return true;
1142}
1143
1144static bool bio_attempt_front_merge(struct request_queue *q,
1145 struct request *req, struct bio *bio)
1146{
1147 const int ff = bio->bi_rw & REQ_FAILFAST_MASK;
1148 sector_t sector;
1149
1150 /*
1151 * Debug stuff, kill later
1152 */
1153 if (!rq_mergeable(req)) {
1154 blk_dump_rq_flags(req, "front");
1155 return false;
1156 }
1157
1158 if (!ll_front_merge_fn(q, req, bio))
1159 return false;
1160
1161 trace_block_bio_frontmerge(q, bio);
1162
1163 if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
1164 blk_rq_set_mixed_merge(req);
1165
1166 sector = bio->bi_sector;
1167
1168 bio->bi_next = req->bio;
1169 req->bio = bio;
1170
1171 /*
1172 * may not be valid. if the low level driver said
1173 * it didn't need a bounce buffer then it better
1174 * not touch req->buffer either...
1175 */
1176 req->buffer = bio_data(bio);
1177 req->__sector = bio->bi_sector;
1178 req->__data_len += bio->bi_size;
1179 req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
1180
1181 drive_stat_acct(req, 0);
1182 return true;
1183}
1184
1185/*
1186 * Attempts to merge with the plugged list in the current process. Returns
1187 * true if merge was succesful, otherwise false.
1188 */
1189static bool attempt_plug_merge(struct task_struct *tsk, struct request_queue *q,
1190 struct bio *bio)
1191{
1192 struct blk_plug *plug;
1193 struct request *rq;
1194 bool ret = false;
1195
1196 plug = tsk->plug;
1197 if (!plug)
1198 goto out;
1199
1200 list_for_each_entry_reverse(rq, &plug->list, queuelist) {
1201 int el_ret;
1202
1203 if (rq->q != q)
1204 continue;
1205
1206 el_ret = elv_try_merge(rq, bio);
1207 if (el_ret == ELEVATOR_BACK_MERGE) {
1208 ret = bio_attempt_back_merge(q, rq, bio);
1209 if (ret)
1210 break;
1211 } else if (el_ret == ELEVATOR_FRONT_MERGE) {
1212 ret = bio_attempt_front_merge(q, rq, bio);
1213 if (ret)
1214 break;
1215 }
1216 }
1217out:
1218 return ret;
1219}
1220
1177void init_request_from_bio(struct request *req, struct bio *bio) 1221void init_request_from_bio(struct request *req, struct bio *bio)
1178{ 1222{
1179 req->cpu = bio->bi_comp_cpu; 1223 req->cpu = bio->bi_comp_cpu;
@@ -1189,26 +1233,12 @@ void init_request_from_bio(struct request *req, struct bio *bio)
1189 blk_rq_bio_prep(req->q, req, bio); 1233 blk_rq_bio_prep(req->q, req, bio);
1190} 1234}
1191 1235
1192/*
1193 * Only disabling plugging for non-rotational devices if it does tagging
1194 * as well, otherwise we do need the proper merging
1195 */
1196static inline bool queue_should_plug(struct request_queue *q)
1197{
1198 return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
1199}
1200
1201static int __make_request(struct request_queue *q, struct bio *bio) 1236static int __make_request(struct request_queue *q, struct bio *bio)
1202{ 1237{
1203 struct request *req;
1204 int el_ret;
1205 unsigned int bytes = bio->bi_size;
1206 const unsigned short prio = bio_prio(bio);
1207 const bool sync = !!(bio->bi_rw & REQ_SYNC); 1238 const bool sync = !!(bio->bi_rw & REQ_SYNC);
1208 const bool unplug = !!(bio->bi_rw & REQ_UNPLUG); 1239 struct blk_plug *plug;
1209 const unsigned long ff = bio->bi_rw & REQ_FAILFAST_MASK; 1240 int el_ret, rw_flags, where = ELEVATOR_INSERT_SORT;
1210 int where = ELEVATOR_INSERT_SORT; 1241 struct request *req;
1211 int rw_flags;
1212 1242
1213 /* 1243 /*
1214 * low level driver can indicate that it wants pages above a 1244 * low level driver can indicate that it wants pages above a
@@ -1217,78 +1247,36 @@ static int __make_request(struct request_queue *q, struct bio *bio)
1217 */ 1247 */
1218 blk_queue_bounce(q, &bio); 1248 blk_queue_bounce(q, &bio);
1219 1249
1220 spin_lock_irq(q->queue_lock);
1221
1222 if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) { 1250 if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) {
1223 where = ELEVATOR_INSERT_FRONT; 1251 spin_lock_irq(q->queue_lock);
1252 where = ELEVATOR_INSERT_FLUSH;
1224 goto get_rq; 1253 goto get_rq;
1225 } 1254 }
1226 1255
1227 if (elv_queue_empty(q)) 1256 /*
1228 goto get_rq; 1257 * Check if we can merge with the plugged list before grabbing
1229 1258 * any locks.
1230 el_ret = elv_merge(q, &req, bio); 1259 */
1231 switch (el_ret) { 1260 if (attempt_plug_merge(current, q, bio))
1232 case ELEVATOR_BACK_MERGE:
1233 BUG_ON(!rq_mergeable(req));
1234
1235 if (!ll_back_merge_fn(q, req, bio))
1236 break;
1237
1238 trace_block_bio_backmerge(q, bio);
1239
1240 if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
1241 blk_rq_set_mixed_merge(req);
1242
1243 req->biotail->bi_next = bio;
1244 req->biotail = bio;
1245 req->__data_len += bytes;
1246 req->ioprio = ioprio_best(req->ioprio, prio);
1247 if (!blk_rq_cpu_valid(req))
1248 req->cpu = bio->bi_comp_cpu;
1249 drive_stat_acct(req, 0);
1250 elv_bio_merged(q, req, bio);
1251 if (!attempt_back_merge(q, req))
1252 elv_merged_request(q, req, el_ret);
1253 goto out; 1261 goto out;
1254 1262
1255 case ELEVATOR_FRONT_MERGE: 1263 spin_lock_irq(q->queue_lock);
1256 BUG_ON(!rq_mergeable(req));
1257
1258 if (!ll_front_merge_fn(q, req, bio))
1259 break;
1260
1261 trace_block_bio_frontmerge(q, bio);
1262 1264
1263 if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff) { 1265 el_ret = elv_merge(q, &req, bio);
1264 blk_rq_set_mixed_merge(req); 1266 if (el_ret == ELEVATOR_BACK_MERGE) {
1265 req->cmd_flags &= ~REQ_FAILFAST_MASK; 1267 BUG_ON(req->cmd_flags & REQ_ON_PLUG);
1266 req->cmd_flags |= ff; 1268 if (bio_attempt_back_merge(q, req, bio)) {
1269 if (!attempt_back_merge(q, req))
1270 elv_merged_request(q, req, el_ret);
1271 goto out_unlock;
1272 }
1273 } else if (el_ret == ELEVATOR_FRONT_MERGE) {
1274 BUG_ON(req->cmd_flags & REQ_ON_PLUG);
1275 if (bio_attempt_front_merge(q, req, bio)) {
1276 if (!attempt_front_merge(q, req))
1277 elv_merged_request(q, req, el_ret);
1278 goto out_unlock;
1267 } 1279 }
1268
1269 bio->bi_next = req->bio;
1270 req->bio = bio;
1271
1272 /*
1273 * may not be valid. if the low level driver said
1274 * it didn't need a bounce buffer then it better
1275 * not touch req->buffer either...
1276 */
1277 req->buffer = bio_data(bio);
1278 req->__sector = bio->bi_sector;
1279 req->__data_len += bytes;
1280 req->ioprio = ioprio_best(req->ioprio, prio);
1281 if (!blk_rq_cpu_valid(req))
1282 req->cpu = bio->bi_comp_cpu;
1283 drive_stat_acct(req, 0);
1284 elv_bio_merged(q, req, bio);
1285 if (!attempt_front_merge(q, req))
1286 elv_merged_request(q, req, el_ret);
1287 goto out;
1288
1289 /* ELV_NO_MERGE: elevator says don't/can't merge. */
1290 default:
1291 ;
1292 } 1280 }
1293 1281
1294get_rq: 1282get_rq:
@@ -1315,20 +1303,35 @@ get_rq:
1315 */ 1303 */
1316 init_request_from_bio(req, bio); 1304 init_request_from_bio(req, bio);
1317 1305
1318 spin_lock_irq(q->queue_lock);
1319 if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) || 1306 if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) ||
1320 bio_flagged(bio, BIO_CPU_AFFINE)) 1307 bio_flagged(bio, BIO_CPU_AFFINE)) {
1321 req->cpu = blk_cpu_to_group(smp_processor_id()); 1308 req->cpu = blk_cpu_to_group(get_cpu());
1322 if (queue_should_plug(q) && elv_queue_empty(q)) 1309 put_cpu();
1323 blk_plug_device(q); 1310 }
1324 1311
1325 /* insert the request into the elevator */ 1312 plug = current->plug;
1326 drive_stat_acct(req, 1); 1313 if (plug) {
1327 __elv_add_request(q, req, where, 0); 1314 if (!plug->should_sort && !list_empty(&plug->list)) {
1315 struct request *__rq;
1316
1317 __rq = list_entry_rq(plug->list.prev);
1318 if (__rq->q != q)
1319 plug->should_sort = 1;
1320 }
1321 /*
1322 * Debug flag, kill later
1323 */
1324 req->cmd_flags |= REQ_ON_PLUG;
1325 list_add_tail(&req->queuelist, &plug->list);
1326 drive_stat_acct(req, 1);
1327 } else {
1328 spin_lock_irq(q->queue_lock);
1329 add_acct_request(q, req, where);
1330 __blk_run_queue(q, false);
1331out_unlock:
1332 spin_unlock_irq(q->queue_lock);
1333 }
1328out: 1334out:
1329 if (unplug || !queue_should_plug(q))
1330 __generic_unplug_device(q);
1331 spin_unlock_irq(q->queue_lock);
1332 return 0; 1335 return 0;
1333} 1336}
1334 1337
@@ -1731,9 +1734,7 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
1731 */ 1734 */
1732 BUG_ON(blk_queued_rq(rq)); 1735 BUG_ON(blk_queued_rq(rq));
1733 1736
1734 drive_stat_acct(rq, 1); 1737 add_acct_request(q, rq, ELEVATOR_INSERT_BACK);
1735 __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
1736
1737 spin_unlock_irqrestore(q->queue_lock, flags); 1738 spin_unlock_irqrestore(q->queue_lock, flags);
1738 1739
1739 return 0; 1740 return 0;
@@ -1805,7 +1806,7 @@ static void blk_account_io_done(struct request *req)
1805 * normal IO on queueing nor completion. Accounting the 1806 * normal IO on queueing nor completion. Accounting the
1806 * containing request is enough. 1807 * containing request is enough.
1807 */ 1808 */
1808 if (blk_do_io_stat(req) && req != &req->q->flush_rq) { 1809 if (blk_do_io_stat(req) && !(req->cmd_flags & REQ_FLUSH_SEQ)) {
1809 unsigned long duration = jiffies - req->start_time; 1810 unsigned long duration = jiffies - req->start_time;
1810 const int rw = rq_data_dir(req); 1811 const int rw = rq_data_dir(req);
1811 struct hd_struct *part; 1812 struct hd_struct *part;
@@ -2628,6 +2629,113 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work)
2628} 2629}
2629EXPORT_SYMBOL(kblockd_schedule_work); 2630EXPORT_SYMBOL(kblockd_schedule_work);
2630 2631
2632int kblockd_schedule_delayed_work(struct request_queue *q,
2633 struct delayed_work *dwork, unsigned long delay)
2634{
2635 return queue_delayed_work(kblockd_workqueue, dwork, delay);
2636}
2637EXPORT_SYMBOL(kblockd_schedule_delayed_work);
2638
2639#define PLUG_MAGIC 0x91827364
2640
2641void blk_start_plug(struct blk_plug *plug)
2642{
2643 struct task_struct *tsk = current;
2644
2645 plug->magic = PLUG_MAGIC;
2646 INIT_LIST_HEAD(&plug->list);
2647 plug->should_sort = 0;
2648
2649 /*
2650 * If this is a nested plug, don't actually assign it. It will be
2651 * flushed on its own.
2652 */
2653 if (!tsk->plug) {
2654 /*
2655 * Store ordering should not be needed here, since a potential
2656 * preempt will imply a full memory barrier
2657 */
2658 tsk->plug = plug;
2659 }
2660}
2661EXPORT_SYMBOL(blk_start_plug);
2662
2663static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b)
2664{
2665 struct request *rqa = container_of(a, struct request, queuelist);
2666 struct request *rqb = container_of(b, struct request, queuelist);
2667
2668 return !(rqa->q == rqb->q);
2669}
2670
2671static void flush_plug_list(struct blk_plug *plug)
2672{
2673 struct request_queue *q;
2674 unsigned long flags;
2675 struct request *rq;
2676
2677 BUG_ON(plug->magic != PLUG_MAGIC);
2678
2679 if (list_empty(&plug->list))
2680 return;
2681
2682 if (plug->should_sort)
2683 list_sort(NULL, &plug->list, plug_rq_cmp);
2684
2685 q = NULL;
2686 local_irq_save(flags);
2687 while (!list_empty(&plug->list)) {
2688 rq = list_entry_rq(plug->list.next);
2689 list_del_init(&rq->queuelist);
2690 BUG_ON(!(rq->cmd_flags & REQ_ON_PLUG));
2691 BUG_ON(!rq->q);
2692 if (rq->q != q) {
2693 if (q) {
2694 __blk_run_queue(q, false);
2695 spin_unlock(q->queue_lock);
2696 }
2697 q = rq->q;
2698 spin_lock(q->queue_lock);
2699 }
2700 rq->cmd_flags &= ~REQ_ON_PLUG;
2701
2702 /*
2703 * rq is already accounted, so use raw insert
2704 */
2705 __elv_add_request(q, rq, ELEVATOR_INSERT_SORT_MERGE);
2706 }
2707
2708 if (q) {
2709 __blk_run_queue(q, false);
2710 spin_unlock(q->queue_lock);
2711 }
2712
2713 BUG_ON(!list_empty(&plug->list));
2714 local_irq_restore(flags);
2715}
2716
2717static void __blk_finish_plug(struct task_struct *tsk, struct blk_plug *plug)
2718{
2719 flush_plug_list(plug);
2720
2721 if (plug == tsk->plug)
2722 tsk->plug = NULL;
2723}
2724
2725void blk_finish_plug(struct blk_plug *plug)
2726{
2727 if (plug)
2728 __blk_finish_plug(current, plug);
2729}
2730EXPORT_SYMBOL(blk_finish_plug);
2731
2732void __blk_flush_plug(struct task_struct *tsk, struct blk_plug *plug)
2733{
2734 __blk_finish_plug(tsk, plug);
2735 tsk->plug = plug;
2736}
2737EXPORT_SYMBOL(__blk_flush_plug);
2738
2631int __init blk_dev_init(void) 2739int __init blk_dev_init(void)
2632{ 2740{
2633 BUILD_BUG_ON(__REQ_NR_BITS > 8 * 2741 BUILD_BUG_ON(__REQ_NR_BITS > 8 *
diff --git a/block/blk-exec.c b/block/blk-exec.c
index cf1456a02acd..7482b7fa863b 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -54,8 +54,8 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
54 rq->end_io = done; 54 rq->end_io = done;
55 WARN_ON(irqs_disabled()); 55 WARN_ON(irqs_disabled());
56 spin_lock_irq(q->queue_lock); 56 spin_lock_irq(q->queue_lock);
57 __elv_add_request(q, rq, where, 1); 57 __elv_add_request(q, rq, where);
58 __generic_unplug_device(q); 58 __blk_run_queue(q, false);
59 /* the queue is stopped so it won't be plugged+unplugged */ 59 /* the queue is stopped so it won't be plugged+unplugged */
60 if (rq->cmd_type == REQ_TYPE_PM_RESUME) 60 if (rq->cmd_type == REQ_TYPE_PM_RESUME)
61 q->request_fn(q); 61 q->request_fn(q);
diff --git a/block/blk-flush.c b/block/blk-flush.c
index b27d0208611b..93d5fd8e51eb 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -1,6 +1,69 @@
1/* 1/*
2 * Functions to sequence FLUSH and FUA writes. 2 * Functions to sequence FLUSH and FUA writes.
3 *
4 * Copyright (C) 2011 Max Planck Institute for Gravitational Physics
5 * Copyright (C) 2011 Tejun Heo <tj@kernel.org>
6 *
7 * This file is released under the GPLv2.
8 *
9 * REQ_{FLUSH|FUA} requests are decomposed to sequences consisted of three
10 * optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request
11 * properties and hardware capability.
12 *
13 * If a request doesn't have data, only REQ_FLUSH makes sense, which
14 * indicates a simple flush request. If there is data, REQ_FLUSH indicates
15 * that the device cache should be flushed before the data is executed, and
16 * REQ_FUA means that the data must be on non-volatile media on request
17 * completion.
18 *
19 * If the device doesn't have writeback cache, FLUSH and FUA don't make any
20 * difference. The requests are either completed immediately if there's no
21 * data or executed as normal requests otherwise.
22 *
23 * If the device has writeback cache and supports FUA, REQ_FLUSH is
24 * translated to PREFLUSH but REQ_FUA is passed down directly with DATA.
25 *
26 * If the device has writeback cache and doesn't support FUA, REQ_FLUSH is
27 * translated to PREFLUSH and REQ_FUA to POSTFLUSH.
28 *
29 * The actual execution of flush is double buffered. Whenever a request
30 * needs to execute PRE or POSTFLUSH, it queues at
31 * q->flush_queue[q->flush_pending_idx]. Once certain criteria are met, a
32 * flush is issued and the pending_idx is toggled. When the flush
33 * completes, all the requests which were pending are proceeded to the next
34 * step. This allows arbitrary merging of different types of FLUSH/FUA
35 * requests.
36 *
37 * Currently, the following conditions are used to determine when to issue
38 * flush.
39 *
40 * C1. At any given time, only one flush shall be in progress. This makes
41 * double buffering sufficient.
42 *
43 * C2. Flush is deferred if any request is executing DATA of its sequence.
44 * This avoids issuing separate POSTFLUSHes for requests which shared
45 * PREFLUSH.
46 *
47 * C3. The second condition is ignored if there is a request which has
48 * waited longer than FLUSH_PENDING_TIMEOUT. This is to avoid
49 * starvation in the unlikely case where there are continuous stream of
50 * FUA (without FLUSH) requests.
51 *
52 * For devices which support FUA, it isn't clear whether C2 (and thus C3)
53 * is beneficial.
54 *
55 * Note that a sequenced FLUSH/FUA request with DATA is completed twice.
56 * Once while executing DATA and again after the whole sequence is
57 * complete. The first completion updates the contained bio but doesn't
58 * finish it so that the bio submitter is notified only after the whole
59 * sequence is complete. This is implemented by testing REQ_FLUSH_SEQ in
60 * req_bio_endio().
61 *
62 * The above peculiarity requires that each FLUSH/FUA request has only one
63 * bio attached to it, which is guaranteed as they aren't allowed to be
64 * merged in the usual way.
3 */ 65 */
66
4#include <linux/kernel.h> 67#include <linux/kernel.h>
5#include <linux/module.h> 68#include <linux/module.h>
6#include <linux/bio.h> 69#include <linux/bio.h>
@@ -11,58 +74,142 @@
11 74
12/* FLUSH/FUA sequences */ 75/* FLUSH/FUA sequences */
13enum { 76enum {
14 QUEUE_FSEQ_STARTED = (1 << 0), /* flushing in progress */ 77 REQ_FSEQ_PREFLUSH = (1 << 0), /* pre-flushing in progress */
15 QUEUE_FSEQ_PREFLUSH = (1 << 1), /* pre-flushing in progress */ 78 REQ_FSEQ_DATA = (1 << 1), /* data write in progress */
16 QUEUE_FSEQ_DATA = (1 << 2), /* data write in progress */ 79 REQ_FSEQ_POSTFLUSH = (1 << 2), /* post-flushing in progress */
17 QUEUE_FSEQ_POSTFLUSH = (1 << 3), /* post-flushing in progress */ 80 REQ_FSEQ_DONE = (1 << 3),
18 QUEUE_FSEQ_DONE = (1 << 4), 81
82 REQ_FSEQ_ACTIONS = REQ_FSEQ_PREFLUSH | REQ_FSEQ_DATA |
83 REQ_FSEQ_POSTFLUSH,
84
85 /*
86 * If flush has been pending longer than the following timeout,
87 * it's issued even if flush_data requests are still in flight.
88 */
89 FLUSH_PENDING_TIMEOUT = 5 * HZ,
19}; 90};
20 91
21static struct request *queue_next_fseq(struct request_queue *q); 92static bool blk_kick_flush(struct request_queue *q);
22 93
23unsigned blk_flush_cur_seq(struct request_queue *q) 94static unsigned int blk_flush_policy(unsigned int fflags, struct request *rq)
24{ 95{
25 if (!q->flush_seq) 96 unsigned int policy = 0;
26 return 0; 97
27 return 1 << ffz(q->flush_seq); 98 if (fflags & REQ_FLUSH) {
99 if (rq->cmd_flags & REQ_FLUSH)
100 policy |= REQ_FSEQ_PREFLUSH;
101 if (blk_rq_sectors(rq))
102 policy |= REQ_FSEQ_DATA;
103 if (!(fflags & REQ_FUA) && (rq->cmd_flags & REQ_FUA))
104 policy |= REQ_FSEQ_POSTFLUSH;
105 }
106 return policy;
28} 107}
29 108
30static struct request *blk_flush_complete_seq(struct request_queue *q, 109static unsigned int blk_flush_cur_seq(struct request *rq)
31 unsigned seq, int error)
32{ 110{
33 struct request *next_rq = NULL; 111 return 1 << ffz(rq->flush.seq);
34 112}
35 if (error && !q->flush_err) 113
36 q->flush_err = error; 114static void blk_flush_restore_request(struct request *rq)
37 115{
38 BUG_ON(q->flush_seq & seq); 116 /*
39 q->flush_seq |= seq; 117 * After flush data completion, @rq->bio is %NULL but we need to
40 118 * complete the bio again. @rq->biotail is guaranteed to equal the
41 if (blk_flush_cur_seq(q) != QUEUE_FSEQ_DONE) { 119 * original @rq->bio. Restore it.
42 /* not complete yet, queue the next flush sequence */ 120 */
43 next_rq = queue_next_fseq(q); 121 rq->bio = rq->biotail;
44 } else { 122
45 /* complete this flush request */ 123 /* make @rq a normal request */
46 __blk_end_request_all(q->orig_flush_rq, q->flush_err); 124 rq->cmd_flags &= ~REQ_FLUSH_SEQ;
47 q->orig_flush_rq = NULL; 125 rq->end_io = NULL;
48 q->flush_seq = 0; 126}
49 127
50 /* dispatch the next flush if there's one */ 128/**
51 if (!list_empty(&q->pending_flushes)) { 129 * blk_flush_complete_seq - complete flush sequence
52 next_rq = list_entry_rq(q->pending_flushes.next); 130 * @rq: FLUSH/FUA request being sequenced
53 list_move(&next_rq->queuelist, &q->queue_head); 131 * @seq: sequences to complete (mask of %REQ_FSEQ_*, can be zero)
54 } 132 * @error: whether an error occurred
133 *
134 * @rq just completed @seq part of its flush sequence, record the
135 * completion and trigger the next step.
136 *
137 * CONTEXT:
138 * spin_lock_irq(q->queue_lock)
139 *
140 * RETURNS:
141 * %true if requests were added to the dispatch queue, %false otherwise.
142 */
143static bool blk_flush_complete_seq(struct request *rq, unsigned int seq,
144 int error)
145{
146 struct request_queue *q = rq->q;
147 struct list_head *pending = &q->flush_queue[q->flush_pending_idx];
148 bool queued = false;
149
150 BUG_ON(rq->flush.seq & seq);
151 rq->flush.seq |= seq;
152
153 if (likely(!error))
154 seq = blk_flush_cur_seq(rq);
155 else
156 seq = REQ_FSEQ_DONE;
157
158 switch (seq) {
159 case REQ_FSEQ_PREFLUSH:
160 case REQ_FSEQ_POSTFLUSH:
161 /* queue for flush */
162 if (list_empty(pending))
163 q->flush_pending_since = jiffies;
164 list_move_tail(&rq->flush.list, pending);
165 break;
166
167 case REQ_FSEQ_DATA:
168 list_move_tail(&rq->flush.list, &q->flush_data_in_flight);
169 list_add(&rq->queuelist, &q->queue_head);
170 queued = true;
171 break;
172
173 case REQ_FSEQ_DONE:
174 /*
175 * @rq was previously adjusted by blk_flush_issue() for
176 * flush sequencing and may already have gone through the
177 * flush data request completion path. Restore @rq for
178 * normal completion and end it.
179 */
180 BUG_ON(!list_empty(&rq->queuelist));
181 list_del_init(&rq->flush.list);
182 blk_flush_restore_request(rq);
183 __blk_end_request_all(rq, error);
184 break;
185
186 default:
187 BUG();
55 } 188 }
56 return next_rq; 189
190 return blk_kick_flush(q) | queued;
57} 191}
58 192
59static void blk_flush_complete_seq_end_io(struct request_queue *q, 193static void flush_end_io(struct request *flush_rq, int error)
60 unsigned seq, int error)
61{ 194{
62 bool was_empty = elv_queue_empty(q); 195 struct request_queue *q = flush_rq->q;
63 struct request *next_rq; 196 struct list_head *running = &q->flush_queue[q->flush_running_idx];
197 bool queued = false;
198 struct request *rq, *n;
64 199
65 next_rq = blk_flush_complete_seq(q, seq, error); 200 BUG_ON(q->flush_pending_idx == q->flush_running_idx);
201
202 /* account completion of the flush request */
203 q->flush_running_idx ^= 1;
204 elv_completed_request(q, flush_rq);
205
206 /* and push the waiting requests to the next stage */
207 list_for_each_entry_safe(rq, n, running, flush.list) {
208 unsigned int seq = blk_flush_cur_seq(rq);
209
210 BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH);
211 queued |= blk_flush_complete_seq(rq, seq, error);
212 }
66 213
67 /* 214 /*
68 * Moving a request silently to empty queue_head may stall the 215 * Moving a request silently to empty queue_head may stall the
@@ -70,127 +217,153 @@ static void blk_flush_complete_seq_end_io(struct request_queue *q,
70 * from request completion path and calling directly into 217 * from request completion path and calling directly into
71 * request_fn may confuse the driver. Always use kblockd. 218 * request_fn may confuse the driver. Always use kblockd.
72 */ 219 */
73 if (was_empty && next_rq) 220 if (queued)
74 __blk_run_queue(q, true); 221 __blk_run_queue(q, true);
75} 222}
76 223
77static void pre_flush_end_io(struct request *rq, int error) 224/**
225 * blk_kick_flush - consider issuing flush request
226 * @q: request_queue being kicked
227 *
228 * Flush related states of @q have changed, consider issuing flush request.
229 * Please read the comment at the top of this file for more info.
230 *
231 * CONTEXT:
232 * spin_lock_irq(q->queue_lock)
233 *
234 * RETURNS:
235 * %true if flush was issued, %false otherwise.
236 */
237static bool blk_kick_flush(struct request_queue *q)
78{ 238{
79 elv_completed_request(rq->q, rq); 239 struct list_head *pending = &q->flush_queue[q->flush_pending_idx];
80 blk_flush_complete_seq_end_io(rq->q, QUEUE_FSEQ_PREFLUSH, error); 240 struct request *first_rq =
241 list_first_entry(pending, struct request, flush.list);
242
243 /* C1 described at the top of this file */
244 if (q->flush_pending_idx != q->flush_running_idx || list_empty(pending))
245 return false;
246
247 /* C2 and C3 */
248 if (!list_empty(&q->flush_data_in_flight) &&
249 time_before(jiffies,
250 q->flush_pending_since + FLUSH_PENDING_TIMEOUT))
251 return false;
252
253 /*
254 * Issue flush and toggle pending_idx. This makes pending_idx
255 * different from running_idx, which means flush is in flight.
256 */
257 blk_rq_init(q, &q->flush_rq);
258 q->flush_rq.cmd_type = REQ_TYPE_FS;
259 q->flush_rq.cmd_flags = WRITE_FLUSH | REQ_FLUSH_SEQ;
260 q->flush_rq.rq_disk = first_rq->rq_disk;
261 q->flush_rq.end_io = flush_end_io;
262
263 q->flush_pending_idx ^= 1;
264 elv_insert(q, &q->flush_rq, ELEVATOR_INSERT_REQUEUE);
265 return true;
81} 266}
82 267
83static void flush_data_end_io(struct request *rq, int error) 268static void flush_data_end_io(struct request *rq, int error)
84{ 269{
85 elv_completed_request(rq->q, rq); 270 struct request_queue *q = rq->q;
86 blk_flush_complete_seq_end_io(rq->q, QUEUE_FSEQ_DATA, error);
87}
88 271
89static void post_flush_end_io(struct request *rq, int error) 272 /*
90{ 273 * After populating an empty queue, kick it to avoid stall. Read
91 elv_completed_request(rq->q, rq); 274 * the comment in flush_end_io().
92 blk_flush_complete_seq_end_io(rq->q, QUEUE_FSEQ_POSTFLUSH, error); 275 */
276 if (blk_flush_complete_seq(rq, REQ_FSEQ_DATA, error))
277 __blk_run_queue(q, true);
93} 278}
94 279
95static void init_flush_request(struct request *rq, struct gendisk *disk) 280/**
281 * blk_insert_flush - insert a new FLUSH/FUA request
282 * @rq: request to insert
283 *
284 * To be called from elv_insert() for %ELEVATOR_INSERT_FLUSH insertions.
285 * @rq is being submitted. Analyze what needs to be done and put it on the
286 * right queue.
287 *
288 * CONTEXT:
289 * spin_lock_irq(q->queue_lock)
290 */
291void blk_insert_flush(struct request *rq)
96{ 292{
97 rq->cmd_type = REQ_TYPE_FS; 293 struct request_queue *q = rq->q;
98 rq->cmd_flags = WRITE_FLUSH; 294 unsigned int fflags = q->flush_flags; /* may change, cache */
99 rq->rq_disk = disk; 295 unsigned int policy = blk_flush_policy(fflags, rq);
100}
101 296
102static struct request *queue_next_fseq(struct request_queue *q) 297 BUG_ON(rq->end_io);
103{ 298 BUG_ON(!rq->bio || rq->bio != rq->biotail);
104 struct request *orig_rq = q->orig_flush_rq;
105 struct request *rq = &q->flush_rq;
106 299
107 blk_rq_init(q, rq); 300 /*
301 * @policy now records what operations need to be done. Adjust
302 * REQ_FLUSH and FUA for the driver.
303 */
304 rq->cmd_flags &= ~REQ_FLUSH;
305 if (!(fflags & REQ_FUA))
306 rq->cmd_flags &= ~REQ_FUA;
108 307
109 switch (blk_flush_cur_seq(q)) { 308 /*
110 case QUEUE_FSEQ_PREFLUSH: 309 * If there's data but flush is not necessary, the request can be
111 init_flush_request(rq, orig_rq->rq_disk); 310 * processed directly without going through flush machinery. Queue
112 rq->end_io = pre_flush_end_io; 311 * for normal execution.
113 break; 312 */
114 case QUEUE_FSEQ_DATA: 313 if ((policy & REQ_FSEQ_DATA) &&
115 init_request_from_bio(rq, orig_rq->bio); 314 !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) {
116 /* 315 list_add(&rq->queuelist, &q->queue_head);
117 * orig_rq->rq_disk may be different from 316 return;
118 * bio->bi_bdev->bd_disk if orig_rq got here through
119 * remapping drivers. Make sure rq->rq_disk points
120 * to the same one as orig_rq.
121 */
122 rq->rq_disk = orig_rq->rq_disk;
123 rq->cmd_flags &= ~(REQ_FLUSH | REQ_FUA);
124 rq->cmd_flags |= orig_rq->cmd_flags & (REQ_FLUSH | REQ_FUA);
125 rq->end_io = flush_data_end_io;
126 break;
127 case QUEUE_FSEQ_POSTFLUSH:
128 init_flush_request(rq, orig_rq->rq_disk);
129 rq->end_io = post_flush_end_io;
130 break;
131 default:
132 BUG();
133 } 317 }
134 318
135 elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); 319 /*
136 return rq; 320 * @rq should go through flush machinery. Mark it part of flush
321 * sequence and submit for further processing.
322 */
323 memset(&rq->flush, 0, sizeof(rq->flush));
324 INIT_LIST_HEAD(&rq->flush.list);
325 rq->cmd_flags |= REQ_FLUSH_SEQ;
326 rq->end_io = flush_data_end_io;
327
328 blk_flush_complete_seq(rq, REQ_FSEQ_ACTIONS & ~policy, 0);
137} 329}
138 330
139struct request *blk_do_flush(struct request_queue *q, struct request *rq) 331/**
332 * blk_abort_flushes - @q is being aborted, abort flush requests
333 * @q: request_queue being aborted
334 *
335 * To be called from elv_abort_queue(). @q is being aborted. Prepare all
336 * FLUSH/FUA requests for abortion.
337 *
338 * CONTEXT:
339 * spin_lock_irq(q->queue_lock)
340 */
341void blk_abort_flushes(struct request_queue *q)
140{ 342{
141 unsigned int fflags = q->flush_flags; /* may change, cache it */ 343 struct request *rq, *n;
142 bool has_flush = fflags & REQ_FLUSH, has_fua = fflags & REQ_FUA; 344 int i;
143 bool do_preflush = has_flush && (rq->cmd_flags & REQ_FLUSH);
144 bool do_postflush = has_flush && !has_fua && (rq->cmd_flags & REQ_FUA);
145 unsigned skip = 0;
146 345
147 /* 346 /*
148 * Special case. If there's data but flush is not necessary, 347 * Requests in flight for data are already owned by the dispatch
149 * the request can be issued directly. 348 * queue or the device driver. Just restore for normal completion.
150 *
151 * Flush w/o data should be able to be issued directly too but
152 * currently some drivers assume that rq->bio contains
153 * non-zero data if it isn't NULL and empty FLUSH requests
154 * getting here usually have bio's without data.
155 */ 349 */
156 if (blk_rq_sectors(rq) && !do_preflush && !do_postflush) { 350 list_for_each_entry_safe(rq, n, &q->flush_data_in_flight, flush.list) {
157 rq->cmd_flags &= ~REQ_FLUSH; 351 list_del_init(&rq->flush.list);
158 if (!has_fua) 352 blk_flush_restore_request(rq);
159 rq->cmd_flags &= ~REQ_FUA;
160 return rq;
161 } 353 }
162 354
163 /* 355 /*
164 * Sequenced flushes can't be processed in parallel. If 356 * We need to give away requests on flush queues. Restore for
165 * another one is already in progress, queue for later 357 * normal completion and put them on the dispatch queue.
166 * processing.
167 */ 358 */
168 if (q->flush_seq) { 359 for (i = 0; i < ARRAY_SIZE(q->flush_queue); i++) {
169 list_move_tail(&rq->queuelist, &q->pending_flushes); 360 list_for_each_entry_safe(rq, n, &q->flush_queue[i],
170 return NULL; 361 flush.list) {
362 list_del_init(&rq->flush.list);
363 blk_flush_restore_request(rq);
364 list_add_tail(&rq->queuelist, &q->queue_head);
365 }
171 } 366 }
172
173 /*
174 * Start a new flush sequence
175 */
176 q->flush_err = 0;
177 q->flush_seq |= QUEUE_FSEQ_STARTED;
178
179 /* adjust FLUSH/FUA of the original request and stash it away */
180 rq->cmd_flags &= ~REQ_FLUSH;
181 if (!has_fua)
182 rq->cmd_flags &= ~REQ_FUA;
183 blk_dequeue_request(rq);
184 q->orig_flush_rq = rq;
185
186 /* skip unneded sequences and return the first one */
187 if (!do_preflush)
188 skip |= QUEUE_FSEQ_PREFLUSH;
189 if (!blk_rq_sectors(rq))
190 skip |= QUEUE_FSEQ_DATA;
191 if (!do_postflush)
192 skip |= QUEUE_FSEQ_POSTFLUSH;
193 return blk_flush_complete_seq(q, skip, 0);
194} 367}
195 368
196static void bio_end_flush(struct bio *bio, int err) 369static void bio_end_flush(struct bio *bio, int err)
diff --git a/block/blk-lib.c b/block/blk-lib.c
index bd3e8df4d5e2..25de73e4759b 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -136,8 +136,6 @@ static void bio_batch_end_io(struct bio *bio, int err)
136 * 136 *
137 * Description: 137 * Description:
138 * Generate and issue number of bios with zerofiled pages. 138 * Generate and issue number of bios with zerofiled pages.
139 * Send barrier at the beginning and at the end if requested. This guarantie
140 * correct request ordering. Empty barrier allow us to avoid post queue flush.
141 */ 139 */
142 140
143int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, 141int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
diff --git a/block/blk-merge.c b/block/blk-merge.c
index ea85e20d5e94..cfcc37cb222b 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -465,3 +465,9 @@ int attempt_front_merge(struct request_queue *q, struct request *rq)
465 465
466 return 0; 466 return 0;
467} 467}
468
469int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
470 struct request *next)
471{
472 return attempt_merge(q, rq, next);
473}
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 36c8c1f2af18..1fa769293597 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -164,25 +164,10 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
164 blk_queue_congestion_threshold(q); 164 blk_queue_congestion_threshold(q);
165 q->nr_batching = BLK_BATCH_REQ; 165 q->nr_batching = BLK_BATCH_REQ;
166 166
167 q->unplug_thresh = 4; /* hmm */
168 q->unplug_delay = msecs_to_jiffies(3); /* 3 milliseconds */
169 if (q->unplug_delay == 0)
170 q->unplug_delay = 1;
171
172 q->unplug_timer.function = blk_unplug_timeout;
173 q->unplug_timer.data = (unsigned long)q;
174
175 blk_set_default_limits(&q->limits); 167 blk_set_default_limits(&q->limits);
176 blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS); 168 blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
177 169
178 /* 170 /*
179 * If the caller didn't supply a lock, fall back to our embedded
180 * per-queue locks
181 */
182 if (!q->queue_lock)
183 q->queue_lock = &q->__queue_lock;
184
185 /*
186 * by default assume old behaviour and bounce for any highmem page 171 * by default assume old behaviour and bounce for any highmem page
187 */ 172 */
188 blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); 173 blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 41fb69150b4d..261c75c665ae 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -471,8 +471,6 @@ static void blk_release_queue(struct kobject *kobj)
471 471
472 blk_sync_queue(q); 472 blk_sync_queue(q);
473 473
474 blk_throtl_exit(q);
475
476 if (rl->rq_pool) 474 if (rl->rq_pool)
477 mempool_destroy(rl->rq_pool); 475 mempool_destroy(rl->rq_pool);
478 476
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index e36cc10a346c..5352bdafbcf0 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -102,7 +102,7 @@ struct throtl_data
102 /* Work for dispatching throttled bios */ 102 /* Work for dispatching throttled bios */
103 struct delayed_work throtl_work; 103 struct delayed_work throtl_work;
104 104
105 atomic_t limits_changed; 105 bool limits_changed;
106}; 106};
107 107
108enum tg_state_flags { 108enum tg_state_flags {
@@ -201,6 +201,7 @@ static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td,
201 RB_CLEAR_NODE(&tg->rb_node); 201 RB_CLEAR_NODE(&tg->rb_node);
202 bio_list_init(&tg->bio_lists[0]); 202 bio_list_init(&tg->bio_lists[0]);
203 bio_list_init(&tg->bio_lists[1]); 203 bio_list_init(&tg->bio_lists[1]);
204 td->limits_changed = false;
204 205
205 /* 206 /*
206 * Take the initial reference that will be released on destroy 207 * Take the initial reference that will be released on destroy
@@ -737,34 +738,36 @@ static void throtl_process_limit_change(struct throtl_data *td)
737 struct throtl_grp *tg; 738 struct throtl_grp *tg;
738 struct hlist_node *pos, *n; 739 struct hlist_node *pos, *n;
739 740
740 if (!atomic_read(&td->limits_changed)) 741 if (!td->limits_changed)
741 return; 742 return;
742 743
743 throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed)); 744 xchg(&td->limits_changed, false);
744 745
745 /* 746 throtl_log(td, "limits changed");
746 * Make sure updates from throtl_update_blkio_group_read_bps() group
747 * of functions to tg->limits_changed are visible. We do not
748 * want update td->limits_changed to be visible but update to
749 * tg->limits_changed not being visible yet on this cpu. Hence
750 * the read barrier.
751 */
752 smp_rmb();
753 747
754 hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) { 748 hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) {
755 if (throtl_tg_on_rr(tg) && tg->limits_changed) { 749 if (!tg->limits_changed)
756 throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu" 750 continue;
757 " riops=%u wiops=%u", tg->bps[READ], 751
758 tg->bps[WRITE], tg->iops[READ], 752 if (!xchg(&tg->limits_changed, false))
759 tg->iops[WRITE]); 753 continue;
754
755 throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu"
756 " riops=%u wiops=%u", tg->bps[READ], tg->bps[WRITE],
757 tg->iops[READ], tg->iops[WRITE]);
758
759 /*
760 * Restart the slices for both READ and WRITES. It
761 * might happen that a group's limit are dropped
762 * suddenly and we don't want to account recently
763 * dispatched IO with new low rate
764 */
765 throtl_start_new_slice(td, tg, 0);
766 throtl_start_new_slice(td, tg, 1);
767
768 if (throtl_tg_on_rr(tg))
760 tg_update_disptime(td, tg); 769 tg_update_disptime(td, tg);
761 tg->limits_changed = false;
762 }
763 } 770 }
764
765 smp_mb__before_atomic_dec();
766 atomic_dec(&td->limits_changed);
767 smp_mb__after_atomic_dec();
768} 771}
769 772
770/* Dispatch throttled bios. Should be called without queue lock held. */ 773/* Dispatch throttled bios. Should be called without queue lock held. */
@@ -774,6 +777,7 @@ static int throtl_dispatch(struct request_queue *q)
774 unsigned int nr_disp = 0; 777 unsigned int nr_disp = 0;
775 struct bio_list bio_list_on_stack; 778 struct bio_list bio_list_on_stack;
776 struct bio *bio; 779 struct bio *bio;
780 struct blk_plug plug;
777 781
778 spin_lock_irq(q->queue_lock); 782 spin_lock_irq(q->queue_lock);
779 783
@@ -802,9 +806,10 @@ out:
802 * immediate dispatch 806 * immediate dispatch
803 */ 807 */
804 if (nr_disp) { 808 if (nr_disp) {
809 blk_start_plug(&plug);
805 while((bio = bio_list_pop(&bio_list_on_stack))) 810 while((bio = bio_list_pop(&bio_list_on_stack)))
806 generic_make_request(bio); 811 generic_make_request(bio);
807 blk_unplug(q); 812 blk_finish_plug(&plug);
808 } 813 }
809 return nr_disp; 814 return nr_disp;
810} 815}
@@ -825,7 +830,8 @@ throtl_schedule_delayed_work(struct throtl_data *td, unsigned long delay)
825 830
826 struct delayed_work *dwork = &td->throtl_work; 831 struct delayed_work *dwork = &td->throtl_work;
827 832
828 if (total_nr_queued(td) > 0) { 833 /* schedule work if limits changed even if no bio is queued */
834 if (total_nr_queued(td) > 0 || td->limits_changed) {
829 /* 835 /*
830 * We might have a work scheduled to be executed in future. 836 * We might have a work scheduled to be executed in future.
831 * Cancel that and schedule a new one. 837 * Cancel that and schedule a new one.
@@ -898,6 +904,15 @@ void throtl_unlink_blkio_group(void *key, struct blkio_group *blkg)
898 spin_unlock_irqrestore(td->queue->queue_lock, flags); 904 spin_unlock_irqrestore(td->queue->queue_lock, flags);
899} 905}
900 906
907static void throtl_update_blkio_group_common(struct throtl_data *td,
908 struct throtl_grp *tg)
909{
910 xchg(&tg->limits_changed, true);
911 xchg(&td->limits_changed, true);
912 /* Schedule a work now to process the limit change */
913 throtl_schedule_delayed_work(td, 0);
914}
915
901/* 916/*
902 * For all update functions, key should be a valid pointer because these 917 * For all update functions, key should be a valid pointer because these
903 * update functions are called under blkcg_lock, that means, blkg is 918 * update functions are called under blkcg_lock, that means, blkg is
@@ -911,64 +926,43 @@ static void throtl_update_blkio_group_read_bps(void *key,
911 struct blkio_group *blkg, u64 read_bps) 926 struct blkio_group *blkg, u64 read_bps)
912{ 927{
913 struct throtl_data *td = key; 928 struct throtl_data *td = key;
929 struct throtl_grp *tg = tg_of_blkg(blkg);
914 930
915 tg_of_blkg(blkg)->bps[READ] = read_bps; 931 tg->bps[READ] = read_bps;
916 /* Make sure read_bps is updated before setting limits_changed */ 932 throtl_update_blkio_group_common(td, tg);
917 smp_wmb();
918 tg_of_blkg(blkg)->limits_changed = true;
919
920 /* Make sure tg->limits_changed is updated before td->limits_changed */
921 smp_mb__before_atomic_inc();
922 atomic_inc(&td->limits_changed);
923 smp_mb__after_atomic_inc();
924
925 /* Schedule a work now to process the limit change */
926 throtl_schedule_delayed_work(td, 0);
927} 933}
928 934
929static void throtl_update_blkio_group_write_bps(void *key, 935static void throtl_update_blkio_group_write_bps(void *key,
930 struct blkio_group *blkg, u64 write_bps) 936 struct blkio_group *blkg, u64 write_bps)
931{ 937{
932 struct throtl_data *td = key; 938 struct throtl_data *td = key;
939 struct throtl_grp *tg = tg_of_blkg(blkg);
933 940
934 tg_of_blkg(blkg)->bps[WRITE] = write_bps; 941 tg->bps[WRITE] = write_bps;
935 smp_wmb(); 942 throtl_update_blkio_group_common(td, tg);
936 tg_of_blkg(blkg)->limits_changed = true;
937 smp_mb__before_atomic_inc();
938 atomic_inc(&td->limits_changed);
939 smp_mb__after_atomic_inc();
940 throtl_schedule_delayed_work(td, 0);
941} 943}
942 944
943static void throtl_update_blkio_group_read_iops(void *key, 945static void throtl_update_blkio_group_read_iops(void *key,
944 struct blkio_group *blkg, unsigned int read_iops) 946 struct blkio_group *blkg, unsigned int read_iops)
945{ 947{
946 struct throtl_data *td = key; 948 struct throtl_data *td = key;
949 struct throtl_grp *tg = tg_of_blkg(blkg);
947 950
948 tg_of_blkg(blkg)->iops[READ] = read_iops; 951 tg->iops[READ] = read_iops;
949 smp_wmb(); 952 throtl_update_blkio_group_common(td, tg);
950 tg_of_blkg(blkg)->limits_changed = true;
951 smp_mb__before_atomic_inc();
952 atomic_inc(&td->limits_changed);
953 smp_mb__after_atomic_inc();
954 throtl_schedule_delayed_work(td, 0);
955} 953}
956 954
957static void throtl_update_blkio_group_write_iops(void *key, 955static void throtl_update_blkio_group_write_iops(void *key,
958 struct blkio_group *blkg, unsigned int write_iops) 956 struct blkio_group *blkg, unsigned int write_iops)
959{ 957{
960 struct throtl_data *td = key; 958 struct throtl_data *td = key;
959 struct throtl_grp *tg = tg_of_blkg(blkg);
961 960
962 tg_of_blkg(blkg)->iops[WRITE] = write_iops; 961 tg->iops[WRITE] = write_iops;
963 smp_wmb(); 962 throtl_update_blkio_group_common(td, tg);
964 tg_of_blkg(blkg)->limits_changed = true;
965 smp_mb__before_atomic_inc();
966 atomic_inc(&td->limits_changed);
967 smp_mb__after_atomic_inc();
968 throtl_schedule_delayed_work(td, 0);
969} 963}
970 964
971void throtl_shutdown_timer_wq(struct request_queue *q) 965static void throtl_shutdown_wq(struct request_queue *q)
972{ 966{
973 struct throtl_data *td = q->td; 967 struct throtl_data *td = q->td;
974 968
@@ -1009,20 +1003,28 @@ int blk_throtl_bio(struct request_queue *q, struct bio **biop)
1009 /* 1003 /*
1010 * There is already another bio queued in same dir. No 1004 * There is already another bio queued in same dir. No
1011 * need to update dispatch time. 1005 * need to update dispatch time.
1012 * Still update the disptime if rate limits on this group
1013 * were changed.
1014 */ 1006 */
1015 if (!tg->limits_changed) 1007 update_disptime = false;
1016 update_disptime = false;
1017 else
1018 tg->limits_changed = false;
1019
1020 goto queue_bio; 1008 goto queue_bio;
1009
1021 } 1010 }
1022 1011
1023 /* Bio is with-in rate limit of group */ 1012 /* Bio is with-in rate limit of group */
1024 if (tg_may_dispatch(td, tg, bio, NULL)) { 1013 if (tg_may_dispatch(td, tg, bio, NULL)) {
1025 throtl_charge_bio(tg, bio); 1014 throtl_charge_bio(tg, bio);
1015
1016 /*
1017 * We need to trim slice even when bios are not being queued
1018 * otherwise it might happen that a bio is not queued for
1019 * a long time and slice keeps on extending and trim is not
1020 * called for a long time. Now if limits are reduced suddenly
1021 * we take into account all the IO dispatched so far at new
1022 * low rate and * newly queued IO gets a really long dispatch
1023 * time.
1024 *
1025 * So keep on trimming slice even if bio is not queued.
1026 */
1027 throtl_trim_slice(td, tg, rw);
1026 goto out; 1028 goto out;
1027 } 1029 }
1028 1030
@@ -1058,7 +1060,7 @@ int blk_throtl_init(struct request_queue *q)
1058 1060
1059 INIT_HLIST_HEAD(&td->tg_list); 1061 INIT_HLIST_HEAD(&td->tg_list);
1060 td->tg_service_tree = THROTL_RB_ROOT; 1062 td->tg_service_tree = THROTL_RB_ROOT;
1061 atomic_set(&td->limits_changed, 0); 1063 td->limits_changed = false;
1062 1064
1063 /* Init root group */ 1065 /* Init root group */
1064 tg = &td->root_tg; 1066 tg = &td->root_tg;
@@ -1070,6 +1072,7 @@ int blk_throtl_init(struct request_queue *q)
1070 /* Practically unlimited BW */ 1072 /* Practically unlimited BW */
1071 tg->bps[0] = tg->bps[1] = -1; 1073 tg->bps[0] = tg->bps[1] = -1;
1072 tg->iops[0] = tg->iops[1] = -1; 1074 tg->iops[0] = tg->iops[1] = -1;
1075 td->limits_changed = false;
1073 1076
1074 /* 1077 /*
1075 * Set root group reference to 2. One reference will be dropped when 1078 * Set root group reference to 2. One reference will be dropped when
@@ -1102,7 +1105,7 @@ void blk_throtl_exit(struct request_queue *q)
1102 1105
1103 BUG_ON(!td); 1106 BUG_ON(!td);
1104 1107
1105 throtl_shutdown_timer_wq(q); 1108 throtl_shutdown_wq(q);
1106 1109
1107 spin_lock_irq(q->queue_lock); 1110 spin_lock_irq(q->queue_lock);
1108 throtl_release_tgs(td); 1111 throtl_release_tgs(td);
@@ -1132,7 +1135,7 @@ void blk_throtl_exit(struct request_queue *q)
1132 * update limits through cgroup and another work got queued, cancel 1135 * update limits through cgroup and another work got queued, cancel
1133 * it. 1136 * it.
1134 */ 1137 */
1135 throtl_shutdown_timer_wq(q); 1138 throtl_shutdown_wq(q);
1136 throtl_td_free(td); 1139 throtl_td_free(td);
1137} 1140}
1138 1141
diff --git a/block/blk.h b/block/blk.h
index 2db8f32838e7..c8db371a921d 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -18,8 +18,6 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq,
18void blk_dequeue_request(struct request *rq); 18void blk_dequeue_request(struct request *rq);
19void __blk_queue_free_tags(struct request_queue *q); 19void __blk_queue_free_tags(struct request_queue *q);
20 20
21void blk_unplug_work(struct work_struct *work);
22void blk_unplug_timeout(unsigned long data);
23void blk_rq_timed_out_timer(unsigned long data); 21void blk_rq_timed_out_timer(unsigned long data);
24void blk_delete_timer(struct request *); 22void blk_delete_timer(struct request *);
25void blk_add_timer(struct request *); 23void blk_add_timer(struct request *);
@@ -51,21 +49,17 @@ static inline void blk_clear_rq_complete(struct request *rq)
51 */ 49 */
52#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash)) 50#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
53 51
54struct request *blk_do_flush(struct request_queue *q, struct request *rq); 52void blk_insert_flush(struct request *rq);
53void blk_abort_flushes(struct request_queue *q);
55 54
56static inline struct request *__elv_next_request(struct request_queue *q) 55static inline struct request *__elv_next_request(struct request_queue *q)
57{ 56{
58 struct request *rq; 57 struct request *rq;
59 58
60 while (1) { 59 while (1) {
61 while (!list_empty(&q->queue_head)) { 60 if (!list_empty(&q->queue_head)) {
62 rq = list_entry_rq(q->queue_head.next); 61 rq = list_entry_rq(q->queue_head.next);
63 if (!(rq->cmd_flags & (REQ_FLUSH | REQ_FUA)) || 62 return rq;
64 rq == &q->flush_rq)
65 return rq;
66 rq = blk_do_flush(q, rq);
67 if (rq)
68 return rq;
69 } 63 }
70 64
71 if (!q->elevator->ops->elevator_dispatch_fn(q, 0)) 65 if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
@@ -109,6 +103,8 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
109 struct bio *bio); 103 struct bio *bio);
110int attempt_back_merge(struct request_queue *q, struct request *rq); 104int attempt_back_merge(struct request_queue *q, struct request *rq);
111int attempt_front_merge(struct request_queue *q, struct request *rq); 105int attempt_front_merge(struct request_queue *q, struct request *rq);
106int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
107 struct request *next);
112void blk_recalc_rq_segments(struct request *rq); 108void blk_recalc_rq_segments(struct request *rq);
113void blk_rq_set_mixed_merge(struct request *rq); 109void blk_rq_set_mixed_merge(struct request *rq);
114 110
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index ea83a4f0c27d..7785169f3c8f 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -54,9 +54,9 @@ static const int cfq_hist_divisor = 4;
54#define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8) 54#define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8)
55 55
56#define RQ_CIC(rq) \ 56#define RQ_CIC(rq) \
57 ((struct cfq_io_context *) (rq)->elevator_private) 57 ((struct cfq_io_context *) (rq)->elevator_private[0])
58#define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2) 58#define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private[1])
59#define RQ_CFQG(rq) (struct cfq_group *) ((rq)->elevator_private3) 59#define RQ_CFQG(rq) (struct cfq_group *) ((rq)->elevator_private[2])
60 60
61static struct kmem_cache *cfq_pool; 61static struct kmem_cache *cfq_pool;
62static struct kmem_cache *cfq_ioc_pool; 62static struct kmem_cache *cfq_ioc_pool;
@@ -146,7 +146,6 @@ struct cfq_queue {
146 struct cfq_rb_root *service_tree; 146 struct cfq_rb_root *service_tree;
147 struct cfq_queue *new_cfqq; 147 struct cfq_queue *new_cfqq;
148 struct cfq_group *cfqg; 148 struct cfq_group *cfqg;
149 struct cfq_group *orig_cfqg;
150 /* Number of sectors dispatched from queue in single dispatch round */ 149 /* Number of sectors dispatched from queue in single dispatch round */
151 unsigned long nr_sectors; 150 unsigned long nr_sectors;
152}; 151};
@@ -179,6 +178,8 @@ struct cfq_group {
179 /* group service_tree key */ 178 /* group service_tree key */
180 u64 vdisktime; 179 u64 vdisktime;
181 unsigned int weight; 180 unsigned int weight;
181 unsigned int new_weight;
182 bool needs_update;
182 183
183 /* number of cfqq currently on this group */ 184 /* number of cfqq currently on this group */
184 int nr_cfqq; 185 int nr_cfqq;
@@ -238,6 +239,7 @@ struct cfq_data {
238 struct rb_root prio_trees[CFQ_PRIO_LISTS]; 239 struct rb_root prio_trees[CFQ_PRIO_LISTS];
239 240
240 unsigned int busy_queues; 241 unsigned int busy_queues;
242 unsigned int busy_sync_queues;
241 243
242 int rq_in_driver; 244 int rq_in_driver;
243 int rq_in_flight[2]; 245 int rq_in_flight[2];
@@ -285,7 +287,6 @@ struct cfq_data {
285 unsigned int cfq_slice_idle; 287 unsigned int cfq_slice_idle;
286 unsigned int cfq_group_idle; 288 unsigned int cfq_group_idle;
287 unsigned int cfq_latency; 289 unsigned int cfq_latency;
288 unsigned int cfq_group_isolation;
289 290
290 unsigned int cic_index; 291 unsigned int cic_index;
291 struct list_head cic_list; 292 struct list_head cic_list;
@@ -501,13 +502,6 @@ static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
501 } 502 }
502} 503}
503 504
504static int cfq_queue_empty(struct request_queue *q)
505{
506 struct cfq_data *cfqd = q->elevator->elevator_data;
507
508 return !cfqd->rq_queued;
509}
510
511/* 505/*
512 * Scale schedule slice based on io priority. Use the sync time slice only 506 * Scale schedule slice based on io priority. Use the sync time slice only
513 * if a queue is marked sync and has sync io queued. A sync queue with async 507 * if a queue is marked sync and has sync io queued. A sync queue with async
@@ -558,15 +552,13 @@ static inline u64 min_vdisktime(u64 min_vdisktime, u64 vdisktime)
558 552
559static void update_min_vdisktime(struct cfq_rb_root *st) 553static void update_min_vdisktime(struct cfq_rb_root *st)
560{ 554{
561 u64 vdisktime = st->min_vdisktime;
562 struct cfq_group *cfqg; 555 struct cfq_group *cfqg;
563 556
564 if (st->left) { 557 if (st->left) {
565 cfqg = rb_entry_cfqg(st->left); 558 cfqg = rb_entry_cfqg(st->left);
566 vdisktime = min_vdisktime(vdisktime, cfqg->vdisktime); 559 st->min_vdisktime = max_vdisktime(st->min_vdisktime,
560 cfqg->vdisktime);
567 } 561 }
568
569 st->min_vdisktime = max_vdisktime(st->min_vdisktime, vdisktime);
570} 562}
571 563
572/* 564/*
@@ -863,7 +855,27 @@ __cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg)
863} 855}
864 856
865static void 857static void
866cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg) 858cfq_update_group_weight(struct cfq_group *cfqg)
859{
860 BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node));
861 if (cfqg->needs_update) {
862 cfqg->weight = cfqg->new_weight;
863 cfqg->needs_update = false;
864 }
865}
866
867static void
868cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg)
869{
870 BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node));
871
872 cfq_update_group_weight(cfqg);
873 __cfq_group_service_tree_add(st, cfqg);
874 st->total_weight += cfqg->weight;
875}
876
877static void
878cfq_group_notify_queue_add(struct cfq_data *cfqd, struct cfq_group *cfqg)
867{ 879{
868 struct cfq_rb_root *st = &cfqd->grp_service_tree; 880 struct cfq_rb_root *st = &cfqd->grp_service_tree;
869 struct cfq_group *__cfqg; 881 struct cfq_group *__cfqg;
@@ -884,13 +896,19 @@ cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg)
884 cfqg->vdisktime = __cfqg->vdisktime + CFQ_IDLE_DELAY; 896 cfqg->vdisktime = __cfqg->vdisktime + CFQ_IDLE_DELAY;
885 } else 897 } else
886 cfqg->vdisktime = st->min_vdisktime; 898 cfqg->vdisktime = st->min_vdisktime;
899 cfq_group_service_tree_add(st, cfqg);
900}
887 901
888 __cfq_group_service_tree_add(st, cfqg); 902static void
889 st->total_weight += cfqg->weight; 903cfq_group_service_tree_del(struct cfq_rb_root *st, struct cfq_group *cfqg)
904{
905 st->total_weight -= cfqg->weight;
906 if (!RB_EMPTY_NODE(&cfqg->rb_node))
907 cfq_rb_erase(&cfqg->rb_node, st);
890} 908}
891 909
892static void 910static void
893cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg) 911cfq_group_notify_queue_del(struct cfq_data *cfqd, struct cfq_group *cfqg)
894{ 912{
895 struct cfq_rb_root *st = &cfqd->grp_service_tree; 913 struct cfq_rb_root *st = &cfqd->grp_service_tree;
896 914
@@ -902,14 +920,13 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg)
902 return; 920 return;
903 921
904 cfq_log_cfqg(cfqd, cfqg, "del_from_rr group"); 922 cfq_log_cfqg(cfqd, cfqg, "del_from_rr group");
905 st->total_weight -= cfqg->weight; 923 cfq_group_service_tree_del(st, cfqg);
906 if (!RB_EMPTY_NODE(&cfqg->rb_node))
907 cfq_rb_erase(&cfqg->rb_node, st);
908 cfqg->saved_workload_slice = 0; 924 cfqg->saved_workload_slice = 0;
909 cfq_blkiocg_update_dequeue_stats(&cfqg->blkg, 1); 925 cfq_blkiocg_update_dequeue_stats(&cfqg->blkg, 1);
910} 926}
911 927
912static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq) 928static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq,
929 unsigned int *unaccounted_time)
913{ 930{
914 unsigned int slice_used; 931 unsigned int slice_used;
915 932
@@ -928,8 +945,13 @@ static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq)
928 1); 945 1);
929 } else { 946 } else {
930 slice_used = jiffies - cfqq->slice_start; 947 slice_used = jiffies - cfqq->slice_start;
931 if (slice_used > cfqq->allocated_slice) 948 if (slice_used > cfqq->allocated_slice) {
949 *unaccounted_time = slice_used - cfqq->allocated_slice;
932 slice_used = cfqq->allocated_slice; 950 slice_used = cfqq->allocated_slice;
951 }
952 if (time_after(cfqq->slice_start, cfqq->dispatch_start))
953 *unaccounted_time += cfqq->slice_start -
954 cfqq->dispatch_start;
933 } 955 }
934 956
935 return slice_used; 957 return slice_used;
@@ -939,12 +961,12 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg,
939 struct cfq_queue *cfqq) 961 struct cfq_queue *cfqq)
940{ 962{
941 struct cfq_rb_root *st = &cfqd->grp_service_tree; 963 struct cfq_rb_root *st = &cfqd->grp_service_tree;
942 unsigned int used_sl, charge; 964 unsigned int used_sl, charge, unaccounted_sl = 0;
943 int nr_sync = cfqg->nr_cfqq - cfqg_busy_async_queues(cfqd, cfqg) 965 int nr_sync = cfqg->nr_cfqq - cfqg_busy_async_queues(cfqd, cfqg)
944 - cfqg->service_tree_idle.count; 966 - cfqg->service_tree_idle.count;
945 967
946 BUG_ON(nr_sync < 0); 968 BUG_ON(nr_sync < 0);
947 used_sl = charge = cfq_cfqq_slice_usage(cfqq); 969 used_sl = charge = cfq_cfqq_slice_usage(cfqq, &unaccounted_sl);
948 970
949 if (iops_mode(cfqd)) 971 if (iops_mode(cfqd))
950 charge = cfqq->slice_dispatch; 972 charge = cfqq->slice_dispatch;
@@ -952,9 +974,10 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg,
952 charge = cfqq->allocated_slice; 974 charge = cfqq->allocated_slice;
953 975
954 /* Can't update vdisktime while group is on service tree */ 976 /* Can't update vdisktime while group is on service tree */
955 cfq_rb_erase(&cfqg->rb_node, st); 977 cfq_group_service_tree_del(st, cfqg);
956 cfqg->vdisktime += cfq_scale_slice(charge, cfqg); 978 cfqg->vdisktime += cfq_scale_slice(charge, cfqg);
957 __cfq_group_service_tree_add(st, cfqg); 979 /* If a new weight was requested, update now, off tree */
980 cfq_group_service_tree_add(st, cfqg);
958 981
959 /* This group is being expired. Save the context */ 982 /* This group is being expired. Save the context */
960 if (time_after(cfqd->workload_expires, jiffies)) { 983 if (time_after(cfqd->workload_expires, jiffies)) {
@@ -970,7 +993,8 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg,
970 cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u disp=%u charge=%u iops=%u" 993 cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u disp=%u charge=%u iops=%u"
971 " sect=%u", used_sl, cfqq->slice_dispatch, charge, 994 " sect=%u", used_sl, cfqq->slice_dispatch, charge,
972 iops_mode(cfqd), cfqq->nr_sectors); 995 iops_mode(cfqd), cfqq->nr_sectors);
973 cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl); 996 cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl,
997 unaccounted_sl);
974 cfq_blkiocg_set_start_empty_time(&cfqg->blkg); 998 cfq_blkiocg_set_start_empty_time(&cfqg->blkg);
975} 999}
976 1000
@@ -985,7 +1009,9 @@ static inline struct cfq_group *cfqg_of_blkg(struct blkio_group *blkg)
985void cfq_update_blkio_group_weight(void *key, struct blkio_group *blkg, 1009void cfq_update_blkio_group_weight(void *key, struct blkio_group *blkg,
986 unsigned int weight) 1010 unsigned int weight)
987{ 1011{
988 cfqg_of_blkg(blkg)->weight = weight; 1012 struct cfq_group *cfqg = cfqg_of_blkg(blkg);
1013 cfqg->new_weight = weight;
1014 cfqg->needs_update = true;
989} 1015}
990 1016
991static struct cfq_group * 1017static struct cfq_group *
@@ -1187,32 +1213,6 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1187 int new_cfqq = 1; 1213 int new_cfqq = 1;
1188 int group_changed = 0; 1214 int group_changed = 0;
1189 1215
1190#ifdef CONFIG_CFQ_GROUP_IOSCHED
1191 if (!cfqd->cfq_group_isolation
1192 && cfqq_type(cfqq) == SYNC_NOIDLE_WORKLOAD
1193 && cfqq->cfqg && cfqq->cfqg != &cfqd->root_group) {
1194 /* Move this cfq to root group */
1195 cfq_log_cfqq(cfqd, cfqq, "moving to root group");
1196 if (!RB_EMPTY_NODE(&cfqq->rb_node))
1197 cfq_group_service_tree_del(cfqd, cfqq->cfqg);
1198 cfqq->orig_cfqg = cfqq->cfqg;
1199 cfqq->cfqg = &cfqd->root_group;
1200 cfqd->root_group.ref++;
1201 group_changed = 1;
1202 } else if (!cfqd->cfq_group_isolation
1203 && cfqq_type(cfqq) == SYNC_WORKLOAD && cfqq->orig_cfqg) {
1204 /* cfqq is sequential now needs to go to its original group */
1205 BUG_ON(cfqq->cfqg != &cfqd->root_group);
1206 if (!RB_EMPTY_NODE(&cfqq->rb_node))
1207 cfq_group_service_tree_del(cfqd, cfqq->cfqg);
1208 cfq_put_cfqg(cfqq->cfqg);
1209 cfqq->cfqg = cfqq->orig_cfqg;
1210 cfqq->orig_cfqg = NULL;
1211 group_changed = 1;
1212 cfq_log_cfqq(cfqd, cfqq, "moved to origin group");
1213 }
1214#endif
1215
1216 service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq), 1216 service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq),
1217 cfqq_type(cfqq)); 1217 cfqq_type(cfqq));
1218 if (cfq_class_idle(cfqq)) { 1218 if (cfq_class_idle(cfqq)) {
@@ -1284,7 +1284,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1284 service_tree->count++; 1284 service_tree->count++;
1285 if ((add_front || !new_cfqq) && !group_changed) 1285 if ((add_front || !new_cfqq) && !group_changed)
1286 return; 1286 return;
1287 cfq_group_service_tree_add(cfqd, cfqq->cfqg); 1287 cfq_group_notify_queue_add(cfqd, cfqq->cfqg);
1288} 1288}
1289 1289
1290static struct cfq_queue * 1290static struct cfq_queue *
@@ -1372,6 +1372,8 @@ static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1372 BUG_ON(cfq_cfqq_on_rr(cfqq)); 1372 BUG_ON(cfq_cfqq_on_rr(cfqq));
1373 cfq_mark_cfqq_on_rr(cfqq); 1373 cfq_mark_cfqq_on_rr(cfqq);
1374 cfqd->busy_queues++; 1374 cfqd->busy_queues++;
1375 if (cfq_cfqq_sync(cfqq))
1376 cfqd->busy_sync_queues++;
1375 1377
1376 cfq_resort_rr_list(cfqd, cfqq); 1378 cfq_resort_rr_list(cfqd, cfqq);
1377} 1379}
@@ -1395,9 +1397,11 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1395 cfqq->p_root = NULL; 1397 cfqq->p_root = NULL;
1396 } 1398 }
1397 1399
1398 cfq_group_service_tree_del(cfqd, cfqq->cfqg); 1400 cfq_group_notify_queue_del(cfqd, cfqq->cfqg);
1399 BUG_ON(!cfqd->busy_queues); 1401 BUG_ON(!cfqd->busy_queues);
1400 cfqd->busy_queues--; 1402 cfqd->busy_queues--;
1403 if (cfq_cfqq_sync(cfqq))
1404 cfqd->busy_sync_queues--;
1401} 1405}
1402 1406
1403/* 1407/*
@@ -2405,6 +2409,7 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
2405 * Does this cfqq already have too much IO in flight? 2409 * Does this cfqq already have too much IO in flight?
2406 */ 2410 */
2407 if (cfqq->dispatched >= max_dispatch) { 2411 if (cfqq->dispatched >= max_dispatch) {
2412 bool promote_sync = false;
2408 /* 2413 /*
2409 * idle queue must always only have a single IO in flight 2414 * idle queue must always only have a single IO in flight
2410 */ 2415 */
@@ -2412,15 +2417,26 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
2412 return false; 2417 return false;
2413 2418
2414 /* 2419 /*
2420 * If there is only one sync queue
2421 * we can ignore async queue here and give the sync
2422 * queue no dispatch limit. The reason is a sync queue can
2423 * preempt async queue, limiting the sync queue doesn't make
2424 * sense. This is useful for aiostress test.
2425 */
2426 if (cfq_cfqq_sync(cfqq) && cfqd->busy_sync_queues == 1)
2427 promote_sync = true;
2428
2429 /*
2415 * We have other queues, don't allow more IO from this one 2430 * We have other queues, don't allow more IO from this one
2416 */ 2431 */
2417 if (cfqd->busy_queues > 1 && cfq_slice_used_soon(cfqd, cfqq)) 2432 if (cfqd->busy_queues > 1 && cfq_slice_used_soon(cfqd, cfqq) &&
2433 !promote_sync)
2418 return false; 2434 return false;
2419 2435
2420 /* 2436 /*
2421 * Sole queue user, no limit 2437 * Sole queue user, no limit
2422 */ 2438 */
2423 if (cfqd->busy_queues == 1) 2439 if (cfqd->busy_queues == 1 || promote_sync)
2424 max_dispatch = -1; 2440 max_dispatch = -1;
2425 else 2441 else
2426 /* 2442 /*
@@ -2542,7 +2558,7 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
2542static void cfq_put_queue(struct cfq_queue *cfqq) 2558static void cfq_put_queue(struct cfq_queue *cfqq)
2543{ 2559{
2544 struct cfq_data *cfqd = cfqq->cfqd; 2560 struct cfq_data *cfqd = cfqq->cfqd;
2545 struct cfq_group *cfqg, *orig_cfqg; 2561 struct cfq_group *cfqg;
2546 2562
2547 BUG_ON(cfqq->ref <= 0); 2563 BUG_ON(cfqq->ref <= 0);
2548 2564
@@ -2554,7 +2570,6 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
2554 BUG_ON(rb_first(&cfqq->sort_list)); 2570 BUG_ON(rb_first(&cfqq->sort_list));
2555 BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]); 2571 BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]);
2556 cfqg = cfqq->cfqg; 2572 cfqg = cfqq->cfqg;
2557 orig_cfqg = cfqq->orig_cfqg;
2558 2573
2559 if (unlikely(cfqd->active_queue == cfqq)) { 2574 if (unlikely(cfqd->active_queue == cfqq)) {
2560 __cfq_slice_expired(cfqd, cfqq, 0); 2575 __cfq_slice_expired(cfqd, cfqq, 0);
@@ -2564,8 +2579,6 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
2564 BUG_ON(cfq_cfqq_on_rr(cfqq)); 2579 BUG_ON(cfq_cfqq_on_rr(cfqq));
2565 kmem_cache_free(cfq_pool, cfqq); 2580 kmem_cache_free(cfq_pool, cfqq);
2566 cfq_put_cfqg(cfqg); 2581 cfq_put_cfqg(cfqg);
2567 if (orig_cfqg)
2568 cfq_put_cfqg(orig_cfqg);
2569} 2582}
2570 2583
2571/* 2584/*
@@ -3613,12 +3626,12 @@ static void cfq_put_request(struct request *rq)
3613 3626
3614 put_io_context(RQ_CIC(rq)->ioc); 3627 put_io_context(RQ_CIC(rq)->ioc);
3615 3628
3616 rq->elevator_private = NULL; 3629 rq->elevator_private[0] = NULL;
3617 rq->elevator_private2 = NULL; 3630 rq->elevator_private[1] = NULL;
3618 3631
3619 /* Put down rq reference on cfqg */ 3632 /* Put down rq reference on cfqg */
3620 cfq_put_cfqg(RQ_CFQG(rq)); 3633 cfq_put_cfqg(RQ_CFQG(rq));
3621 rq->elevator_private3 = NULL; 3634 rq->elevator_private[2] = NULL;
3622 3635
3623 cfq_put_queue(cfqq); 3636 cfq_put_queue(cfqq);
3624 } 3637 }
@@ -3705,13 +3718,12 @@ new_queue:
3705 } 3718 }
3706 3719
3707 cfqq->allocated[rw]++; 3720 cfqq->allocated[rw]++;
3708 cfqq->ref++;
3709 rq->elevator_private = cic;
3710 rq->elevator_private2 = cfqq;
3711 rq->elevator_private3 = cfq_ref_get_cfqg(cfqq->cfqg);
3712 3721
3722 cfqq->ref++;
3723 rq->elevator_private[0] = cic;
3724 rq->elevator_private[1] = cfqq;
3725 rq->elevator_private[2] = cfq_ref_get_cfqg(cfqq->cfqg);
3713 spin_unlock_irqrestore(q->queue_lock, flags); 3726 spin_unlock_irqrestore(q->queue_lock, flags);
3714
3715 return 0; 3727 return 0;
3716 3728
3717queue_fail: 3729queue_fail:
@@ -3953,7 +3965,6 @@ static void *cfq_init_queue(struct request_queue *q)
3953 cfqd->cfq_slice_idle = cfq_slice_idle; 3965 cfqd->cfq_slice_idle = cfq_slice_idle;
3954 cfqd->cfq_group_idle = cfq_group_idle; 3966 cfqd->cfq_group_idle = cfq_group_idle;
3955 cfqd->cfq_latency = 1; 3967 cfqd->cfq_latency = 1;
3956 cfqd->cfq_group_isolation = 0;
3957 cfqd->hw_tag = -1; 3968 cfqd->hw_tag = -1;
3958 /* 3969 /*
3959 * we optimistically start assuming sync ops weren't delayed in last 3970 * we optimistically start assuming sync ops weren't delayed in last
@@ -4029,7 +4040,6 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
4029SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); 4040SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
4030SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); 4041SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
4031SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); 4042SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
4032SHOW_FUNCTION(cfq_group_isolation_show, cfqd->cfq_group_isolation, 0);
4033#undef SHOW_FUNCTION 4043#undef SHOW_FUNCTION
4034 4044
4035#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ 4045#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
@@ -4063,7 +4073,6 @@ STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
4063STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, 4073STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
4064 UINT_MAX, 0); 4074 UINT_MAX, 0);
4065STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); 4075STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
4066STORE_FUNCTION(cfq_group_isolation_store, &cfqd->cfq_group_isolation, 0, 1, 0);
4067#undef STORE_FUNCTION 4076#undef STORE_FUNCTION
4068 4077
4069#define CFQ_ATTR(name) \ 4078#define CFQ_ATTR(name) \
@@ -4081,7 +4090,6 @@ static struct elv_fs_entry cfq_attrs[] = {
4081 CFQ_ATTR(slice_idle), 4090 CFQ_ATTR(slice_idle),
4082 CFQ_ATTR(group_idle), 4091 CFQ_ATTR(group_idle),
4083 CFQ_ATTR(low_latency), 4092 CFQ_ATTR(low_latency),
4084 CFQ_ATTR(group_isolation),
4085 __ATTR_NULL 4093 __ATTR_NULL
4086}; 4094};
4087 4095
@@ -4096,7 +4104,6 @@ static struct elevator_type iosched_cfq = {
4096 .elevator_add_req_fn = cfq_insert_request, 4104 .elevator_add_req_fn = cfq_insert_request,
4097 .elevator_activate_req_fn = cfq_activate_request, 4105 .elevator_activate_req_fn = cfq_activate_request,
4098 .elevator_deactivate_req_fn = cfq_deactivate_request, 4106 .elevator_deactivate_req_fn = cfq_deactivate_request,
4099 .elevator_queue_empty_fn = cfq_queue_empty,
4100 .elevator_completed_req_fn = cfq_completed_request, 4107 .elevator_completed_req_fn = cfq_completed_request,
4101 .elevator_former_req_fn = elv_rb_former_request, 4108 .elevator_former_req_fn = elv_rb_former_request,
4102 .elevator_latter_req_fn = elv_rb_latter_request, 4109 .elevator_latter_req_fn = elv_rb_latter_request,
diff --git a/block/cfq.h b/block/cfq.h
index 54a6d90f8e8c..2a155927e37c 100644
--- a/block/cfq.h
+++ b/block/cfq.h
@@ -16,9 +16,9 @@ static inline void cfq_blkiocg_update_dequeue_stats(struct blkio_group *blkg,
16} 16}
17 17
18static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg, 18static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg,
19 unsigned long time) 19 unsigned long time, unsigned long unaccounted_time)
20{ 20{
21 blkiocg_update_timeslice_used(blkg, time); 21 blkiocg_update_timeslice_used(blkg, time, unaccounted_time);
22} 22}
23 23
24static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg) 24static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg)
@@ -85,7 +85,7 @@ static inline void cfq_blkiocg_update_dequeue_stats(struct blkio_group *blkg,
85 unsigned long dequeue) {} 85 unsigned long dequeue) {}
86 86
87static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg, 87static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg,
88 unsigned long time) {} 88 unsigned long time, unsigned long unaccounted_time) {}
89static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg) {} 89static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg) {}
90static inline void cfq_blkiocg_update_io_remove_stats(struct blkio_group *blkg, 90static inline void cfq_blkiocg_update_io_remove_stats(struct blkio_group *blkg,
91 bool direction, bool sync) {} 91 bool direction, bool sync) {}
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index b547cbca7b23..5139c0ea1864 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -326,14 +326,6 @@ dispatch_request:
326 return 1; 326 return 1;
327} 327}
328 328
329static int deadline_queue_empty(struct request_queue *q)
330{
331 struct deadline_data *dd = q->elevator->elevator_data;
332
333 return list_empty(&dd->fifo_list[WRITE])
334 && list_empty(&dd->fifo_list[READ]);
335}
336
337static void deadline_exit_queue(struct elevator_queue *e) 329static void deadline_exit_queue(struct elevator_queue *e)
338{ 330{
339 struct deadline_data *dd = e->elevator_data; 331 struct deadline_data *dd = e->elevator_data;
@@ -445,7 +437,6 @@ static struct elevator_type iosched_deadline = {
445 .elevator_merge_req_fn = deadline_merged_requests, 437 .elevator_merge_req_fn = deadline_merged_requests,
446 .elevator_dispatch_fn = deadline_dispatch_requests, 438 .elevator_dispatch_fn = deadline_dispatch_requests,
447 .elevator_add_req_fn = deadline_add_request, 439 .elevator_add_req_fn = deadline_add_request,
448 .elevator_queue_empty_fn = deadline_queue_empty,
449 .elevator_former_req_fn = elv_rb_former_request, 440 .elevator_former_req_fn = elv_rb_former_request,
450 .elevator_latter_req_fn = elv_rb_latter_request, 441 .elevator_latter_req_fn = elv_rb_latter_request,
451 .elevator_init_fn = deadline_init_queue, 442 .elevator_init_fn = deadline_init_queue,
diff --git a/block/elevator.c b/block/elevator.c
index 236e93c1f46c..c387d3168734 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -113,7 +113,7 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio)
113} 113}
114EXPORT_SYMBOL(elv_rq_merge_ok); 114EXPORT_SYMBOL(elv_rq_merge_ok);
115 115
116static inline int elv_try_merge(struct request *__rq, struct bio *bio) 116int elv_try_merge(struct request *__rq, struct bio *bio)
117{ 117{
118 int ret = ELEVATOR_NO_MERGE; 118 int ret = ELEVATOR_NO_MERGE;
119 119
@@ -421,6 +421,8 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq)
421 struct list_head *entry; 421 struct list_head *entry;
422 int stop_flags; 422 int stop_flags;
423 423
424 BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
425
424 if (q->last_merge == rq) 426 if (q->last_merge == rq)
425 q->last_merge = NULL; 427 q->last_merge = NULL;
426 428
@@ -519,6 +521,40 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
519 return ELEVATOR_NO_MERGE; 521 return ELEVATOR_NO_MERGE;
520} 522}
521 523
524/*
525 * Attempt to do an insertion back merge. Only check for the case where
526 * we can append 'rq' to an existing request, so we can throw 'rq' away
527 * afterwards.
528 *
529 * Returns true if we merged, false otherwise
530 */
531static bool elv_attempt_insert_merge(struct request_queue *q,
532 struct request *rq)
533{
534 struct request *__rq;
535
536 if (blk_queue_nomerges(q))
537 return false;
538
539 /*
540 * First try one-hit cache.
541 */
542 if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq))
543 return true;
544
545 if (blk_queue_noxmerges(q))
546 return false;
547
548 /*
549 * See if our hash lookup can find a potential backmerge.
550 */
551 __rq = elv_rqhash_find(q, blk_rq_pos(rq));
552 if (__rq && blk_attempt_req_merge(q, __rq, rq))
553 return true;
554
555 return false;
556}
557
522void elv_merged_request(struct request_queue *q, struct request *rq, int type) 558void elv_merged_request(struct request_queue *q, struct request *rq, int type)
523{ 559{
524 struct elevator_queue *e = q->elevator; 560 struct elevator_queue *e = q->elevator;
@@ -536,14 +572,18 @@ void elv_merge_requests(struct request_queue *q, struct request *rq,
536 struct request *next) 572 struct request *next)
537{ 573{
538 struct elevator_queue *e = q->elevator; 574 struct elevator_queue *e = q->elevator;
575 const int next_sorted = next->cmd_flags & REQ_SORTED;
539 576
540 if (e->ops->elevator_merge_req_fn) 577 if (next_sorted && e->ops->elevator_merge_req_fn)
541 e->ops->elevator_merge_req_fn(q, rq, next); 578 e->ops->elevator_merge_req_fn(q, rq, next);
542 579
543 elv_rqhash_reposition(q, rq); 580 elv_rqhash_reposition(q, rq);
544 elv_rqhash_del(q, next);
545 581
546 q->nr_sorted--; 582 if (next_sorted) {
583 elv_rqhash_del(q, next);
584 q->nr_sorted--;
585 }
586
547 q->last_merge = rq; 587 q->last_merge = rq;
548} 588}
549 589
@@ -617,21 +657,12 @@ void elv_quiesce_end(struct request_queue *q)
617 657
618void elv_insert(struct request_queue *q, struct request *rq, int where) 658void elv_insert(struct request_queue *q, struct request *rq, int where)
619{ 659{
620 int unplug_it = 1;
621
622 trace_block_rq_insert(q, rq); 660 trace_block_rq_insert(q, rq);
623 661
624 rq->q = q; 662 rq->q = q;
625 663
626 switch (where) { 664 switch (where) {
627 case ELEVATOR_INSERT_REQUEUE: 665 case ELEVATOR_INSERT_REQUEUE:
628 /*
629 * Most requeues happen because of a busy condition,
630 * don't force unplug of the queue for that case.
631 * Clear unplug_it and fall through.
632 */
633 unplug_it = 0;
634
635 case ELEVATOR_INSERT_FRONT: 666 case ELEVATOR_INSERT_FRONT:
636 rq->cmd_flags |= REQ_SOFTBARRIER; 667 rq->cmd_flags |= REQ_SOFTBARRIER;
637 list_add(&rq->queuelist, &q->queue_head); 668 list_add(&rq->queuelist, &q->queue_head);
@@ -654,6 +685,14 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
654 __blk_run_queue(q, false); 685 __blk_run_queue(q, false);
655 break; 686 break;
656 687
688 case ELEVATOR_INSERT_SORT_MERGE:
689 /*
690 * If we succeed in merging this request with one in the
691 * queue already, we are done - rq has now been freed,
692 * so no need to do anything further.
693 */
694 if (elv_attempt_insert_merge(q, rq))
695 break;
657 case ELEVATOR_INSERT_SORT: 696 case ELEVATOR_INSERT_SORT:
658 BUG_ON(rq->cmd_type != REQ_TYPE_FS && 697 BUG_ON(rq->cmd_type != REQ_TYPE_FS &&
659 !(rq->cmd_flags & REQ_DISCARD)); 698 !(rq->cmd_flags & REQ_DISCARD));
@@ -673,24 +712,21 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
673 q->elevator->ops->elevator_add_req_fn(q, rq); 712 q->elevator->ops->elevator_add_req_fn(q, rq);
674 break; 713 break;
675 714
715 case ELEVATOR_INSERT_FLUSH:
716 rq->cmd_flags |= REQ_SOFTBARRIER;
717 blk_insert_flush(rq);
718 break;
676 default: 719 default:
677 printk(KERN_ERR "%s: bad insertion point %d\n", 720 printk(KERN_ERR "%s: bad insertion point %d\n",
678 __func__, where); 721 __func__, where);
679 BUG(); 722 BUG();
680 } 723 }
681
682 if (unplug_it && blk_queue_plugged(q)) {
683 int nrq = q->rq.count[BLK_RW_SYNC] + q->rq.count[BLK_RW_ASYNC]
684 - queue_in_flight(q);
685
686 if (nrq >= q->unplug_thresh)
687 __generic_unplug_device(q);
688 }
689} 724}
690 725
691void __elv_add_request(struct request_queue *q, struct request *rq, int where, 726void __elv_add_request(struct request_queue *q, struct request *rq, int where)
692 int plug)
693{ 727{
728 BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
729
694 if (rq->cmd_flags & REQ_SOFTBARRIER) { 730 if (rq->cmd_flags & REQ_SOFTBARRIER) {
695 /* barriers are scheduling boundary, update end_sector */ 731 /* barriers are scheduling boundary, update end_sector */
696 if (rq->cmd_type == REQ_TYPE_FS || 732 if (rq->cmd_type == REQ_TYPE_FS ||
@@ -702,38 +738,20 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where,
702 where == ELEVATOR_INSERT_SORT) 738 where == ELEVATOR_INSERT_SORT)
703 where = ELEVATOR_INSERT_BACK; 739 where = ELEVATOR_INSERT_BACK;
704 740
705 if (plug)
706 blk_plug_device(q);
707
708 elv_insert(q, rq, where); 741 elv_insert(q, rq, where);
709} 742}
710EXPORT_SYMBOL(__elv_add_request); 743EXPORT_SYMBOL(__elv_add_request);
711 744
712void elv_add_request(struct request_queue *q, struct request *rq, int where, 745void elv_add_request(struct request_queue *q, struct request *rq, int where)
713 int plug)
714{ 746{
715 unsigned long flags; 747 unsigned long flags;
716 748
717 spin_lock_irqsave(q->queue_lock, flags); 749 spin_lock_irqsave(q->queue_lock, flags);
718 __elv_add_request(q, rq, where, plug); 750 __elv_add_request(q, rq, where);
719 spin_unlock_irqrestore(q->queue_lock, flags); 751 spin_unlock_irqrestore(q->queue_lock, flags);
720} 752}
721EXPORT_SYMBOL(elv_add_request); 753EXPORT_SYMBOL(elv_add_request);
722 754
723int elv_queue_empty(struct request_queue *q)
724{
725 struct elevator_queue *e = q->elevator;
726
727 if (!list_empty(&q->queue_head))
728 return 0;
729
730 if (e->ops->elevator_queue_empty_fn)
731 return e->ops->elevator_queue_empty_fn(q);
732
733 return 1;
734}
735EXPORT_SYMBOL(elv_queue_empty);
736
737struct request *elv_latter_request(struct request_queue *q, struct request *rq) 755struct request *elv_latter_request(struct request_queue *q, struct request *rq)
738{ 756{
739 struct elevator_queue *e = q->elevator; 757 struct elevator_queue *e = q->elevator;
@@ -759,7 +777,7 @@ int elv_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
759 if (e->ops->elevator_set_req_fn) 777 if (e->ops->elevator_set_req_fn)
760 return e->ops->elevator_set_req_fn(q, rq, gfp_mask); 778 return e->ops->elevator_set_req_fn(q, rq, gfp_mask);
761 779
762 rq->elevator_private = NULL; 780 rq->elevator_private[0] = NULL;
763 return 0; 781 return 0;
764} 782}
765 783
@@ -785,6 +803,8 @@ void elv_abort_queue(struct request_queue *q)
785{ 803{
786 struct request *rq; 804 struct request *rq;
787 805
806 blk_abort_flushes(q);
807
788 while (!list_empty(&q->queue_head)) { 808 while (!list_empty(&q->queue_head)) {
789 rq = list_entry_rq(q->queue_head.next); 809 rq = list_entry_rq(q->queue_head.next);
790 rq->cmd_flags |= REQ_QUIET; 810 rq->cmd_flags |= REQ_QUIET;
diff --git a/block/genhd.c b/block/genhd.c
index cbf1112a885c..c91a2dac6b6b 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1158,14 +1158,14 @@ static int diskstats_show(struct seq_file *seqf, void *v)
1158 "%u %lu %lu %llu %u %u %u %u\n", 1158 "%u %lu %lu %llu %u %u %u %u\n",
1159 MAJOR(part_devt(hd)), MINOR(part_devt(hd)), 1159 MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
1160 disk_name(gp, hd->partno, buf), 1160 disk_name(gp, hd->partno, buf),
1161 part_stat_read(hd, ios[0]), 1161 part_stat_read(hd, ios[READ]),
1162 part_stat_read(hd, merges[0]), 1162 part_stat_read(hd, merges[READ]),
1163 (unsigned long long)part_stat_read(hd, sectors[0]), 1163 (unsigned long long)part_stat_read(hd, sectors[READ]),
1164 jiffies_to_msecs(part_stat_read(hd, ticks[0])), 1164 jiffies_to_msecs(part_stat_read(hd, ticks[READ])),
1165 part_stat_read(hd, ios[1]), 1165 part_stat_read(hd, ios[WRITE]),
1166 part_stat_read(hd, merges[1]), 1166 part_stat_read(hd, merges[WRITE]),
1167 (unsigned long long)part_stat_read(hd, sectors[1]), 1167 (unsigned long long)part_stat_read(hd, sectors[WRITE]),
1168 jiffies_to_msecs(part_stat_read(hd, ticks[1])), 1168 jiffies_to_msecs(part_stat_read(hd, ticks[WRITE])),
1169 part_in_flight(hd), 1169 part_in_flight(hd),
1170 jiffies_to_msecs(part_stat_read(hd, io_ticks)), 1170 jiffies_to_msecs(part_stat_read(hd, io_ticks)),
1171 jiffies_to_msecs(part_stat_read(hd, time_in_queue)) 1171 jiffies_to_msecs(part_stat_read(hd, time_in_queue))
@@ -1494,7 +1494,7 @@ void disk_block_events(struct gendisk *disk)
1494void disk_unblock_events(struct gendisk *disk) 1494void disk_unblock_events(struct gendisk *disk)
1495{ 1495{
1496 if (disk->ev) 1496 if (disk->ev)
1497 __disk_unblock_events(disk, true); 1497 __disk_unblock_events(disk, false);
1498} 1498}
1499 1499
1500/** 1500/**
diff --git a/block/noop-iosched.c b/block/noop-iosched.c
index 232c4b38cd37..06389e9ef96d 100644
--- a/block/noop-iosched.c
+++ b/block/noop-iosched.c
@@ -39,13 +39,6 @@ static void noop_add_request(struct request_queue *q, struct request *rq)
39 list_add_tail(&rq->queuelist, &nd->queue); 39 list_add_tail(&rq->queuelist, &nd->queue);
40} 40}
41 41
42static int noop_queue_empty(struct request_queue *q)
43{
44 struct noop_data *nd = q->elevator->elevator_data;
45
46 return list_empty(&nd->queue);
47}
48
49static struct request * 42static struct request *
50noop_former_request(struct request_queue *q, struct request *rq) 43noop_former_request(struct request_queue *q, struct request *rq)
51{ 44{
@@ -90,7 +83,6 @@ static struct elevator_type elevator_noop = {
90 .elevator_merge_req_fn = noop_merged_requests, 83 .elevator_merge_req_fn = noop_merged_requests,
91 .elevator_dispatch_fn = noop_dispatch, 84 .elevator_dispatch_fn = noop_dispatch,
92 .elevator_add_req_fn = noop_add_request, 85 .elevator_add_req_fn = noop_add_request,
93 .elevator_queue_empty_fn = noop_queue_empty,
94 .elevator_former_req_fn = noop_former_request, 86 .elevator_former_req_fn = noop_former_request,
95 .elevator_latter_req_fn = noop_latter_request, 87 .elevator_latter_req_fn = noop_latter_request,
96 .elevator_init_fn = noop_init_queue, 88 .elevator_init_fn = noop_init_queue,
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 6afceb3d4034..a43fa1a57d57 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -298,7 +298,7 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev,
298static ssize_t acpi_pad_rrtime_show(struct device *dev, 298static ssize_t acpi_pad_rrtime_show(struct device *dev,
299 struct device_attribute *attr, char *buf) 299 struct device_attribute *attr, char *buf)
300{ 300{
301 return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time); 301 return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time);
302} 302}
303static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, 303static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR,
304 acpi_pad_rrtime_show, 304 acpi_pad_rrtime_show,
@@ -321,7 +321,7 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev,
321static ssize_t acpi_pad_idlepct_show(struct device *dev, 321static ssize_t acpi_pad_idlepct_show(struct device *dev,
322 struct device_attribute *attr, char *buf) 322 struct device_attribute *attr, char *buf)
323{ 323{
324 return scnprintf(buf, PAGE_SIZE, "%d", idle_pct); 324 return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct);
325} 325}
326static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, 326static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR,
327 acpi_pad_idlepct_show, 327 acpi_pad_idlepct_show,
@@ -342,8 +342,11 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev,
342static ssize_t acpi_pad_idlecpus_show(struct device *dev, 342static ssize_t acpi_pad_idlecpus_show(struct device *dev,
343 struct device_attribute *attr, char *buf) 343 struct device_attribute *attr, char *buf)
344{ 344{
345 return cpumask_scnprintf(buf, PAGE_SIZE, 345 int n = 0;
346 to_cpumask(pad_busy_cpus_bits)); 346 n = cpumask_scnprintf(buf, PAGE_SIZE-2, to_cpumask(pad_busy_cpus_bits));
347 buf[n++] = '\n';
348 buf[n] = '\0';
349 return n;
347} 350}
348static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, 351static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR,
349 acpi_pad_idlecpus_show, 352 acpi_pad_idlecpus_show,
@@ -453,7 +456,7 @@ static void acpi_pad_notify(acpi_handle handle, u32 event,
453 dev_name(&device->dev), event, 0); 456 dev_name(&device->dev), event, 0);
454 break; 457 break;
455 default: 458 default:
456 printk(KERN_WARNING"Unsupported event [0x%x]\n", event); 459 printk(KERN_WARNING "Unsupported event [0x%x]\n", event);
457 break; 460 break;
458 } 461 }
459} 462}
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index eec2eadd2431..a1224712fd0c 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -10,7 +10,7 @@ obj-y += acpi.o
10 10
11acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ 11acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
12 dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ 12 dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \
13 dsinit.o 13 dsinit.o dsargs.o dscontrol.o dswload2.o
14 14
15acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ 15acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \
16 evmisc.o evrgnini.o evxface.o evxfregn.o \ 16 evmisc.o evrgnini.o evxface.o evxfregn.o \
@@ -45,4 +45,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
45acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ 45acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
46 utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ 46 utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
47 utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ 47 utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \
48 utosi.o utxferror.o 48 utosi.o utxferror.o utdecode.o
diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h
index 666271b65418..2d1b7ffa377a 100644
--- a/drivers/acpi/acpica/acdispat.h
+++ b/drivers/acpi/acpica/acdispat.h
@@ -48,7 +48,7 @@
48#define NAMEOF_ARG_NTE "__A0" 48#define NAMEOF_ARG_NTE "__A0"
49 49
50/* 50/*
51 * dsopcode - support for late evaluation 51 * dsargs - execution of dynamic arguments for static objects
52 */ 52 */
53acpi_status 53acpi_status
54acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); 54acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc);
@@ -62,6 +62,20 @@ acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc);
62 62
63acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc); 63acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc);
64 64
65/*
66 * dscontrol - support for execution control opcodes
67 */
68acpi_status
69acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
70 union acpi_parse_object *op);
71
72acpi_status
73acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
74 union acpi_parse_object *op);
75
76/*
77 * dsopcode - support for late operand evaluation
78 */
65acpi_status 79acpi_status
66acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, 80acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
67 union acpi_parse_object *op); 81 union acpi_parse_object *op);
@@ -86,17 +100,6 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
86acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); 100acpi_status acpi_ds_initialize_region(acpi_handle obj_handle);
87 101
88/* 102/*
89 * dsctrl - Parser/Interpreter interface, control stack routines
90 */
91acpi_status
92acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
93 union acpi_parse_object *op);
94
95acpi_status
96acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
97 union acpi_parse_object *op);
98
99/*
100 * dsexec - Parser/Interpreter interface, method execution callbacks 103 * dsexec - Parser/Interpreter interface, method execution callbacks
101 */ 104 */
102acpi_status 105acpi_status
@@ -136,23 +139,26 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
136 struct acpi_walk_state *walk_state); 139 struct acpi_walk_state *walk_state);
137 140
138/* 141/*
139 * dsload - Parser/Interpreter interface, namespace load callbacks 142 * dsload - Parser/Interpreter interface, pass 1 namespace load callbacks
140 */ 143 */
141acpi_status 144acpi_status
145acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
146
147acpi_status
142acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state, 148acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
143 union acpi_parse_object **out_op); 149 union acpi_parse_object **out_op);
144 150
145acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state); 151acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state);
146 152
153/*
154 * dsload - Parser/Interpreter interface, pass 2 namespace load callbacks
155 */
147acpi_status 156acpi_status
148acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, 157acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
149 union acpi_parse_object **out_op); 158 union acpi_parse_object **out_op);
150 159
151acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state); 160acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state);
152 161
153acpi_status
154acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
155
156/* 162/*
157 * dsmthdat - method data (locals/args) 163 * dsmthdat - method data (locals/args)
158 */ 164 */
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 82a1bd283db8..d69750b83b36 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -273,6 +273,10 @@ ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS];
273ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; 273ACPI_EXTERN u8 acpi_gbl_last_owner_id_index;
274ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; 274ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset;
275 275
276/* Initialization sequencing */
277
278ACPI_EXTERN u8 acpi_gbl_reg_methods_executed;
279
276/* Misc */ 280/* Misc */
277 281
278ACPI_EXTERN u32 acpi_gbl_original_mode; 282ACPI_EXTERN u32 acpi_gbl_original_mode;
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index edc25867ad9d..c7f743ca395b 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -89,25 +89,6 @@ union acpi_parse_object;
89#define ACPI_MAX_MUTEX 7 89#define ACPI_MAX_MUTEX 7
90#define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1 90#define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1
91 91
92#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
93#ifdef DEFINE_ACPI_GLOBALS
94
95/* Debug names for the mutexes above */
96
97static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
98 "ACPI_MTX_Interpreter",
99 "ACPI_MTX_Namespace",
100 "ACPI_MTX_Tables",
101 "ACPI_MTX_Events",
102 "ACPI_MTX_Caches",
103 "ACPI_MTX_Memory",
104 "ACPI_MTX_CommandComplete",
105 "ACPI_MTX_CommandReady"
106};
107
108#endif
109#endif
110
111/* Lock structure for reader/writer interfaces */ 92/* Lock structure for reader/writer interfaces */
112 93
113struct acpi_rw_lock { 94struct acpi_rw_lock {
diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c
new file mode 100644
index 000000000000..8c7b99728aa2
--- /dev/null
+++ b/drivers/acpi/acpica/dsargs.c
@@ -0,0 +1,391 @@
1/******************************************************************************
2 *
3 * Module Name: dsargs - Support for execution of dynamic arguments for static
4 * objects (regions, fields, buffer fields, etc.)
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include "accommon.h"
47#include "acparser.h"
48#include "amlcode.h"
49#include "acdispat.h"
50#include "acnamesp.h"
51
52#define _COMPONENT ACPI_DISPATCHER
53ACPI_MODULE_NAME("dsargs")
54
55/* Local prototypes */
56static acpi_status
57acpi_ds_execute_arguments(struct acpi_namespace_node *node,
58 struct acpi_namespace_node *scope_node,
59 u32 aml_length, u8 *aml_start);
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ds_execute_arguments
64 *
65 * PARAMETERS: Node - Object NS node
66 * scope_node - Parent NS node
67 * aml_length - Length of executable AML
68 * aml_start - Pointer to the AML
69 *
70 * RETURN: Status.
71 *
72 * DESCRIPTION: Late (deferred) execution of region or field arguments
73 *
74 ******************************************************************************/
75
76static acpi_status
77acpi_ds_execute_arguments(struct acpi_namespace_node *node,
78 struct acpi_namespace_node *scope_node,
79 u32 aml_length, u8 *aml_start)
80{
81 acpi_status status;
82 union acpi_parse_object *op;
83 struct acpi_walk_state *walk_state;
84
85 ACPI_FUNCTION_TRACE(ds_execute_arguments);
86
87 /* Allocate a new parser op to be the root of the parsed tree */
88
89 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
90 if (!op) {
91 return_ACPI_STATUS(AE_NO_MEMORY);
92 }
93
94 /* Save the Node for use in acpi_ps_parse_aml */
95
96 op->common.node = scope_node;
97
98 /* Create and initialize a new parser state */
99
100 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
101 if (!walk_state) {
102 status = AE_NO_MEMORY;
103 goto cleanup;
104 }
105
106 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
107 aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
108 if (ACPI_FAILURE(status)) {
109 acpi_ds_delete_walk_state(walk_state);
110 goto cleanup;
111 }
112
113 /* Mark this parse as a deferred opcode */
114
115 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
116 walk_state->deferred_node = node;
117
118 /* Pass1: Parse the entire declaration */
119
120 status = acpi_ps_parse_aml(walk_state);
121 if (ACPI_FAILURE(status)) {
122 goto cleanup;
123 }
124
125 /* Get and init the Op created above */
126
127 op->common.node = node;
128 acpi_ps_delete_parse_tree(op);
129
130 /* Evaluate the deferred arguments */
131
132 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
133 if (!op) {
134 return_ACPI_STATUS(AE_NO_MEMORY);
135 }
136
137 op->common.node = scope_node;
138
139 /* Create and initialize a new parser state */
140
141 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
142 if (!walk_state) {
143 status = AE_NO_MEMORY;
144 goto cleanup;
145 }
146
147 /* Execute the opcode and arguments */
148
149 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
150 aml_length, NULL, ACPI_IMODE_EXECUTE);
151 if (ACPI_FAILURE(status)) {
152 acpi_ds_delete_walk_state(walk_state);
153 goto cleanup;
154 }
155
156 /* Mark this execution as a deferred opcode */
157
158 walk_state->deferred_node = node;
159 status = acpi_ps_parse_aml(walk_state);
160
161 cleanup:
162 acpi_ps_delete_parse_tree(op);
163 return_ACPI_STATUS(status);
164}
165
166/*******************************************************************************
167 *
168 * FUNCTION: acpi_ds_get_buffer_field_arguments
169 *
170 * PARAMETERS: obj_desc - A valid buffer_field object
171 *
172 * RETURN: Status.
173 *
174 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
175 * evaluation of these field attributes.
176 *
177 ******************************************************************************/
178
179acpi_status
180acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
181{
182 union acpi_operand_object *extra_desc;
183 struct acpi_namespace_node *node;
184 acpi_status status;
185
186 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
187
188 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
189 return_ACPI_STATUS(AE_OK);
190 }
191
192 /* Get the AML pointer (method object) and buffer_field node */
193
194 extra_desc = acpi_ns_get_secondary_object(obj_desc);
195 node = obj_desc->buffer_field.node;
196
197 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD,
198 node, NULL));
199
200 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
201 acpi_ut_get_node_name(node)));
202
203 /* Execute the AML code for the term_arg arguments */
204
205 status = acpi_ds_execute_arguments(node, node->parent,
206 extra_desc->extra.aml_length,
207 extra_desc->extra.aml_start);
208 return_ACPI_STATUS(status);
209}
210
211/*******************************************************************************
212 *
213 * FUNCTION: acpi_ds_get_bank_field_arguments
214 *
215 * PARAMETERS: obj_desc - A valid bank_field object
216 *
217 * RETURN: Status.
218 *
219 * DESCRIPTION: Get bank_field bank_value. This implements the late
220 * evaluation of these field attributes.
221 *
222 ******************************************************************************/
223
224acpi_status
225acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
226{
227 union acpi_operand_object *extra_desc;
228 struct acpi_namespace_node *node;
229 acpi_status status;
230
231 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
232
233 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
234 return_ACPI_STATUS(AE_OK);
235 }
236
237 /* Get the AML pointer (method object) and bank_field node */
238
239 extra_desc = acpi_ns_get_secondary_object(obj_desc);
240 node = obj_desc->bank_field.node;
241
242 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
243 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
244
245 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
246 acpi_ut_get_node_name(node)));
247
248 /* Execute the AML code for the term_arg arguments */
249
250 status = acpi_ds_execute_arguments(node, node->parent,
251 extra_desc->extra.aml_length,
252 extra_desc->extra.aml_start);
253 return_ACPI_STATUS(status);
254}
255
256/*******************************************************************************
257 *
258 * FUNCTION: acpi_ds_get_buffer_arguments
259 *
260 * PARAMETERS: obj_desc - A valid Buffer object
261 *
262 * RETURN: Status.
263 *
264 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
265 * the late evaluation of these attributes.
266 *
267 ******************************************************************************/
268
269acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
270{
271 struct acpi_namespace_node *node;
272 acpi_status status;
273
274 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
275
276 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
277 return_ACPI_STATUS(AE_OK);
278 }
279
280 /* Get the Buffer node */
281
282 node = obj_desc->buffer.node;
283 if (!node) {
284 ACPI_ERROR((AE_INFO,
285 "No pointer back to namespace node in buffer object %p",
286 obj_desc));
287 return_ACPI_STATUS(AE_AML_INTERNAL);
288 }
289
290 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
291
292 /* Execute the AML code for the term_arg arguments */
293
294 status = acpi_ds_execute_arguments(node, node,
295 obj_desc->buffer.aml_length,
296 obj_desc->buffer.aml_start);
297 return_ACPI_STATUS(status);
298}
299
300/*******************************************************************************
301 *
302 * FUNCTION: acpi_ds_get_package_arguments
303 *
304 * PARAMETERS: obj_desc - A valid Package object
305 *
306 * RETURN: Status.
307 *
308 * DESCRIPTION: Get Package length and initializer byte list. This implements
309 * the late evaluation of these attributes.
310 *
311 ******************************************************************************/
312
313acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
314{
315 struct acpi_namespace_node *node;
316 acpi_status status;
317
318 ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
319
320 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
321 return_ACPI_STATUS(AE_OK);
322 }
323
324 /* Get the Package node */
325
326 node = obj_desc->package.node;
327 if (!node) {
328 ACPI_ERROR((AE_INFO,
329 "No pointer back to namespace node in package %p",
330 obj_desc));
331 return_ACPI_STATUS(AE_AML_INTERNAL);
332 }
333
334 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
335
336 /* Execute the AML code for the term_arg arguments */
337
338 status = acpi_ds_execute_arguments(node, node,
339 obj_desc->package.aml_length,
340 obj_desc->package.aml_start);
341 return_ACPI_STATUS(status);
342}
343
344/*******************************************************************************
345 *
346 * FUNCTION: acpi_ds_get_region_arguments
347 *
348 * PARAMETERS: obj_desc - A valid region object
349 *
350 * RETURN: Status.
351 *
352 * DESCRIPTION: Get region address and length. This implements the late
353 * evaluation of these region attributes.
354 *
355 ******************************************************************************/
356
357acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
358{
359 struct acpi_namespace_node *node;
360 acpi_status status;
361 union acpi_operand_object *extra_desc;
362
363 ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
364
365 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
366 return_ACPI_STATUS(AE_OK);
367 }
368
369 extra_desc = acpi_ns_get_secondary_object(obj_desc);
370 if (!extra_desc) {
371 return_ACPI_STATUS(AE_NOT_EXIST);
372 }
373
374 /* Get the Region node */
375
376 node = obj_desc->region.node;
377
378 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
379 (ACPI_TYPE_REGION, node, NULL));
380
381 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
382 acpi_ut_get_node_name(node),
383 extra_desc->extra.aml_start));
384
385 /* Execute the argument AML */
386
387 status = acpi_ds_execute_arguments(node, node->parent,
388 extra_desc->extra.aml_length,
389 extra_desc->extra.aml_start);
390 return_ACPI_STATUS(status);
391}
diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c
new file mode 100644
index 000000000000..26c49fff58da
--- /dev/null
+++ b/drivers/acpi/acpica/dscontrol.c
@@ -0,0 +1,410 @@
1/******************************************************************************
2 *
3 * Module Name: dscontrol - Support for execution control opcodes -
4 * if/else/while/return
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include "accommon.h"
47#include "amlcode.h"
48#include "acdispat.h"
49#include "acinterp.h"
50
51#define _COMPONENT ACPI_DISPATCHER
52ACPI_MODULE_NAME("dscontrol")
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ds_exec_begin_control_op
57 *
58 * PARAMETERS: walk_list - The list that owns the walk stack
59 * Op - The control Op
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Handles all control ops encountered during control method
64 * execution.
65 *
66 ******************************************************************************/
67acpi_status
68acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
69 union acpi_parse_object *op)
70{
71 acpi_status status = AE_OK;
72 union acpi_generic_state *control_state;
73
74 ACPI_FUNCTION_NAME(ds_exec_begin_control_op);
75
76 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
77 op, op->common.aml_opcode, walk_state));
78
79 switch (op->common.aml_opcode) {
80 case AML_WHILE_OP:
81
82 /*
83 * If this is an additional iteration of a while loop, continue.
84 * There is no need to allocate a new control state.
85 */
86 if (walk_state->control_state) {
87 if (walk_state->control_state->control.
88 aml_predicate_start ==
89 (walk_state->parser_state.aml - 1)) {
90
91 /* Reset the state to start-of-loop */
92
93 walk_state->control_state->common.state =
94 ACPI_CONTROL_CONDITIONAL_EXECUTING;
95 break;
96 }
97 }
98
99 /*lint -fallthrough */
100
101 case AML_IF_OP:
102
103 /*
104 * IF/WHILE: Create a new control state to manage these
105 * constructs. We need to manage these as a stack, in order
106 * to handle nesting.
107 */
108 control_state = acpi_ut_create_control_state();
109 if (!control_state) {
110 status = AE_NO_MEMORY;
111 break;
112 }
113 /*
114 * Save a pointer to the predicate for multiple executions
115 * of a loop
116 */
117 control_state->control.aml_predicate_start =
118 walk_state->parser_state.aml - 1;
119 control_state->control.package_end =
120 walk_state->parser_state.pkg_end;
121 control_state->control.opcode = op->common.aml_opcode;
122
123 /* Push the control state on this walk's control stack */
124
125 acpi_ut_push_generic_state(&walk_state->control_state,
126 control_state);
127 break;
128
129 case AML_ELSE_OP:
130
131 /* Predicate is in the state object */
132 /* If predicate is true, the IF was executed, ignore ELSE part */
133
134 if (walk_state->last_predicate) {
135 status = AE_CTRL_TRUE;
136 }
137
138 break;
139
140 case AML_RETURN_OP:
141
142 break;
143
144 default:
145 break;
146 }
147
148 return (status);
149}
150
151/*******************************************************************************
152 *
153 * FUNCTION: acpi_ds_exec_end_control_op
154 *
155 * PARAMETERS: walk_list - The list that owns the walk stack
156 * Op - The control Op
157 *
158 * RETURN: Status
159 *
160 * DESCRIPTION: Handles all control ops encountered during control method
161 * execution.
162 *
163 ******************************************************************************/
164
165acpi_status
166acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
167 union acpi_parse_object * op)
168{
169 acpi_status status = AE_OK;
170 union acpi_generic_state *control_state;
171
172 ACPI_FUNCTION_NAME(ds_exec_end_control_op);
173
174 switch (op->common.aml_opcode) {
175 case AML_IF_OP:
176
177 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
178
179 /*
180 * Save the result of the predicate in case there is an
181 * ELSE to come
182 */
183 walk_state->last_predicate =
184 (u8)walk_state->control_state->common.value;
185
186 /*
187 * Pop the control state that was created at the start
188 * of the IF and free it
189 */
190 control_state =
191 acpi_ut_pop_generic_state(&walk_state->control_state);
192 acpi_ut_delete_generic_state(control_state);
193 break;
194
195 case AML_ELSE_OP:
196
197 break;
198
199 case AML_WHILE_OP:
200
201 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
202
203 control_state = walk_state->control_state;
204 if (control_state->common.value) {
205
206 /* Predicate was true, the body of the loop was just executed */
207
208 /*
209 * This loop counter mechanism allows the interpreter to escape
210 * possibly infinite loops. This can occur in poorly written AML
211 * when the hardware does not respond within a while loop and the
212 * loop does not implement a timeout.
213 */
214 control_state->control.loop_count++;
215 if (control_state->control.loop_count >
216 ACPI_MAX_LOOP_ITERATIONS) {
217 status = AE_AML_INFINITE_LOOP;
218 break;
219 }
220
221 /*
222 * Go back and evaluate the predicate and maybe execute the loop
223 * another time
224 */
225 status = AE_CTRL_PENDING;
226 walk_state->aml_last_while =
227 control_state->control.aml_predicate_start;
228 break;
229 }
230
231 /* Predicate was false, terminate this while loop */
232
233 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
234 "[WHILE_OP] termination! Op=%p\n", op));
235
236 /* Pop this control state and free it */
237
238 control_state =
239 acpi_ut_pop_generic_state(&walk_state->control_state);
240 acpi_ut_delete_generic_state(control_state);
241 break;
242
243 case AML_RETURN_OP:
244
245 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
246 "[RETURN_OP] Op=%p Arg=%p\n", op,
247 op->common.value.arg));
248
249 /*
250 * One optional operand -- the return value
251 * It can be either an immediate operand or a result that
252 * has been bubbled up the tree
253 */
254 if (op->common.value.arg) {
255
256 /* Since we have a real Return(), delete any implicit return */
257
258 acpi_ds_clear_implicit_return(walk_state);
259
260 /* Return statement has an immediate operand */
261
262 status =
263 acpi_ds_create_operands(walk_state,
264 op->common.value.arg);
265 if (ACPI_FAILURE(status)) {
266 return (status);
267 }
268
269 /*
270 * If value being returned is a Reference (such as
271 * an arg or local), resolve it now because it may
272 * cease to exist at the end of the method.
273 */
274 status =
275 acpi_ex_resolve_to_value(&walk_state->operands[0],
276 walk_state);
277 if (ACPI_FAILURE(status)) {
278 return (status);
279 }
280
281 /*
282 * Get the return value and save as the last result
283 * value. This is the only place where walk_state->return_desc
284 * is set to anything other than zero!
285 */
286 walk_state->return_desc = walk_state->operands[0];
287 } else if (walk_state->result_count) {
288
289 /* Since we have a real Return(), delete any implicit return */
290
291 acpi_ds_clear_implicit_return(walk_state);
292
293 /*
294 * The return value has come from a previous calculation.
295 *
296 * If value being returned is a Reference (such as
297 * an arg or local), resolve it now because it may
298 * cease to exist at the end of the method.
299 *
300 * Allow references created by the Index operator to return
301 * unchanged.
302 */
303 if ((ACPI_GET_DESCRIPTOR_TYPE
304 (walk_state->results->results.obj_desc[0]) ==
305 ACPI_DESC_TYPE_OPERAND)
306 && ((walk_state->results->results.obj_desc[0])->
307 common.type == ACPI_TYPE_LOCAL_REFERENCE)
308 && ((walk_state->results->results.obj_desc[0])->
309 reference.class != ACPI_REFCLASS_INDEX)) {
310 status =
311 acpi_ex_resolve_to_value(&walk_state->
312 results->results.
313 obj_desc[0],
314 walk_state);
315 if (ACPI_FAILURE(status)) {
316 return (status);
317 }
318 }
319
320 walk_state->return_desc =
321 walk_state->results->results.obj_desc[0];
322 } else {
323 /* No return operand */
324
325 if (walk_state->num_operands) {
326 acpi_ut_remove_reference(walk_state->
327 operands[0]);
328 }
329
330 walk_state->operands[0] = NULL;
331 walk_state->num_operands = 0;
332 walk_state->return_desc = NULL;
333 }
334
335 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
336 "Completed RETURN_OP State=%p, RetVal=%p\n",
337 walk_state, walk_state->return_desc));
338
339 /* End the control method execution right now */
340
341 status = AE_CTRL_TERMINATE;
342 break;
343
344 case AML_NOOP_OP:
345
346 /* Just do nothing! */
347 break;
348
349 case AML_BREAK_POINT_OP:
350
351 /*
352 * Set the single-step flag. This will cause the debugger (if present)
353 * to break to the console within the AML debugger at the start of the
354 * next AML instruction.
355 */
356 ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
357 ACPI_DEBUGGER_EXEC(acpi_os_printf
358 ("**break** Executed AML BreakPoint opcode\n"));
359
360 /* Call to the OSL in case OS wants a piece of the action */
361
362 status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
363 "Executed AML Breakpoint opcode");
364 break;
365
366 case AML_BREAK_OP:
367 case AML_CONTINUE_OP: /* ACPI 2.0 */
368
369 /* Pop and delete control states until we find a while */
370
371 while (walk_state->control_state &&
372 (walk_state->control_state->control.opcode !=
373 AML_WHILE_OP)) {
374 control_state =
375 acpi_ut_pop_generic_state(&walk_state->
376 control_state);
377 acpi_ut_delete_generic_state(control_state);
378 }
379
380 /* No while found? */
381
382 if (!walk_state->control_state) {
383 return (AE_AML_NO_WHILE);
384 }
385
386 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
387
388 walk_state->aml_last_while =
389 walk_state->control_state->control.package_end;
390
391 /* Return status depending on opcode */
392
393 if (op->common.aml_opcode == AML_BREAK_OP) {
394 status = AE_CTRL_BREAK;
395 } else {
396 status = AE_CTRL_CONTINUE;
397 }
398 break;
399
400 default:
401
402 ACPI_ERROR((AE_INFO, "Unknown control opcode=0x%X Op=%p",
403 op->common.aml_opcode, op));
404
405 status = AE_AML_BAD_OPCODE;
406 break;
407 }
408
409 return (status);
410}
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index bbecf293aeeb..c627a288e027 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -1,7 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Module Name: dsopcode - Dispatcher Op Region support and handling of 3 * Module Name: dsopcode - Dispatcher suport for regions and fields
4 * "control" opcodes
5 * 4 *
6 *****************************************************************************/ 5 *****************************************************************************/
7 6
@@ -57,11 +56,6 @@ ACPI_MODULE_NAME("dsopcode")
57 56
58/* Local prototypes */ 57/* Local prototypes */
59static acpi_status 58static acpi_status
60acpi_ds_execute_arguments(struct acpi_namespace_node *node,
61 struct acpi_namespace_node *scope_node,
62 u32 aml_length, u8 * aml_start);
63
64static acpi_status
65acpi_ds_init_buffer_field(u16 aml_opcode, 59acpi_ds_init_buffer_field(u16 aml_opcode,
66 union acpi_operand_object *obj_desc, 60 union acpi_operand_object *obj_desc,
67 union acpi_operand_object *buffer_desc, 61 union acpi_operand_object *buffer_desc,
@@ -71,361 +65,6 @@ acpi_ds_init_buffer_field(u16 aml_opcode,
71 65
72/******************************************************************************* 66/*******************************************************************************
73 * 67 *
74 * FUNCTION: acpi_ds_execute_arguments
75 *
76 * PARAMETERS: Node - Object NS node
77 * scope_node - Parent NS node
78 * aml_length - Length of executable AML
79 * aml_start - Pointer to the AML
80 *
81 * RETURN: Status.
82 *
83 * DESCRIPTION: Late (deferred) execution of region or field arguments
84 *
85 ******************************************************************************/
86
87static acpi_status
88acpi_ds_execute_arguments(struct acpi_namespace_node *node,
89 struct acpi_namespace_node *scope_node,
90 u32 aml_length, u8 * aml_start)
91{
92 acpi_status status;
93 union acpi_parse_object *op;
94 struct acpi_walk_state *walk_state;
95
96 ACPI_FUNCTION_TRACE(ds_execute_arguments);
97
98 /*
99 * Allocate a new parser op to be the root of the parsed tree
100 */
101 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
102 if (!op) {
103 return_ACPI_STATUS(AE_NO_MEMORY);
104 }
105
106 /* Save the Node for use in acpi_ps_parse_aml */
107
108 op->common.node = scope_node;
109
110 /* Create and initialize a new parser state */
111
112 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
113 if (!walk_state) {
114 status = AE_NO_MEMORY;
115 goto cleanup;
116 }
117
118 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
119 aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
120 if (ACPI_FAILURE(status)) {
121 acpi_ds_delete_walk_state(walk_state);
122 goto cleanup;
123 }
124
125 /* Mark this parse as a deferred opcode */
126
127 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
128 walk_state->deferred_node = node;
129
130 /* Pass1: Parse the entire declaration */
131
132 status = acpi_ps_parse_aml(walk_state);
133 if (ACPI_FAILURE(status)) {
134 goto cleanup;
135 }
136
137 /* Get and init the Op created above */
138
139 op->common.node = node;
140 acpi_ps_delete_parse_tree(op);
141
142 /* Evaluate the deferred arguments */
143
144 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
145 if (!op) {
146 return_ACPI_STATUS(AE_NO_MEMORY);
147 }
148
149 op->common.node = scope_node;
150
151 /* Create and initialize a new parser state */
152
153 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
154 if (!walk_state) {
155 status = AE_NO_MEMORY;
156 goto cleanup;
157 }
158
159 /* Execute the opcode and arguments */
160
161 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
162 aml_length, NULL, ACPI_IMODE_EXECUTE);
163 if (ACPI_FAILURE(status)) {
164 acpi_ds_delete_walk_state(walk_state);
165 goto cleanup;
166 }
167
168 /* Mark this execution as a deferred opcode */
169
170 walk_state->deferred_node = node;
171 status = acpi_ps_parse_aml(walk_state);
172
173 cleanup:
174 acpi_ps_delete_parse_tree(op);
175 return_ACPI_STATUS(status);
176}
177
178/*******************************************************************************
179 *
180 * FUNCTION: acpi_ds_get_buffer_field_arguments
181 *
182 * PARAMETERS: obj_desc - A valid buffer_field object
183 *
184 * RETURN: Status.
185 *
186 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
187 * evaluation of these field attributes.
188 *
189 ******************************************************************************/
190
191acpi_status
192acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
193{
194 union acpi_operand_object *extra_desc;
195 struct acpi_namespace_node *node;
196 acpi_status status;
197
198 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
199
200 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
201 return_ACPI_STATUS(AE_OK);
202 }
203
204 /* Get the AML pointer (method object) and buffer_field node */
205
206 extra_desc = acpi_ns_get_secondary_object(obj_desc);
207 node = obj_desc->buffer_field.node;
208
209 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
210 (ACPI_TYPE_BUFFER_FIELD, node, NULL));
211 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
212 acpi_ut_get_node_name(node)));
213
214 /* Execute the AML code for the term_arg arguments */
215
216 status = acpi_ds_execute_arguments(node, node->parent,
217 extra_desc->extra.aml_length,
218 extra_desc->extra.aml_start);
219 return_ACPI_STATUS(status);
220}
221
222/*******************************************************************************
223 *
224 * FUNCTION: acpi_ds_get_bank_field_arguments
225 *
226 * PARAMETERS: obj_desc - A valid bank_field object
227 *
228 * RETURN: Status.
229 *
230 * DESCRIPTION: Get bank_field bank_value. This implements the late
231 * evaluation of these field attributes.
232 *
233 ******************************************************************************/
234
235acpi_status
236acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
237{
238 union acpi_operand_object *extra_desc;
239 struct acpi_namespace_node *node;
240 acpi_status status;
241
242 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
243
244 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
245 return_ACPI_STATUS(AE_OK);
246 }
247
248 /* Get the AML pointer (method object) and bank_field node */
249
250 extra_desc = acpi_ns_get_secondary_object(obj_desc);
251 node = obj_desc->bank_field.node;
252
253 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
254 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
255 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
256 acpi_ut_get_node_name(node)));
257
258 /* Execute the AML code for the term_arg arguments */
259
260 status = acpi_ds_execute_arguments(node, node->parent,
261 extra_desc->extra.aml_length,
262 extra_desc->extra.aml_start);
263 return_ACPI_STATUS(status);
264}
265
266/*******************************************************************************
267 *
268 * FUNCTION: acpi_ds_get_buffer_arguments
269 *
270 * PARAMETERS: obj_desc - A valid Buffer object
271 *
272 * RETURN: Status.
273 *
274 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
275 * the late evaluation of these attributes.
276 *
277 ******************************************************************************/
278
279acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
280{
281 struct acpi_namespace_node *node;
282 acpi_status status;
283
284 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
285
286 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
287 return_ACPI_STATUS(AE_OK);
288 }
289
290 /* Get the Buffer node */
291
292 node = obj_desc->buffer.node;
293 if (!node) {
294 ACPI_ERROR((AE_INFO,
295 "No pointer back to namespace node in buffer object %p",
296 obj_desc));
297 return_ACPI_STATUS(AE_AML_INTERNAL);
298 }
299
300 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
301
302 /* Execute the AML code for the term_arg arguments */
303
304 status = acpi_ds_execute_arguments(node, node,
305 obj_desc->buffer.aml_length,
306 obj_desc->buffer.aml_start);
307 return_ACPI_STATUS(status);
308}
309
310/*******************************************************************************
311 *
312 * FUNCTION: acpi_ds_get_package_arguments
313 *
314 * PARAMETERS: obj_desc - A valid Package object
315 *
316 * RETURN: Status.
317 *
318 * DESCRIPTION: Get Package length and initializer byte list. This implements
319 * the late evaluation of these attributes.
320 *
321 ******************************************************************************/
322
323acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
324{
325 struct acpi_namespace_node *node;
326 acpi_status status;
327
328 ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
329
330 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
331 return_ACPI_STATUS(AE_OK);
332 }
333
334 /* Get the Package node */
335
336 node = obj_desc->package.node;
337 if (!node) {
338 ACPI_ERROR((AE_INFO,
339 "No pointer back to namespace node in package %p",
340 obj_desc));
341 return_ACPI_STATUS(AE_AML_INTERNAL);
342 }
343
344 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
345
346 /* Execute the AML code for the term_arg arguments */
347
348 status = acpi_ds_execute_arguments(node, node,
349 obj_desc->package.aml_length,
350 obj_desc->package.aml_start);
351 return_ACPI_STATUS(status);
352}
353
354/*****************************************************************************
355 *
356 * FUNCTION: acpi_ds_get_region_arguments
357 *
358 * PARAMETERS: obj_desc - A valid region object
359 *
360 * RETURN: Status.
361 *
362 * DESCRIPTION: Get region address and length. This implements the late
363 * evaluation of these region attributes.
364 *
365 ****************************************************************************/
366
367acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
368{
369 struct acpi_namespace_node *node;
370 acpi_status status;
371 union acpi_operand_object *extra_desc;
372
373 ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
374
375 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
376 return_ACPI_STATUS(AE_OK);
377 }
378
379 extra_desc = acpi_ns_get_secondary_object(obj_desc);
380 if (!extra_desc) {
381 return_ACPI_STATUS(AE_NOT_EXIST);
382 }
383
384 /* Get the Region node */
385
386 node = obj_desc->region.node;
387
388 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
389 (ACPI_TYPE_REGION, node, NULL));
390
391 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
392 acpi_ut_get_node_name(node),
393 extra_desc->extra.aml_start));
394
395 /* Execute the argument AML */
396
397 status = acpi_ds_execute_arguments(node, node->parent,
398 extra_desc->extra.aml_length,
399 extra_desc->extra.aml_start);
400 if (ACPI_FAILURE(status)) {
401 return_ACPI_STATUS(status);
402 }
403
404 /* Validate the region address/length via the host OS */
405
406 status = acpi_os_validate_address(obj_desc->region.space_id,
407 obj_desc->region.address,
408 (acpi_size) obj_desc->region.length,
409 acpi_ut_get_node_name(node));
410
411 if (ACPI_FAILURE(status)) {
412 /*
413 * Invalid address/length. We will emit an error message and mark
414 * the region as invalid, so that it will cause an additional error if
415 * it is ever used. Then return AE_OK.
416 */
417 ACPI_EXCEPTION((AE_INFO, status,
418 "During address validation of OpRegion [%4.4s]",
419 node->name.ascii));
420 obj_desc->common.flags |= AOPOBJ_INVALID;
421 status = AE_OK;
422 }
423
424 return_ACPI_STATUS(status);
425}
426
427/*******************************************************************************
428 *
429 * FUNCTION: acpi_ds_initialize_region 68 * FUNCTION: acpi_ds_initialize_region
430 * 69 *
431 * PARAMETERS: obj_handle - Region namespace node 70 * PARAMETERS: obj_handle - Region namespace node
@@ -826,8 +465,9 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
826 * 465 *
827 * RETURN: Status 466 * RETURN: Status
828 * 467 *
829 * DESCRIPTION: Get region address and length 468 * DESCRIPTION: Get region address and length.
830 * Called from acpi_ds_exec_end_op during data_table_region parse tree walk 469 * Called from acpi_ds_exec_end_op during data_table_region parse
470 * tree walk.
831 * 471 *
832 ******************************************************************************/ 472 ******************************************************************************/
833 473
@@ -1114,360 +754,3 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
1114 acpi_ut_remove_reference(operand_desc); 754 acpi_ut_remove_reference(operand_desc);
1115 return_ACPI_STATUS(status); 755 return_ACPI_STATUS(status);
1116} 756}
1117
1118/*******************************************************************************
1119 *
1120 * FUNCTION: acpi_ds_exec_begin_control_op
1121 *
1122 * PARAMETERS: walk_list - The list that owns the walk stack
1123 * Op - The control Op
1124 *
1125 * RETURN: Status
1126 *
1127 * DESCRIPTION: Handles all control ops encountered during control method
1128 * execution.
1129 *
1130 ******************************************************************************/
1131
1132acpi_status
1133acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
1134 union acpi_parse_object *op)
1135{
1136 acpi_status status = AE_OK;
1137 union acpi_generic_state *control_state;
1138
1139 ACPI_FUNCTION_NAME(ds_exec_begin_control_op);
1140
1141 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
1142 op->common.aml_opcode, walk_state));
1143
1144 switch (op->common.aml_opcode) {
1145 case AML_WHILE_OP:
1146
1147 /*
1148 * If this is an additional iteration of a while loop, continue.
1149 * There is no need to allocate a new control state.
1150 */
1151 if (walk_state->control_state) {
1152 if (walk_state->control_state->control.aml_predicate_start
1153 == (walk_state->parser_state.aml - 1)) {
1154
1155 /* Reset the state to start-of-loop */
1156
1157 walk_state->control_state->common.state =
1158 ACPI_CONTROL_CONDITIONAL_EXECUTING;
1159 break;
1160 }
1161 }
1162
1163 /*lint -fallthrough */
1164
1165 case AML_IF_OP:
1166
1167 /*
1168 * IF/WHILE: Create a new control state to manage these
1169 * constructs. We need to manage these as a stack, in order
1170 * to handle nesting.
1171 */
1172 control_state = acpi_ut_create_control_state();
1173 if (!control_state) {
1174 status = AE_NO_MEMORY;
1175 break;
1176 }
1177 /*
1178 * Save a pointer to the predicate for multiple executions
1179 * of a loop
1180 */
1181 control_state->control.aml_predicate_start =
1182 walk_state->parser_state.aml - 1;
1183 control_state->control.package_end =
1184 walk_state->parser_state.pkg_end;
1185 control_state->control.opcode = op->common.aml_opcode;
1186
1187 /* Push the control state on this walk's control stack */
1188
1189 acpi_ut_push_generic_state(&walk_state->control_state,
1190 control_state);
1191 break;
1192
1193 case AML_ELSE_OP:
1194
1195 /* Predicate is in the state object */
1196 /* If predicate is true, the IF was executed, ignore ELSE part */
1197
1198 if (walk_state->last_predicate) {
1199 status = AE_CTRL_TRUE;
1200 }
1201
1202 break;
1203
1204 case AML_RETURN_OP:
1205
1206 break;
1207
1208 default:
1209 break;
1210 }
1211
1212 return (status);
1213}
1214
1215/*******************************************************************************
1216 *
1217 * FUNCTION: acpi_ds_exec_end_control_op
1218 *
1219 * PARAMETERS: walk_list - The list that owns the walk stack
1220 * Op - The control Op
1221 *
1222 * RETURN: Status
1223 *
1224 * DESCRIPTION: Handles all control ops encountered during control method
1225 * execution.
1226 *
1227 ******************************************************************************/
1228
1229acpi_status
1230acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
1231 union acpi_parse_object * op)
1232{
1233 acpi_status status = AE_OK;
1234 union acpi_generic_state *control_state;
1235
1236 ACPI_FUNCTION_NAME(ds_exec_end_control_op);
1237
1238 switch (op->common.aml_opcode) {
1239 case AML_IF_OP:
1240
1241 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
1242
1243 /*
1244 * Save the result of the predicate in case there is an
1245 * ELSE to come
1246 */
1247 walk_state->last_predicate =
1248 (u8) walk_state->control_state->common.value;
1249
1250 /*
1251 * Pop the control state that was created at the start
1252 * of the IF and free it
1253 */
1254 control_state =
1255 acpi_ut_pop_generic_state(&walk_state->control_state);
1256 acpi_ut_delete_generic_state(control_state);
1257 break;
1258
1259 case AML_ELSE_OP:
1260
1261 break;
1262
1263 case AML_WHILE_OP:
1264
1265 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
1266
1267 control_state = walk_state->control_state;
1268 if (control_state->common.value) {
1269
1270 /* Predicate was true, the body of the loop was just executed */
1271
1272 /*
1273 * This loop counter mechanism allows the interpreter to escape
1274 * possibly infinite loops. This can occur in poorly written AML
1275 * when the hardware does not respond within a while loop and the
1276 * loop does not implement a timeout.
1277 */
1278 control_state->control.loop_count++;
1279 if (control_state->control.loop_count >
1280 ACPI_MAX_LOOP_ITERATIONS) {
1281 status = AE_AML_INFINITE_LOOP;
1282 break;
1283 }
1284
1285 /*
1286 * Go back and evaluate the predicate and maybe execute the loop
1287 * another time
1288 */
1289 status = AE_CTRL_PENDING;
1290 walk_state->aml_last_while =
1291 control_state->control.aml_predicate_start;
1292 break;
1293 }
1294
1295 /* Predicate was false, terminate this while loop */
1296
1297 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1298 "[WHILE_OP] termination! Op=%p\n", op));
1299
1300 /* Pop this control state and free it */
1301
1302 control_state =
1303 acpi_ut_pop_generic_state(&walk_state->control_state);
1304 acpi_ut_delete_generic_state(control_state);
1305 break;
1306
1307 case AML_RETURN_OP:
1308
1309 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1310 "[RETURN_OP] Op=%p Arg=%p\n", op,
1311 op->common.value.arg));
1312
1313 /*
1314 * One optional operand -- the return value
1315 * It can be either an immediate operand or a result that
1316 * has been bubbled up the tree
1317 */
1318 if (op->common.value.arg) {
1319
1320 /* Since we have a real Return(), delete any implicit return */
1321
1322 acpi_ds_clear_implicit_return(walk_state);
1323
1324 /* Return statement has an immediate operand */
1325
1326 status =
1327 acpi_ds_create_operands(walk_state,
1328 op->common.value.arg);
1329 if (ACPI_FAILURE(status)) {
1330 return (status);
1331 }
1332
1333 /*
1334 * If value being returned is a Reference (such as
1335 * an arg or local), resolve it now because it may
1336 * cease to exist at the end of the method.
1337 */
1338 status =
1339 acpi_ex_resolve_to_value(&walk_state->operands[0],
1340 walk_state);
1341 if (ACPI_FAILURE(status)) {
1342 return (status);
1343 }
1344
1345 /*
1346 * Get the return value and save as the last result
1347 * value. This is the only place where walk_state->return_desc
1348 * is set to anything other than zero!
1349 */
1350 walk_state->return_desc = walk_state->operands[0];
1351 } else if (walk_state->result_count) {
1352
1353 /* Since we have a real Return(), delete any implicit return */
1354
1355 acpi_ds_clear_implicit_return(walk_state);
1356
1357 /*
1358 * The return value has come from a previous calculation.
1359 *
1360 * If value being returned is a Reference (such as
1361 * an arg or local), resolve it now because it may
1362 * cease to exist at the end of the method.
1363 *
1364 * Allow references created by the Index operator to return unchanged.
1365 */
1366 if ((ACPI_GET_DESCRIPTOR_TYPE
1367 (walk_state->results->results.obj_desc[0]) ==
1368 ACPI_DESC_TYPE_OPERAND)
1369 && ((walk_state->results->results.obj_desc[0])->
1370 common.type == ACPI_TYPE_LOCAL_REFERENCE)
1371 && ((walk_state->results->results.obj_desc[0])->
1372 reference.class != ACPI_REFCLASS_INDEX)) {
1373 status =
1374 acpi_ex_resolve_to_value(&walk_state->
1375 results->results.
1376 obj_desc[0],
1377 walk_state);
1378 if (ACPI_FAILURE(status)) {
1379 return (status);
1380 }
1381 }
1382
1383 walk_state->return_desc =
1384 walk_state->results->results.obj_desc[0];
1385 } else {
1386 /* No return operand */
1387
1388 if (walk_state->num_operands) {
1389 acpi_ut_remove_reference(walk_state->
1390 operands[0]);
1391 }
1392
1393 walk_state->operands[0] = NULL;
1394 walk_state->num_operands = 0;
1395 walk_state->return_desc = NULL;
1396 }
1397
1398 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1399 "Completed RETURN_OP State=%p, RetVal=%p\n",
1400 walk_state, walk_state->return_desc));
1401
1402 /* End the control method execution right now */
1403
1404 status = AE_CTRL_TERMINATE;
1405 break;
1406
1407 case AML_NOOP_OP:
1408
1409 /* Just do nothing! */
1410 break;
1411
1412 case AML_BREAK_POINT_OP:
1413
1414 /*
1415 * Set the single-step flag. This will cause the debugger (if present)
1416 * to break to the console within the AML debugger at the start of the
1417 * next AML instruction.
1418 */
1419 ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
1420 ACPI_DEBUGGER_EXEC(acpi_os_printf
1421 ("**break** Executed AML BreakPoint opcode\n"));
1422
1423 /* Call to the OSL in case OS wants a piece of the action */
1424
1425 status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
1426 "Executed AML Breakpoint opcode");
1427 break;
1428
1429 case AML_BREAK_OP:
1430 case AML_CONTINUE_OP: /* ACPI 2.0 */
1431
1432 /* Pop and delete control states until we find a while */
1433
1434 while (walk_state->control_state &&
1435 (walk_state->control_state->control.opcode !=
1436 AML_WHILE_OP)) {
1437 control_state =
1438 acpi_ut_pop_generic_state(&walk_state->
1439 control_state);
1440 acpi_ut_delete_generic_state(control_state);
1441 }
1442
1443 /* No while found? */
1444
1445 if (!walk_state->control_state) {
1446 return (AE_AML_NO_WHILE);
1447 }
1448
1449 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
1450
1451 walk_state->aml_last_while =
1452 walk_state->control_state->control.package_end;
1453
1454 /* Return status depending on opcode */
1455
1456 if (op->common.aml_opcode == AML_BREAK_OP) {
1457 status = AE_CTRL_BREAK;
1458 } else {
1459 status = AE_CTRL_CONTINUE;
1460 }
1461 break;
1462
1463 default:
1464
1465 ACPI_ERROR((AE_INFO, "Unknown control opcode=0x%X Op=%p",
1466 op->common.aml_opcode, op));
1467
1468 status = AE_AML_BAD_OPCODE;
1469 break;
1470 }
1471
1472 return (status);
1473}
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c
index 52566ff5e903..23a3b1ab20c1 100644
--- a/drivers/acpi/acpica/dswload.c
+++ b/drivers/acpi/acpica/dswload.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks 3 * Module Name: dswload - Dispatcher first pass namespace load callbacks
4 * 4 *
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
@@ -48,7 +48,6 @@
48#include "acdispat.h" 48#include "acdispat.h"
49#include "acinterp.h" 49#include "acinterp.h"
50#include "acnamesp.h" 50#include "acnamesp.h"
51#include "acevents.h"
52 51
53#ifdef ACPI_ASL_COMPILER 52#ifdef ACPI_ASL_COMPILER
54#include <acpi/acdisasm.h> 53#include <acpi/acdisasm.h>
@@ -537,670 +536,3 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
537 536
538 return_ACPI_STATUS(status); 537 return_ACPI_STATUS(status);
539} 538}
540
541/*******************************************************************************
542 *
543 * FUNCTION: acpi_ds_load2_begin_op
544 *
545 * PARAMETERS: walk_state - Current state of the parse tree walk
546 * out_op - Wher to return op if a new one is created
547 *
548 * RETURN: Status
549 *
550 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
551 *
552 ******************************************************************************/
553
554acpi_status
555acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
556 union acpi_parse_object **out_op)
557{
558 union acpi_parse_object *op;
559 struct acpi_namespace_node *node;
560 acpi_status status;
561 acpi_object_type object_type;
562 char *buffer_ptr;
563 u32 flags;
564
565 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
566
567 op = walk_state->op;
568 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
569 walk_state));
570
571 if (op) {
572 if ((walk_state->control_state) &&
573 (walk_state->control_state->common.state ==
574 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
575
576 /* We are executing a while loop outside of a method */
577
578 status = acpi_ds_exec_begin_op(walk_state, out_op);
579 return_ACPI_STATUS(status);
580 }
581
582 /* We only care about Namespace opcodes here */
583
584 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
585 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
586 (!(walk_state->op_info->flags & AML_NAMED))) {
587 return_ACPI_STATUS(AE_OK);
588 }
589
590 /* Get the name we are going to enter or lookup in the namespace */
591
592 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
593
594 /* For Namepath op, get the path string */
595
596 buffer_ptr = op->common.value.string;
597 if (!buffer_ptr) {
598
599 /* No name, just exit */
600
601 return_ACPI_STATUS(AE_OK);
602 }
603 } else {
604 /* Get name from the op */
605
606 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
607 }
608 } else {
609 /* Get the namestring from the raw AML */
610
611 buffer_ptr =
612 acpi_ps_get_next_namestring(&walk_state->parser_state);
613 }
614
615 /* Map the opcode into an internal object type */
616
617 object_type = walk_state->op_info->object_type;
618
619 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
620 "State=%p Op=%p Type=%X\n", walk_state, op,
621 object_type));
622
623 switch (walk_state->opcode) {
624 case AML_FIELD_OP:
625 case AML_BANK_FIELD_OP:
626 case AML_INDEX_FIELD_OP:
627
628 node = NULL;
629 status = AE_OK;
630 break;
631
632 case AML_INT_NAMEPATH_OP:
633 /*
634 * The name_path is an object reference to an existing object.
635 * Don't enter the name into the namespace, but look it up
636 * for use later.
637 */
638 status =
639 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
640 object_type, ACPI_IMODE_EXECUTE,
641 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
642 break;
643
644 case AML_SCOPE_OP:
645
646 /* Special case for Scope(\) -> refers to the Root node */
647
648 if (op && (op->named.node == acpi_gbl_root_node)) {
649 node = op->named.node;
650
651 status =
652 acpi_ds_scope_stack_push(node, object_type,
653 walk_state);
654 if (ACPI_FAILURE(status)) {
655 return_ACPI_STATUS(status);
656 }
657 } else {
658 /*
659 * The Path is an object reference to an existing object.
660 * Don't enter the name into the namespace, but look it up
661 * for use later.
662 */
663 status =
664 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
665 object_type, ACPI_IMODE_EXECUTE,
666 ACPI_NS_SEARCH_PARENT, walk_state,
667 &(node));
668 if (ACPI_FAILURE(status)) {
669#ifdef ACPI_ASL_COMPILER
670 if (status == AE_NOT_FOUND) {
671 status = AE_OK;
672 } else {
673 ACPI_ERROR_NAMESPACE(buffer_ptr,
674 status);
675 }
676#else
677 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
678#endif
679 return_ACPI_STATUS(status);
680 }
681 }
682
683 /*
684 * We must check to make sure that the target is
685 * one of the opcodes that actually opens a scope
686 */
687 switch (node->type) {
688 case ACPI_TYPE_ANY:
689 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
690 case ACPI_TYPE_DEVICE:
691 case ACPI_TYPE_POWER:
692 case ACPI_TYPE_PROCESSOR:
693 case ACPI_TYPE_THERMAL:
694
695 /* These are acceptable types */
696 break;
697
698 case ACPI_TYPE_INTEGER:
699 case ACPI_TYPE_STRING:
700 case ACPI_TYPE_BUFFER:
701
702 /*
703 * These types we will allow, but we will change the type.
704 * This enables some existing code of the form:
705 *
706 * Name (DEB, 0)
707 * Scope (DEB) { ... }
708 */
709 ACPI_WARNING((AE_INFO,
710 "Type override - [%4.4s] had invalid type (%s) "
711 "for Scope operator, changed to type ANY\n",
712 acpi_ut_get_node_name(node),
713 acpi_ut_get_type_name(node->type)));
714
715 node->type = ACPI_TYPE_ANY;
716 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
717 break;
718
719 default:
720
721 /* All other types are an error */
722
723 ACPI_ERROR((AE_INFO,
724 "Invalid type (%s) for target of "
725 "Scope operator [%4.4s] (Cannot override)",
726 acpi_ut_get_type_name(node->type),
727 acpi_ut_get_node_name(node)));
728
729 return (AE_AML_OPERAND_TYPE);
730 }
731 break;
732
733 default:
734
735 /* All other opcodes */
736
737 if (op && op->common.node) {
738
739 /* This op/node was previously entered into the namespace */
740
741 node = op->common.node;
742
743 if (acpi_ns_opens_scope(object_type)) {
744 status =
745 acpi_ds_scope_stack_push(node, object_type,
746 walk_state);
747 if (ACPI_FAILURE(status)) {
748 return_ACPI_STATUS(status);
749 }
750 }
751
752 return_ACPI_STATUS(AE_OK);
753 }
754
755 /*
756 * Enter the named type into the internal namespace. We enter the name
757 * as we go downward in the parse tree. Any necessary subobjects that
758 * involve arguments to the opcode must be created as we go back up the
759 * parse tree later.
760 *
761 * Note: Name may already exist if we are executing a deferred opcode.
762 */
763 if (walk_state->deferred_node) {
764
765 /* This name is already in the namespace, get the node */
766
767 node = walk_state->deferred_node;
768 status = AE_OK;
769 break;
770 }
771
772 flags = ACPI_NS_NO_UPSEARCH;
773 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
774
775 /* Execution mode, node cannot already exist, node is temporary */
776
777 flags |= ACPI_NS_ERROR_IF_FOUND;
778
779 if (!
780 (walk_state->
781 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
782 flags |= ACPI_NS_TEMPORARY;
783 }
784 }
785
786 /* Add new entry or lookup existing entry */
787
788 status =
789 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
790 object_type, ACPI_IMODE_LOAD_PASS2, flags,
791 walk_state, &node);
792
793 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
794 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
795 "***New Node [%4.4s] %p is temporary\n",
796 acpi_ut_get_node_name(node), node));
797 }
798 break;
799 }
800
801 if (ACPI_FAILURE(status)) {
802 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
803 return_ACPI_STATUS(status);
804 }
805
806 if (!op) {
807
808 /* Create a new op */
809
810 op = acpi_ps_alloc_op(walk_state->opcode);
811 if (!op) {
812 return_ACPI_STATUS(AE_NO_MEMORY);
813 }
814
815 /* Initialize the new op */
816
817 if (node) {
818 op->named.name = node->name.integer;
819 }
820 *out_op = op;
821 }
822
823 /*
824 * Put the Node in the "op" object that the parser uses, so we
825 * can get it again quickly when this scope is closed
826 */
827 op->common.node = node;
828 return_ACPI_STATUS(status);
829}
830
831/*******************************************************************************
832 *
833 * FUNCTION: acpi_ds_load2_end_op
834 *
835 * PARAMETERS: walk_state - Current state of the parse tree walk
836 *
837 * RETURN: Status
838 *
839 * DESCRIPTION: Ascending callback used during the loading of the namespace,
840 * both control methods and everything else.
841 *
842 ******************************************************************************/
843
844acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
845{
846 union acpi_parse_object *op;
847 acpi_status status = AE_OK;
848 acpi_object_type object_type;
849 struct acpi_namespace_node *node;
850 union acpi_parse_object *arg;
851 struct acpi_namespace_node *new_node;
852#ifndef ACPI_NO_METHOD_EXECUTION
853 u32 i;
854 u8 region_space;
855#endif
856
857 ACPI_FUNCTION_TRACE(ds_load2_end_op);
858
859 op = walk_state->op;
860 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
861 walk_state->op_info->name, op, walk_state));
862
863 /* Check if opcode had an associated namespace object */
864
865 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
866 return_ACPI_STATUS(AE_OK);
867 }
868
869 if (op->common.aml_opcode == AML_SCOPE_OP) {
870 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
871 "Ending scope Op=%p State=%p\n", op,
872 walk_state));
873 }
874
875 object_type = walk_state->op_info->object_type;
876
877 /*
878 * Get the Node/name from the earlier lookup
879 * (It was saved in the *op structure)
880 */
881 node = op->common.node;
882
883 /*
884 * Put the Node on the object stack (Contains the ACPI Name of
885 * this object)
886 */
887 walk_state->operands[0] = (void *)node;
888 walk_state->num_operands = 1;
889
890 /* Pop the scope stack */
891
892 if (acpi_ns_opens_scope(object_type) &&
893 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
894 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
895 "(%s) Popping scope for Op %p\n",
896 acpi_ut_get_type_name(object_type), op));
897
898 status = acpi_ds_scope_stack_pop(walk_state);
899 if (ACPI_FAILURE(status)) {
900 goto cleanup;
901 }
902 }
903
904 /*
905 * Named operations are as follows:
906 *
907 * AML_ALIAS
908 * AML_BANKFIELD
909 * AML_CREATEBITFIELD
910 * AML_CREATEBYTEFIELD
911 * AML_CREATEDWORDFIELD
912 * AML_CREATEFIELD
913 * AML_CREATEQWORDFIELD
914 * AML_CREATEWORDFIELD
915 * AML_DATA_REGION
916 * AML_DEVICE
917 * AML_EVENT
918 * AML_FIELD
919 * AML_INDEXFIELD
920 * AML_METHOD
921 * AML_METHODCALL
922 * AML_MUTEX
923 * AML_NAME
924 * AML_NAMEDFIELD
925 * AML_OPREGION
926 * AML_POWERRES
927 * AML_PROCESSOR
928 * AML_SCOPE
929 * AML_THERMALZONE
930 */
931
932 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
933 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
934 acpi_ps_get_opcode_name(op->common.aml_opcode),
935 walk_state, op, node));
936
937 /* Decode the opcode */
938
939 arg = op->common.value.arg;
940
941 switch (walk_state->op_info->type) {
942#ifndef ACPI_NO_METHOD_EXECUTION
943
944 case AML_TYPE_CREATE_FIELD:
945 /*
946 * Create the field object, but the field buffer and index must
947 * be evaluated later during the execution phase
948 */
949 status = acpi_ds_create_buffer_field(op, walk_state);
950 break;
951
952 case AML_TYPE_NAMED_FIELD:
953 /*
954 * If we are executing a method, initialize the field
955 */
956 if (walk_state->method_node) {
957 status = acpi_ds_init_field_objects(op, walk_state);
958 }
959
960 switch (op->common.aml_opcode) {
961 case AML_INDEX_FIELD_OP:
962
963 status =
964 acpi_ds_create_index_field(op,
965 (acpi_handle) arg->
966 common.node, walk_state);
967 break;
968
969 case AML_BANK_FIELD_OP:
970
971 status =
972 acpi_ds_create_bank_field(op, arg->common.node,
973 walk_state);
974 break;
975
976 case AML_FIELD_OP:
977
978 status =
979 acpi_ds_create_field(op, arg->common.node,
980 walk_state);
981 break;
982
983 default:
984 /* All NAMED_FIELD opcodes must be handled above */
985 break;
986 }
987 break;
988
989 case AML_TYPE_NAMED_SIMPLE:
990
991 status = acpi_ds_create_operands(walk_state, arg);
992 if (ACPI_FAILURE(status)) {
993 goto cleanup;
994 }
995
996 switch (op->common.aml_opcode) {
997 case AML_PROCESSOR_OP:
998
999 status = acpi_ex_create_processor(walk_state);
1000 break;
1001
1002 case AML_POWER_RES_OP:
1003
1004 status = acpi_ex_create_power_resource(walk_state);
1005 break;
1006
1007 case AML_MUTEX_OP:
1008
1009 status = acpi_ex_create_mutex(walk_state);
1010 break;
1011
1012 case AML_EVENT_OP:
1013
1014 status = acpi_ex_create_event(walk_state);
1015 break;
1016
1017 case AML_ALIAS_OP:
1018
1019 status = acpi_ex_create_alias(walk_state);
1020 break;
1021
1022 default:
1023 /* Unknown opcode */
1024
1025 status = AE_OK;
1026 goto cleanup;
1027 }
1028
1029 /* Delete operands */
1030
1031 for (i = 1; i < walk_state->num_operands; i++) {
1032 acpi_ut_remove_reference(walk_state->operands[i]);
1033 walk_state->operands[i] = NULL;
1034 }
1035
1036 break;
1037#endif /* ACPI_NO_METHOD_EXECUTION */
1038
1039 case AML_TYPE_NAMED_COMPLEX:
1040
1041 switch (op->common.aml_opcode) {
1042#ifndef ACPI_NO_METHOD_EXECUTION
1043 case AML_REGION_OP:
1044 case AML_DATA_REGION_OP:
1045
1046 if (op->common.aml_opcode == AML_REGION_OP) {
1047 region_space = (acpi_adr_space_type)
1048 ((op->common.value.arg)->common.value.
1049 integer);
1050 } else {
1051 region_space = REGION_DATA_TABLE;
1052 }
1053
1054 /*
1055 * The op_region is not fully parsed at this time. The only valid
1056 * argument is the space_id. (We must save the address of the
1057 * AML of the address and length operands)
1058 *
1059 * If we have a valid region, initialize it. The namespace is
1060 * unlocked at this point.
1061 *
1062 * Need to unlock interpreter if it is locked (if we are running
1063 * a control method), in order to allow _REG methods to be run
1064 * during acpi_ev_initialize_region.
1065 */
1066 if (walk_state->method_node) {
1067 /*
1068 * Executing a method: initialize the region and unlock
1069 * the interpreter
1070 */
1071 status =
1072 acpi_ex_create_region(op->named.data,
1073 op->named.length,
1074 region_space,
1075 walk_state);
1076 if (ACPI_FAILURE(status)) {
1077 return (status);
1078 }
1079
1080 acpi_ex_exit_interpreter();
1081 }
1082
1083 status =
1084 acpi_ev_initialize_region
1085 (acpi_ns_get_attached_object(node), FALSE);
1086 if (walk_state->method_node) {
1087 acpi_ex_enter_interpreter();
1088 }
1089
1090 if (ACPI_FAILURE(status)) {
1091 /*
1092 * If AE_NOT_EXIST is returned, it is not fatal
1093 * because many regions get created before a handler
1094 * is installed for said region.
1095 */
1096 if (AE_NOT_EXIST == status) {
1097 status = AE_OK;
1098 }
1099 }
1100 break;
1101
1102 case AML_NAME_OP:
1103
1104 status = acpi_ds_create_node(walk_state, node, op);
1105 break;
1106
1107 case AML_METHOD_OP:
1108 /*
1109 * method_op pkg_length name_string method_flags term_list
1110 *
1111 * Note: We must create the method node/object pair as soon as we
1112 * see the method declaration. This allows later pass1 parsing
1113 * of invocations of the method (need to know the number of
1114 * arguments.)
1115 */
1116 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1117 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
1118 walk_state, op, op->named.node));
1119
1120 if (!acpi_ns_get_attached_object(op->named.node)) {
1121 walk_state->operands[0] =
1122 ACPI_CAST_PTR(void, op->named.node);
1123 walk_state->num_operands = 1;
1124
1125 status =
1126 acpi_ds_create_operands(walk_state,
1127 op->common.value.
1128 arg);
1129 if (ACPI_SUCCESS(status)) {
1130 status =
1131 acpi_ex_create_method(op->named.
1132 data,
1133 op->named.
1134 length,
1135 walk_state);
1136 }
1137 walk_state->operands[0] = NULL;
1138 walk_state->num_operands = 0;
1139
1140 if (ACPI_FAILURE(status)) {
1141 return_ACPI_STATUS(status);
1142 }
1143 }
1144 break;
1145
1146#endif /* ACPI_NO_METHOD_EXECUTION */
1147
1148 default:
1149 /* All NAMED_COMPLEX opcodes must be handled above */
1150 break;
1151 }
1152 break;
1153
1154 case AML_CLASS_INTERNAL:
1155
1156 /* case AML_INT_NAMEPATH_OP: */
1157 break;
1158
1159 case AML_CLASS_METHOD_CALL:
1160
1161 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1162 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
1163 walk_state, op, node));
1164
1165 /*
1166 * Lookup the method name and save the Node
1167 */
1168 status =
1169 acpi_ns_lookup(walk_state->scope_info,
1170 arg->common.value.string, ACPI_TYPE_ANY,
1171 ACPI_IMODE_LOAD_PASS2,
1172 ACPI_NS_SEARCH_PARENT |
1173 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
1174 &(new_node));
1175 if (ACPI_SUCCESS(status)) {
1176 /*
1177 * Make sure that what we found is indeed a method
1178 * We didn't search for a method on purpose, to see if the name
1179 * would resolve
1180 */
1181 if (new_node->type != ACPI_TYPE_METHOD) {
1182 status = AE_AML_OPERAND_TYPE;
1183 }
1184
1185 /* We could put the returned object (Node) on the object stack for
1186 * later, but for now, we will put it in the "op" object that the
1187 * parser uses, so we can get it again at the end of this scope
1188 */
1189 op->common.node = new_node;
1190 } else {
1191 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
1192 }
1193 break;
1194
1195 default:
1196 break;
1197 }
1198
1199 cleanup:
1200
1201 /* Remove the Node pushed at the very beginning */
1202
1203 walk_state->operands[0] = NULL;
1204 walk_state->num_operands = 0;
1205 return_ACPI_STATUS(status);
1206}
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c
new file mode 100644
index 000000000000..4be4e921dfe1
--- /dev/null
+++ b/drivers/acpi/acpica/dswload2.c
@@ -0,0 +1,720 @@
1/******************************************************************************
2 *
3 * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acparser.h"
47#include "amlcode.h"
48#include "acdispat.h"
49#include "acinterp.h"
50#include "acnamesp.h"
51#include "acevents.h"
52
53#define _COMPONENT ACPI_DISPATCHER
54ACPI_MODULE_NAME("dswload2")
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ds_load2_begin_op
59 *
60 * PARAMETERS: walk_state - Current state of the parse tree walk
61 * out_op - Wher to return op if a new one is created
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
66 *
67 ******************************************************************************/
68acpi_status
69acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
70 union acpi_parse_object **out_op)
71{
72 union acpi_parse_object *op;
73 struct acpi_namespace_node *node;
74 acpi_status status;
75 acpi_object_type object_type;
76 char *buffer_ptr;
77 u32 flags;
78
79 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
80
81 op = walk_state->op;
82 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
83 walk_state));
84
85 if (op) {
86 if ((walk_state->control_state) &&
87 (walk_state->control_state->common.state ==
88 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
89
90 /* We are executing a while loop outside of a method */
91
92 status = acpi_ds_exec_begin_op(walk_state, out_op);
93 return_ACPI_STATUS(status);
94 }
95
96 /* We only care about Namespace opcodes here */
97
98 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
99 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
100 (!(walk_state->op_info->flags & AML_NAMED))) {
101 return_ACPI_STATUS(AE_OK);
102 }
103
104 /* Get the name we are going to enter or lookup in the namespace */
105
106 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
107
108 /* For Namepath op, get the path string */
109
110 buffer_ptr = op->common.value.string;
111 if (!buffer_ptr) {
112
113 /* No name, just exit */
114
115 return_ACPI_STATUS(AE_OK);
116 }
117 } else {
118 /* Get name from the op */
119
120 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
121 }
122 } else {
123 /* Get the namestring from the raw AML */
124
125 buffer_ptr =
126 acpi_ps_get_next_namestring(&walk_state->parser_state);
127 }
128
129 /* Map the opcode into an internal object type */
130
131 object_type = walk_state->op_info->object_type;
132
133 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
134 "State=%p Op=%p Type=%X\n", walk_state, op,
135 object_type));
136
137 switch (walk_state->opcode) {
138 case AML_FIELD_OP:
139 case AML_BANK_FIELD_OP:
140 case AML_INDEX_FIELD_OP:
141
142 node = NULL;
143 status = AE_OK;
144 break;
145
146 case AML_INT_NAMEPATH_OP:
147 /*
148 * The name_path is an object reference to an existing object.
149 * Don't enter the name into the namespace, but look it up
150 * for use later.
151 */
152 status =
153 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
154 object_type, ACPI_IMODE_EXECUTE,
155 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
156 break;
157
158 case AML_SCOPE_OP:
159
160 /* Special case for Scope(\) -> refers to the Root node */
161
162 if (op && (op->named.node == acpi_gbl_root_node)) {
163 node = op->named.node;
164
165 status =
166 acpi_ds_scope_stack_push(node, object_type,
167 walk_state);
168 if (ACPI_FAILURE(status)) {
169 return_ACPI_STATUS(status);
170 }
171 } else {
172 /*
173 * The Path is an object reference to an existing object.
174 * Don't enter the name into the namespace, but look it up
175 * for use later.
176 */
177 status =
178 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
179 object_type, ACPI_IMODE_EXECUTE,
180 ACPI_NS_SEARCH_PARENT, walk_state,
181 &(node));
182 if (ACPI_FAILURE(status)) {
183#ifdef ACPI_ASL_COMPILER
184 if (status == AE_NOT_FOUND) {
185 status = AE_OK;
186 } else {
187 ACPI_ERROR_NAMESPACE(buffer_ptr,
188 status);
189 }
190#else
191 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
192#endif
193 return_ACPI_STATUS(status);
194 }
195 }
196
197 /*
198 * We must check to make sure that the target is
199 * one of the opcodes that actually opens a scope
200 */
201 switch (node->type) {
202 case ACPI_TYPE_ANY:
203 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
204 case ACPI_TYPE_DEVICE:
205 case ACPI_TYPE_POWER:
206 case ACPI_TYPE_PROCESSOR:
207 case ACPI_TYPE_THERMAL:
208
209 /* These are acceptable types */
210 break;
211
212 case ACPI_TYPE_INTEGER:
213 case ACPI_TYPE_STRING:
214 case ACPI_TYPE_BUFFER:
215
216 /*
217 * These types we will allow, but we will change the type.
218 * This enables some existing code of the form:
219 *
220 * Name (DEB, 0)
221 * Scope (DEB) { ... }
222 */
223 ACPI_WARNING((AE_INFO,
224 "Type override - [%4.4s] had invalid type (%s) "
225 "for Scope operator, changed to type ANY\n",
226 acpi_ut_get_node_name(node),
227 acpi_ut_get_type_name(node->type)));
228
229 node->type = ACPI_TYPE_ANY;
230 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
231 break;
232
233 default:
234
235 /* All other types are an error */
236
237 ACPI_ERROR((AE_INFO,
238 "Invalid type (%s) for target of "
239 "Scope operator [%4.4s] (Cannot override)",
240 acpi_ut_get_type_name(node->type),
241 acpi_ut_get_node_name(node)));
242
243 return (AE_AML_OPERAND_TYPE);
244 }
245 break;
246
247 default:
248
249 /* All other opcodes */
250
251 if (op && op->common.node) {
252
253 /* This op/node was previously entered into the namespace */
254
255 node = op->common.node;
256
257 if (acpi_ns_opens_scope(object_type)) {
258 status =
259 acpi_ds_scope_stack_push(node, object_type,
260 walk_state);
261 if (ACPI_FAILURE(status)) {
262 return_ACPI_STATUS(status);
263 }
264 }
265
266 return_ACPI_STATUS(AE_OK);
267 }
268
269 /*
270 * Enter the named type into the internal namespace. We enter the name
271 * as we go downward in the parse tree. Any necessary subobjects that
272 * involve arguments to the opcode must be created as we go back up the
273 * parse tree later.
274 *
275 * Note: Name may already exist if we are executing a deferred opcode.
276 */
277 if (walk_state->deferred_node) {
278
279 /* This name is already in the namespace, get the node */
280
281 node = walk_state->deferred_node;
282 status = AE_OK;
283 break;
284 }
285
286 flags = ACPI_NS_NO_UPSEARCH;
287 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
288
289 /* Execution mode, node cannot already exist, node is temporary */
290
291 flags |= ACPI_NS_ERROR_IF_FOUND;
292
293 if (!
294 (walk_state->
295 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
296 flags |= ACPI_NS_TEMPORARY;
297 }
298 }
299
300 /* Add new entry or lookup existing entry */
301
302 status =
303 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
304 object_type, ACPI_IMODE_LOAD_PASS2, flags,
305 walk_state, &node);
306
307 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
308 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
309 "***New Node [%4.4s] %p is temporary\n",
310 acpi_ut_get_node_name(node), node));
311 }
312 break;
313 }
314
315 if (ACPI_FAILURE(status)) {
316 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
317 return_ACPI_STATUS(status);
318 }
319
320 if (!op) {
321
322 /* Create a new op */
323
324 op = acpi_ps_alloc_op(walk_state->opcode);
325 if (!op) {
326 return_ACPI_STATUS(AE_NO_MEMORY);
327 }
328
329 /* Initialize the new op */
330
331 if (node) {
332 op->named.name = node->name.integer;
333 }
334 *out_op = op;
335 }
336
337 /*
338 * Put the Node in the "op" object that the parser uses, so we
339 * can get it again quickly when this scope is closed
340 */
341 op->common.node = node;
342 return_ACPI_STATUS(status);
343}
344
345/*******************************************************************************
346 *
347 * FUNCTION: acpi_ds_load2_end_op
348 *
349 * PARAMETERS: walk_state - Current state of the parse tree walk
350 *
351 * RETURN: Status
352 *
353 * DESCRIPTION: Ascending callback used during the loading of the namespace,
354 * both control methods and everything else.
355 *
356 ******************************************************************************/
357
358acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
359{
360 union acpi_parse_object *op;
361 acpi_status status = AE_OK;
362 acpi_object_type object_type;
363 struct acpi_namespace_node *node;
364 union acpi_parse_object *arg;
365 struct acpi_namespace_node *new_node;
366#ifndef ACPI_NO_METHOD_EXECUTION
367 u32 i;
368 u8 region_space;
369#endif
370
371 ACPI_FUNCTION_TRACE(ds_load2_end_op);
372
373 op = walk_state->op;
374 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
375 walk_state->op_info->name, op, walk_state));
376
377 /* Check if opcode had an associated namespace object */
378
379 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
380 return_ACPI_STATUS(AE_OK);
381 }
382
383 if (op->common.aml_opcode == AML_SCOPE_OP) {
384 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
385 "Ending scope Op=%p State=%p\n", op,
386 walk_state));
387 }
388
389 object_type = walk_state->op_info->object_type;
390
391 /*
392 * Get the Node/name from the earlier lookup
393 * (It was saved in the *op structure)
394 */
395 node = op->common.node;
396
397 /*
398 * Put the Node on the object stack (Contains the ACPI Name of
399 * this object)
400 */
401 walk_state->operands[0] = (void *)node;
402 walk_state->num_operands = 1;
403
404 /* Pop the scope stack */
405
406 if (acpi_ns_opens_scope(object_type) &&
407 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
408 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
409 "(%s) Popping scope for Op %p\n",
410 acpi_ut_get_type_name(object_type), op));
411
412 status = acpi_ds_scope_stack_pop(walk_state);
413 if (ACPI_FAILURE(status)) {
414 goto cleanup;
415 }
416 }
417
418 /*
419 * Named operations are as follows:
420 *
421 * AML_ALIAS
422 * AML_BANKFIELD
423 * AML_CREATEBITFIELD
424 * AML_CREATEBYTEFIELD
425 * AML_CREATEDWORDFIELD
426 * AML_CREATEFIELD
427 * AML_CREATEQWORDFIELD
428 * AML_CREATEWORDFIELD
429 * AML_DATA_REGION
430 * AML_DEVICE
431 * AML_EVENT
432 * AML_FIELD
433 * AML_INDEXFIELD
434 * AML_METHOD
435 * AML_METHODCALL
436 * AML_MUTEX
437 * AML_NAME
438 * AML_NAMEDFIELD
439 * AML_OPREGION
440 * AML_POWERRES
441 * AML_PROCESSOR
442 * AML_SCOPE
443 * AML_THERMALZONE
444 */
445
446 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
447 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
448 acpi_ps_get_opcode_name(op->common.aml_opcode),
449 walk_state, op, node));
450
451 /* Decode the opcode */
452
453 arg = op->common.value.arg;
454
455 switch (walk_state->op_info->type) {
456#ifndef ACPI_NO_METHOD_EXECUTION
457
458 case AML_TYPE_CREATE_FIELD:
459 /*
460 * Create the field object, but the field buffer and index must
461 * be evaluated later during the execution phase
462 */
463 status = acpi_ds_create_buffer_field(op, walk_state);
464 break;
465
466 case AML_TYPE_NAMED_FIELD:
467 /*
468 * If we are executing a method, initialize the field
469 */
470 if (walk_state->method_node) {
471 status = acpi_ds_init_field_objects(op, walk_state);
472 }
473
474 switch (op->common.aml_opcode) {
475 case AML_INDEX_FIELD_OP:
476
477 status =
478 acpi_ds_create_index_field(op,
479 (acpi_handle) arg->
480 common.node, walk_state);
481 break;
482
483 case AML_BANK_FIELD_OP:
484
485 status =
486 acpi_ds_create_bank_field(op, arg->common.node,
487 walk_state);
488 break;
489
490 case AML_FIELD_OP:
491
492 status =
493 acpi_ds_create_field(op, arg->common.node,
494 walk_state);
495 break;
496
497 default:
498 /* All NAMED_FIELD opcodes must be handled above */
499 break;
500 }
501 break;
502
503 case AML_TYPE_NAMED_SIMPLE:
504
505 status = acpi_ds_create_operands(walk_state, arg);
506 if (ACPI_FAILURE(status)) {
507 goto cleanup;
508 }
509
510 switch (op->common.aml_opcode) {
511 case AML_PROCESSOR_OP:
512
513 status = acpi_ex_create_processor(walk_state);
514 break;
515
516 case AML_POWER_RES_OP:
517
518 status = acpi_ex_create_power_resource(walk_state);
519 break;
520
521 case AML_MUTEX_OP:
522
523 status = acpi_ex_create_mutex(walk_state);
524 break;
525
526 case AML_EVENT_OP:
527
528 status = acpi_ex_create_event(walk_state);
529 break;
530
531 case AML_ALIAS_OP:
532
533 status = acpi_ex_create_alias(walk_state);
534 break;
535
536 default:
537 /* Unknown opcode */
538
539 status = AE_OK;
540 goto cleanup;
541 }
542
543 /* Delete operands */
544
545 for (i = 1; i < walk_state->num_operands; i++) {
546 acpi_ut_remove_reference(walk_state->operands[i]);
547 walk_state->operands[i] = NULL;
548 }
549
550 break;
551#endif /* ACPI_NO_METHOD_EXECUTION */
552
553 case AML_TYPE_NAMED_COMPLEX:
554
555 switch (op->common.aml_opcode) {
556#ifndef ACPI_NO_METHOD_EXECUTION
557 case AML_REGION_OP:
558 case AML_DATA_REGION_OP:
559
560 if (op->common.aml_opcode == AML_REGION_OP) {
561 region_space = (acpi_adr_space_type)
562 ((op->common.value.arg)->common.value.
563 integer);
564 } else {
565 region_space = REGION_DATA_TABLE;
566 }
567
568 /*
569 * The op_region is not fully parsed at this time. The only valid
570 * argument is the space_id. (We must save the address of the
571 * AML of the address and length operands)
572 *
573 * If we have a valid region, initialize it. The namespace is
574 * unlocked at this point.
575 *
576 * Need to unlock interpreter if it is locked (if we are running
577 * a control method), in order to allow _REG methods to be run
578 * during acpi_ev_initialize_region.
579 */
580 if (walk_state->method_node) {
581 /*
582 * Executing a method: initialize the region and unlock
583 * the interpreter
584 */
585 status =
586 acpi_ex_create_region(op->named.data,
587 op->named.length,
588 region_space,
589 walk_state);
590 if (ACPI_FAILURE(status)) {
591 return (status);
592 }
593
594 acpi_ex_exit_interpreter();
595 }
596
597 status =
598 acpi_ev_initialize_region
599 (acpi_ns_get_attached_object(node), FALSE);
600 if (walk_state->method_node) {
601 acpi_ex_enter_interpreter();
602 }
603
604 if (ACPI_FAILURE(status)) {
605 /*
606 * If AE_NOT_EXIST is returned, it is not fatal
607 * because many regions get created before a handler
608 * is installed for said region.
609 */
610 if (AE_NOT_EXIST == status) {
611 status = AE_OK;
612 }
613 }
614 break;
615
616 case AML_NAME_OP:
617
618 status = acpi_ds_create_node(walk_state, node, op);
619 break;
620
621 case AML_METHOD_OP:
622 /*
623 * method_op pkg_length name_string method_flags term_list
624 *
625 * Note: We must create the method node/object pair as soon as we
626 * see the method declaration. This allows later pass1 parsing
627 * of invocations of the method (need to know the number of
628 * arguments.)
629 */
630 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
631 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
632 walk_state, op, op->named.node));
633
634 if (!acpi_ns_get_attached_object(op->named.node)) {
635 walk_state->operands[0] =
636 ACPI_CAST_PTR(void, op->named.node);
637 walk_state->num_operands = 1;
638
639 status =
640 acpi_ds_create_operands(walk_state,
641 op->common.value.
642 arg);
643 if (ACPI_SUCCESS(status)) {
644 status =
645 acpi_ex_create_method(op->named.
646 data,
647 op->named.
648 length,
649 walk_state);
650 }
651 walk_state->operands[0] = NULL;
652 walk_state->num_operands = 0;
653
654 if (ACPI_FAILURE(status)) {
655 return_ACPI_STATUS(status);
656 }
657 }
658 break;
659
660#endif /* ACPI_NO_METHOD_EXECUTION */
661
662 default:
663 /* All NAMED_COMPLEX opcodes must be handled above */
664 break;
665 }
666 break;
667
668 case AML_CLASS_INTERNAL:
669
670 /* case AML_INT_NAMEPATH_OP: */
671 break;
672
673 case AML_CLASS_METHOD_CALL:
674
675 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
676 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
677 walk_state, op, node));
678
679 /*
680 * Lookup the method name and save the Node
681 */
682 status =
683 acpi_ns_lookup(walk_state->scope_info,
684 arg->common.value.string, ACPI_TYPE_ANY,
685 ACPI_IMODE_LOAD_PASS2,
686 ACPI_NS_SEARCH_PARENT |
687 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
688 &(new_node));
689 if (ACPI_SUCCESS(status)) {
690 /*
691 * Make sure that what we found is indeed a method
692 * We didn't search for a method on purpose, to see if the name
693 * would resolve
694 */
695 if (new_node->type != ACPI_TYPE_METHOD) {
696 status = AE_AML_OPERAND_TYPE;
697 }
698
699 /* We could put the returned object (Node) on the object stack for
700 * later, but for now, we will put it in the "op" object that the
701 * parser uses, so we can get it again at the end of this scope
702 */
703 op->common.node = new_node;
704 } else {
705 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
706 }
707 break;
708
709 default:
710 break;
711 }
712
713 cleanup:
714
715 /* Remove the Node pushed at the very beginning */
716
717 walk_state->operands[0] = NULL;
718 walk_state->num_operands = 0;
719 return_ACPI_STATUS(status);
720}
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f4725212eb48..65c79add3b19 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -373,6 +373,15 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
373 373
374 gpe_register_info = &gpe_block->register_info[i]; 374 gpe_register_info = &gpe_block->register_info[i];
375 375
376 /*
377 * Optimization: If there are no GPEs enabled within this
378 * register, we can safely ignore the entire register.
379 */
380 if (!(gpe_register_info->enable_for_run |
381 gpe_register_info->enable_for_wake)) {
382 continue;
383 }
384
376 /* Read the Status Register */ 385 /* Read the Status Register */
377 386
378 status = 387 status =
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 785a5ee64585..bea7223d7a71 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -231,6 +231,8 @@ acpi_status acpi_ev_initialize_op_regions(void)
231 } 231 }
232 } 232 }
233 233
234 acpi_gbl_reg_methods_executed = TRUE;
235
234 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 236 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
235 return_ACPI_STATUS(status); 237 return_ACPI_STATUS(status);
236} 238}
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index eb7386763712..c85c8c45599d 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -110,9 +110,39 @@ acpi_install_address_space_handler(acpi_handle device,
110 goto unlock_and_exit; 110 goto unlock_and_exit;
111 } 111 }
112 112
113 /* Run all _REG methods for this address space */ 113 /*
114 * For the default space_iDs, (the IDs for which there are default region handlers
115 * installed) Only execute the _REG methods if the global initialization _REG
116 * methods have already been run (via acpi_initialize_objects). In other words,
117 * we will defer the execution of the _REG methods for these space_iDs until
118 * execution of acpi_initialize_objects. This is done because we need the handlers
119 * for the default spaces (mem/io/pci/table) to be installed before we can run
120 * any control methods (or _REG methods). There is known BIOS code that depends
121 * on this.
122 *
123 * For all other space_iDs, we can safely execute the _REG methods immediately.
124 * This means that for IDs like embedded_controller, this function should be called
125 * only after acpi_enable_subsystem has been called.
126 */
127 switch (space_id) {
128 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
129 case ACPI_ADR_SPACE_SYSTEM_IO:
130 case ACPI_ADR_SPACE_PCI_CONFIG:
131 case ACPI_ADR_SPACE_DATA_TABLE:
132
133 if (acpi_gbl_reg_methods_executed) {
134
135 /* Run all _REG methods for this address space */
136
137 status = acpi_ev_execute_reg_methods(node, space_id);
138 }
139 break;
140
141 default:
114 142
115 status = acpi_ev_execute_reg_methods(node, space_id); 143 status = acpi_ev_execute_reg_methods(node, space_id);
144 break;
145 }
116 146
117 unlock_and_exit: 147 unlock_and_exit:
118 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 148 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index 6c79c29f082d..f915a7f3f921 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -280,13 +280,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
280 if (ACPI_FAILURE(status)) { 280 if (ACPI_FAILURE(status)) {
281 if (status == AE_NOT_IMPLEMENTED) { 281 if (status == AE_NOT_IMPLEMENTED) {
282 ACPI_ERROR((AE_INFO, 282 ACPI_ERROR((AE_INFO,
283 "Region %s(0x%X) not implemented", 283 "Region %s (ID=%u) not implemented",
284 acpi_ut_get_region_name(rgn_desc->region. 284 acpi_ut_get_region_name(rgn_desc->region.
285 space_id), 285 space_id),
286 rgn_desc->region.space_id)); 286 rgn_desc->region.space_id));
287 } else if (status == AE_NOT_EXIST) { 287 } else if (status == AE_NOT_EXIST) {
288 ACPI_ERROR((AE_INFO, 288 ACPI_ERROR((AE_INFO,
289 "Region %s(0x%X) has no handler", 289 "Region %s (ID=%u) has no handler",
290 acpi_ut_get_region_name(rgn_desc->region. 290 acpi_ut_get_region_name(rgn_desc->region.
291 space_id), 291 space_id),
292 rgn_desc->region.space_id)); 292 rgn_desc->region.space_id));
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index 6f98d210e71c..f75f81ad15c9 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -80,14 +80,14 @@ acpi_status acpi_reset(void)
80 80
81 if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 81 if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
82 /* 82 /*
83 * For I/O space, write directly to the OSL. This bypasses the port 83 * For I/O space, write directly to the OSL. This
84 * validation mechanism, which may block a valid write to the reset 84 * bypasses the port validation mechanism, which may
85 * register. 85 * block a valid write to the reset register. Spec
86 * section 4.7.3.6 requires register width to be 8.
86 */ 87 */
87 status = 88 status =
88 acpi_os_write_port((acpi_io_address) reset_reg->address, 89 acpi_os_write_port((acpi_io_address) reset_reg->address,
89 acpi_gbl_FADT.reset_value, 90 acpi_gbl_FADT.reset_value, 8);
90 reset_reg->bit_width);
91 } else { 91 } else {
92 /* Write the reset value to the reset register */ 92 /* Write the reset value to the reset register */
93 93
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 428d44e2d162..6f5588e62c0a 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -384,8 +384,11 @@ static void acpi_tb_convert_fadt(void)
384 * 384 *
385 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at 385 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
386 * offset 45, 55, 95, and the word located at offset 109, 110. 386 * offset 45, 55, 95, and the word located at offset 109, 110.
387 *
388 * Note: The FADT revision value is unreliable. Only the length can be
389 * trusted.
387 */ 390 */
388 if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) { 391 if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) {
389 acpi_gbl_FADT.preferred_profile = 0; 392 acpi_gbl_FADT.preferred_profile = 0;
390 acpi_gbl_FADT.pstate_control = 0; 393 acpi_gbl_FADT.pstate_control = 0;
391 acpi_gbl_FADT.cst_control = 0; 394 acpi_gbl_FADT.cst_control = 0;
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
new file mode 100644
index 000000000000..136a814cec69
--- /dev/null
+++ b/drivers/acpi/acpica/utdecode.c
@@ -0,0 +1,548 @@
1/******************************************************************************
2 *
3 * Module Name: utdecode - Utility decoding routines (value-to-string)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acnamesp.h"
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utdecode")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_format_exception
54 *
55 * PARAMETERS: Status - The acpi_status code to be formatted
56 *
57 * RETURN: A string containing the exception text. A valid pointer is
58 * always returned.
59 *
60 * DESCRIPTION: This function translates an ACPI exception into an ASCII string
61 * It is here instead of utxface.c so it is always present.
62 *
63 ******************************************************************************/
64const char *acpi_format_exception(acpi_status status)
65{
66 const char *exception = NULL;
67
68 ACPI_FUNCTION_ENTRY();
69
70 exception = acpi_ut_validate_exception(status);
71 if (!exception) {
72
73 /* Exception code was not recognized */
74
75 ACPI_ERROR((AE_INFO,
76 "Unknown exception code: 0x%8.8X", status));
77
78 exception = "UNKNOWN_STATUS_CODE";
79 }
80
81 return (ACPI_CAST_PTR(const char, exception));
82}
83
84ACPI_EXPORT_SYMBOL(acpi_format_exception)
85
86/*
87 * Properties of the ACPI Object Types, both internal and external.
88 * The table is indexed by values of acpi_object_type
89 */
90const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = {
91 ACPI_NS_NORMAL, /* 00 Any */
92 ACPI_NS_NORMAL, /* 01 Number */
93 ACPI_NS_NORMAL, /* 02 String */
94 ACPI_NS_NORMAL, /* 03 Buffer */
95 ACPI_NS_NORMAL, /* 04 Package */
96 ACPI_NS_NORMAL, /* 05 field_unit */
97 ACPI_NS_NEWSCOPE, /* 06 Device */
98 ACPI_NS_NORMAL, /* 07 Event */
99 ACPI_NS_NEWSCOPE, /* 08 Method */
100 ACPI_NS_NORMAL, /* 09 Mutex */
101 ACPI_NS_NORMAL, /* 10 Region */
102 ACPI_NS_NEWSCOPE, /* 11 Power */
103 ACPI_NS_NEWSCOPE, /* 12 Processor */
104 ACPI_NS_NEWSCOPE, /* 13 Thermal */
105 ACPI_NS_NORMAL, /* 14 buffer_field */
106 ACPI_NS_NORMAL, /* 15 ddb_handle */
107 ACPI_NS_NORMAL, /* 16 Debug Object */
108 ACPI_NS_NORMAL, /* 17 def_field */
109 ACPI_NS_NORMAL, /* 18 bank_field */
110 ACPI_NS_NORMAL, /* 19 index_field */
111 ACPI_NS_NORMAL, /* 20 Reference */
112 ACPI_NS_NORMAL, /* 21 Alias */
113 ACPI_NS_NORMAL, /* 22 method_alias */
114 ACPI_NS_NORMAL, /* 23 Notify */
115 ACPI_NS_NORMAL, /* 24 Address Handler */
116 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
117 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
118 ACPI_NS_NEWSCOPE, /* 27 Scope */
119 ACPI_NS_NORMAL, /* 28 Extra */
120 ACPI_NS_NORMAL, /* 29 Data */
121 ACPI_NS_NORMAL /* 30 Invalid */
122};
123
124/*******************************************************************************
125 *
126 * FUNCTION: acpi_ut_hex_to_ascii_char
127 *
128 * PARAMETERS: Integer - Contains the hex digit
129 * Position - bit position of the digit within the
130 * integer (multiple of 4)
131 *
132 * RETURN: The converted Ascii character
133 *
134 * DESCRIPTION: Convert a hex digit to an Ascii character
135 *
136 ******************************************************************************/
137
138/* Hex to ASCII conversion table */
139
140static const char acpi_gbl_hex_to_ascii[] = {
141 '0', '1', '2', '3', '4', '5', '6', '7',
142 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
143};
144
145char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
146{
147
148 return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
149}
150
151/*******************************************************************************
152 *
153 * FUNCTION: acpi_ut_get_region_name
154 *
155 * PARAMETERS: Space ID - ID for the region
156 *
157 * RETURN: Decoded region space_id name
158 *
159 * DESCRIPTION: Translate a Space ID into a name string (Debug only)
160 *
161 ******************************************************************************/
162
163/* Region type decoding */
164
165const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
166 "SystemMemory",
167 "SystemIO",
168 "PCI_Config",
169 "EmbeddedControl",
170 "SMBus",
171 "SystemCMOS",
172 "PCIBARTarget",
173 "IPMI",
174 "DataTable"
175};
176
177char *acpi_ut_get_region_name(u8 space_id)
178{
179
180 if (space_id >= ACPI_USER_REGION_BEGIN) {
181 return ("UserDefinedRegion");
182 } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
183 return ("FunctionalFixedHW");
184 } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) {
185 return ("InvalidSpaceId");
186 }
187
188 return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id]));
189}
190
191/*******************************************************************************
192 *
193 * FUNCTION: acpi_ut_get_event_name
194 *
195 * PARAMETERS: event_id - Fixed event ID
196 *
197 * RETURN: Decoded event ID name
198 *
199 * DESCRIPTION: Translate a Event ID into a name string (Debug only)
200 *
201 ******************************************************************************/
202
203/* Event type decoding */
204
205static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = {
206 "PM_Timer",
207 "GlobalLock",
208 "PowerButton",
209 "SleepButton",
210 "RealTimeClock",
211};
212
213char *acpi_ut_get_event_name(u32 event_id)
214{
215
216 if (event_id > ACPI_EVENT_MAX) {
217 return ("InvalidEventID");
218 }
219
220 return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id]));
221}
222
223/*******************************************************************************
224 *
225 * FUNCTION: acpi_ut_get_type_name
226 *
227 * PARAMETERS: Type - An ACPI object type
228 *
229 * RETURN: Decoded ACPI object type name
230 *
231 * DESCRIPTION: Translate a Type ID into a name string (Debug only)
232 *
233 ******************************************************************************/
234
235/*
236 * Elements of acpi_gbl_ns_type_names below must match
237 * one-to-one with values of acpi_object_type
238 *
239 * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
240 * when stored in a table it really means that we have thus far seen no
241 * evidence to indicate what type is actually going to be stored for this entry.
242 */
243static const char acpi_gbl_bad_type[] = "UNDEFINED";
244
245/* Printable names of the ACPI object types */
246
247static const char *acpi_gbl_ns_type_names[] = {
248 /* 00 */ "Untyped",
249 /* 01 */ "Integer",
250 /* 02 */ "String",
251 /* 03 */ "Buffer",
252 /* 04 */ "Package",
253 /* 05 */ "FieldUnit",
254 /* 06 */ "Device",
255 /* 07 */ "Event",
256 /* 08 */ "Method",
257 /* 09 */ "Mutex",
258 /* 10 */ "Region",
259 /* 11 */ "Power",
260 /* 12 */ "Processor",
261 /* 13 */ "Thermal",
262 /* 14 */ "BufferField",
263 /* 15 */ "DdbHandle",
264 /* 16 */ "DebugObject",
265 /* 17 */ "RegionField",
266 /* 18 */ "BankField",
267 /* 19 */ "IndexField",
268 /* 20 */ "Reference",
269 /* 21 */ "Alias",
270 /* 22 */ "MethodAlias",
271 /* 23 */ "Notify",
272 /* 24 */ "AddrHandler",
273 /* 25 */ "ResourceDesc",
274 /* 26 */ "ResourceFld",
275 /* 27 */ "Scope",
276 /* 28 */ "Extra",
277 /* 29 */ "Data",
278 /* 30 */ "Invalid"
279};
280
281char *acpi_ut_get_type_name(acpi_object_type type)
282{
283
284 if (type > ACPI_TYPE_INVALID) {
285 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
286 }
287
288 return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type]));
289}
290
291char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
292{
293
294 if (!obj_desc) {
295 return ("[NULL Object Descriptor]");
296 }
297
298 return (acpi_ut_get_type_name(obj_desc->common.type));
299}
300
301/*******************************************************************************
302 *
303 * FUNCTION: acpi_ut_get_node_name
304 *
305 * PARAMETERS: Object - A namespace node
306 *
307 * RETURN: ASCII name of the node
308 *
309 * DESCRIPTION: Validate the node and return the node's ACPI name.
310 *
311 ******************************************************************************/
312
313char *acpi_ut_get_node_name(void *object)
314{
315 struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
316
317 /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
318
319 if (!object) {
320 return ("NULL");
321 }
322
323 /* Check for Root node */
324
325 if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) {
326 return ("\"\\\" ");
327 }
328
329 /* Descriptor must be a namespace node */
330
331 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
332 return ("####");
333 }
334
335 /*
336 * Ensure name is valid. The name was validated/repaired when the node
337 * was created, but make sure it has not been corrupted.
338 */
339 acpi_ut_repair_name(node->name.ascii);
340
341 /* Return the name */
342
343 return (node->name.ascii);
344}
345
346/*******************************************************************************
347 *
348 * FUNCTION: acpi_ut_get_descriptor_name
349 *
350 * PARAMETERS: Object - An ACPI object
351 *
352 * RETURN: Decoded name of the descriptor type
353 *
354 * DESCRIPTION: Validate object and return the descriptor type
355 *
356 ******************************************************************************/
357
358/* Printable names of object descriptor types */
359
360static const char *acpi_gbl_desc_type_names[] = {
361 /* 00 */ "Not a Descriptor",
362 /* 01 */ "Cached",
363 /* 02 */ "State-Generic",
364 /* 03 */ "State-Update",
365 /* 04 */ "State-Package",
366 /* 05 */ "State-Control",
367 /* 06 */ "State-RootParseScope",
368 /* 07 */ "State-ParseScope",
369 /* 08 */ "State-WalkScope",
370 /* 09 */ "State-Result",
371 /* 10 */ "State-Notify",
372 /* 11 */ "State-Thread",
373 /* 12 */ "Walk",
374 /* 13 */ "Parser",
375 /* 14 */ "Operand",
376 /* 15 */ "Node"
377};
378
379char *acpi_ut_get_descriptor_name(void *object)
380{
381
382 if (!object) {
383 return ("NULL OBJECT");
384 }
385
386 if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) {
387 return ("Not a Descriptor");
388 }
389
390 return (ACPI_CAST_PTR(char,
391 acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE
392 (object)]));
393
394}
395
396/*******************************************************************************
397 *
398 * FUNCTION: acpi_ut_get_reference_name
399 *
400 * PARAMETERS: Object - An ACPI reference object
401 *
402 * RETURN: Decoded name of the type of reference
403 *
404 * DESCRIPTION: Decode a reference object sub-type to a string.
405 *
406 ******************************************************************************/
407
408/* Printable names of reference object sub-types */
409
410static const char *acpi_gbl_ref_class_names[] = {
411 /* 00 */ "Local",
412 /* 01 */ "Argument",
413 /* 02 */ "RefOf",
414 /* 03 */ "Index",
415 /* 04 */ "DdbHandle",
416 /* 05 */ "Named Object",
417 /* 06 */ "Debug"
418};
419
420const char *acpi_ut_get_reference_name(union acpi_operand_object *object)
421{
422
423 if (!object) {
424 return ("NULL Object");
425 }
426
427 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
428 return ("Not an Operand object");
429 }
430
431 if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
432 return ("Not a Reference object");
433 }
434
435 if (object->reference.class > ACPI_REFCLASS_MAX) {
436 return ("Unknown Reference class");
437 }
438
439 return (acpi_gbl_ref_class_names[object->reference.class]);
440}
441
442#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
443/*
444 * Strings and procedures used for debug only
445 */
446
447/*******************************************************************************
448 *
449 * FUNCTION: acpi_ut_get_mutex_name
450 *
451 * PARAMETERS: mutex_id - The predefined ID for this mutex.
452 *
453 * RETURN: Decoded name of the internal mutex
454 *
455 * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
456 *
457 ******************************************************************************/
458
459/* Names for internal mutex objects, used for debug output */
460
461static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
462 "ACPI_MTX_Interpreter",
463 "ACPI_MTX_Namespace",
464 "ACPI_MTX_Tables",
465 "ACPI_MTX_Events",
466 "ACPI_MTX_Caches",
467 "ACPI_MTX_Memory",
468 "ACPI_MTX_CommandComplete",
469 "ACPI_MTX_CommandReady"
470};
471
472char *acpi_ut_get_mutex_name(u32 mutex_id)
473{
474
475 if (mutex_id > ACPI_MAX_MUTEX) {
476 return ("Invalid Mutex ID");
477 }
478
479 return (acpi_gbl_mutex_names[mutex_id]);
480}
481
482/*******************************************************************************
483 *
484 * FUNCTION: acpi_ut_get_notify_name
485 *
486 * PARAMETERS: notify_value - Value from the Notify() request
487 *
488 * RETURN: Decoded name for the notify value
489 *
490 * DESCRIPTION: Translate a Notify Value to a notify namestring.
491 *
492 ******************************************************************************/
493
494/* Names for Notify() values, used for debug output */
495
496static const char *acpi_gbl_notify_value_names[] = {
497 "Bus Check",
498 "Device Check",
499 "Device Wake",
500 "Eject Request",
501 "Device Check Light",
502 "Frequency Mismatch",
503 "Bus Mode Mismatch",
504 "Power Fault",
505 "Capabilities Check",
506 "Device PLD Check",
507 "Reserved",
508 "System Locality Update"
509};
510
511const char *acpi_ut_get_notify_name(u32 notify_value)
512{
513
514 if (notify_value <= ACPI_NOTIFY_MAX) {
515 return (acpi_gbl_notify_value_names[notify_value]);
516 } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
517 return ("Reserved");
518 } else { /* Greater or equal to 0x80 */
519
520 return ("**Device Specific**");
521 }
522}
523#endif
524
525/*******************************************************************************
526 *
527 * FUNCTION: acpi_ut_valid_object_type
528 *
529 * PARAMETERS: Type - Object type to be validated
530 *
531 * RETURN: TRUE if valid object type, FALSE otherwise
532 *
533 * DESCRIPTION: Validate an object type
534 *
535 ******************************************************************************/
536
537u8 acpi_ut_valid_object_type(acpi_object_type type)
538{
539
540 if (type > ACPI_TYPE_LOCAL_MAX) {
541
542 /* Note: Assumes all TYPEs are contiguous (external/local) */
543
544 return (FALSE);
545 }
546
547 return (TRUE);
548}
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index 97dd9bbf055a..833a38a9c905 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -45,7 +45,6 @@
45 45
46#include <acpi/acpi.h> 46#include <acpi/acpi.h>
47#include "accommon.h" 47#include "accommon.h"
48#include "acnamesp.h"
49 48
50#define _COMPONENT ACPI_UTILITIES 49#define _COMPONENT ACPI_UTILITIES
51ACPI_MODULE_NAME("utglobal") 50ACPI_MODULE_NAME("utglobal")
@@ -107,43 +106,6 @@ const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = {
107 106
108/******************************************************************************* 107/*******************************************************************************
109 * 108 *
110 * FUNCTION: acpi_format_exception
111 *
112 * PARAMETERS: Status - The acpi_status code to be formatted
113 *
114 * RETURN: A string containing the exception text. A valid pointer is
115 * always returned.
116 *
117 * DESCRIPTION: This function translates an ACPI exception into an ASCII string
118 * It is here instead of utxface.c so it is always present.
119 *
120 ******************************************************************************/
121
122const char *acpi_format_exception(acpi_status status)
123{
124 const char *exception = NULL;
125
126 ACPI_FUNCTION_ENTRY();
127
128 exception = acpi_ut_validate_exception(status);
129 if (!exception) {
130
131 /* Exception code was not recognized */
132
133 ACPI_ERROR((AE_INFO,
134 "Unknown exception code: 0x%8.8X", status));
135
136 exception = "UNKNOWN_STATUS_CODE";
137 dump_stack();
138 }
139
140 return (ACPI_CAST_PTR(const char, exception));
141}
142
143ACPI_EXPORT_SYMBOL(acpi_format_exception)
144
145/*******************************************************************************
146 *
147 * Namespace globals 109 * Namespace globals
148 * 110 *
149 ******************************************************************************/ 111 ******************************************************************************/
@@ -177,71 +139,6 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
177 {NULL, ACPI_TYPE_ANY, NULL} 139 {NULL, ACPI_TYPE_ANY, NULL}
178}; 140};
179 141
180/*
181 * Properties of the ACPI Object Types, both internal and external.
182 * The table is indexed by values of acpi_object_type
183 */
184const u8 acpi_gbl_ns_properties[] = {
185 ACPI_NS_NORMAL, /* 00 Any */
186 ACPI_NS_NORMAL, /* 01 Number */
187 ACPI_NS_NORMAL, /* 02 String */
188 ACPI_NS_NORMAL, /* 03 Buffer */
189 ACPI_NS_NORMAL, /* 04 Package */
190 ACPI_NS_NORMAL, /* 05 field_unit */
191 ACPI_NS_NEWSCOPE, /* 06 Device */
192 ACPI_NS_NORMAL, /* 07 Event */
193 ACPI_NS_NEWSCOPE, /* 08 Method */
194 ACPI_NS_NORMAL, /* 09 Mutex */
195 ACPI_NS_NORMAL, /* 10 Region */
196 ACPI_NS_NEWSCOPE, /* 11 Power */
197 ACPI_NS_NEWSCOPE, /* 12 Processor */
198 ACPI_NS_NEWSCOPE, /* 13 Thermal */
199 ACPI_NS_NORMAL, /* 14 buffer_field */
200 ACPI_NS_NORMAL, /* 15 ddb_handle */
201 ACPI_NS_NORMAL, /* 16 Debug Object */
202 ACPI_NS_NORMAL, /* 17 def_field */
203 ACPI_NS_NORMAL, /* 18 bank_field */
204 ACPI_NS_NORMAL, /* 19 index_field */
205 ACPI_NS_NORMAL, /* 20 Reference */
206 ACPI_NS_NORMAL, /* 21 Alias */
207 ACPI_NS_NORMAL, /* 22 method_alias */
208 ACPI_NS_NORMAL, /* 23 Notify */
209 ACPI_NS_NORMAL, /* 24 Address Handler */
210 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
211 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
212 ACPI_NS_NEWSCOPE, /* 27 Scope */
213 ACPI_NS_NORMAL, /* 28 Extra */
214 ACPI_NS_NORMAL, /* 29 Data */
215 ACPI_NS_NORMAL /* 30 Invalid */
216};
217
218/* Hex to ASCII conversion table */
219
220static const char acpi_gbl_hex_to_ascii[] = {
221 '0', '1', '2', '3', '4', '5', '6', '7',
222 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
223};
224
225/*******************************************************************************
226 *
227 * FUNCTION: acpi_ut_hex_to_ascii_char
228 *
229 * PARAMETERS: Integer - Contains the hex digit
230 * Position - bit position of the digit within the
231 * integer (multiple of 4)
232 *
233 * RETURN: The converted Ascii character
234 *
235 * DESCRIPTION: Convert a hex digit to an Ascii character
236 *
237 ******************************************************************************/
238
239char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
240{
241
242 return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
243}
244
245/****************************************************************************** 142/******************************************************************************
246 * 143 *
247 * Event and Hardware globals 144 * Event and Hardware globals
@@ -341,386 +238,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
341 238
342/******************************************************************************* 239/*******************************************************************************
343 * 240 *
344 * FUNCTION: acpi_ut_get_region_name
345 *
346 * PARAMETERS: None.
347 *
348 * RETURN: Status
349 *
350 * DESCRIPTION: Translate a Space ID into a name string (Debug only)
351 *
352 ******************************************************************************/
353
354/* Region type decoding */
355
356const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
357 "SystemMemory",
358 "SystemIO",
359 "PCI_Config",
360 "EmbeddedControl",
361 "SMBus",
362 "SystemCMOS",
363 "PCIBARTarget",
364 "IPMI",
365 "DataTable"
366};
367
368char *acpi_ut_get_region_name(u8 space_id)
369{
370
371 if (space_id >= ACPI_USER_REGION_BEGIN) {
372 return ("UserDefinedRegion");
373 } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) {
374 return ("InvalidSpaceId");
375 }
376
377 return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id]));
378}
379
380/*******************************************************************************
381 *
382 * FUNCTION: acpi_ut_get_event_name
383 *
384 * PARAMETERS: None.
385 *
386 * RETURN: Status
387 *
388 * DESCRIPTION: Translate a Event ID into a name string (Debug only)
389 *
390 ******************************************************************************/
391
392/* Event type decoding */
393
394static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = {
395 "PM_Timer",
396 "GlobalLock",
397 "PowerButton",
398 "SleepButton",
399 "RealTimeClock",
400};
401
402char *acpi_ut_get_event_name(u32 event_id)
403{
404
405 if (event_id > ACPI_EVENT_MAX) {
406 return ("InvalidEventID");
407 }
408
409 return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id]));
410}
411
412/*******************************************************************************
413 *
414 * FUNCTION: acpi_ut_get_type_name
415 *
416 * PARAMETERS: None.
417 *
418 * RETURN: Status
419 *
420 * DESCRIPTION: Translate a Type ID into a name string (Debug only)
421 *
422 ******************************************************************************/
423
424/*
425 * Elements of acpi_gbl_ns_type_names below must match
426 * one-to-one with values of acpi_object_type
427 *
428 * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
429 * when stored in a table it really means that we have thus far seen no
430 * evidence to indicate what type is actually going to be stored for this entry.
431 */
432static const char acpi_gbl_bad_type[] = "UNDEFINED";
433
434/* Printable names of the ACPI object types */
435
436static const char *acpi_gbl_ns_type_names[] = {
437 /* 00 */ "Untyped",
438 /* 01 */ "Integer",
439 /* 02 */ "String",
440 /* 03 */ "Buffer",
441 /* 04 */ "Package",
442 /* 05 */ "FieldUnit",
443 /* 06 */ "Device",
444 /* 07 */ "Event",
445 /* 08 */ "Method",
446 /* 09 */ "Mutex",
447 /* 10 */ "Region",
448 /* 11 */ "Power",
449 /* 12 */ "Processor",
450 /* 13 */ "Thermal",
451 /* 14 */ "BufferField",
452 /* 15 */ "DdbHandle",
453 /* 16 */ "DebugObject",
454 /* 17 */ "RegionField",
455 /* 18 */ "BankField",
456 /* 19 */ "IndexField",
457 /* 20 */ "Reference",
458 /* 21 */ "Alias",
459 /* 22 */ "MethodAlias",
460 /* 23 */ "Notify",
461 /* 24 */ "AddrHandler",
462 /* 25 */ "ResourceDesc",
463 /* 26 */ "ResourceFld",
464 /* 27 */ "Scope",
465 /* 28 */ "Extra",
466 /* 29 */ "Data",
467 /* 30 */ "Invalid"
468};
469
470char *acpi_ut_get_type_name(acpi_object_type type)
471{
472
473 if (type > ACPI_TYPE_INVALID) {
474 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
475 }
476
477 return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type]));
478}
479
480char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
481{
482
483 if (!obj_desc) {
484 return ("[NULL Object Descriptor]");
485 }
486
487 return (acpi_ut_get_type_name(obj_desc->common.type));
488}
489
490/*******************************************************************************
491 *
492 * FUNCTION: acpi_ut_get_node_name
493 *
494 * PARAMETERS: Object - A namespace node
495 *
496 * RETURN: Pointer to a string
497 *
498 * DESCRIPTION: Validate the node and return the node's ACPI name.
499 *
500 ******************************************************************************/
501
502char *acpi_ut_get_node_name(void *object)
503{
504 struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
505
506 /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
507
508 if (!object) {
509 return ("NULL");
510 }
511
512 /* Check for Root node */
513
514 if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) {
515 return ("\"\\\" ");
516 }
517
518 /* Descriptor must be a namespace node */
519
520 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
521 return ("####");
522 }
523
524 /* Name must be a valid ACPI name */
525
526 if (!acpi_ut_valid_acpi_name(node->name.integer)) {
527 node->name.integer = acpi_ut_repair_name(node->name.ascii);
528 }
529
530 /* Return the name */
531
532 return (node->name.ascii);
533}
534
535/*******************************************************************************
536 *
537 * FUNCTION: acpi_ut_get_descriptor_name
538 *
539 * PARAMETERS: Object - An ACPI object
540 *
541 * RETURN: Pointer to a string
542 *
543 * DESCRIPTION: Validate object and return the descriptor type
544 *
545 ******************************************************************************/
546
547/* Printable names of object descriptor types */
548
549static const char *acpi_gbl_desc_type_names[] = {
550 /* 00 */ "Invalid",
551 /* 01 */ "Cached",
552 /* 02 */ "State-Generic",
553 /* 03 */ "State-Update",
554 /* 04 */ "State-Package",
555 /* 05 */ "State-Control",
556 /* 06 */ "State-RootParseScope",
557 /* 07 */ "State-ParseScope",
558 /* 08 */ "State-WalkScope",
559 /* 09 */ "State-Result",
560 /* 10 */ "State-Notify",
561 /* 11 */ "State-Thread",
562 /* 12 */ "Walk",
563 /* 13 */ "Parser",
564 /* 14 */ "Operand",
565 /* 15 */ "Node"
566};
567
568char *acpi_ut_get_descriptor_name(void *object)
569{
570
571 if (!object) {
572 return ("NULL OBJECT");
573 }
574
575 if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) {
576 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
577 }
578
579 return (ACPI_CAST_PTR(char,
580 acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE
581 (object)]));
582
583}
584
585/*******************************************************************************
586 *
587 * FUNCTION: acpi_ut_get_reference_name
588 *
589 * PARAMETERS: Object - An ACPI reference object
590 *
591 * RETURN: Pointer to a string
592 *
593 * DESCRIPTION: Decode a reference object sub-type to a string.
594 *
595 ******************************************************************************/
596
597/* Printable names of reference object sub-types */
598
599static const char *acpi_gbl_ref_class_names[] = {
600 /* 00 */ "Local",
601 /* 01 */ "Argument",
602 /* 02 */ "RefOf",
603 /* 03 */ "Index",
604 /* 04 */ "DdbHandle",
605 /* 05 */ "Named Object",
606 /* 06 */ "Debug"
607};
608
609const char *acpi_ut_get_reference_name(union acpi_operand_object *object)
610{
611 if (!object)
612 return "NULL Object";
613
614 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND)
615 return "Not an Operand object";
616
617 if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE)
618 return "Not a Reference object";
619
620 if (object->reference.class > ACPI_REFCLASS_MAX)
621 return "Unknown Reference class";
622
623 return acpi_gbl_ref_class_names[object->reference.class];
624}
625
626#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
627/*
628 * Strings and procedures used for debug only
629 */
630
631/*******************************************************************************
632 *
633 * FUNCTION: acpi_ut_get_mutex_name
634 *
635 * PARAMETERS: mutex_id - The predefined ID for this mutex.
636 *
637 * RETURN: String containing the name of the mutex. Always returns a valid
638 * pointer.
639 *
640 * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
641 *
642 ******************************************************************************/
643
644char *acpi_ut_get_mutex_name(u32 mutex_id)
645{
646
647 if (mutex_id > ACPI_MAX_MUTEX) {
648 return ("Invalid Mutex ID");
649 }
650
651 return (acpi_gbl_mutex_names[mutex_id]);
652}
653
654/*******************************************************************************
655 *
656 * FUNCTION: acpi_ut_get_notify_name
657 *
658 * PARAMETERS: notify_value - Value from the Notify() request
659 *
660 * RETURN: String corresponding to the Notify Value.
661 *
662 * DESCRIPTION: Translate a Notify Value to a notify namestring.
663 *
664 ******************************************************************************/
665
666/* Names for Notify() values, used for debug output */
667
668static const char *acpi_gbl_notify_value_names[] = {
669 "Bus Check",
670 "Device Check",
671 "Device Wake",
672 "Eject Request",
673 "Device Check Light",
674 "Frequency Mismatch",
675 "Bus Mode Mismatch",
676 "Power Fault",
677 "Capabilities Check",
678 "Device PLD Check",
679 "Reserved",
680 "System Locality Update"
681};
682
683const char *acpi_ut_get_notify_name(u32 notify_value)
684{
685
686 if (notify_value <= ACPI_NOTIFY_MAX) {
687 return (acpi_gbl_notify_value_names[notify_value]);
688 } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
689 return ("Reserved");
690 } else { /* Greater or equal to 0x80 */
691
692 return ("**Device Specific**");
693 }
694}
695#endif
696
697/*******************************************************************************
698 *
699 * FUNCTION: acpi_ut_valid_object_type
700 *
701 * PARAMETERS: Type - Object type to be validated
702 *
703 * RETURN: TRUE if valid object type, FALSE otherwise
704 *
705 * DESCRIPTION: Validate an object type
706 *
707 ******************************************************************************/
708
709u8 acpi_ut_valid_object_type(acpi_object_type type)
710{
711
712 if (type > ACPI_TYPE_LOCAL_MAX) {
713
714 /* Note: Assumes all TYPEs are contiguous (external/local) */
715
716 return (FALSE);
717 }
718
719 return (TRUE);
720}
721
722/*******************************************************************************
723 *
724 * FUNCTION: acpi_ut_init_globals 241 * FUNCTION: acpi_ut_init_globals
725 * 242 *
726 * PARAMETERS: None 243 * PARAMETERS: None
@@ -806,6 +323,7 @@ acpi_status acpi_ut_init_globals(void)
806 acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; 323 acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
807 acpi_gbl_osi_data = 0; 324 acpi_gbl_osi_data = 0;
808 acpi_gbl_osi_mutex = NULL; 325 acpi_gbl_osi_mutex = NULL;
326 acpi_gbl_reg_methods_executed = FALSE;
809 327
810 /* Hardware oriented */ 328 /* Hardware oriented */
811 329
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index e91680c7e047..66a03caa2ad9 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -22,6 +22,13 @@ config ACPI_APEI_GHES
22 by firmware to produce more valuable hardware error 22 by firmware to produce more valuable hardware error
23 information for Linux. 23 information for Linux.
24 24
25config ACPI_APEI_PCIEAER
26 bool "APEI PCIe AER logging/recovering support"
27 depends on ACPI_APEI && PCIEAER
28 help
29 PCIe AER errors may be reported via APEI firmware first mode.
30 Turn on this option to enable the corresponding support.
31
25config ACPI_APEI_EINJ 32config ACPI_APEI_EINJ
26 tristate "APEI Error INJection (EINJ)" 33 tristate "APEI Error INJection (EINJ)"
27 depends on ACPI_APEI && DEBUG_FS 34 depends on ACPI_APEI && DEBUG_FS
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
index 31464a006d76..5d4189464d63 100644
--- a/drivers/acpi/apei/cper.c
+++ b/drivers/acpi/apei/cper.c
@@ -29,6 +29,7 @@
29#include <linux/time.h> 29#include <linux/time.h>
30#include <linux/cper.h> 30#include <linux/cper.h>
31#include <linux/acpi.h> 31#include <linux/acpi.h>
32#include <linux/aer.h>
32 33
33/* 34/*
34 * CPER record ID need to be unique even after reboot, because record 35 * CPER record ID need to be unique even after reboot, because record
@@ -70,8 +71,8 @@ static const char *cper_severity_str(unsigned int severity)
70 * If the output length is longer than 80, multiple line will be 71 * If the output length is longer than 80, multiple line will be
71 * printed, with @pfx is printed at the beginning of each line. 72 * printed, with @pfx is printed at the beginning of each line.
72 */ 73 */
73static void cper_print_bits(const char *pfx, unsigned int bits, 74void cper_print_bits(const char *pfx, unsigned int bits,
74 const char *strs[], unsigned int strs_size) 75 const char *strs[], unsigned int strs_size)
75{ 76{
76 int i, len = 0; 77 int i, len = 0;
77 const char *str; 78 const char *str;
@@ -81,6 +82,8 @@ static void cper_print_bits(const char *pfx, unsigned int bits,
81 if (!(bits & (1U << i))) 82 if (!(bits & (1U << i)))
82 continue; 83 continue;
83 str = strs[i]; 84 str = strs[i];
85 if (!str)
86 continue;
84 if (len && len + strlen(str) + 2 > 80) { 87 if (len && len + strlen(str) + 2 > 80) {
85 printk("%s\n", buf); 88 printk("%s\n", buf);
86 len = 0; 89 len = 0;
@@ -243,7 +246,8 @@ static const char *cper_pcie_port_type_strs[] = {
243 "root complex event collector", 246 "root complex event collector",
244}; 247};
245 248
246static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie) 249static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
250 const struct acpi_hest_generic_data *gdata)
247{ 251{
248 if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) 252 if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
249 printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, 253 printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
@@ -276,6 +280,12 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie)
276 printk( 280 printk(
277 "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", 281 "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
278 pfx, pcie->bridge.secondary_status, pcie->bridge.control); 282 pfx, pcie->bridge.secondary_status, pcie->bridge.control);
283#ifdef CONFIG_ACPI_APEI_PCIEAER
284 if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) {
285 struct aer_capability_regs *aer_regs = (void *)pcie->aer_info;
286 cper_print_aer(pfx, gdata->error_severity, aer_regs);
287 }
288#endif
279} 289}
280 290
281static const char *apei_estatus_section_flag_strs[] = { 291static const char *apei_estatus_section_flag_strs[] = {
@@ -322,7 +332,7 @@ static void apei_estatus_print_section(
322 struct cper_sec_pcie *pcie = (void *)(gdata + 1); 332 struct cper_sec_pcie *pcie = (void *)(gdata + 1);
323 printk("%s""section_type: PCIe error\n", pfx); 333 printk("%s""section_type: PCIe error\n", pfx);
324 if (gdata->error_data_length >= sizeof(*pcie)) 334 if (gdata->error_data_length >= sizeof(*pcie))
325 cper_print_pcie(pfx, pcie); 335 cper_print_pcie(pfx, pcie, gdata);
326 else 336 else
327 goto err_section_too_small; 337 goto err_section_too_small;
328 } else 338 } else
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c
index de73caf3cebc..a4cfb64c86a1 100644
--- a/drivers/acpi/apei/erst-dbg.c
+++ b/drivers/acpi/apei/erst-dbg.c
@@ -43,12 +43,27 @@ static DEFINE_MUTEX(erst_dbg_mutex);
43 43
44static int erst_dbg_open(struct inode *inode, struct file *file) 44static int erst_dbg_open(struct inode *inode, struct file *file)
45{ 45{
46 int rc, *pos;
47
46 if (erst_disable) 48 if (erst_disable)
47 return -ENODEV; 49 return -ENODEV;
48 50
51 pos = (int *)&file->private_data;
52
53 rc = erst_get_record_id_begin(pos);
54 if (rc)
55 return rc;
56
49 return nonseekable_open(inode, file); 57 return nonseekable_open(inode, file);
50} 58}
51 59
60static int erst_dbg_release(struct inode *inode, struct file *file)
61{
62 erst_get_record_id_end();
63
64 return 0;
65}
66
52static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 67static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
53{ 68{
54 int rc; 69 int rc;
@@ -79,18 +94,20 @@ static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
79static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, 94static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf,
80 size_t usize, loff_t *off) 95 size_t usize, loff_t *off)
81{ 96{
82 int rc; 97 int rc, *pos;
83 ssize_t len = 0; 98 ssize_t len = 0;
84 u64 id; 99 u64 id;
85 100
86 if (*off != 0) 101 if (*off)
87 return -EINVAL; 102 return -EINVAL;
88 103
89 if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) 104 if (mutex_lock_interruptible(&erst_dbg_mutex) != 0)
90 return -EINTR; 105 return -EINTR;
91 106
107 pos = (int *)&filp->private_data;
108
92retry_next: 109retry_next:
93 rc = erst_get_next_record_id(&id); 110 rc = erst_get_record_id_next(pos, &id);
94 if (rc) 111 if (rc)
95 goto out; 112 goto out;
96 /* no more record */ 113 /* no more record */
@@ -181,6 +198,7 @@ out:
181static const struct file_operations erst_dbg_ops = { 198static const struct file_operations erst_dbg_ops = {
182 .owner = THIS_MODULE, 199 .owner = THIS_MODULE,
183 .open = erst_dbg_open, 200 .open = erst_dbg_open,
201 .release = erst_dbg_release,
184 .read = erst_dbg_read, 202 .read = erst_dbg_read,
185 .write = erst_dbg_write, 203 .write = erst_dbg_write,
186 .unlocked_ioctl = erst_dbg_ioctl, 204 .unlocked_ioctl = erst_dbg_ioctl,
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index c02005abce43..d6cb0ff6988e 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -430,6 +430,22 @@ ssize_t erst_get_record_count(void)
430} 430}
431EXPORT_SYMBOL_GPL(erst_get_record_count); 431EXPORT_SYMBOL_GPL(erst_get_record_count);
432 432
433#define ERST_RECORD_ID_CACHE_SIZE_MIN 16
434#define ERST_RECORD_ID_CACHE_SIZE_MAX 1024
435
436struct erst_record_id_cache {
437 struct mutex lock;
438 u64 *entries;
439 int len;
440 int size;
441 int refcount;
442};
443
444static struct erst_record_id_cache erst_record_id_cache = {
445 .lock = __MUTEX_INITIALIZER(erst_record_id_cache.lock),
446 .refcount = 0,
447};
448
433static int __erst_get_next_record_id(u64 *record_id) 449static int __erst_get_next_record_id(u64 *record_id)
434{ 450{
435 struct apei_exec_context ctx; 451 struct apei_exec_context ctx;
@@ -444,26 +460,179 @@ static int __erst_get_next_record_id(u64 *record_id)
444 return 0; 460 return 0;
445} 461}
446 462
463int erst_get_record_id_begin(int *pos)
464{
465 int rc;
466
467 if (erst_disable)
468 return -ENODEV;
469
470 rc = mutex_lock_interruptible(&erst_record_id_cache.lock);
471 if (rc)
472 return rc;
473 erst_record_id_cache.refcount++;
474 mutex_unlock(&erst_record_id_cache.lock);
475
476 *pos = 0;
477
478 return 0;
479}
480EXPORT_SYMBOL_GPL(erst_get_record_id_begin);
481
482/* erst_record_id_cache.lock must be held by caller */
483static int __erst_record_id_cache_add_one(void)
484{
485 u64 id, prev_id, first_id;
486 int i, rc;
487 u64 *entries;
488 unsigned long flags;
489
490 id = prev_id = first_id = APEI_ERST_INVALID_RECORD_ID;
491retry:
492 raw_spin_lock_irqsave(&erst_lock, flags);
493 rc = __erst_get_next_record_id(&id);
494 raw_spin_unlock_irqrestore(&erst_lock, flags);
495 if (rc == -ENOENT)
496 return 0;
497 if (rc)
498 return rc;
499 if (id == APEI_ERST_INVALID_RECORD_ID)
500 return 0;
501 /* can not skip current ID, or loop back to first ID */
502 if (id == prev_id || id == first_id)
503 return 0;
504 if (first_id == APEI_ERST_INVALID_RECORD_ID)
505 first_id = id;
506 prev_id = id;
507
508 entries = erst_record_id_cache.entries;
509 for (i = 0; i < erst_record_id_cache.len; i++) {
510 if (entries[i] == id)
511 break;
512 }
513 /* record id already in cache, try next */
514 if (i < erst_record_id_cache.len)
515 goto retry;
516 if (erst_record_id_cache.len >= erst_record_id_cache.size) {
517 int new_size, alloc_size;
518 u64 *new_entries;
519
520 new_size = erst_record_id_cache.size * 2;
521 new_size = clamp_val(new_size, ERST_RECORD_ID_CACHE_SIZE_MIN,
522 ERST_RECORD_ID_CACHE_SIZE_MAX);
523 if (new_size <= erst_record_id_cache.size) {
524 if (printk_ratelimit())
525 pr_warning(FW_WARN ERST_PFX
526 "too many record ID!\n");
527 return 0;
528 }
529 alloc_size = new_size * sizeof(entries[0]);
530 if (alloc_size < PAGE_SIZE)
531 new_entries = kmalloc(alloc_size, GFP_KERNEL);
532 else
533 new_entries = vmalloc(alloc_size);
534 if (!new_entries)
535 return -ENOMEM;
536 memcpy(new_entries, entries,
537 erst_record_id_cache.len * sizeof(entries[0]));
538 if (erst_record_id_cache.size < PAGE_SIZE)
539 kfree(entries);
540 else
541 vfree(entries);
542 erst_record_id_cache.entries = entries = new_entries;
543 erst_record_id_cache.size = new_size;
544 }
545 entries[i] = id;
546 erst_record_id_cache.len++;
547
548 return 1;
549}
550
447/* 551/*
448 * Get the record ID of an existing error record on the persistent 552 * Get the record ID of an existing error record on the persistent
449 * storage. If there is no error record on the persistent storage, the 553 * storage. If there is no error record on the persistent storage, the
450 * returned record_id is APEI_ERST_INVALID_RECORD_ID. 554 * returned record_id is APEI_ERST_INVALID_RECORD_ID.
451 */ 555 */
452int erst_get_next_record_id(u64 *record_id) 556int erst_get_record_id_next(int *pos, u64 *record_id)
453{ 557{
454 int rc; 558 int rc = 0;
455 unsigned long flags; 559 u64 *entries;
456 560
457 if (erst_disable) 561 if (erst_disable)
458 return -ENODEV; 562 return -ENODEV;
459 563
460 raw_spin_lock_irqsave(&erst_lock, flags); 564 /* must be enclosed by erst_get_record_id_begin/end */
461 rc = __erst_get_next_record_id(record_id); 565 BUG_ON(!erst_record_id_cache.refcount);
462 raw_spin_unlock_irqrestore(&erst_lock, flags); 566 BUG_ON(*pos < 0 || *pos > erst_record_id_cache.len);
567
568 mutex_lock(&erst_record_id_cache.lock);
569 entries = erst_record_id_cache.entries;
570 for (; *pos < erst_record_id_cache.len; (*pos)++)
571 if (entries[*pos] != APEI_ERST_INVALID_RECORD_ID)
572 break;
573 /* found next record id in cache */
574 if (*pos < erst_record_id_cache.len) {
575 *record_id = entries[*pos];
576 (*pos)++;
577 goto out_unlock;
578 }
579
580 /* Try to add one more record ID to cache */
581 rc = __erst_record_id_cache_add_one();
582 if (rc < 0)
583 goto out_unlock;
584 /* successfully add one new ID */
585 if (rc == 1) {
586 *record_id = erst_record_id_cache.entries[*pos];
587 (*pos)++;
588 rc = 0;
589 } else {
590 *pos = -1;
591 *record_id = APEI_ERST_INVALID_RECORD_ID;
592 }
593out_unlock:
594 mutex_unlock(&erst_record_id_cache.lock);
463 595
464 return rc; 596 return rc;
465} 597}
466EXPORT_SYMBOL_GPL(erst_get_next_record_id); 598EXPORT_SYMBOL_GPL(erst_get_record_id_next);
599
600/* erst_record_id_cache.lock must be held by caller */
601static void __erst_record_id_cache_compact(void)
602{
603 int i, wpos = 0;
604 u64 *entries;
605
606 if (erst_record_id_cache.refcount)
607 return;
608
609 entries = erst_record_id_cache.entries;
610 for (i = 0; i < erst_record_id_cache.len; i++) {
611 if (entries[i] == APEI_ERST_INVALID_RECORD_ID)
612 continue;
613 if (wpos != i)
614 memcpy(&entries[wpos], &entries[i], sizeof(entries[i]));
615 wpos++;
616 }
617 erst_record_id_cache.len = wpos;
618}
619
620void erst_get_record_id_end(void)
621{
622 /*
623 * erst_disable != 0 should be detected by invoker via the
624 * return value of erst_get_record_id_begin/next, so this
625 * function should not be called for erst_disable != 0.
626 */
627 BUG_ON(erst_disable);
628
629 mutex_lock(&erst_record_id_cache.lock);
630 erst_record_id_cache.refcount--;
631 BUG_ON(erst_record_id_cache.refcount < 0);
632 __erst_record_id_cache_compact();
633 mutex_unlock(&erst_record_id_cache.lock);
634}
635EXPORT_SYMBOL_GPL(erst_get_record_id_end);
467 636
468static int __erst_write_to_storage(u64 offset) 637static int __erst_write_to_storage(u64 offset)
469{ 638{
@@ -704,56 +873,34 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
704} 873}
705EXPORT_SYMBOL_GPL(erst_read); 874EXPORT_SYMBOL_GPL(erst_read);
706 875
707/*
708 * If return value > buflen, the buffer size is not big enough,
709 * else if return value = 0, there is no more record to read,
710 * else if return value < 0, something goes wrong,
711 * else everything is OK, and return value is record length
712 */
713ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
714{
715 int rc;
716 ssize_t len;
717 unsigned long flags;
718 u64 record_id;
719
720 if (erst_disable)
721 return -ENODEV;
722
723 raw_spin_lock_irqsave(&erst_lock, flags);
724 rc = __erst_get_next_record_id(&record_id);
725 if (rc) {
726 raw_spin_unlock_irqrestore(&erst_lock, flags);
727 return rc;
728 }
729 /* no more record */
730 if (record_id == APEI_ERST_INVALID_RECORD_ID) {
731 raw_spin_unlock_irqrestore(&erst_lock, flags);
732 return 0;
733 }
734
735 len = __erst_read(record_id, record, buflen);
736 raw_spin_unlock_irqrestore(&erst_lock, flags);
737
738 return len;
739}
740EXPORT_SYMBOL_GPL(erst_read_next);
741
742int erst_clear(u64 record_id) 876int erst_clear(u64 record_id)
743{ 877{
744 int rc; 878 int rc, i;
745 unsigned long flags; 879 unsigned long flags;
880 u64 *entries;
746 881
747 if (erst_disable) 882 if (erst_disable)
748 return -ENODEV; 883 return -ENODEV;
749 884
885 rc = mutex_lock_interruptible(&erst_record_id_cache.lock);
886 if (rc)
887 return rc;
750 raw_spin_lock_irqsave(&erst_lock, flags); 888 raw_spin_lock_irqsave(&erst_lock, flags);
751 if (erst_erange.attr & ERST_RANGE_NVRAM) 889 if (erst_erange.attr & ERST_RANGE_NVRAM)
752 rc = __erst_clear_from_nvram(record_id); 890 rc = __erst_clear_from_nvram(record_id);
753 else 891 else
754 rc = __erst_clear_from_storage(record_id); 892 rc = __erst_clear_from_storage(record_id);
755 raw_spin_unlock_irqrestore(&erst_lock, flags); 893 raw_spin_unlock_irqrestore(&erst_lock, flags);
756 894 if (rc)
895 goto out;
896 entries = erst_record_id_cache.entries;
897 for (i = 0; i < erst_record_id_cache.len; i++) {
898 if (entries[i] == record_id)
899 entries[i] = APEI_ERST_INVALID_RECORD_ID;
900 }
901 __erst_record_id_cache_compact();
902out:
903 mutex_unlock(&erst_record_id_cache.lock);
757 return rc; 904 return rc;
758} 905}
759EXPORT_SYMBOL_GPL(erst_clear); 906EXPORT_SYMBOL_GPL(erst_clear);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index ac1a599f5147..fcc13ac0aa18 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -33,6 +33,7 @@
33#include <linux/async.h> 33#include <linux/async.h>
34#include <linux/dmi.h> 34#include <linux/dmi.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/suspend.h>
36 37
37#ifdef CONFIG_ACPI_PROCFS_POWER 38#ifdef CONFIG_ACPI_PROCFS_POWER
38#include <linux/proc_fs.h> 39#include <linux/proc_fs.h>
@@ -102,6 +103,7 @@ struct acpi_battery {
102 struct mutex lock; 103 struct mutex lock;
103 struct power_supply bat; 104 struct power_supply bat;
104 struct acpi_device *device; 105 struct acpi_device *device;
106 struct notifier_block pm_nb;
105 unsigned long update_time; 107 unsigned long update_time;
106 int rate_now; 108 int rate_now;
107 int capacity_now; 109 int capacity_now;
@@ -940,6 +942,21 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
940 power_supply_changed(&battery->bat); 942 power_supply_changed(&battery->bat);
941} 943}
942 944
945static int battery_notify(struct notifier_block *nb,
946 unsigned long mode, void *_unused)
947{
948 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
949 pm_nb);
950 switch (mode) {
951 case PM_POST_SUSPEND:
952 sysfs_remove_battery(battery);
953 sysfs_add_battery(battery);
954 break;
955 }
956
957 return 0;
958}
959
943static int acpi_battery_add(struct acpi_device *device) 960static int acpi_battery_add(struct acpi_device *device)
944{ 961{
945 int result = 0; 962 int result = 0;
@@ -972,6 +989,10 @@ static int acpi_battery_add(struct acpi_device *device)
972#endif 989#endif
973 kfree(battery); 990 kfree(battery);
974 } 991 }
992
993 battery->pm_nb.notifier_call = battery_notify;
994 register_pm_notifier(&battery->pm_nb);
995
975 return result; 996 return result;
976} 997}
977 998
@@ -982,6 +1003,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
982 if (!device || !acpi_driver_data(device)) 1003 if (!device || !acpi_driver_data(device))
983 return -EINVAL; 1004 return -EINVAL;
984 battery = acpi_driver_data(device); 1005 battery = acpi_driver_data(device);
1006 unregister_pm_notifier(&battery->pm_nb);
985#ifdef CONFIG_ACPI_PROCFS_POWER 1007#ifdef CONFIG_ACPI_PROCFS_POWER
986 acpi_battery_remove_fs(device); 1008 acpi_battery_remove_fs(device);
987#endif 1009#endif
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 76bbb78a5ad9..d27d072472f9 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -78,8 +78,6 @@ static int acpi_button_add(struct acpi_device *device);
78static int acpi_button_remove(struct acpi_device *device, int type); 78static int acpi_button_remove(struct acpi_device *device, int type);
79static int acpi_button_resume(struct acpi_device *device); 79static int acpi_button_resume(struct acpi_device *device);
80static void acpi_button_notify(struct acpi_device *device, u32 event); 80static void acpi_button_notify(struct acpi_device *device, u32 event);
81static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
82static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
83 81
84static struct acpi_driver acpi_button_driver = { 82static struct acpi_driver acpi_button_driver = {
85 .name = "button", 83 .name = "button",
@@ -98,22 +96,7 @@ struct acpi_button {
98 struct input_dev *input; 96 struct input_dev *input;
99 char phys[32]; /* for input device */ 97 char phys[32]; /* for input device */
100 unsigned long pushed; 98 unsigned long pushed;
101}; 99 bool wakeup_enabled;
102
103static const struct file_operations acpi_button_info_fops = {
104 .owner = THIS_MODULE,
105 .open = acpi_button_info_open_fs,
106 .read = seq_read,
107 .llseek = seq_lseek,
108 .release = single_release,
109};
110
111static const struct file_operations acpi_button_state_fops = {
112 .owner = THIS_MODULE,
113 .open = acpi_button_state_open_fs,
114 .read = seq_read,
115 .llseek = seq_lseek,
116 .release = single_release,
117}; 100};
118 101
119static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); 102static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
@@ -124,20 +107,7 @@ static struct acpi_device *lid_device;
124 -------------------------------------------------------------------------- */ 107 -------------------------------------------------------------------------- */
125 108
126static struct proc_dir_entry *acpi_button_dir; 109static struct proc_dir_entry *acpi_button_dir;
127 110static struct proc_dir_entry *acpi_lid_dir;
128static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
129{
130 struct acpi_device *device = seq->private;
131
132 seq_printf(seq, "type: %s\n",
133 acpi_device_name(device));
134 return 0;
135}
136
137static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
138{
139 return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
140}
141 111
142static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) 112static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
143{ 113{
@@ -157,77 +127,85 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
157 return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); 127 return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
158} 128}
159 129
160static struct proc_dir_entry *acpi_power_dir; 130static const struct file_operations acpi_button_state_fops = {
161static struct proc_dir_entry *acpi_sleep_dir; 131 .owner = THIS_MODULE,
162static struct proc_dir_entry *acpi_lid_dir; 132 .open = acpi_button_state_open_fs,
133 .read = seq_read,
134 .llseek = seq_lseek,
135 .release = single_release,
136};
163 137
164static int acpi_button_add_fs(struct acpi_device *device) 138static int acpi_button_add_fs(struct acpi_device *device)
165{ 139{
166 struct acpi_button *button = acpi_driver_data(device); 140 struct acpi_button *button = acpi_driver_data(device);
167 struct proc_dir_entry *entry = NULL; 141 struct proc_dir_entry *entry = NULL;
142 int ret = 0;
168 143
169 switch (button->type) { 144 /* procfs I/F for ACPI lid device only */
170 case ACPI_BUTTON_TYPE_POWER: 145 if (button->type != ACPI_BUTTON_TYPE_LID)
171 if (!acpi_power_dir) 146 return 0;
172 acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 147
173 acpi_button_dir); 148 if (acpi_button_dir || acpi_lid_dir) {
174 entry = acpi_power_dir; 149 printk(KERN_ERR PREFIX "More than one Lid device found!\n");
175 break; 150 return -EEXIST;
176 case ACPI_BUTTON_TYPE_SLEEP:
177 if (!acpi_sleep_dir)
178 acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
179 acpi_button_dir);
180 entry = acpi_sleep_dir;
181 break;
182 case ACPI_BUTTON_TYPE_LID:
183 if (!acpi_lid_dir)
184 acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,
185 acpi_button_dir);
186 entry = acpi_lid_dir;
187 break;
188 } 151 }
189 152
190 if (!entry) 153 /* create /proc/acpi/button */
154 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
155 if (!acpi_button_dir)
191 return -ENODEV; 156 return -ENODEV;
192 157
193 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); 158 /* create /proc/acpi/button/lid */
194 if (!acpi_device_dir(device)) 159 acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
195 return -ENODEV; 160 if (!acpi_lid_dir) {
161 ret = -ENODEV;
162 goto remove_button_dir;
163 }
196 164
197 /* 'info' [R] */ 165 /* create /proc/acpi/button/lid/LID/ */
198 entry = proc_create_data(ACPI_BUTTON_FILE_INFO, 166 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir);
199 S_IRUGO, acpi_device_dir(device), 167 if (!acpi_device_dir(device)) {
200 &acpi_button_info_fops, device); 168 ret = -ENODEV;
201 if (!entry) 169 goto remove_lid_dir;
202 return -ENODEV; 170 }
203 171
204 /* show lid state [R] */ 172 /* create /proc/acpi/button/lid/LID/state */
205 if (button->type == ACPI_BUTTON_TYPE_LID) { 173 entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
206 entry = proc_create_data(ACPI_BUTTON_FILE_STATE, 174 S_IRUGO, acpi_device_dir(device),
207 S_IRUGO, acpi_device_dir(device), 175 &acpi_button_state_fops, device);
208 &acpi_button_state_fops, device); 176 if (!entry) {
209 if (!entry) 177 ret = -ENODEV;
210 return -ENODEV; 178 goto remove_dev_dir;
211 } 179 }
212 180
213 return 0; 181done:
182 return ret;
183
184remove_dev_dir:
185 remove_proc_entry(acpi_device_bid(device),
186 acpi_lid_dir);
187 acpi_device_dir(device) = NULL;
188remove_lid_dir:
189 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
190remove_button_dir:
191 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
192 goto done;
214} 193}
215 194
216static int acpi_button_remove_fs(struct acpi_device *device) 195static int acpi_button_remove_fs(struct acpi_device *device)
217{ 196{
218 struct acpi_button *button = acpi_driver_data(device); 197 struct acpi_button *button = acpi_driver_data(device);
219 198
220 if (acpi_device_dir(device)) { 199 if (button->type != ACPI_BUTTON_TYPE_LID)
221 if (button->type == ACPI_BUTTON_TYPE_LID) 200 return 0;
222 remove_proc_entry(ACPI_BUTTON_FILE_STATE,
223 acpi_device_dir(device));
224 remove_proc_entry(ACPI_BUTTON_FILE_INFO,
225 acpi_device_dir(device));
226 201
227 remove_proc_entry(acpi_device_bid(device), 202 remove_proc_entry(ACPI_BUTTON_FILE_STATE,
228 acpi_device_dir(device)->parent); 203 acpi_device_dir(device));
229 acpi_device_dir(device) = NULL; 204 remove_proc_entry(acpi_device_bid(device),
230 } 205 acpi_lid_dir);
206 acpi_device_dir(device) = NULL;
207 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
208 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
231 209
232 return 0; 210 return 0;
233} 211}
@@ -430,8 +408,10 @@ static int acpi_button_add(struct acpi_device *device)
430 /* Button's GPE is run-wake GPE */ 408 /* Button's GPE is run-wake GPE */
431 acpi_enable_gpe(device->wakeup.gpe_device, 409 acpi_enable_gpe(device->wakeup.gpe_device,
432 device->wakeup.gpe_number); 410 device->wakeup.gpe_number);
433 device->wakeup.run_wake_count++; 411 if (!device_may_wakeup(&device->dev)) {
434 device_set_wakeup_enable(&device->dev, true); 412 device_set_wakeup_enable(&device->dev, true);
413 button->wakeup_enabled = true;
414 }
435 } 415 }
436 416
437 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); 417 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
@@ -453,8 +433,8 @@ static int acpi_button_remove(struct acpi_device *device, int type)
453 if (device->wakeup.flags.valid) { 433 if (device->wakeup.flags.valid) {
454 acpi_disable_gpe(device->wakeup.gpe_device, 434 acpi_disable_gpe(device->wakeup.gpe_device,
455 device->wakeup.gpe_number); 435 device->wakeup.gpe_number);
456 device->wakeup.run_wake_count--; 436 if (button->wakeup_enabled)
457 device_set_wakeup_enable(&device->dev, false); 437 device_set_wakeup_enable(&device->dev, false);
458 } 438 }
459 439
460 acpi_button_remove_fs(device); 440 acpi_button_remove_fs(device);
@@ -465,32 +445,12 @@ static int acpi_button_remove(struct acpi_device *device, int type)
465 445
466static int __init acpi_button_init(void) 446static int __init acpi_button_init(void)
467{ 447{
468 int result; 448 return acpi_bus_register_driver(&acpi_button_driver);
469
470 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
471 if (!acpi_button_dir)
472 return -ENODEV;
473
474 result = acpi_bus_register_driver(&acpi_button_driver);
475 if (result < 0) {
476 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
477 return -ENODEV;
478 }
479
480 return 0;
481} 449}
482 450
483static void __exit acpi_button_exit(void) 451static void __exit acpi_button_exit(void)
484{ 452{
485 acpi_bus_unregister_driver(&acpi_button_driver); 453 acpi_bus_unregister_driver(&acpi_button_driver);
486
487 if (acpi_power_dir)
488 remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir);
489 if (acpi_sleep_dir)
490 remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir);
491 if (acpi_lid_dir)
492 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
493 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
494} 454}
495 455
496module_init(acpi_button_init); 456module_init(acpi_button_init);
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
index 411620ef84c2..05b44201a614 100644
--- a/drivers/acpi/ec_sys.c
+++ b/drivers/acpi/ec_sys.c
@@ -24,10 +24,6 @@ MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may "
24 24
25#define EC_SPACE_SIZE 256 25#define EC_SPACE_SIZE 256
26 26
27struct sysdev_class acpi_ec_sysdev_class = {
28 .name = "ec",
29};
30
31static struct dentry *acpi_ec_debugfs_dir; 27static struct dentry *acpi_ec_debugfs_dir;
32 28
33static int acpi_ec_open_io(struct inode *i, struct file *f) 29static int acpi_ec_open_io(struct inode *i, struct file *f)
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index b1cc81a0431b..4bfb759deb10 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -21,8 +21,6 @@
21#ifndef _ACPI_INTERNAL_H_ 21#ifndef _ACPI_INTERNAL_H_
22#define _ACPI_INTERNAL_H_ 22#define _ACPI_INTERNAL_H_
23 23
24#include <linux/sysdev.h>
25
26#define PREFIX "ACPI: " 24#define PREFIX "ACPI: "
27 25
28int init_acpi_device_notify(void); 26int init_acpi_device_notify(void);
@@ -64,7 +62,6 @@ struct acpi_ec {
64 struct list_head list; 62 struct list_head list;
65 struct transaction *curr; 63 struct transaction *curr;
66 spinlock_t curr_lock; 64 spinlock_t curr_lock;
67 struct sys_device sysdev;
68}; 65};
69 66
70extern struct acpi_ec *first_ec; 67extern struct acpi_ec *first_ec;
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
index fa5a1df42b79..096787b43c96 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -26,6 +26,7 @@ struct nvs_page {
26 unsigned int size; 26 unsigned int size;
27 void *kaddr; 27 void *kaddr;
28 void *data; 28 void *data;
29 bool unmap;
29 struct list_head node; 30 struct list_head node;
30}; 31};
31 32
@@ -44,6 +45,9 @@ int suspend_nvs_register(unsigned long start, unsigned long size)
44{ 45{
45 struct nvs_page *entry, *next; 46 struct nvs_page *entry, *next;
46 47
48 pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
49 start, size);
50
47 while (size > 0) { 51 while (size > 0) {
48 unsigned int nr_bytes; 52 unsigned int nr_bytes;
49 53
@@ -81,7 +85,13 @@ void suspend_nvs_free(void)
81 free_page((unsigned long)entry->data); 85 free_page((unsigned long)entry->data);
82 entry->data = NULL; 86 entry->data = NULL;
83 if (entry->kaddr) { 87 if (entry->kaddr) {
84 iounmap(entry->kaddr); 88 if (entry->unmap) {
89 iounmap(entry->kaddr);
90 entry->unmap = false;
91 } else {
92 acpi_os_unmap_memory(entry->kaddr,
93 entry->size);
94 }
85 entry->kaddr = NULL; 95 entry->kaddr = NULL;
86 } 96 }
87 } 97 }
@@ -115,8 +125,14 @@ int suspend_nvs_save(void)
115 125
116 list_for_each_entry(entry, &nvs_list, node) 126 list_for_each_entry(entry, &nvs_list, node)
117 if (entry->data) { 127 if (entry->data) {
118 entry->kaddr = acpi_os_ioremap(entry->phys_start, 128 unsigned long phys = entry->phys_start;
119 entry->size); 129 unsigned int size = entry->size;
130
131 entry->kaddr = acpi_os_get_iomem(phys, size);
132 if (!entry->kaddr) {
133 entry->kaddr = acpi_os_ioremap(phys, size);
134 entry->unmap = !!entry->kaddr;
135 }
120 if (!entry->kaddr) { 136 if (!entry->kaddr) {
121 suspend_nvs_free(); 137 suspend_nvs_free();
122 return -ENOMEM; 138 return -ENOMEM;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 4a6753009d79..45ad4ffef533 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -76,7 +76,6 @@ EXPORT_SYMBOL(acpi_in_debugger);
76extern char line_buf[80]; 76extern char line_buf[80];
77#endif /*ENABLE_DEBUGGER */ 77#endif /*ENABLE_DEBUGGER */
78 78
79static unsigned int acpi_irq_irq;
80static acpi_osd_handler acpi_irq_handler; 79static acpi_osd_handler acpi_irq_handler;
81static void *acpi_irq_context; 80static void *acpi_irq_context;
82static struct workqueue_struct *kacpid_wq; 81static struct workqueue_struct *kacpid_wq;
@@ -105,11 +104,11 @@ struct acpi_ioremap {
105 void __iomem *virt; 104 void __iomem *virt;
106 acpi_physical_address phys; 105 acpi_physical_address phys;
107 acpi_size size; 106 acpi_size size;
108 struct kref ref; 107 unsigned long refcount;
109}; 108};
110 109
111static LIST_HEAD(acpi_ioremaps); 110static LIST_HEAD(acpi_ioremaps);
112static DEFINE_SPINLOCK(acpi_ioremap_lock); 111static DEFINE_MUTEX(acpi_ioremap_lock);
113 112
114static void __init acpi_osi_setup_late(void); 113static void __init acpi_osi_setup_late(void);
115 114
@@ -285,6 +284,22 @@ acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
285 return NULL; 284 return NULL;
286} 285}
287 286
287void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
288{
289 struct acpi_ioremap *map;
290 void __iomem *virt = NULL;
291
292 mutex_lock(&acpi_ioremap_lock);
293 map = acpi_map_lookup(phys, size);
294 if (map) {
295 virt = map->virt + (phys - map->phys);
296 map->refcount++;
297 }
298 mutex_unlock(&acpi_ioremap_lock);
299 return virt;
300}
301EXPORT_SYMBOL_GPL(acpi_os_get_iomem);
302
288/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ 303/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
289static struct acpi_ioremap * 304static struct acpi_ioremap *
290acpi_map_lookup_virt(void __iomem *virt, acpi_size size) 305acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
@@ -302,8 +317,7 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
302void __iomem *__init_refok 317void __iomem *__init_refok
303acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 318acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
304{ 319{
305 struct acpi_ioremap *map, *tmp_map; 320 struct acpi_ioremap *map;
306 unsigned long flags;
307 void __iomem *virt; 321 void __iomem *virt;
308 acpi_physical_address pg_off; 322 acpi_physical_address pg_off;
309 acpi_size pg_sz; 323 acpi_size pg_sz;
@@ -316,14 +330,25 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
316 if (!acpi_gbl_permanent_mmap) 330 if (!acpi_gbl_permanent_mmap)
317 return __acpi_map_table((unsigned long)phys, size); 331 return __acpi_map_table((unsigned long)phys, size);
318 332
333 mutex_lock(&acpi_ioremap_lock);
334 /* Check if there's a suitable mapping already. */
335 map = acpi_map_lookup(phys, size);
336 if (map) {
337 map->refcount++;
338 goto out;
339 }
340
319 map = kzalloc(sizeof(*map), GFP_KERNEL); 341 map = kzalloc(sizeof(*map), GFP_KERNEL);
320 if (!map) 342 if (!map) {
343 mutex_unlock(&acpi_ioremap_lock);
321 return NULL; 344 return NULL;
345 }
322 346
323 pg_off = round_down(phys, PAGE_SIZE); 347 pg_off = round_down(phys, PAGE_SIZE);
324 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; 348 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
325 virt = acpi_os_ioremap(pg_off, pg_sz); 349 virt = acpi_os_ioremap(pg_off, pg_sz);
326 if (!virt) { 350 if (!virt) {
351 mutex_unlock(&acpi_ioremap_lock);
327 kfree(map); 352 kfree(map);
328 return NULL; 353 return NULL;
329 } 354 }
@@ -332,62 +357,51 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
332 map->virt = virt; 357 map->virt = virt;
333 map->phys = pg_off; 358 map->phys = pg_off;
334 map->size = pg_sz; 359 map->size = pg_sz;
335 kref_init(&map->ref); 360 map->refcount = 1;
336 361
337 spin_lock_irqsave(&acpi_ioremap_lock, flags);
338 /* Check if page has already been mapped. */
339 tmp_map = acpi_map_lookup(phys, size);
340 if (tmp_map) {
341 kref_get(&tmp_map->ref);
342 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
343 iounmap(map->virt);
344 kfree(map);
345 return tmp_map->virt + (phys - tmp_map->phys);
346 }
347 list_add_tail_rcu(&map->list, &acpi_ioremaps); 362 list_add_tail_rcu(&map->list, &acpi_ioremaps);
348 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
349 363
364 out:
365 mutex_unlock(&acpi_ioremap_lock);
350 return map->virt + (phys - map->phys); 366 return map->virt + (phys - map->phys);
351} 367}
352EXPORT_SYMBOL_GPL(acpi_os_map_memory); 368EXPORT_SYMBOL_GPL(acpi_os_map_memory);
353 369
354static void acpi_kref_del_iomap(struct kref *ref) 370static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
355{ 371{
356 struct acpi_ioremap *map; 372 if (!--map->refcount)
373 list_del_rcu(&map->list);
374}
357 375
358 map = container_of(ref, struct acpi_ioremap, ref); 376static void acpi_os_map_cleanup(struct acpi_ioremap *map)
359 list_del_rcu(&map->list); 377{
378 if (!map->refcount) {
379 synchronize_rcu();
380 iounmap(map->virt);
381 kfree(map);
382 }
360} 383}
361 384
362void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) 385void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
363{ 386{
364 struct acpi_ioremap *map; 387 struct acpi_ioremap *map;
365 unsigned long flags;
366 int del;
367 388
368 if (!acpi_gbl_permanent_mmap) { 389 if (!acpi_gbl_permanent_mmap) {
369 __acpi_unmap_table(virt, size); 390 __acpi_unmap_table(virt, size);
370 return; 391 return;
371 } 392 }
372 393
373 spin_lock_irqsave(&acpi_ioremap_lock, flags); 394 mutex_lock(&acpi_ioremap_lock);
374 map = acpi_map_lookup_virt(virt, size); 395 map = acpi_map_lookup_virt(virt, size);
375 if (!map) { 396 if (!map) {
376 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 397 mutex_unlock(&acpi_ioremap_lock);
377 printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt); 398 WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
378 dump_stack();
379 return; 399 return;
380 } 400 }
401 acpi_os_drop_map_ref(map);
402 mutex_unlock(&acpi_ioremap_lock);
381 403
382 del = kref_put(&map->ref, acpi_kref_del_iomap); 404 acpi_os_map_cleanup(map);
383 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
384
385 if (!del)
386 return;
387
388 synchronize_rcu();
389 iounmap(map->virt);
390 kfree(map);
391} 405}
392EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); 406EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
393 407
@@ -397,7 +411,7 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
397 __acpi_unmap_table(virt, size); 411 __acpi_unmap_table(virt, size);
398} 412}
399 413
400int acpi_os_map_generic_address(struct acpi_generic_address *addr) 414static int acpi_os_map_generic_address(struct acpi_generic_address *addr)
401{ 415{
402 void __iomem *virt; 416 void __iomem *virt;
403 417
@@ -413,13 +427,10 @@ int acpi_os_map_generic_address(struct acpi_generic_address *addr)
413 427
414 return 0; 428 return 0;
415} 429}
416EXPORT_SYMBOL_GPL(acpi_os_map_generic_address);
417 430
418void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) 431static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
419{ 432{
420 void __iomem *virt; 433 struct acpi_ioremap *map;
421 unsigned long flags;
422 acpi_size size = addr->bit_width / 8;
423 434
424 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) 435 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
425 return; 436 return;
@@ -427,13 +438,17 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
427 if (!addr->address || !addr->bit_width) 438 if (!addr->address || !addr->bit_width)
428 return; 439 return;
429 440
430 spin_lock_irqsave(&acpi_ioremap_lock, flags); 441 mutex_lock(&acpi_ioremap_lock);
431 virt = acpi_map_vaddr_lookup(addr->address, size); 442 map = acpi_map_lookup(addr->address, addr->bit_width / 8);
432 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 443 if (!map) {
444 mutex_unlock(&acpi_ioremap_lock);
445 return;
446 }
447 acpi_os_drop_map_ref(map);
448 mutex_unlock(&acpi_ioremap_lock);
433 449
434 acpi_os_unmap_memory(virt, size); 450 acpi_os_map_cleanup(map);
435} 451}
436EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address);
437 452
438#ifdef ACPI_FUTURE_USAGE 453#ifdef ACPI_FUTURE_USAGE
439acpi_status 454acpi_status
@@ -516,11 +531,15 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
516 acpi_irq_stats_init(); 531 acpi_irq_stats_init();
517 532
518 /* 533 /*
519 * Ignore the GSI from the core, and use the value in our copy of the 534 * ACPI interrupts different from the SCI in our copy of the FADT are
520 * FADT. It may not be the same if an interrupt source override exists 535 * not supported.
521 * for the SCI.
522 */ 536 */
523 gsi = acpi_gbl_FADT.sci_interrupt; 537 if (gsi != acpi_gbl_FADT.sci_interrupt)
538 return AE_BAD_PARAMETER;
539
540 if (acpi_irq_handler)
541 return AE_ALREADY_ACQUIRED;
542
524 if (acpi_gsi_to_irq(gsi, &irq) < 0) { 543 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
525 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", 544 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
526 gsi); 545 gsi);
@@ -531,20 +550,20 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
531 acpi_irq_context = context; 550 acpi_irq_context = context;
532 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { 551 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
533 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); 552 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
553 acpi_irq_handler = NULL;
534 return AE_NOT_ACQUIRED; 554 return AE_NOT_ACQUIRED;
535 } 555 }
536 acpi_irq_irq = irq;
537 556
538 return AE_OK; 557 return AE_OK;
539} 558}
540 559
541acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) 560acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
542{ 561{
543 if (irq) { 562 if (irq != acpi_gbl_FADT.sci_interrupt)
544 free_irq(irq, acpi_irq); 563 return AE_BAD_PARAMETER;
545 acpi_irq_handler = NULL; 564
546 acpi_irq_irq = 0; 565 free_irq(irq, acpi_irq);
547 } 566 acpi_irq_handler = NULL;
548 567
549 return AE_OK; 568 return AE_OK;
550} 569}
@@ -1603,7 +1622,7 @@ acpi_status __init acpi_os_initialize1(void)
1603acpi_status acpi_os_terminate(void) 1622acpi_status acpi_os_terminate(void)
1604{ 1623{
1605 if (acpi_irq_handler) { 1624 if (acpi_irq_handler) {
1606 acpi_os_remove_interrupt_handler(acpi_irq_irq, 1625 acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt,
1607 acpi_irq_handler); 1626 acpi_irq_handler);
1608 } 1627 }
1609 1628
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 9ff80a7e9f6a..4a29763b8eb4 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -29,7 +29,7 @@
29 * for IRQ management (e.g. start()->_SRS). 29 * for IRQ management (e.g. start()->_SRS).
30 */ 30 */
31 31
32#include <linux/sysdev.h> 32#include <linux/syscore_ops.h>
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/init.h> 35#include <linux/init.h>
@@ -757,14 +757,13 @@ static int acpi_pci_link_resume(struct acpi_pci_link *link)
757 return 0; 757 return 0;
758} 758}
759 759
760static int irqrouter_resume(struct sys_device *dev) 760static void irqrouter_resume(void)
761{ 761{
762 struct acpi_pci_link *link; 762 struct acpi_pci_link *link;
763 763
764 list_for_each_entry(link, &acpi_link_list, list) { 764 list_for_each_entry(link, &acpi_link_list, list) {
765 acpi_pci_link_resume(link); 765 acpi_pci_link_resume(link);
766 } 766 }
767 return 0;
768} 767}
769 768
770static int acpi_pci_link_remove(struct acpi_device *device, int type) 769static int acpi_pci_link_remove(struct acpi_device *device, int type)
@@ -871,32 +870,19 @@ static int __init acpi_irq_balance_set(char *str)
871 870
872__setup("acpi_irq_balance", acpi_irq_balance_set); 871__setup("acpi_irq_balance", acpi_irq_balance_set);
873 872
874/* FIXME: we will remove this interface after all drivers call pci_disable_device */ 873static struct syscore_ops irqrouter_syscore_ops = {
875static struct sysdev_class irqrouter_sysdev_class = {
876 .name = "irqrouter",
877 .resume = irqrouter_resume, 874 .resume = irqrouter_resume,
878}; 875};
879 876
880static struct sys_device device_irqrouter = { 877static int __init irqrouter_init_ops(void)
881 .id = 0,
882 .cls = &irqrouter_sysdev_class,
883};
884
885static int __init irqrouter_init_sysfs(void)
886{ 878{
887 int error; 879 if (!acpi_disabled && !acpi_noirq)
880 register_syscore_ops(&irqrouter_syscore_ops);
888 881
889 if (acpi_disabled || acpi_noirq) 882 return 0;
890 return 0;
891
892 error = sysdev_class_register(&irqrouter_sysdev_class);
893 if (!error)
894 error = sysdev_register(&device_irqrouter);
895
896 return error;
897} 883}
898 884
899device_initcall(irqrouter_init_sysfs); 885device_initcall(irqrouter_init_ops);
900 886
901static int __init acpi_pci_link_init(void) 887static int __init acpi_pci_link_init(void)
902{ 888{
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 3c1a2fec8cda..25bf17da69fd 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -19,7 +19,7 @@
19#define _COMPONENT ACPI_PROCESSOR_COMPONENT 19#define _COMPONENT ACPI_PROCESSOR_COMPONENT
20ACPI_MODULE_NAME("processor_core"); 20ACPI_MODULE_NAME("processor_core");
21 21
22static int set_no_mwait(const struct dmi_system_id *id) 22static int __init set_no_mwait(const struct dmi_system_id *id)
23{ 23{
24 printk(KERN_NOTICE PREFIX "%s detected - " 24 printk(KERN_NOTICE PREFIX "%s detected - "
25 "disabling mwait for CPU C-states\n", id->ident); 25 "disabling mwait for CPU C-states\n", id->ident);
@@ -27,7 +27,7 @@ static int set_no_mwait(const struct dmi_system_id *id)
27 return 0; 27 return 0;
28} 28}
29 29
30static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { 30static struct dmi_system_id __initdata processor_idle_dmi_table[] = {
31 { 31 {
32 set_no_mwait, "Extensa 5220", { 32 set_no_mwait, "Extensa 5220", {
33 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), 33 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
@@ -183,7 +183,7 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
183EXPORT_SYMBOL_GPL(acpi_get_cpuid); 183EXPORT_SYMBOL_GPL(acpi_get_cpuid);
184#endif 184#endif
185 185
186static bool processor_physically_present(acpi_handle handle) 186static bool __init processor_physically_present(acpi_handle handle)
187{ 187{
188 int cpuid, type; 188 int cpuid, type;
189 u32 acpi_id; 189 u32 acpi_id;
@@ -223,7 +223,7 @@ static bool processor_physically_present(acpi_handle handle)
223 return true; 223 return true;
224} 224}
225 225
226static void acpi_set_pdc_bits(u32 *buf) 226static void __cpuinit acpi_set_pdc_bits(u32 *buf)
227{ 227{
228 buf[0] = ACPI_PDC_REVISION_ID; 228 buf[0] = ACPI_PDC_REVISION_ID;
229 buf[1] = 1; 229 buf[1] = 1;
@@ -235,7 +235,7 @@ static void acpi_set_pdc_bits(u32 *buf)
235 arch_acpi_set_pdc_bits(buf); 235 arch_acpi_set_pdc_bits(buf);
236} 236}
237 237
238static struct acpi_object_list *acpi_processor_alloc_pdc(void) 238static struct acpi_object_list *__cpuinit acpi_processor_alloc_pdc(void)
239{ 239{
240 struct acpi_object_list *obj_list; 240 struct acpi_object_list *obj_list;
241 union acpi_object *obj; 241 union acpi_object *obj;
@@ -278,7 +278,7 @@ static struct acpi_object_list *acpi_processor_alloc_pdc(void)
278 * _PDC is required for a BIOS-OS handshake for most of the newer 278 * _PDC is required for a BIOS-OS handshake for most of the newer
279 * ACPI processor features. 279 * ACPI processor features.
280 */ 280 */
281static int 281static int __cpuinit
282acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) 282acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
283{ 283{
284 acpi_status status = AE_OK; 284 acpi_status status = AE_OK;
@@ -306,7 +306,7 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
306 return status; 306 return status;
307} 307}
308 308
309void acpi_processor_set_pdc(acpi_handle handle) 309void __cpuinit acpi_processor_set_pdc(acpi_handle handle)
310{ 310{
311 struct acpi_object_list *obj_list; 311 struct acpi_object_list *obj_list;
312 312
@@ -323,9 +323,8 @@ void acpi_processor_set_pdc(acpi_handle handle)
323 kfree(obj_list->pointer); 323 kfree(obj_list->pointer);
324 kfree(obj_list); 324 kfree(obj_list);
325} 325}
326EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
327 326
328static acpi_status 327static acpi_status __init
329early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) 328early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
330{ 329{
331 if (processor_physically_present(handle) == false) 330 if (processor_physically_present(handle) == false)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 360a74e6add0..a4e0f1ba6040 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -635,8 +635,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
635 return 0; 635 return 0;
636} 636}
637 637
638static void __ref acpi_processor_hotplug_notify(acpi_handle handle, 638static void acpi_processor_hotplug_notify(acpi_handle handle,
639 u32 event, void *data) 639 u32 event, void *data)
640{ 640{
641 struct acpi_processor *pr; 641 struct acpi_processor *pr;
642 struct acpi_device *device = NULL; 642 struct acpi_device *device = NULL;
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index 93f91142d7ad..a6c77e8b37bd 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -15,9 +15,15 @@ void acpi_reboot(void)
15 15
16 rr = &acpi_gbl_FADT.reset_register; 16 rr = &acpi_gbl_FADT.reset_register;
17 17
18 /* Is the reset register supported? */ 18 /* ACPI reset register was only introduced with v2 of the FADT */
19 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || 19
20 rr->bit_width != 8 || rr->bit_offset != 0) 20 if (acpi_gbl_FADT.header.revision < 2)
21 return;
22
23 /* Is the reset register supported? The spec says we should be
24 * checking the bit width and bit offset, but Windows ignores
25 * these fields */
26 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
21 return; 27 return;
22 28
23 reset_value = acpi_gbl_FADT.reset_value; 29 reset_value = acpi_gbl_FADT.reset_value;
@@ -45,6 +51,4 @@ void acpi_reboot(void)
45 acpi_reset(); 51 acpi_reset();
46 break; 52 break;
47 } 53 }
48 /* Wait ten seconds */
49 acpi_os_stall(10000000);
50} 54}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b99e62494607..b136c9c1e531 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -797,7 +797,6 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
797 acpi_status status; 797 acpi_status status;
798 acpi_event_status event_status; 798 acpi_event_status event_status;
799 799
800 device->wakeup.run_wake_count = 0;
801 device->wakeup.flags.notifier_present = 0; 800 device->wakeup.flags.notifier_present = 0;
802 801
803 /* Power button, Lid switch always enable wakeup */ 802 /* Power button, Lid switch always enable wakeup */
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 1850dac8f45c..6c949602cbd1 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -200,8 +200,6 @@ static void acpi_pm_end(void)
200#endif /* CONFIG_ACPI_SLEEP */ 200#endif /* CONFIG_ACPI_SLEEP */
201 201
202#ifdef CONFIG_SUSPEND 202#ifdef CONFIG_SUSPEND
203extern void do_suspend_lowlevel(void);
204
205static u32 acpi_suspend_states[] = { 203static u32 acpi_suspend_states[] = {
206 [PM_SUSPEND_ON] = ACPI_STATE_S0, 204 [PM_SUSPEND_ON] = ACPI_STATE_S0,
207 [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, 205 [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
@@ -244,20 +242,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
244static int acpi_suspend_enter(suspend_state_t pm_state) 242static int acpi_suspend_enter(suspend_state_t pm_state)
245{ 243{
246 acpi_status status = AE_OK; 244 acpi_status status = AE_OK;
247 unsigned long flags = 0;
248 u32 acpi_state = acpi_target_sleep_state; 245 u32 acpi_state = acpi_target_sleep_state;
246 int error;
249 247
250 ACPI_FLUSH_CPU_CACHE(); 248 ACPI_FLUSH_CPU_CACHE();
251 249
252 /* Do arch specific saving of state. */
253 if (acpi_state == ACPI_STATE_S3) {
254 int error = acpi_save_state_mem();
255
256 if (error)
257 return error;
258 }
259
260 local_irq_save(flags);
261 switch (acpi_state) { 250 switch (acpi_state) {
262 case ACPI_STATE_S1: 251 case ACPI_STATE_S1:
263 barrier(); 252 barrier();
@@ -265,7 +254,10 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
265 break; 254 break;
266 255
267 case ACPI_STATE_S3: 256 case ACPI_STATE_S3:
268 do_suspend_lowlevel(); 257 error = acpi_suspend_lowlevel();
258 if (error)
259 return error;
260 pr_info(PREFIX "Low-level resume complete\n");
269 break; 261 break;
270 } 262 }
271 263
@@ -291,13 +283,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
291 /* Allow EC transactions to happen. */ 283 /* Allow EC transactions to happen. */
292 acpi_ec_unblock_transactions_early(); 284 acpi_ec_unblock_transactions_early();
293 285
294 local_irq_restore(flags);
295 printk(KERN_DEBUG "Back to C!\n");
296
297 /* restore processor state */
298 if (acpi_state == ACPI_STATE_S3)
299 acpi_restore_state_mem();
300
301 suspend_nvs_restore(); 286 suspend_nvs_restore();
302 287
303 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 288 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -473,16 +458,13 @@ static int acpi_hibernation_begin(void)
473static int acpi_hibernation_enter(void) 458static int acpi_hibernation_enter(void)
474{ 459{
475 acpi_status status = AE_OK; 460 acpi_status status = AE_OK;
476 unsigned long flags = 0;
477 461
478 ACPI_FLUSH_CPU_CACHE(); 462 ACPI_FLUSH_CPU_CACHE();
479 463
480 local_irq_save(flags);
481 /* This shouldn't return. If it returns, we have a problem */ 464 /* This shouldn't return. If it returns, we have a problem */
482 status = acpi_enter_sleep_state(ACPI_STATE_S4); 465 status = acpi_enter_sleep_state(ACPI_STATE_S4);
483 /* Reprogram control registers and execute _BFS */ 466 /* Reprogram control registers and execute _BFS */
484 acpi_leave_sleep_state_prep(ACPI_STATE_S4); 467 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
485 local_irq_restore(flags);
486 468
487 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 469 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
488} 470}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 1f286ab461d3..79882104e431 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -140,13 +140,14 @@ static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo)
140 return 0; 140 return 0;
141} 141}
142 142
143static int DAC960_media_changed(struct gendisk *disk) 143static unsigned int DAC960_check_events(struct gendisk *disk,
144 unsigned int clearing)
144{ 145{
145 DAC960_Controller_T *p = disk->queue->queuedata; 146 DAC960_Controller_T *p = disk->queue->queuedata;
146 int drive_nr = (long)disk->private_data; 147 int drive_nr = (long)disk->private_data;
147 148
148 if (!p->LogicalDriveInitiallyAccessible[drive_nr]) 149 if (!p->LogicalDriveInitiallyAccessible[drive_nr])
149 return 1; 150 return DISK_EVENT_MEDIA_CHANGE;
150 return 0; 151 return 0;
151} 152}
152 153
@@ -163,7 +164,7 @@ static const struct block_device_operations DAC960_BlockDeviceOperations = {
163 .owner = THIS_MODULE, 164 .owner = THIS_MODULE,
164 .open = DAC960_open, 165 .open = DAC960_open,
165 .getgeo = DAC960_getgeo, 166 .getgeo = DAC960_getgeo,
166 .media_changed = DAC960_media_changed, 167 .check_events = DAC960_check_events,
167 .revalidate_disk = DAC960_revalidate_disk, 168 .revalidate_disk = DAC960_revalidate_disk,
168}; 169};
169 170
@@ -2546,6 +2547,7 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
2546 disk->major = MajorNumber; 2547 disk->major = MajorNumber;
2547 disk->first_minor = n << DAC960_MaxPartitionsBits; 2548 disk->first_minor = n << DAC960_MaxPartitionsBits;
2548 disk->fops = &DAC960_BlockDeviceOperations; 2549 disk->fops = &DAC960_BlockDeviceOperations;
2550 disk->events = DISK_EVENT_MEDIA_CHANGE;
2549 } 2551 }
2550 /* 2552 /*
2551 Indicate the Block Device Registration completed successfully, 2553 Indicate the Block Device Registration completed successfully,
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 363855ca376e..456c0cc90dcf 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1658,12 +1658,12 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
1658} 1658}
1659 1659
1660/* 1660/*
1661 * floppy-change is never called from an interrupt, so we can relax a bit 1661 * check_events is never called from an interrupt, so we can relax a bit
1662 * here, sleep etc. Note that floppy-on tries to set current_DOR to point 1662 * here, sleep etc. Note that floppy-on tries to set current_DOR to point
1663 * to the desired drive, but it will probably not survive the sleep if 1663 * to the desired drive, but it will probably not survive the sleep if
1664 * several floppies are used at the same time: thus the loop. 1664 * several floppies are used at the same time: thus the loop.
1665 */ 1665 */
1666static int amiga_floppy_change(struct gendisk *disk) 1666static unsigned amiga_check_events(struct gendisk *disk, unsigned int clearing)
1667{ 1667{
1668 struct amiga_floppy_struct *p = disk->private_data; 1668 struct amiga_floppy_struct *p = disk->private_data;
1669 int drive = p - unit; 1669 int drive = p - unit;
@@ -1686,7 +1686,7 @@ static int amiga_floppy_change(struct gendisk *disk)
1686 p->dirty = 0; 1686 p->dirty = 0;
1687 writepending = 0; /* if this was true before, too bad! */ 1687 writepending = 0; /* if this was true before, too bad! */
1688 writefromint = 0; 1688 writefromint = 0;
1689 return 1; 1689 return DISK_EVENT_MEDIA_CHANGE;
1690 } 1690 }
1691 return 0; 1691 return 0;
1692} 1692}
@@ -1697,7 +1697,7 @@ static const struct block_device_operations floppy_fops = {
1697 .release = floppy_release, 1697 .release = floppy_release,
1698 .ioctl = fd_ioctl, 1698 .ioctl = fd_ioctl,
1699 .getgeo = fd_getgeo, 1699 .getgeo = fd_getgeo,
1700 .media_changed = amiga_floppy_change, 1700 .check_events = amiga_check_events,
1701}; 1701};
1702 1702
1703static int __init fd_probe_drives(void) 1703static int __init fd_probe_drives(void)
@@ -1736,6 +1736,7 @@ static int __init fd_probe_drives(void)
1736 disk->major = FLOPPY_MAJOR; 1736 disk->major = FLOPPY_MAJOR;
1737 disk->first_minor = drive; 1737 disk->first_minor = drive;
1738 disk->fops = &floppy_fops; 1738 disk->fops = &floppy_fops;
1739 disk->events = DISK_EVENT_MEDIA_CHANGE;
1739 sprintf(disk->disk_name, "fd%d", drive); 1740 sprintf(disk->disk_name, "fd%d", drive);
1740 disk->private_data = &unit[drive]; 1741 disk->private_data = &unit[drive];
1741 set_capacity(disk, 880*2); 1742 set_capacity(disk, 880*2);
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 605a67e40bbf..c871eae14120 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1324,23 +1324,24 @@ static void finish_fdc_done( int dummy )
1324 * due to unrecognised disk changes. 1324 * due to unrecognised disk changes.
1325 */ 1325 */
1326 1326
1327static int check_floppy_change(struct gendisk *disk) 1327static unsigned int floppy_check_events(struct gendisk *disk,
1328 unsigned int clearing)
1328{ 1329{
1329 struct atari_floppy_struct *p = disk->private_data; 1330 struct atari_floppy_struct *p = disk->private_data;
1330 unsigned int drive = p - unit; 1331 unsigned int drive = p - unit;
1331 if (test_bit (drive, &fake_change)) { 1332 if (test_bit (drive, &fake_change)) {
1332 /* simulated change (e.g. after formatting) */ 1333 /* simulated change (e.g. after formatting) */
1333 return 1; 1334 return DISK_EVENT_MEDIA_CHANGE;
1334 } 1335 }
1335 if (test_bit (drive, &changed_floppies)) { 1336 if (test_bit (drive, &changed_floppies)) {
1336 /* surely changed (the WP signal changed at least once) */ 1337 /* surely changed (the WP signal changed at least once) */
1337 return 1; 1338 return DISK_EVENT_MEDIA_CHANGE;
1338 } 1339 }
1339 if (UD.wpstat) { 1340 if (UD.wpstat) {
1340 /* WP is on -> could be changed: to be sure, buffers should be 1341 /* WP is on -> could be changed: to be sure, buffers should be
1341 * invalidated... 1342 * invalidated...
1342 */ 1343 */
1343 return 1; 1344 return DISK_EVENT_MEDIA_CHANGE;
1344 } 1345 }
1345 1346
1346 return 0; 1347 return 0;
@@ -1570,7 +1571,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
1570 * or the next access will revalidate - and clear UDT :-( 1571 * or the next access will revalidate - and clear UDT :-(
1571 */ 1572 */
1572 1573
1573 if (check_floppy_change(disk)) 1574 if (floppy_check_events(disk, 0))
1574 floppy_revalidate(disk); 1575 floppy_revalidate(disk);
1575 1576
1576 if (UD.flags & FTD_MSG) 1577 if (UD.flags & FTD_MSG)
@@ -1904,7 +1905,7 @@ static const struct block_device_operations floppy_fops = {
1904 .open = floppy_unlocked_open, 1905 .open = floppy_unlocked_open,
1905 .release = floppy_release, 1906 .release = floppy_release,
1906 .ioctl = fd_ioctl, 1907 .ioctl = fd_ioctl,
1907 .media_changed = check_floppy_change, 1908 .check_events = floppy_check_events,
1908 .revalidate_disk= floppy_revalidate, 1909 .revalidate_disk= floppy_revalidate,
1909}; 1910};
1910 1911
@@ -1963,6 +1964,7 @@ static int __init atari_floppy_init (void)
1963 unit[i].disk->first_minor = i; 1964 unit[i].disk->first_minor = i;
1964 sprintf(unit[i].disk->disk_name, "fd%d", i); 1965 sprintf(unit[i].disk->disk_name, "fd%d", i);
1965 unit[i].disk->fops = &floppy_fops; 1966 unit[i].disk->fops = &floppy_fops;
1967 unit[i].disk->events = DISK_EVENT_MEDIA_CHANGE;
1966 unit[i].disk->private_data = &unit[i]; 1968 unit[i].disk->private_data = &unit[i];
1967 unit[i].disk->queue = blk_init_queue(do_fd_request, 1969 unit[i].disk->queue = blk_init_queue(do_fd_request,
1968 &ataflop_lock); 1970 &ataflop_lock);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 9279272b3732..35658f445fca 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3170,12 +3170,6 @@ static void do_cciss_request(struct request_queue *q)
3170 int sg_index = 0; 3170 int sg_index = 0;
3171 int chained = 0; 3171 int chained = 0;
3172 3172
3173 /* We call start_io here in case there is a command waiting on the
3174 * queue that has not been sent.
3175 */
3176 if (blk_queue_plugged(q))
3177 goto startio;
3178
3179 queue: 3173 queue:
3180 creq = blk_peek_request(q); 3174 creq = blk_peek_request(q);
3181 if (!creq) 3175 if (!creq)
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 946dad4caef3..b2fceb53e809 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -911,9 +911,6 @@ static void do_ida_request(struct request_queue *q)
911 struct scatterlist tmp_sg[SG_MAX]; 911 struct scatterlist tmp_sg[SG_MAX];
912 int i, dir, seg; 912 int i, dir, seg;
913 913
914 if (blk_queue_plugged(q))
915 goto startio;
916
917queue_next: 914queue_next:
918 creq = blk_peek_request(q); 915 creq = blk_peek_request(q);
919 if (!creq) 916 if (!creq)
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index ba95cba192be..aca302492ff2 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -80,7 +80,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
80 80
81 if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) 81 if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags))
82 rw |= REQ_FUA; 82 rw |= REQ_FUA;
83 rw |= REQ_UNPLUG | REQ_SYNC; 83 rw |= REQ_SYNC;
84 84
85 bio = bio_alloc(GFP_NOIO, 1); 85 bio = bio_alloc(GFP_NOIO, 1);
86 bio->bi_bdev = bdev->md_bdev; 86 bio->bi_bdev = bdev->md_bdev;
@@ -689,8 +689,6 @@ void drbd_al_to_on_disk_bm(struct drbd_conf *mdev)
689 } 689 }
690 } 690 }
691 691
692 drbd_blk_run_queue(bdev_get_queue(mdev->ldev->md_bdev));
693
694 /* always (try to) flush bitmap to stable storage */ 692 /* always (try to) flush bitmap to stable storage */
695 drbd_md_flush(mdev); 693 drbd_md_flush(mdev);
696 694
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index fd42832f785b..0645ca829a94 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -840,7 +840,6 @@ static int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)
840 for (i = 0; i < num_pages; i++) 840 for (i = 0; i < num_pages; i++)
841 bm_page_io_async(mdev, b, i, rw); 841 bm_page_io_async(mdev, b, i, rw);
842 842
843 drbd_blk_run_queue(bdev_get_queue(mdev->ldev->md_bdev));
844 wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0); 843 wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0);
845 844
846 if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) { 845 if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) {
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 3803a0348937..b0bd27dfc1e8 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -377,7 +377,7 @@ union p_header {
377#define DP_HARDBARRIER 1 /* depricated */ 377#define DP_HARDBARRIER 1 /* depricated */
378#define DP_RW_SYNC 2 /* equals REQ_SYNC */ 378#define DP_RW_SYNC 2 /* equals REQ_SYNC */
379#define DP_MAY_SET_IN_SYNC 4 379#define DP_MAY_SET_IN_SYNC 4
380#define DP_UNPLUG 8 /* equals REQ_UNPLUG */ 380#define DP_UNPLUG 8 /* not used anymore */
381#define DP_FUA 16 /* equals REQ_FUA */ 381#define DP_FUA 16 /* equals REQ_FUA */
382#define DP_FLUSH 32 /* equals REQ_FLUSH */ 382#define DP_FLUSH 32 /* equals REQ_FLUSH */
383#define DP_DISCARD 64 /* equals REQ_DISCARD */ 383#define DP_DISCARD 64 /* equals REQ_DISCARD */
@@ -2382,20 +2382,6 @@ static inline int drbd_queue_order_type(struct drbd_conf *mdev)
2382 return QUEUE_ORDERED_NONE; 2382 return QUEUE_ORDERED_NONE;
2383} 2383}
2384 2384
2385static inline void drbd_blk_run_queue(struct request_queue *q)
2386{
2387 if (q && q->unplug_fn)
2388 q->unplug_fn(q);
2389}
2390
2391static inline void drbd_kick_lo(struct drbd_conf *mdev)
2392{
2393 if (get_ldev(mdev)) {
2394 drbd_blk_run_queue(bdev_get_queue(mdev->ldev->backing_bdev));
2395 put_ldev(mdev);
2396 }
2397}
2398
2399static inline void drbd_md_flush(struct drbd_conf *mdev) 2385static inline void drbd_md_flush(struct drbd_conf *mdev)
2400{ 2386{
2401 int r; 2387 int r;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 29cd0dc9fe4f..8a43ce0edeed 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2477,12 +2477,11 @@ static u32 bio_flags_to_wire(struct drbd_conf *mdev, unsigned long bi_rw)
2477{ 2477{
2478 if (mdev->agreed_pro_version >= 95) 2478 if (mdev->agreed_pro_version >= 95)
2479 return (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) | 2479 return (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
2480 (bi_rw & REQ_UNPLUG ? DP_UNPLUG : 0) |
2481 (bi_rw & REQ_FUA ? DP_FUA : 0) | 2480 (bi_rw & REQ_FUA ? DP_FUA : 0) |
2482 (bi_rw & REQ_FLUSH ? DP_FLUSH : 0) | 2481 (bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
2483 (bi_rw & REQ_DISCARD ? DP_DISCARD : 0); 2482 (bi_rw & REQ_DISCARD ? DP_DISCARD : 0);
2484 else 2483 else
2485 return bi_rw & (REQ_SYNC | REQ_UNPLUG) ? DP_RW_SYNC : 0; 2484 return bi_rw & REQ_SYNC ? DP_RW_SYNC : 0;
2486} 2485}
2487 2486
2488/* Used to send write requests 2487/* Used to send write requests
@@ -2719,35 +2718,6 @@ static int drbd_release(struct gendisk *gd, fmode_t mode)
2719 return 0; 2718 return 0;
2720} 2719}
2721 2720
2722static void drbd_unplug_fn(struct request_queue *q)
2723{
2724 struct drbd_conf *mdev = q->queuedata;
2725
2726 /* unplug FIRST */
2727 spin_lock_irq(q->queue_lock);
2728 blk_remove_plug(q);
2729 spin_unlock_irq(q->queue_lock);
2730
2731 /* only if connected */
2732 spin_lock_irq(&mdev->req_lock);
2733 if (mdev->state.pdsk >= D_INCONSISTENT && mdev->state.conn >= C_CONNECTED) {
2734 D_ASSERT(mdev->state.role == R_PRIMARY);
2735 if (test_and_clear_bit(UNPLUG_REMOTE, &mdev->flags)) {
2736 /* add to the data.work queue,
2737 * unless already queued.
2738 * XXX this might be a good addition to drbd_queue_work
2739 * anyways, to detect "double queuing" ... */
2740 if (list_empty(&mdev->unplug_work.list))
2741 drbd_queue_work(&mdev->data.work,
2742 &mdev->unplug_work);
2743 }
2744 }
2745 spin_unlock_irq(&mdev->req_lock);
2746
2747 if (mdev->state.disk >= D_INCONSISTENT)
2748 drbd_kick_lo(mdev);
2749}
2750
2751static void drbd_set_defaults(struct drbd_conf *mdev) 2721static void drbd_set_defaults(struct drbd_conf *mdev)
2752{ 2722{
2753 /* This way we get a compile error when sync_conf grows, 2723 /* This way we get a compile error when sync_conf grows,
@@ -3222,9 +3192,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
3222 blk_queue_max_segment_size(q, DRBD_MAX_SEGMENT_SIZE); 3192 blk_queue_max_segment_size(q, DRBD_MAX_SEGMENT_SIZE);
3223 blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); 3193 blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
3224 blk_queue_merge_bvec(q, drbd_merge_bvec); 3194 blk_queue_merge_bvec(q, drbd_merge_bvec);
3225 q->queue_lock = &mdev->req_lock; /* needed since we use */ 3195 q->queue_lock = &mdev->req_lock;
3226 /* plugging on a queue, that actually has no requests! */
3227 q->unplug_fn = drbd_unplug_fn;
3228 3196
3229 mdev->md_io_page = alloc_page(GFP_KERNEL); 3197 mdev->md_io_page = alloc_page(GFP_KERNEL);
3230 if (!mdev->md_io_page) 3198 if (!mdev->md_io_page)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 24487d4fb202..8e68be939deb 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -187,15 +187,6 @@ static struct page *drbd_pp_first_pages_or_try_alloc(struct drbd_conf *mdev, int
187 return NULL; 187 return NULL;
188} 188}
189 189
190/* kick lower level device, if we have more than (arbitrary number)
191 * reference counts on it, which typically are locally submitted io
192 * requests. don't use unacked_cnt, so we speed up proto A and B, too. */
193static void maybe_kick_lo(struct drbd_conf *mdev)
194{
195 if (atomic_read(&mdev->local_cnt) >= mdev->net_conf->unplug_watermark)
196 drbd_kick_lo(mdev);
197}
198
199static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed) 190static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed)
200{ 191{
201 struct drbd_epoch_entry *e; 192 struct drbd_epoch_entry *e;
@@ -219,7 +210,6 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_conf *mdev)
219 LIST_HEAD(reclaimed); 210 LIST_HEAD(reclaimed);
220 struct drbd_epoch_entry *e, *t; 211 struct drbd_epoch_entry *e, *t;
221 212
222 maybe_kick_lo(mdev);
223 spin_lock_irq(&mdev->req_lock); 213 spin_lock_irq(&mdev->req_lock);
224 reclaim_net_ee(mdev, &reclaimed); 214 reclaim_net_ee(mdev, &reclaimed);
225 spin_unlock_irq(&mdev->req_lock); 215 spin_unlock_irq(&mdev->req_lock);
@@ -436,8 +426,7 @@ void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head)
436 while (!list_empty(head)) { 426 while (!list_empty(head)) {
437 prepare_to_wait(&mdev->ee_wait, &wait, TASK_UNINTERRUPTIBLE); 427 prepare_to_wait(&mdev->ee_wait, &wait, TASK_UNINTERRUPTIBLE);
438 spin_unlock_irq(&mdev->req_lock); 428 spin_unlock_irq(&mdev->req_lock);
439 drbd_kick_lo(mdev); 429 io_schedule();
440 schedule();
441 finish_wait(&mdev->ee_wait, &wait); 430 finish_wait(&mdev->ee_wait, &wait);
442 spin_lock_irq(&mdev->req_lock); 431 spin_lock_irq(&mdev->req_lock);
443 } 432 }
@@ -1111,8 +1100,6 @@ next_bio:
1111 /* > e->sector, unless this is the first bio */ 1100 /* > e->sector, unless this is the first bio */
1112 bio->bi_sector = sector; 1101 bio->bi_sector = sector;
1113 bio->bi_bdev = mdev->ldev->backing_bdev; 1102 bio->bi_bdev = mdev->ldev->backing_bdev;
1114 /* we special case some flags in the multi-bio case, see below
1115 * (REQ_UNPLUG) */
1116 bio->bi_rw = rw; 1103 bio->bi_rw = rw;
1117 bio->bi_private = e; 1104 bio->bi_private = e;
1118 bio->bi_end_io = drbd_endio_sec; 1105 bio->bi_end_io = drbd_endio_sec;
@@ -1141,13 +1128,8 @@ next_bio:
1141 bios = bios->bi_next; 1128 bios = bios->bi_next;
1142 bio->bi_next = NULL; 1129 bio->bi_next = NULL;
1143 1130
1144 /* strip off REQ_UNPLUG unless it is the last bio */
1145 if (bios)
1146 bio->bi_rw &= ~REQ_UNPLUG;
1147
1148 drbd_generic_make_request(mdev, fault_type, bio); 1131 drbd_generic_make_request(mdev, fault_type, bio);
1149 } while (bios); 1132 } while (bios);
1150 maybe_kick_lo(mdev);
1151 return 0; 1133 return 0;
1152 1134
1153fail: 1135fail:
@@ -1167,9 +1149,6 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign
1167 1149
1168 inc_unacked(mdev); 1150 inc_unacked(mdev);
1169 1151
1170 if (mdev->net_conf->wire_protocol != DRBD_PROT_C)
1171 drbd_kick_lo(mdev);
1172
1173 mdev->current_epoch->barrier_nr = p->barrier; 1152 mdev->current_epoch->barrier_nr = p->barrier;
1174 rv = drbd_may_finish_epoch(mdev, mdev->current_epoch, EV_GOT_BARRIER_NR); 1153 rv = drbd_may_finish_epoch(mdev, mdev->current_epoch, EV_GOT_BARRIER_NR);
1175 1154
@@ -1636,12 +1615,11 @@ static unsigned long write_flags_to_bio(struct drbd_conf *mdev, u32 dpf)
1636{ 1615{
1637 if (mdev->agreed_pro_version >= 95) 1616 if (mdev->agreed_pro_version >= 95)
1638 return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) | 1617 return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
1639 (dpf & DP_UNPLUG ? REQ_UNPLUG : 0) |
1640 (dpf & DP_FUA ? REQ_FUA : 0) | 1618 (dpf & DP_FUA ? REQ_FUA : 0) |
1641 (dpf & DP_FLUSH ? REQ_FUA : 0) | 1619 (dpf & DP_FLUSH ? REQ_FUA : 0) |
1642 (dpf & DP_DISCARD ? REQ_DISCARD : 0); 1620 (dpf & DP_DISCARD ? REQ_DISCARD : 0);
1643 else 1621 else
1644 return dpf & DP_RW_SYNC ? (REQ_SYNC | REQ_UNPLUG) : 0; 1622 return dpf & DP_RW_SYNC ? REQ_SYNC : 0;
1645} 1623}
1646 1624
1647/* mirrored write */ 1625/* mirrored write */
@@ -3556,9 +3534,6 @@ static int receive_skip(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
3556 3534
3557static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) 3535static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
3558{ 3536{
3559 if (mdev->state.disk >= D_INCONSISTENT)
3560 drbd_kick_lo(mdev);
3561
3562 /* Make sure we've acked all the TCP data associated 3537 /* Make sure we've acked all the TCP data associated
3563 * with the data requests being unplugged */ 3538 * with the data requests being unplugged */
3564 drbd_tcp_quickack(mdev->data.socket); 3539 drbd_tcp_quickack(mdev->data.socket);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 11a75d32a2e2..ad3fc6228f27 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -960,10 +960,6 @@ allocate_barrier:
960 bio_endio(req->private_bio, -EIO); 960 bio_endio(req->private_bio, -EIO);
961 } 961 }
962 962
963 /* we need to plug ALWAYS since we possibly need to kick lo_dev.
964 * we plug after submit, so we won't miss an unplug event */
965 drbd_plug_device(mdev);
966
967 return 0; 963 return 0;
968 964
969fail_conflicting: 965fail_conflicting:
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 34f224b018b3..e027446590d3 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -792,7 +792,6 @@ int drbd_resync_finished(struct drbd_conf *mdev)
792 * queue (or even the read operations for those packets 792 * queue (or even the read operations for those packets
793 * is not finished by now). Retry in 100ms. */ 793 * is not finished by now). Retry in 100ms. */
794 794
795 drbd_kick_lo(mdev);
796 __set_current_state(TASK_INTERRUPTIBLE); 795 __set_current_state(TASK_INTERRUPTIBLE);
797 schedule_timeout(HZ / 10); 796 schedule_timeout(HZ / 10);
798 w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC); 797 w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC);
diff --git a/drivers/block/drbd/drbd_wrappers.h b/drivers/block/drbd/drbd_wrappers.h
index defdb5013ea3..53586fa5ae1b 100644
--- a/drivers/block/drbd/drbd_wrappers.h
+++ b/drivers/block/drbd/drbd_wrappers.h
@@ -45,24 +45,6 @@ static inline void drbd_generic_make_request(struct drbd_conf *mdev,
45 generic_make_request(bio); 45 generic_make_request(bio);
46} 46}
47 47
48static inline void drbd_plug_device(struct drbd_conf *mdev)
49{
50 struct request_queue *q;
51 q = bdev_get_queue(mdev->this_bdev);
52
53 spin_lock_irq(q->queue_lock);
54
55/* XXX the check on !blk_queue_plugged is redundant,
56 * implicitly checked in blk_plug_device */
57
58 if (!blk_queue_plugged(q)) {
59 blk_plug_device(q);
60 del_timer(&q->unplug_timer);
61 /* unplugging should not happen automatically... */
62 }
63 spin_unlock_irq(q->queue_lock);
64}
65
66static inline int drbd_crypto_is_hash(struct crypto_tfm *tfm) 48static inline int drbd_crypto_is_hash(struct crypto_tfm *tfm)
67{ 49{
68 return (crypto_tfm_alg_type(tfm) & CRYPTO_ALG_TYPE_HASH_MASK) 50 return (crypto_tfm_alg_type(tfm) & CRYPTO_ALG_TYPE_HASH_MASK)
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 77fc76f8aea9..301d7a9a41a6 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3770,13 +3770,14 @@ out2:
3770/* 3770/*
3771 * Check if the disk has been changed or if a change has been faked. 3771 * Check if the disk has been changed or if a change has been faked.
3772 */ 3772 */
3773static int check_floppy_change(struct gendisk *disk) 3773static unsigned int floppy_check_events(struct gendisk *disk,
3774 unsigned int clearing)
3774{ 3775{
3775 int drive = (long)disk->private_data; 3776 int drive = (long)disk->private_data;
3776 3777
3777 if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || 3778 if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
3778 test_bit(FD_VERIFY_BIT, &UDRS->flags)) 3779 test_bit(FD_VERIFY_BIT, &UDRS->flags))
3779 return 1; 3780 return DISK_EVENT_MEDIA_CHANGE;
3780 3781
3781 if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { 3782 if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
3782 lock_fdc(drive, false); 3783 lock_fdc(drive, false);
@@ -3788,7 +3789,7 @@ static int check_floppy_change(struct gendisk *disk)
3788 test_bit(FD_VERIFY_BIT, &UDRS->flags) || 3789 test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
3789 test_bit(drive, &fake_change) || 3790 test_bit(drive, &fake_change) ||
3790 drive_no_geom(drive)) 3791 drive_no_geom(drive))
3791 return 1; 3792 return DISK_EVENT_MEDIA_CHANGE;
3792 return 0; 3793 return 0;
3793} 3794}
3794 3795
@@ -3837,7 +3838,6 @@ static int __floppy_read_block_0(struct block_device *bdev)
3837 bio.bi_end_io = floppy_rb0_complete; 3838 bio.bi_end_io = floppy_rb0_complete;
3838 3839
3839 submit_bio(READ, &bio); 3840 submit_bio(READ, &bio);
3840 generic_unplug_device(bdev_get_queue(bdev));
3841 process_fd_request(); 3841 process_fd_request();
3842 wait_for_completion(&complete); 3842 wait_for_completion(&complete);
3843 3843
@@ -3898,7 +3898,7 @@ static const struct block_device_operations floppy_fops = {
3898 .release = floppy_release, 3898 .release = floppy_release,
3899 .ioctl = fd_ioctl, 3899 .ioctl = fd_ioctl,
3900 .getgeo = fd_getgeo, 3900 .getgeo = fd_getgeo,
3901 .media_changed = check_floppy_change, 3901 .check_events = floppy_check_events,
3902 .revalidate_disk = floppy_revalidate, 3902 .revalidate_disk = floppy_revalidate,
3903}; 3903};
3904 3904
@@ -4205,6 +4205,7 @@ static int __init floppy_init(void)
4205 disks[dr]->major = FLOPPY_MAJOR; 4205 disks[dr]->major = FLOPPY_MAJOR;
4206 disks[dr]->first_minor = TOMINOR(dr); 4206 disks[dr]->first_minor = TOMINOR(dr);
4207 disks[dr]->fops = &floppy_fops; 4207 disks[dr]->fops = &floppy_fops;
4208 disks[dr]->events = DISK_EVENT_MEDIA_CHANGE;
4208 sprintf(disks[dr]->disk_name, "fd%d", dr); 4209 sprintf(disks[dr]->disk_name, "fd%d", dr);
4209 4210
4210 init_timer(&motor_off_timer[dr]); 4211 init_timer(&motor_off_timer[dr]);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index dbf31ec9114d..a076a14ca72d 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -540,17 +540,6 @@ out:
540 return 0; 540 return 0;
541} 541}
542 542
543/*
544 * kick off io on the underlying address space
545 */
546static void loop_unplug(struct request_queue *q)
547{
548 struct loop_device *lo = q->queuedata;
549
550 queue_flag_clear_unlocked(QUEUE_FLAG_PLUGGED, q);
551 blk_run_address_space(lo->lo_backing_file->f_mapping);
552}
553
554struct switch_request { 543struct switch_request {
555 struct file *file; 544 struct file *file;
556 struct completion wait; 545 struct completion wait;
@@ -917,7 +906,6 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
917 */ 906 */
918 blk_queue_make_request(lo->lo_queue, loop_make_request); 907 blk_queue_make_request(lo->lo_queue, loop_make_request);
919 lo->lo_queue->queuedata = lo; 908 lo->lo_queue->queuedata = lo;
920 lo->lo_queue->unplug_fn = loop_unplug;
921 909
922 if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) 910 if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
923 blk_queue_flush(lo->lo_queue, REQ_FLUSH); 911 blk_queue_flush(lo->lo_queue, REQ_FLUSH);
@@ -1019,7 +1007,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
1019 1007
1020 kthread_stop(lo->lo_thread); 1008 kthread_stop(lo->lo_thread);
1021 1009
1022 lo->lo_queue->unplug_fn = NULL;
1023 lo->lo_backing_file = NULL; 1010 lo->lo_backing_file = NULL;
1024 1011
1025 loop_release_xfer(lo); 1012 loop_release_xfer(lo);
@@ -1636,9 +1623,6 @@ out:
1636 1623
1637static void loop_free(struct loop_device *lo) 1624static void loop_free(struct loop_device *lo)
1638{ 1625{
1639 if (!lo->lo_queue->queue_lock)
1640 lo->lo_queue->queue_lock = &lo->lo_queue->__queue_lock;
1641
1642 blk_cleanup_queue(lo->lo_queue); 1626 blk_cleanup_queue(lo->lo_queue);
1643 put_disk(lo->lo_disk); 1627 put_disk(lo->lo_disk);
1644 list_del(&lo->lo_list); 1628 list_del(&lo->lo_list);
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 62cec6afd7ad..2f2ccf686251 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -172,7 +172,8 @@ module_param_array(drive3, int, NULL, 0);
172static int pcd_open(struct cdrom_device_info *cdi, int purpose); 172static int pcd_open(struct cdrom_device_info *cdi, int purpose);
173static void pcd_release(struct cdrom_device_info *cdi); 173static void pcd_release(struct cdrom_device_info *cdi);
174static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr); 174static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
175static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr); 175static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
176 unsigned int clearing, int slot_nr);
176static int pcd_tray_move(struct cdrom_device_info *cdi, int position); 177static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
177static int pcd_lock_door(struct cdrom_device_info *cdi, int lock); 178static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
178static int pcd_drive_reset(struct cdrom_device_info *cdi); 179static int pcd_drive_reset(struct cdrom_device_info *cdi);
@@ -257,10 +258,11 @@ static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
257 return ret; 258 return ret;
258} 259}
259 260
260static int pcd_block_media_changed(struct gendisk *disk) 261static unsigned int pcd_block_check_events(struct gendisk *disk,
262 unsigned int clearing)
261{ 263{
262 struct pcd_unit *cd = disk->private_data; 264 struct pcd_unit *cd = disk->private_data;
263 return cdrom_media_changed(&cd->info); 265 return cdrom_check_events(&cd->info, clearing);
264} 266}
265 267
266static const struct block_device_operations pcd_bdops = { 268static const struct block_device_operations pcd_bdops = {
@@ -268,14 +270,14 @@ static const struct block_device_operations pcd_bdops = {
268 .open = pcd_block_open, 270 .open = pcd_block_open,
269 .release = pcd_block_release, 271 .release = pcd_block_release,
270 .ioctl = pcd_block_ioctl, 272 .ioctl = pcd_block_ioctl,
271 .media_changed = pcd_block_media_changed, 273 .check_events = pcd_block_check_events,
272}; 274};
273 275
274static struct cdrom_device_ops pcd_dops = { 276static struct cdrom_device_ops pcd_dops = {
275 .open = pcd_open, 277 .open = pcd_open,
276 .release = pcd_release, 278 .release = pcd_release,
277 .drive_status = pcd_drive_status, 279 .drive_status = pcd_drive_status,
278 .media_changed = pcd_media_changed, 280 .check_events = pcd_check_events,
279 .tray_move = pcd_tray_move, 281 .tray_move = pcd_tray_move,
280 .lock_door = pcd_lock_door, 282 .lock_door = pcd_lock_door,
281 .get_mcn = pcd_get_mcn, 283 .get_mcn = pcd_get_mcn,
@@ -318,6 +320,7 @@ static void pcd_init_units(void)
318 disk->first_minor = unit; 320 disk->first_minor = unit;
319 strcpy(disk->disk_name, cd->name); /* umm... */ 321 strcpy(disk->disk_name, cd->name); /* umm... */
320 disk->fops = &pcd_bdops; 322 disk->fops = &pcd_bdops;
323 disk->events = DISK_EVENT_MEDIA_CHANGE;
321 } 324 }
322} 325}
323 326
@@ -502,13 +505,14 @@ static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc)
502 505
503#define DBMSG(msg) ((verbose>1)?(msg):NULL) 506#define DBMSG(msg) ((verbose>1)?(msg):NULL)
504 507
505static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr) 508static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
509 unsigned int clearing, int slot_nr)
506{ 510{
507 struct pcd_unit *cd = cdi->handle; 511 struct pcd_unit *cd = cdi->handle;
508 int res = cd->changed; 512 int res = cd->changed;
509 if (res) 513 if (res)
510 cd->changed = 0; 514 cd->changed = 0;
511 return res; 515 return res ? DISK_EVENT_MEDIA_CHANGE : 0;
512} 516}
513 517
514static int pcd_lock_door(struct cdrom_device_info *cdi, int lock) 518static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index c0ee1558b9bb..21dfdb776869 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -794,7 +794,7 @@ static int pd_release(struct gendisk *p, fmode_t mode)
794 return 0; 794 return 0;
795} 795}
796 796
797static int pd_check_media(struct gendisk *p) 797static unsigned int pd_check_events(struct gendisk *p, unsigned int clearing)
798{ 798{
799 struct pd_unit *disk = p->private_data; 799 struct pd_unit *disk = p->private_data;
800 int r; 800 int r;
@@ -803,7 +803,7 @@ static int pd_check_media(struct gendisk *p)
803 pd_special_command(disk, pd_media_check); 803 pd_special_command(disk, pd_media_check);
804 r = disk->changed; 804 r = disk->changed;
805 disk->changed = 0; 805 disk->changed = 0;
806 return r; 806 return r ? DISK_EVENT_MEDIA_CHANGE : 0;
807} 807}
808 808
809static int pd_revalidate(struct gendisk *p) 809static int pd_revalidate(struct gendisk *p)
@@ -822,7 +822,7 @@ static const struct block_device_operations pd_fops = {
822 .release = pd_release, 822 .release = pd_release,
823 .ioctl = pd_ioctl, 823 .ioctl = pd_ioctl,
824 .getgeo = pd_getgeo, 824 .getgeo = pd_getgeo,
825 .media_changed = pd_check_media, 825 .check_events = pd_check_events,
826 .revalidate_disk= pd_revalidate 826 .revalidate_disk= pd_revalidate
827}; 827};
828 828
@@ -837,6 +837,7 @@ static void pd_probe_drive(struct pd_unit *disk)
837 p->fops = &pd_fops; 837 p->fops = &pd_fops;
838 p->major = major; 838 p->major = major;
839 p->first_minor = (disk - pd) << PD_BITS; 839 p->first_minor = (disk - pd) << PD_BITS;
840 p->events = DISK_EVENT_MEDIA_CHANGE;
840 disk->gd = p; 841 disk->gd = p;
841 p->private_data = disk; 842 p->private_data = disk;
842 p->queue = pd_queue; 843 p->queue = pd_queue;
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 635f25dd9e10..7adeb1edbf43 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -243,7 +243,8 @@ static struct pf_unit units[PF_UNITS];
243static int pf_identify(struct pf_unit *pf); 243static int pf_identify(struct pf_unit *pf);
244static void pf_lock(struct pf_unit *pf, int func); 244static void pf_lock(struct pf_unit *pf, int func);
245static void pf_eject(struct pf_unit *pf); 245static void pf_eject(struct pf_unit *pf);
246static int pf_check_media(struct gendisk *disk); 246static unsigned int pf_check_events(struct gendisk *disk,
247 unsigned int clearing);
247 248
248static char pf_scratch[512]; /* scratch block buffer */ 249static char pf_scratch[512]; /* scratch block buffer */
249 250
@@ -270,7 +271,7 @@ static const struct block_device_operations pf_fops = {
270 .release = pf_release, 271 .release = pf_release,
271 .ioctl = pf_ioctl, 272 .ioctl = pf_ioctl,
272 .getgeo = pf_getgeo, 273 .getgeo = pf_getgeo,
273 .media_changed = pf_check_media, 274 .check_events = pf_check_events,
274}; 275};
275 276
276static void __init pf_init_units(void) 277static void __init pf_init_units(void)
@@ -293,6 +294,7 @@ static void __init pf_init_units(void)
293 disk->first_minor = unit; 294 disk->first_minor = unit;
294 strcpy(disk->disk_name, pf->name); 295 strcpy(disk->disk_name, pf->name);
295 disk->fops = &pf_fops; 296 disk->fops = &pf_fops;
297 disk->events = DISK_EVENT_MEDIA_CHANGE;
296 if (!(*drives[unit])[D_PRT]) 298 if (!(*drives[unit])[D_PRT])
297 pf_drive_count++; 299 pf_drive_count++;
298 } 300 }
@@ -377,9 +379,9 @@ static int pf_release(struct gendisk *disk, fmode_t mode)
377 379
378} 380}
379 381
380static int pf_check_media(struct gendisk *disk) 382static unsigned int pf_check_events(struct gendisk *disk, unsigned int clearing)
381{ 383{
382 return 1; 384 return DISK_EVENT_MEDIA_CHANGE;
383} 385}
384 386
385static inline int status_reg(struct pf_unit *pf) 387static inline int status_reg(struct pf_unit *pf)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 77d70eebb6b2..07a382eaf0a8 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1606,8 +1606,6 @@ static int kcdrwd(void *foobar)
1606 min_sleep_time = pkt->sleep_time; 1606 min_sleep_time = pkt->sleep_time;
1607 } 1607 }
1608 1608
1609 generic_unplug_device(bdev_get_queue(pd->bdev));
1610
1611 VPRINTK("kcdrwd: sleeping\n"); 1609 VPRINTK("kcdrwd: sleeping\n");
1612 residue = schedule_timeout(min_sleep_time); 1610 residue = schedule_timeout(min_sleep_time);
1613 VPRINTK("kcdrwd: wake up\n"); 1611 VPRINTK("kcdrwd: wake up\n");
@@ -2796,7 +2794,8 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
2796 return ret; 2794 return ret;
2797} 2795}
2798 2796
2799static int pkt_media_changed(struct gendisk *disk) 2797static unsigned int pkt_check_events(struct gendisk *disk,
2798 unsigned int clearing)
2800{ 2799{
2801 struct pktcdvd_device *pd = disk->private_data; 2800 struct pktcdvd_device *pd = disk->private_data;
2802 struct gendisk *attached_disk; 2801 struct gendisk *attached_disk;
@@ -2806,9 +2805,9 @@ static int pkt_media_changed(struct gendisk *disk)
2806 if (!pd->bdev) 2805 if (!pd->bdev)
2807 return 0; 2806 return 0;
2808 attached_disk = pd->bdev->bd_disk; 2807 attached_disk = pd->bdev->bd_disk;
2809 if (!attached_disk) 2808 if (!attached_disk || !attached_disk->fops->check_events)
2810 return 0; 2809 return 0;
2811 return attached_disk->fops->media_changed(attached_disk); 2810 return attached_disk->fops->check_events(attached_disk, clearing);
2812} 2811}
2813 2812
2814static const struct block_device_operations pktcdvd_ops = { 2813static const struct block_device_operations pktcdvd_ops = {
@@ -2816,7 +2815,7 @@ static const struct block_device_operations pktcdvd_ops = {
2816 .open = pkt_open, 2815 .open = pkt_open,
2817 .release = pkt_close, 2816 .release = pkt_close,
2818 .ioctl = pkt_ioctl, 2817 .ioctl = pkt_ioctl,
2819 .media_changed = pkt_media_changed, 2818 .check_events = pkt_check_events,
2820}; 2819};
2821 2820
2822static char *pktcdvd_devnode(struct gendisk *gd, mode_t *mode) 2821static char *pktcdvd_devnode(struct gendisk *gd, mode_t *mode)
@@ -2889,6 +2888,10 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
2889 if (ret) 2888 if (ret)
2890 goto out_new_dev; 2889 goto out_new_dev;
2891 2890
2891 /* inherit events of the host device */
2892 disk->events = pd->bdev->bd_disk->events;
2893 disk->async_events = pd->bdev->bd_disk->async_events;
2894
2892 add_disk(disk); 2895 add_disk(disk);
2893 2896
2894 pkt_sysfs_dev_new(pd); 2897 pkt_sysfs_dev_new(pd);
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index 75333d0a3327..24a482f2fbd6 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -741,11 +741,12 @@ static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
741 return 0; 741 return 0;
742} 742}
743 743
744static int floppy_check_change(struct gendisk *disk) 744static unsigned int floppy_check_events(struct gendisk *disk,
745 unsigned int clearing)
745{ 746{
746 struct floppy_state *fs = disk->private_data; 747 struct floppy_state *fs = disk->private_data;
747 748
748 return fs->ejected; 749 return fs->ejected ? DISK_EVENT_MEDIA_CHANGE : 0;
749} 750}
750 751
751static int floppy_revalidate(struct gendisk *disk) 752static int floppy_revalidate(struct gendisk *disk)
@@ -772,7 +773,7 @@ static const struct block_device_operations floppy_fops = {
772 .release = floppy_release, 773 .release = floppy_release,
773 .ioctl = floppy_ioctl, 774 .ioctl = floppy_ioctl,
774 .getgeo = floppy_getgeo, 775 .getgeo = floppy_getgeo,
775 .media_changed = floppy_check_change, 776 .check_events = floppy_check_events,
776 .revalidate_disk = floppy_revalidate, 777 .revalidate_disk = floppy_revalidate,
777}; 778};
778 779
@@ -857,6 +858,7 @@ static int __devinit swim_floppy_init(struct swim_priv *swd)
857 swd->unit[drive].disk->first_minor = drive; 858 swd->unit[drive].disk->first_minor = drive;
858 sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive); 859 sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
859 swd->unit[drive].disk->fops = &floppy_fops; 860 swd->unit[drive].disk->fops = &floppy_fops;
861 swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE;
860 swd->unit[drive].disk->private_data = &swd->unit[drive]; 862 swd->unit[drive].disk->private_data = &swd->unit[drive];
861 swd->unit[drive].disk->queue = swd->queue; 863 swd->unit[drive].disk->queue = swd->queue;
862 set_capacity(swd->unit[drive].disk, 2880); 864 set_capacity(swd->unit[drive].disk, 2880);
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index bf3a5b859299..4c10f56facbf 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -250,7 +250,8 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
250 unsigned int cmd, unsigned long param); 250 unsigned int cmd, unsigned long param);
251static int floppy_open(struct block_device *bdev, fmode_t mode); 251static int floppy_open(struct block_device *bdev, fmode_t mode);
252static int floppy_release(struct gendisk *disk, fmode_t mode); 252static int floppy_release(struct gendisk *disk, fmode_t mode);
253static int floppy_check_change(struct gendisk *disk); 253static unsigned int floppy_check_events(struct gendisk *disk,
254 unsigned int clearing);
254static int floppy_revalidate(struct gendisk *disk); 255static int floppy_revalidate(struct gendisk *disk);
255 256
256static bool swim3_end_request(int err, unsigned int nr_bytes) 257static bool swim3_end_request(int err, unsigned int nr_bytes)
@@ -975,10 +976,11 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
975 return 0; 976 return 0;
976} 977}
977 978
978static int floppy_check_change(struct gendisk *disk) 979static unsigned int floppy_check_events(struct gendisk *disk,
980 unsigned int clearing)
979{ 981{
980 struct floppy_state *fs = disk->private_data; 982 struct floppy_state *fs = disk->private_data;
981 return fs->ejected; 983 return fs->ejected ? DISK_EVENT_MEDIA_CHANGE : 0;
982} 984}
983 985
984static int floppy_revalidate(struct gendisk *disk) 986static int floppy_revalidate(struct gendisk *disk)
@@ -1025,7 +1027,7 @@ static const struct block_device_operations floppy_fops = {
1025 .open = floppy_unlocked_open, 1027 .open = floppy_unlocked_open,
1026 .release = floppy_release, 1028 .release = floppy_release,
1027 .ioctl = floppy_ioctl, 1029 .ioctl = floppy_ioctl,
1028 .media_changed = floppy_check_change, 1030 .check_events = floppy_check_events,
1029 .revalidate_disk= floppy_revalidate, 1031 .revalidate_disk= floppy_revalidate,
1030}; 1032};
1031 1033
@@ -1161,6 +1163,7 @@ static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device
1161 disk->major = FLOPPY_MAJOR; 1163 disk->major = FLOPPY_MAJOR;
1162 disk->first_minor = i; 1164 disk->first_minor = i;
1163 disk->fops = &floppy_fops; 1165 disk->fops = &floppy_fops;
1166 disk->events = DISK_EVENT_MEDIA_CHANGE;
1164 disk->private_data = &floppy_states[i]; 1167 disk->private_data = &floppy_states[i];
1165 disk->queue = swim3_queue; 1168 disk->queue = swim3_queue;
1166 disk->flags |= GENHD_FL_REMOVABLE; 1169 disk->flags |= GENHD_FL_REMOVABLE;
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 9ae3bb713286..68b9430c7cfe 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1788,7 +1788,8 @@ static int ub_bd_revalidate(struct gendisk *disk)
1788 * 1788 *
1789 * The return code is bool! 1789 * The return code is bool!
1790 */ 1790 */
1791static int ub_bd_media_changed(struct gendisk *disk) 1791static unsigned int ub_bd_check_events(struct gendisk *disk,
1792 unsigned int clearing)
1792{ 1793{
1793 struct ub_lun *lun = disk->private_data; 1794 struct ub_lun *lun = disk->private_data;
1794 1795
@@ -1806,10 +1807,10 @@ static int ub_bd_media_changed(struct gendisk *disk)
1806 */ 1807 */
1807 if (ub_sync_tur(lun->udev, lun) != 0) { 1808 if (ub_sync_tur(lun->udev, lun) != 0) {
1808 lun->changed = 1; 1809 lun->changed = 1;
1809 return 1; 1810 return DISK_EVENT_MEDIA_CHANGE;
1810 } 1811 }
1811 1812
1812 return lun->changed; 1813 return lun->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
1813} 1814}
1814 1815
1815static const struct block_device_operations ub_bd_fops = { 1816static const struct block_device_operations ub_bd_fops = {
@@ -1817,7 +1818,7 @@ static const struct block_device_operations ub_bd_fops = {
1817 .open = ub_bd_unlocked_open, 1818 .open = ub_bd_unlocked_open,
1818 .release = ub_bd_release, 1819 .release = ub_bd_release,
1819 .ioctl = ub_bd_ioctl, 1820 .ioctl = ub_bd_ioctl,
1820 .media_changed = ub_bd_media_changed, 1821 .check_events = ub_bd_check_events,
1821 .revalidate_disk = ub_bd_revalidate, 1822 .revalidate_disk = ub_bd_revalidate,
1822}; 1823};
1823 1824
@@ -2333,6 +2334,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
2333 disk->major = UB_MAJOR; 2334 disk->major = UB_MAJOR;
2334 disk->first_minor = lun->id * UB_PARTS_PER_LUN; 2335 disk->first_minor = lun->id * UB_PARTS_PER_LUN;
2335 disk->fops = &ub_bd_fops; 2336 disk->fops = &ub_bd_fops;
2337 disk->events = DISK_EVENT_MEDIA_CHANGE;
2336 disk->private_data = lun; 2338 disk->private_data = lun;
2337 disk->driverfs_dev = &sc->intf->dev; 2339 disk->driverfs_dev = &sc->intf->dev;
2338 2340
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 8be57151f5d6..031ca720d926 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -241,8 +241,7 @@ static void dump_dmastat(struct cardinfo *card, unsigned int dmastat)
241 * 241 *
242 * Whenever IO on the active page completes, the Ready page is activated 242 * Whenever IO on the active page completes, the Ready page is activated
243 * and the ex-Active page is clean out and made Ready. 243 * and the ex-Active page is clean out and made Ready.
244 * Otherwise the Ready page is only activated when it becomes full, or 244 * Otherwise the Ready page is only activated when it becomes full.
245 * when mm_unplug_device is called via the unplug_io_fn.
246 * 245 *
247 * If a request arrives while both pages a full, it is queued, and b_rdev is 246 * If a request arrives while both pages a full, it is queued, and b_rdev is
248 * overloaded to record whether it was a read or a write. 247 * overloaded to record whether it was a read or a write.
@@ -333,17 +332,6 @@ static inline void reset_page(struct mm_page *page)
333 page->biotail = &page->bio; 332 page->biotail = &page->bio;
334} 333}
335 334
336static void mm_unplug_device(struct request_queue *q)
337{
338 struct cardinfo *card = q->queuedata;
339 unsigned long flags;
340
341 spin_lock_irqsave(&card->lock, flags);
342 if (blk_remove_plug(q))
343 activate(card);
344 spin_unlock_irqrestore(&card->lock, flags);
345}
346
347/* 335/*
348 * If there is room on Ready page, take 336 * If there is room on Ready page, take
349 * one bh off list and add it. 337 * one bh off list and add it.
@@ -535,7 +523,6 @@ static int mm_make_request(struct request_queue *q, struct bio *bio)
535 *card->biotail = bio; 523 *card->biotail = bio;
536 bio->bi_next = NULL; 524 bio->bi_next = NULL;
537 card->biotail = &bio->bi_next; 525 card->biotail = &bio->bi_next;
538 blk_plug_device(q);
539 spin_unlock_irq(&card->lock); 526 spin_unlock_irq(&card->lock);
540 527
541 return 0; 528 return 0;
@@ -779,20 +766,10 @@ static int mm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
779 return 0; 766 return 0;
780} 767}
781 768
782/*
783 * Future support for removable devices
784 */
785static int mm_check_change(struct gendisk *disk)
786{
787/* struct cardinfo *dev = disk->private_data; */
788 return 0;
789}
790
791static const struct block_device_operations mm_fops = { 769static const struct block_device_operations mm_fops = {
792 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
793 .getgeo = mm_getgeo, 771 .getgeo = mm_getgeo,
794 .revalidate_disk = mm_revalidate, 772 .revalidate_disk = mm_revalidate,
795 .media_changed = mm_check_change,
796}; 773};
797 774
798static int __devinit mm_pci_probe(struct pci_dev *dev, 775static int __devinit mm_pci_probe(struct pci_dev *dev,
@@ -907,7 +884,6 @@ static int __devinit mm_pci_probe(struct pci_dev *dev,
907 blk_queue_make_request(card->queue, mm_make_request); 884 blk_queue_make_request(card->queue, mm_make_request);
908 card->queue->queue_lock = &card->lock; 885 card->queue->queue_lock = &card->lock;
909 card->queue->queuedata = card; 886 card->queue->queuedata = card;
910 card->queue->unplug_fn = mm_unplug_device;
911 887
912 tasklet_init(&card->tasklet, process_page, (unsigned long)card); 888 tasklet_init(&card->tasklet, process_page, (unsigned long)card);
913 889
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 2c590a796aa1..73354b081ed3 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -867,12 +867,12 @@ static void ace_request(struct request_queue * q)
867 } 867 }
868} 868}
869 869
870static int ace_media_changed(struct gendisk *gd) 870static unsigned int ace_check_events(struct gendisk *gd, unsigned int clearing)
871{ 871{
872 struct ace_device *ace = gd->private_data; 872 struct ace_device *ace = gd->private_data;
873 dev_dbg(ace->dev, "ace_media_changed(): %i\n", ace->media_change); 873 dev_dbg(ace->dev, "ace_check_events(): %i\n", ace->media_change);
874 874
875 return ace->media_change; 875 return ace->media_change ? DISK_EVENT_MEDIA_CHANGE : 0;
876} 876}
877 877
878static int ace_revalidate_disk(struct gendisk *gd) 878static int ace_revalidate_disk(struct gendisk *gd)
@@ -953,7 +953,7 @@ static const struct block_device_operations ace_fops = {
953 .owner = THIS_MODULE, 953 .owner = THIS_MODULE,
954 .open = ace_open, 954 .open = ace_open,
955 .release = ace_release, 955 .release = ace_release,
956 .media_changed = ace_media_changed, 956 .check_events = ace_check_events,
957 .revalidate_disk = ace_revalidate_disk, 957 .revalidate_disk = ace_revalidate_disk,
958 .getgeo = ace_getgeo, 958 .getgeo = ace_getgeo,
959}; 959};
@@ -1005,6 +1005,7 @@ static int __devinit ace_setup(struct ace_device *ace)
1005 ace->gd->major = ace_major; 1005 ace->gd->major = ace_major;
1006 ace->gd->first_minor = ace->id * ACE_NUM_MINORS; 1006 ace->gd->first_minor = ace->id * ACE_NUM_MINORS;
1007 ace->gd->fops = &ace_fops; 1007 ace->gd->fops = &ace_fops;
1008 ace->gd->events = DISK_EVENT_MEDIA_CHANGE;
1008 ace->gd->queue = ace->queue; 1009 ace->gd->queue = ace->queue;
1009 ace->gd->private_data = ace; 1010 ace->gd->private_data = ace;
1010 snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a'); 1011 snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a');
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 64a21461c408..b2b034fea34e 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -395,10 +395,12 @@ static int gdrom_drivestatus(struct cdrom_device_info *cd_info, int ignore)
395 return CDS_NO_INFO; 395 return CDS_NO_INFO;
396} 396}
397 397
398static int gdrom_mediachanged(struct cdrom_device_info *cd_info, int ignore) 398static unsigned int gdrom_check_events(struct cdrom_device_info *cd_info,
399 unsigned int clearing, int ignore)
399{ 400{
400 /* check the sense key */ 401 /* check the sense key */
401 return (__raw_readb(GDROM_ERROR_REG) & 0xF0) == 0x60; 402 return (__raw_readb(GDROM_ERROR_REG) & 0xF0) == 0x60 ?
403 DISK_EVENT_MEDIA_CHANGE : 0;
402} 404}
403 405
404/* reset the G1 bus */ 406/* reset the G1 bus */
@@ -483,7 +485,7 @@ static struct cdrom_device_ops gdrom_ops = {
483 .open = gdrom_open, 485 .open = gdrom_open,
484 .release = gdrom_release, 486 .release = gdrom_release,
485 .drive_status = gdrom_drivestatus, 487 .drive_status = gdrom_drivestatus,
486 .media_changed = gdrom_mediachanged, 488 .check_events = gdrom_check_events,
487 .get_last_session = gdrom_get_last_session, 489 .get_last_session = gdrom_get_last_session,
488 .reset = gdrom_hardreset, 490 .reset = gdrom_hardreset,
489 .audio_ioctl = gdrom_audio_ioctl, 491 .audio_ioctl = gdrom_audio_ioctl,
@@ -509,9 +511,10 @@ static int gdrom_bdops_release(struct gendisk *disk, fmode_t mode)
509 return 0; 511 return 0;
510} 512}
511 513
512static int gdrom_bdops_mediachanged(struct gendisk *disk) 514static unsigned int gdrom_bdops_check_events(struct gendisk *disk,
515 unsigned int clearing)
513{ 516{
514 return cdrom_media_changed(gd.cd_info); 517 return cdrom_check_events(gd.cd_info, clearing);
515} 518}
516 519
517static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode, 520static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode,
@@ -530,7 +533,7 @@ static const struct block_device_operations gdrom_bdops = {
530 .owner = THIS_MODULE, 533 .owner = THIS_MODULE,
531 .open = gdrom_bdops_open, 534 .open = gdrom_bdops_open,
532 .release = gdrom_bdops_release, 535 .release = gdrom_bdops_release,
533 .media_changed = gdrom_bdops_mediachanged, 536 .check_events = gdrom_bdops_check_events,
534 .ioctl = gdrom_bdops_ioctl, 537 .ioctl = gdrom_bdops_ioctl,
535}; 538};
536 539
@@ -800,6 +803,7 @@ static int __devinit probe_gdrom(struct platform_device *devptr)
800 goto probe_fail_cdrom_register; 803 goto probe_fail_cdrom_register;
801 } 804 }
802 gd.disk->fops = &gdrom_bdops; 805 gd.disk->fops = &gdrom_bdops;
806 gd.disk->events = DISK_EVENT_MEDIA_CHANGE;
803 /* latch on to the interrupt */ 807 /* latch on to the interrupt */
804 err = gdrom_set_interrupt_handlers(); 808 err = gdrom_set_interrupt_handlers();
805 if (err) 809 if (err)
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index be73a9b493a6..4e874c5fa605 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -186,10 +186,11 @@ static int viocd_blk_ioctl(struct block_device *bdev, fmode_t mode,
186 return ret; 186 return ret;
187} 187}
188 188
189static int viocd_blk_media_changed(struct gendisk *disk) 189static unsigned int viocd_blk_check_events(struct gendisk *disk,
190 unsigned int clearing)
190{ 191{
191 struct disk_info *di = disk->private_data; 192 struct disk_info *di = disk->private_data;
192 return cdrom_media_changed(&di->viocd_info); 193 return cdrom_check_events(&di->viocd_info, clearing);
193} 194}
194 195
195static const struct block_device_operations viocd_fops = { 196static const struct block_device_operations viocd_fops = {
@@ -197,7 +198,7 @@ static const struct block_device_operations viocd_fops = {
197 .open = viocd_blk_open, 198 .open = viocd_blk_open,
198 .release = viocd_blk_release, 199 .release = viocd_blk_release,
199 .ioctl = viocd_blk_ioctl, 200 .ioctl = viocd_blk_ioctl,
200 .media_changed = viocd_blk_media_changed, 201 .check_events = viocd_blk_check_events,
201}; 202};
202 203
203static int viocd_open(struct cdrom_device_info *cdi, int purpose) 204static int viocd_open(struct cdrom_device_info *cdi, int purpose)
@@ -320,7 +321,8 @@ static void do_viocd_request(struct request_queue *q)
320 } 321 }
321} 322}
322 323
323static int viocd_media_changed(struct cdrom_device_info *cdi, int disc_nr) 324static unsigned int viocd_check_events(struct cdrom_device_info *cdi,
325 unsigned int clearing, int disc_nr)
324{ 326{
325 struct viocd_waitevent we; 327 struct viocd_waitevent we;
326 HvLpEvent_Rc hvrc; 328 HvLpEvent_Rc hvrc;
@@ -340,7 +342,7 @@ static int viocd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
340 if (hvrc != 0) { 342 if (hvrc != 0) {
341 pr_warning("bad rc on HvCallEvent_signalLpEventFast %d\n", 343 pr_warning("bad rc on HvCallEvent_signalLpEventFast %d\n",
342 (int)hvrc); 344 (int)hvrc);
343 return -EIO; 345 return 0;
344 } 346 }
345 347
346 wait_for_completion(&we.com); 348 wait_for_completion(&we.com);
@@ -354,7 +356,7 @@ static int viocd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
354 return 0; 356 return 0;
355 } 357 }
356 358
357 return we.changed; 359 return we.changed ? DISK_EVENT_MEDIA_CHANGE : 0;
358} 360}
359 361
360static int viocd_lock_door(struct cdrom_device_info *cdi, int locking) 362static int viocd_lock_door(struct cdrom_device_info *cdi, int locking)
@@ -550,7 +552,7 @@ static int viocd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
550static struct cdrom_device_ops viocd_dops = { 552static struct cdrom_device_ops viocd_dops = {
551 .open = viocd_open, 553 .open = viocd_open,
552 .release = viocd_release, 554 .release = viocd_release,
553 .media_changed = viocd_media_changed, 555 .check_events = viocd_check_events,
554 .lock_door = viocd_lock_door, 556 .lock_door = viocd_lock_door,
555 .generic_packet = viocd_packet, 557 .generic_packet = viocd_packet,
556 .audio_ioctl = viocd_audio_ioctl, 558 .audio_ioctl = viocd_audio_ioctl,
@@ -624,6 +626,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
624 gendisk->queue = q; 626 gendisk->queue = q;
625 gendisk->fops = &viocd_fops; 627 gendisk->fops = &viocd_fops;
626 gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; 628 gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE;
629 gendisk->events = DISK_EVENT_MEDIA_CHANGE;
627 set_capacity(gendisk, 0); 630 set_capacity(gendisk, 0);
628 gendisk->private_data = d; 631 gendisk->private_data = d;
629 d->viocd_disk = gendisk; 632 d->viocd_disk = gendisk;
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index f69f90a61873..d2c75feff7df 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -27,6 +27,7 @@
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/mfd/core.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31 32
32#include <linux/timb_dma.h> 33#include <linux/timb_dma.h>
@@ -684,7 +685,7 @@ static irqreturn_t td_irq(int irq, void *devid)
684 685
685static int __devinit td_probe(struct platform_device *pdev) 686static int __devinit td_probe(struct platform_device *pdev)
686{ 687{
687 struct timb_dma_platform_data *pdata = pdev->dev.platform_data; 688 struct timb_dma_platform_data *pdata = mfd_get_data(pdev);
688 struct timb_dma *td; 689 struct timb_dma *td;
689 struct resource *iomem; 690 struct resource *iomem;
690 int irq; 691 int irq;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b46442d7d66e..d8d0cda2641d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -100,18 +100,21 @@ config GPIO_VR41XX
100 Say yes here to support the NEC VR4100 series General-purpose I/O Uint 100 Say yes here to support the NEC VR4100 series General-purpose I/O Uint
101 101
102config GPIO_SCH 102config GPIO_SCH
103 tristate "Intel SCH GPIO" 103 tristate "Intel SCH/TunnelCreek GPIO"
104 depends on GPIOLIB && PCI && X86 104 depends on GPIOLIB && PCI && X86
105 select MFD_CORE 105 select MFD_CORE
106 select LPC_SCH 106 select LPC_SCH
107 help 107 help
108 Say yes here to support GPIO interface on Intel Poulsbo SCH. 108 Say yes here to support GPIO interface on Intel Poulsbo SCH
109 or Intel Tunnel Creek processor.
109 The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are 110 The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are
110 powered by the core power rail and are turned off during sleep 111 powered by the core power rail and are turned off during sleep
111 modes (S3 and higher). The remaining four GPIOs are powered by 112 modes (S3 and higher). The remaining four GPIOs are powered by
112 the Intel SCH suspend power supply. These GPIOs remain 113 the Intel SCH suspend power supply. These GPIOs remain
113 active during S3. The suspend powered GPIOs can be used to wake the 114 active during S3. The suspend powered GPIOs can be used to wake the
114 system from the Suspend-to-RAM state. 115 system from the Suspend-to-RAM state.
116 The Intel Tunnel Creek processor has 5 GPIOs powered by the
117 core power rail and 9 from suspend power supply.
115 118
116 This driver can also be built as a module. If so, the module 119 This driver can also be built as a module. If so, the module
117 will be called sch-gpio. 120 will be called sch-gpio.
diff --git a/drivers/gpio/janz-ttl.c b/drivers/gpio/janz-ttl.c
index 813ac077e5d7..2514fb075f4a 100644
--- a/drivers/gpio/janz-ttl.c
+++ b/drivers/gpio/janz-ttl.c
@@ -15,6 +15,7 @@
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/mfd/core.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/gpio.h> 20#include <linux/gpio.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
@@ -149,7 +150,7 @@ static int __devinit ttl_probe(struct platform_device *pdev)
149 struct resource *res; 150 struct resource *res;
150 int ret; 151 int ret;
151 152
152 pdata = pdev->dev.platform_data; 153 pdata = mfd_get_data(pdev);
153 if (!pdata) { 154 if (!pdata) {
154 dev_err(dev, "no platform data\n"); 155 dev_err(dev, "no platform data\n");
155 ret = -ENXIO; 156 ret = -ENXIO;
diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c
index 897e0577e65e..a9bda881935a 100644
--- a/drivers/gpio/rdc321x-gpio.c
+++ b/drivers/gpio/rdc321x-gpio.c
@@ -27,6 +27,7 @@
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29#include <linux/mfd/rdc321x.h> 29#include <linux/mfd/rdc321x.h>
30#include <linux/mfd/core.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31 32
32struct rdc321x_gpio { 33struct rdc321x_gpio {
@@ -135,7 +136,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev)
135 struct rdc321x_gpio *rdc321x_gpio_dev; 136 struct rdc321x_gpio *rdc321x_gpio_dev;
136 struct rdc321x_gpio_pdata *pdata; 137 struct rdc321x_gpio_pdata *pdata;
137 138
138 pdata = platform_get_drvdata(pdev); 139 pdata = mfd_get_data(pdev);
139 if (!pdata) { 140 if (!pdata) {
140 dev_err(&pdev->dev, "no platform data supplied\n"); 141 dev_err(&pdev->dev, "no platform data supplied\n");
141 return -ENODEV; 142 return -ENODEV;
diff --git a/drivers/gpio/sch_gpio.c b/drivers/gpio/sch_gpio.c
index 583521352c16..56060421cdff 100644
--- a/drivers/gpio/sch_gpio.c
+++ b/drivers/gpio/sch_gpio.c
@@ -25,6 +25,7 @@
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/acpi.h> 26#include <linux/acpi.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/pci_ids.h>
28 29
29#include <linux/gpio.h> 30#include <linux/gpio.h>
30 31
@@ -187,7 +188,11 @@ static struct gpio_chip sch_gpio_resume = {
187static int __devinit sch_gpio_probe(struct platform_device *pdev) 188static int __devinit sch_gpio_probe(struct platform_device *pdev)
188{ 189{
189 struct resource *res; 190 struct resource *res;
190 int err; 191 int err, id;
192
193 id = pdev->id;
194 if (!id)
195 return -ENODEV;
191 196
192 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 197 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
193 if (!res) 198 if (!res)
@@ -198,12 +203,40 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev)
198 203
199 gpio_ba = res->start; 204 gpio_ba = res->start;
200 205
201 sch_gpio_core.base = 0; 206 switch (id) {
202 sch_gpio_core.ngpio = 10; 207 case PCI_DEVICE_ID_INTEL_SCH_LPC:
203 sch_gpio_core.dev = &pdev->dev; 208 sch_gpio_core.base = 0;
209 sch_gpio_core.ngpio = 10;
210
211 sch_gpio_resume.base = 10;
212 sch_gpio_resume.ngpio = 4;
213
214 /*
215 * GPIO[6:0] enabled by default
216 * GPIO7 is configured by the CMC as SLPIOVR
217 * Enable GPIO[9:8] core powered gpios explicitly
218 */
219 outb(0x3, gpio_ba + CGEN + 1);
220 /*
221 * SUS_GPIO[2:0] enabled by default
222 * Enable SUS_GPIO3 resume powered gpio explicitly
223 */
224 outb(0x8, gpio_ba + RGEN);
225 break;
226
227 case PCI_DEVICE_ID_INTEL_ITC_LPC:
228 sch_gpio_core.base = 0;
229 sch_gpio_core.ngpio = 5;
230
231 sch_gpio_resume.base = 5;
232 sch_gpio_resume.ngpio = 9;
233 break;
234
235 default:
236 return -ENODEV;
237 }
204 238
205 sch_gpio_resume.base = 10; 239 sch_gpio_core.dev = &pdev->dev;
206 sch_gpio_resume.ngpio = 4;
207 sch_gpio_resume.dev = &pdev->dev; 240 sch_gpio_resume.dev = &pdev->dev;
208 241
209 err = gpiochip_add(&sch_gpio_core); 242 err = gpiochip_add(&sch_gpio_core);
@@ -214,18 +247,6 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev)
214 if (err < 0) 247 if (err < 0)
215 goto err_sch_gpio_resume; 248 goto err_sch_gpio_resume;
216 249
217 /*
218 * GPIO[6:0] enabled by default
219 * GPIO7 is configured by the CMC as SLPIOVR
220 * Enable GPIO[9:8] core powered gpios explicitly
221 */
222 outb(0x3, gpio_ba + CGEN + 1);
223 /*
224 * SUS_GPIO[2:0] enabled by default
225 * Enable SUS_GPIO3 resume powered gpio explicitly
226 */
227 outb(0x8, gpio_ba + RGEN);
228
229 return 0; 250 return 0;
230 251
231err_sch_gpio_resume: 252err_sch_gpio_resume:
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index 58c8f30352dd..ffcd815b8b8b 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/mfd/core.h>
26#include <linux/irq.h> 27#include <linux/irq.h>
27#include <linux/io.h> 28#include <linux/io.h>
28#include <linux/timb_gpio.h> 29#include <linux/timb_gpio.h>
@@ -228,7 +229,7 @@ static int __devinit timbgpio_probe(struct platform_device *pdev)
228 struct gpio_chip *gc; 229 struct gpio_chip *gc;
229 struct timbgpio *tgpio; 230 struct timbgpio *tgpio;
230 struct resource *iomem; 231 struct resource *iomem;
231 struct timbgpio_platform_data *pdata = pdev->dev.platform_data; 232 struct timbgpio_platform_data *pdata = mfd_get_data(pdev);
232 int irq = platform_get_irq(pdev, 0); 233 int irq = platform_get_irq(pdev, 0);
233 234
234 if (!pdata || pdata->nr_pins > 32) { 235 if (!pdata || pdata->nr_pins > 32) {
@@ -319,14 +320,13 @@ err_mem:
319static int __devexit timbgpio_remove(struct platform_device *pdev) 320static int __devexit timbgpio_remove(struct platform_device *pdev)
320{ 321{
321 int err; 322 int err;
322 struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
323 struct timbgpio *tgpio = platform_get_drvdata(pdev); 323 struct timbgpio *tgpio = platform_get_drvdata(pdev);
324 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 324 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
325 int irq = platform_get_irq(pdev, 0); 325 int irq = platform_get_irq(pdev, 0);
326 326
327 if (irq >= 0 && tgpio->irq_base > 0) { 327 if (irq >= 0 && tgpio->irq_base > 0) {
328 int i; 328 int i;
329 for (i = 0; i < pdata->nr_pins; i++) { 329 for (i = 0; i < tgpio->gpio.ngpio; i++) {
330 set_irq_chip(tgpio->irq_base + i, NULL); 330 set_irq_chip(tgpio->irq_base + i, NULL);
331 set_irq_chip_data(tgpio->irq_base + i, NULL); 331 set_irq_chip_data(tgpio->irq_base + i, NULL);
332 } 332 }
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 4c95b5fd9df3..799e1490cf24 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1073,6 +1073,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
1073 uint32_t __user *encoder_id; 1073 uint32_t __user *encoder_id;
1074 struct drm_mode_group *mode_group; 1074 struct drm_mode_group *mode_group;
1075 1075
1076 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1077 return -EINVAL;
1078
1076 mutex_lock(&dev->mode_config.mutex); 1079 mutex_lock(&dev->mode_config.mutex);
1077 1080
1078 /* 1081 /*
@@ -1244,6 +1247,9 @@ int drm_mode_getcrtc(struct drm_device *dev,
1244 struct drm_mode_object *obj; 1247 struct drm_mode_object *obj;
1245 int ret = 0; 1248 int ret = 0;
1246 1249
1250 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1251 return -EINVAL;
1252
1247 mutex_lock(&dev->mode_config.mutex); 1253 mutex_lock(&dev->mode_config.mutex);
1248 1254
1249 obj = drm_mode_object_find(dev, crtc_resp->crtc_id, 1255 obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
@@ -1312,6 +1318,9 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
1312 uint64_t __user *prop_values; 1318 uint64_t __user *prop_values;
1313 uint32_t __user *encoder_ptr; 1319 uint32_t __user *encoder_ptr;
1314 1320
1321 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1322 return -EINVAL;
1323
1315 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); 1324 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1316 1325
1317 DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id); 1326 DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
@@ -1431,6 +1440,9 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
1431 struct drm_encoder *encoder; 1440 struct drm_encoder *encoder;
1432 int ret = 0; 1441 int ret = 0;
1433 1442
1443 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1444 return -EINVAL;
1445
1434 mutex_lock(&dev->mode_config.mutex); 1446 mutex_lock(&dev->mode_config.mutex);
1435 obj = drm_mode_object_find(dev, enc_resp->encoder_id, 1447 obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1436 DRM_MODE_OBJECT_ENCODER); 1448 DRM_MODE_OBJECT_ENCODER);
@@ -1486,6 +1498,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
1486 int ret = 0; 1498 int ret = 0;
1487 int i; 1499 int i;
1488 1500
1501 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1502 return -EINVAL;
1503
1489 mutex_lock(&dev->mode_config.mutex); 1504 mutex_lock(&dev->mode_config.mutex);
1490 obj = drm_mode_object_find(dev, crtc_req->crtc_id, 1505 obj = drm_mode_object_find(dev, crtc_req->crtc_id,
1491 DRM_MODE_OBJECT_CRTC); 1506 DRM_MODE_OBJECT_CRTC);
@@ -1603,6 +1618,9 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
1603 struct drm_crtc *crtc; 1618 struct drm_crtc *crtc;
1604 int ret = 0; 1619 int ret = 0;
1605 1620
1621 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1622 return -EINVAL;
1623
1606 if (!req->flags) { 1624 if (!req->flags) {
1607 DRM_ERROR("no operation set\n"); 1625 DRM_ERROR("no operation set\n");
1608 return -EINVAL; 1626 return -EINVAL;
@@ -1667,6 +1685,9 @@ int drm_mode_addfb(struct drm_device *dev,
1667 struct drm_framebuffer *fb; 1685 struct drm_framebuffer *fb;
1668 int ret = 0; 1686 int ret = 0;
1669 1687
1688 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1689 return -EINVAL;
1690
1670 if ((config->min_width > r->width) || (r->width > config->max_width)) { 1691 if ((config->min_width > r->width) || (r->width > config->max_width)) {
1671 DRM_ERROR("mode new framebuffer width not within limits\n"); 1692 DRM_ERROR("mode new framebuffer width not within limits\n");
1672 return -EINVAL; 1693 return -EINVAL;
@@ -1724,6 +1745,9 @@ int drm_mode_rmfb(struct drm_device *dev,
1724 int ret = 0; 1745 int ret = 0;
1725 int found = 0; 1746 int found = 0;
1726 1747
1748 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1749 return -EINVAL;
1750
1727 mutex_lock(&dev->mode_config.mutex); 1751 mutex_lock(&dev->mode_config.mutex);
1728 obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB); 1752 obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
1729 /* TODO check that we realy get a framebuffer back. */ 1753 /* TODO check that we realy get a framebuffer back. */
@@ -1780,6 +1804,9 @@ int drm_mode_getfb(struct drm_device *dev,
1780 struct drm_framebuffer *fb; 1804 struct drm_framebuffer *fb;
1781 int ret = 0; 1805 int ret = 0;
1782 1806
1807 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1808 return -EINVAL;
1809
1783 mutex_lock(&dev->mode_config.mutex); 1810 mutex_lock(&dev->mode_config.mutex);
1784 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); 1811 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
1785 if (!obj) { 1812 if (!obj) {
@@ -1813,6 +1840,9 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
1813 int num_clips; 1840 int num_clips;
1814 int ret = 0; 1841 int ret = 0;
1815 1842
1843 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1844 return -EINVAL;
1845
1816 mutex_lock(&dev->mode_config.mutex); 1846 mutex_lock(&dev->mode_config.mutex);
1817 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); 1847 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
1818 if (!obj) { 1848 if (!obj) {
@@ -1996,6 +2026,9 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
1996 struct drm_mode_modeinfo *umode = &mode_cmd->mode; 2026 struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1997 int ret = 0; 2027 int ret = 0;
1998 2028
2029 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2030 return -EINVAL;
2031
1999 mutex_lock(&dev->mode_config.mutex); 2032 mutex_lock(&dev->mode_config.mutex);
2000 2033
2001 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2034 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
@@ -2042,6 +2075,9 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
2042 struct drm_mode_modeinfo *umode = &mode_cmd->mode; 2075 struct drm_mode_modeinfo *umode = &mode_cmd->mode;
2043 int ret = 0; 2076 int ret = 0;
2044 2077
2078 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2079 return -EINVAL;
2080
2045 mutex_lock(&dev->mode_config.mutex); 2081 mutex_lock(&dev->mode_config.mutex);
2046 2082
2047 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2083 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
@@ -2211,6 +2247,9 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
2211 uint64_t __user *values_ptr; 2247 uint64_t __user *values_ptr;
2212 uint32_t __user *blob_length_ptr; 2248 uint32_t __user *blob_length_ptr;
2213 2249
2250 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2251 return -EINVAL;
2252
2214 mutex_lock(&dev->mode_config.mutex); 2253 mutex_lock(&dev->mode_config.mutex);
2215 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); 2254 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2216 if (!obj) { 2255 if (!obj) {
@@ -2333,6 +2372,9 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
2333 int ret = 0; 2372 int ret = 0;
2334 void *blob_ptr; 2373 void *blob_ptr;
2335 2374
2375 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2376 return -EINVAL;
2377
2336 mutex_lock(&dev->mode_config.mutex); 2378 mutex_lock(&dev->mode_config.mutex);
2337 obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB); 2379 obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
2338 if (!obj) { 2380 if (!obj) {
@@ -2393,6 +2435,9 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
2393 int ret = -EINVAL; 2435 int ret = -EINVAL;
2394 int i; 2436 int i;
2395 2437
2438 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2439 return -EINVAL;
2440
2396 mutex_lock(&dev->mode_config.mutex); 2441 mutex_lock(&dev->mode_config.mutex);
2397 2442
2398 obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2443 obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
@@ -2509,6 +2554,9 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
2509 int size; 2554 int size;
2510 int ret = 0; 2555 int ret = 0;
2511 2556
2557 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2558 return -EINVAL;
2559
2512 mutex_lock(&dev->mode_config.mutex); 2560 mutex_lock(&dev->mode_config.mutex);
2513 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); 2561 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2514 if (!obj) { 2562 if (!obj) {
@@ -2560,6 +2608,9 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
2560 int size; 2608 int size;
2561 int ret = 0; 2609 int ret = 0;
2562 2610
2611 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2612 return -EINVAL;
2613
2563 mutex_lock(&dev->mode_config.mutex); 2614 mutex_lock(&dev->mode_config.mutex);
2564 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); 2615 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2565 if (!obj) { 2616 if (!obj) {
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 57ce27c9a747..74e4ff578017 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -499,11 +499,12 @@ EXPORT_SYMBOL(drm_gem_vm_open);
499void drm_gem_vm_close(struct vm_area_struct *vma) 499void drm_gem_vm_close(struct vm_area_struct *vma)
500{ 500{
501 struct drm_gem_object *obj = vma->vm_private_data; 501 struct drm_gem_object *obj = vma->vm_private_data;
502 struct drm_device *dev = obj->dev;
502 503
503 mutex_lock(&obj->dev->struct_mutex); 504 mutex_lock(&dev->struct_mutex);
504 drm_vm_close_locked(vma); 505 drm_vm_close_locked(vma);
505 drm_gem_object_unreference(obj); 506 drm_gem_object_unreference(obj);
506 mutex_unlock(&obj->dev->struct_mutex); 507 mutex_unlock(&dev->struct_mutex);
507} 508}
508EXPORT_SYMBOL(drm_gem_vm_close); 509EXPORT_SYMBOL(drm_gem_vm_close);
509 510
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7f6912a16761..904d7e9c8e47 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -280,6 +280,9 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
280 if (dev->driver->dumb_create) 280 if (dev->driver->dumb_create)
281 req->value = 1; 281 req->value = 1;
282 break; 282 break;
283 case DRM_CAP_VBLANK_HIGH_CRTC:
284 req->value = 1;
285 break;
283 default: 286 default:
284 return -EINVAL; 287 return -EINVAL;
285 } 288 }
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index a34ef97d3c81..741457bd1c46 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1125,7 +1125,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1125{ 1125{
1126 union drm_wait_vblank *vblwait = data; 1126 union drm_wait_vblank *vblwait = data;
1127 int ret = 0; 1127 int ret = 0;
1128 unsigned int flags, seq, crtc; 1128 unsigned int flags, seq, crtc, high_crtc;
1129 1129
1130 if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled)) 1130 if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
1131 return -EINVAL; 1131 return -EINVAL;
@@ -1134,16 +1134,21 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1134 return -EINVAL; 1134 return -EINVAL;
1135 1135
1136 if (vblwait->request.type & 1136 if (vblwait->request.type &
1137 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) { 1137 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
1138 _DRM_VBLANK_HIGH_CRTC_MASK)) {
1138 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", 1139 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
1139 vblwait->request.type, 1140 vblwait->request.type,
1140 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)); 1141 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
1142 _DRM_VBLANK_HIGH_CRTC_MASK));
1141 return -EINVAL; 1143 return -EINVAL;
1142 } 1144 }
1143 1145
1144 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; 1146 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
1145 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; 1147 high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
1146 1148 if (high_crtc)
1149 crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
1150 else
1151 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
1147 if (crtc >= dev->num_crtcs) 1152 if (crtc >= dev->num_crtcs)
1148 return -EINVAL; 1153 return -EINVAL;
1149 1154
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 09e0327fc6ce..87c8e29465e3 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -892,7 +892,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
892 seq_printf(m, "Render p-state limit: %d\n", 892 seq_printf(m, "Render p-state limit: %d\n",
893 rp_state_limits & 0xff); 893 rp_state_limits & 0xff);
894 seq_printf(m, "CAGF: %dMHz\n", ((rpstat & GEN6_CAGF_MASK) >> 894 seq_printf(m, "CAGF: %dMHz\n", ((rpstat & GEN6_CAGF_MASK) >>
895 GEN6_CAGF_SHIFT) * 100); 895 GEN6_CAGF_SHIFT) * 50);
896 seq_printf(m, "RP CUR UP EI: %dus\n", rpupei & 896 seq_printf(m, "RP CUR UP EI: %dus\n", rpupei &
897 GEN6_CURICONT_MASK); 897 GEN6_CURICONT_MASK);
898 seq_printf(m, "RP CUR UP: %dus\n", rpcurup & 898 seq_printf(m, "RP CUR UP: %dus\n", rpcurup &
@@ -908,15 +908,15 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
908 908
909 max_freq = (rp_state_cap & 0xff0000) >> 16; 909 max_freq = (rp_state_cap & 0xff0000) >> 16;
910 seq_printf(m, "Lowest (RPN) frequency: %dMHz\n", 910 seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
911 max_freq * 100); 911 max_freq * 50);
912 912
913 max_freq = (rp_state_cap & 0xff00) >> 8; 913 max_freq = (rp_state_cap & 0xff00) >> 8;
914 seq_printf(m, "Nominal (RP1) frequency: %dMHz\n", 914 seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
915 max_freq * 100); 915 max_freq * 50);
916 916
917 max_freq = rp_state_cap & 0xff; 917 max_freq = rp_state_cap & 0xff;
918 seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", 918 seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
919 max_freq * 100); 919 max_freq * 50);
920 920
921 __gen6_gt_force_wake_put(dev_priv); 921 __gen6_gt_force_wake_put(dev_priv);
922 } else { 922 } else {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c4c2855d002d..7ce3f353af33 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -224,7 +224,7 @@ i915_gem_dumb_create(struct drm_file *file,
224 struct drm_mode_create_dumb *args) 224 struct drm_mode_create_dumb *args)
225{ 225{
226 /* have to work out size/pitch and return them */ 226 /* have to work out size/pitch and return them */
227 args->pitch = ALIGN(args->width & ((args->bpp + 1) / 8), 64); 227 args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
228 args->size = args->pitch * args->height; 228 args->size = args->pitch * args->height;
229 return i915_gem_create(file, dev, 229 return i915_gem_create(file, dev,
230 args->size, &args->handle); 230 args->size, &args->handle);
@@ -1356,9 +1356,10 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj)
1356 if (!obj->fault_mappable) 1356 if (!obj->fault_mappable)
1357 return; 1357 return;
1358 1358
1359 unmap_mapping_range(obj->base.dev->dev_mapping, 1359 if (obj->base.dev->dev_mapping)
1360 (loff_t)obj->base.map_list.hash.key<<PAGE_SHIFT, 1360 unmap_mapping_range(obj->base.dev->dev_mapping,
1361 obj->base.size, 1); 1361 (loff_t)obj->base.map_list.hash.key<<PAGE_SHIFT,
1362 obj->base.size, 1);
1362 1363
1363 obj->fault_mappable = false; 1364 obj->fault_mappable = false;
1364} 1365}
@@ -1796,8 +1797,10 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
1796 return; 1797 return;
1797 1798
1798 spin_lock(&file_priv->mm.lock); 1799 spin_lock(&file_priv->mm.lock);
1799 list_del(&request->client_list); 1800 if (request->file_priv) {
1800 request->file_priv = NULL; 1801 list_del(&request->client_list);
1802 request->file_priv = NULL;
1803 }
1801 spin_unlock(&file_priv->mm.lock); 1804 spin_unlock(&file_priv->mm.lock);
1802} 1805}
1803 1806
@@ -2217,13 +2220,18 @@ i915_gem_flush_ring(struct intel_ring_buffer *ring,
2217{ 2220{
2218 int ret; 2221 int ret;
2219 2222
2223 if (((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) == 0)
2224 return 0;
2225
2220 trace_i915_gem_ring_flush(ring, invalidate_domains, flush_domains); 2226 trace_i915_gem_ring_flush(ring, invalidate_domains, flush_domains);
2221 2227
2222 ret = ring->flush(ring, invalidate_domains, flush_domains); 2228 ret = ring->flush(ring, invalidate_domains, flush_domains);
2223 if (ret) 2229 if (ret)
2224 return ret; 2230 return ret;
2225 2231
2226 i915_gem_process_flushing_list(ring, flush_domains); 2232 if (flush_domains & I915_GEM_GPU_DOMAINS)
2233 i915_gem_process_flushing_list(ring, flush_domains);
2234
2227 return 0; 2235 return 0;
2228} 2236}
2229 2237
@@ -2579,8 +2587,23 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
2579 reg = &dev_priv->fence_regs[obj->fence_reg]; 2587 reg = &dev_priv->fence_regs[obj->fence_reg];
2580 list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list); 2588 list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list);
2581 2589
2582 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) 2590 if (obj->tiling_changed) {
2583 pipelined = NULL; 2591 ret = i915_gem_object_flush_fence(obj, pipelined);
2592 if (ret)
2593 return ret;
2594
2595 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
2596 pipelined = NULL;
2597
2598 if (pipelined) {
2599 reg->setup_seqno =
2600 i915_gem_next_request_seqno(pipelined);
2601 obj->last_fenced_seqno = reg->setup_seqno;
2602 obj->last_fenced_ring = pipelined;
2603 }
2604
2605 goto update;
2606 }
2584 2607
2585 if (!pipelined) { 2608 if (!pipelined) {
2586 if (reg->setup_seqno) { 2609 if (reg->setup_seqno) {
@@ -2599,31 +2622,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
2599 ret = i915_gem_object_flush_fence(obj, pipelined); 2622 ret = i915_gem_object_flush_fence(obj, pipelined);
2600 if (ret) 2623 if (ret)
2601 return ret; 2624 return ret;
2602 } else if (obj->tiling_changed) {
2603 if (obj->fenced_gpu_access) {
2604 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
2605 ret = i915_gem_flush_ring(obj->ring,
2606 0, obj->base.write_domain);
2607 if (ret)
2608 return ret;
2609 }
2610
2611 obj->fenced_gpu_access = false;
2612 }
2613 }
2614
2615 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
2616 pipelined = NULL;
2617 BUG_ON(!pipelined && reg->setup_seqno);
2618
2619 if (obj->tiling_changed) {
2620 if (pipelined) {
2621 reg->setup_seqno =
2622 i915_gem_next_request_seqno(pipelined);
2623 obj->last_fenced_seqno = reg->setup_seqno;
2624 obj->last_fenced_ring = pipelined;
2625 }
2626 goto update;
2627 } 2625 }
2628 2626
2629 return 0; 2627 return 0;
@@ -3606,6 +3604,8 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj)
3606 return; 3604 return;
3607 } 3605 }
3608 3606
3607 trace_i915_gem_object_destroy(obj);
3608
3609 if (obj->base.map_list.map) 3609 if (obj->base.map_list.map)
3610 i915_gem_free_mmap_offset(obj); 3610 i915_gem_free_mmap_offset(obj);
3611 3611
@@ -3615,8 +3615,6 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj)
3615 kfree(obj->page_cpu_valid); 3615 kfree(obj->page_cpu_valid);
3616 kfree(obj->bit_17); 3616 kfree(obj->bit_17);
3617 kfree(obj); 3617 kfree(obj);
3618
3619 trace_i915_gem_object_destroy(obj);
3620} 3618}
3621 3619
3622void i915_gem_free_object(struct drm_gem_object *gem_obj) 3620void i915_gem_free_object(struct drm_gem_object *gem_obj)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7ff7f933ddf1..20a4cc5b818f 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -367,6 +367,10 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
367 uint32_t __iomem *reloc_entry; 367 uint32_t __iomem *reloc_entry;
368 void __iomem *reloc_page; 368 void __iomem *reloc_page;
369 369
370 /* We can't wait for rendering with pagefaults disabled */
371 if (obj->active && in_atomic())
372 return -EFAULT;
373
370 ret = i915_gem_object_set_to_gtt_domain(obj, 1); 374 ret = i915_gem_object_set_to_gtt_domain(obj, 1);
371 if (ret) 375 if (ret)
372 return ret; 376 return ret;
@@ -440,15 +444,24 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
440 struct list_head *objects) 444 struct list_head *objects)
441{ 445{
442 struct drm_i915_gem_object *obj; 446 struct drm_i915_gem_object *obj;
443 int ret; 447 int ret = 0;
444 448
449 /* This is the fast path and we cannot handle a pagefault whilst
450 * holding the struct mutex lest the user pass in the relocations
451 * contained within a mmaped bo. For in such a case we, the page
452 * fault handler would call i915_gem_fault() and we would try to
453 * acquire the struct mutex again. Obviously this is bad and so
454 * lockdep complains vehemently.
455 */
456 pagefault_disable();
445 list_for_each_entry(obj, objects, exec_list) { 457 list_for_each_entry(obj, objects, exec_list) {
446 ret = i915_gem_execbuffer_relocate_object(obj, eb); 458 ret = i915_gem_execbuffer_relocate_object(obj, eb);
447 if (ret) 459 if (ret)
448 return ret; 460 break;
449 } 461 }
462 pagefault_enable();
450 463
451 return 0; 464 return ret;
452} 465}
453 466
454static int 467static int
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3106c0dc8389..432fc04c6bff 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1516,9 +1516,10 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
1516 1516
1517 reg = PIPECONF(pipe); 1517 reg = PIPECONF(pipe);
1518 val = I915_READ(reg); 1518 val = I915_READ(reg);
1519 val |= PIPECONF_ENABLE; 1519 if (val & PIPECONF_ENABLE)
1520 I915_WRITE(reg, val); 1520 return;
1521 POSTING_READ(reg); 1521
1522 I915_WRITE(reg, val | PIPECONF_ENABLE);
1522 intel_wait_for_vblank(dev_priv->dev, pipe); 1523 intel_wait_for_vblank(dev_priv->dev, pipe);
1523} 1524}
1524 1525
@@ -1552,9 +1553,10 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
1552 1553
1553 reg = PIPECONF(pipe); 1554 reg = PIPECONF(pipe);
1554 val = I915_READ(reg); 1555 val = I915_READ(reg);
1555 val &= ~PIPECONF_ENABLE; 1556 if ((val & PIPECONF_ENABLE) == 0)
1556 I915_WRITE(reg, val); 1557 return;
1557 POSTING_READ(reg); 1558
1559 I915_WRITE(reg, val & ~PIPECONF_ENABLE);
1558 intel_wait_for_pipe_off(dev_priv->dev, pipe); 1560 intel_wait_for_pipe_off(dev_priv->dev, pipe);
1559} 1561}
1560 1562
@@ -1577,9 +1579,10 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv,
1577 1579
1578 reg = DSPCNTR(plane); 1580 reg = DSPCNTR(plane);
1579 val = I915_READ(reg); 1581 val = I915_READ(reg);
1580 val |= DISPLAY_PLANE_ENABLE; 1582 if (val & DISPLAY_PLANE_ENABLE)
1581 I915_WRITE(reg, val); 1583 return;
1582 POSTING_READ(reg); 1584
1585 I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE);
1583 intel_wait_for_vblank(dev_priv->dev, pipe); 1586 intel_wait_for_vblank(dev_priv->dev, pipe);
1584} 1587}
1585 1588
@@ -1610,9 +1613,10 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv,
1610 1613
1611 reg = DSPCNTR(plane); 1614 reg = DSPCNTR(plane);
1612 val = I915_READ(reg); 1615 val = I915_READ(reg);
1613 val &= ~DISPLAY_PLANE_ENABLE; 1616 if ((val & DISPLAY_PLANE_ENABLE) == 0)
1614 I915_WRITE(reg, val); 1617 return;
1615 POSTING_READ(reg); 1618
1619 I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE);
1616 intel_flush_display_plane(dev_priv, plane); 1620 intel_flush_display_plane(dev_priv, plane);
1617 intel_wait_for_vblank(dev_priv->dev, pipe); 1621 intel_wait_for_vblank(dev_priv->dev, pipe);
1618} 1622}
@@ -1769,7 +1773,6 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
1769 return; 1773 return;
1770 1774
1771 I915_WRITE(DPFC_CONTROL, dpfc_ctl & ~DPFC_CTL_EN); 1775 I915_WRITE(DPFC_CONTROL, dpfc_ctl & ~DPFC_CTL_EN);
1772 POSTING_READ(DPFC_CONTROL);
1773 intel_wait_for_vblank(dev, intel_crtc->pipe); 1776 intel_wait_for_vblank(dev, intel_crtc->pipe);
1774 } 1777 }
1775 1778
@@ -1861,7 +1864,6 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
1861 return; 1864 return;
1862 1865
1863 I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl & ~DPFC_CTL_EN); 1866 I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl & ~DPFC_CTL_EN);
1864 POSTING_READ(ILK_DPFC_CONTROL);
1865 intel_wait_for_vblank(dev, intel_crtc->pipe); 1867 intel_wait_for_vblank(dev, intel_crtc->pipe);
1866 } 1868 }
1867 1869
@@ -3883,10 +3885,7 @@ static bool g4x_compute_srwm(struct drm_device *dev,
3883 display, cursor); 3885 display, cursor);
3884} 3886}
3885 3887
3886static inline bool single_plane_enabled(unsigned int mask) 3888#define single_plane_enabled(mask) is_power_of_2(mask)
3887{
3888 return mask && (mask & -mask) == 0;
3889}
3890 3889
3891static void g4x_update_wm(struct drm_device *dev) 3890static void g4x_update_wm(struct drm_device *dev)
3892{ 3891{
@@ -5777,7 +5776,6 @@ static void intel_increase_pllclock(struct drm_crtc *crtc)
5777 5776
5778 dpll &= ~DISPLAY_RATE_SELECT_FPA1; 5777 dpll &= ~DISPLAY_RATE_SELECT_FPA1;
5779 I915_WRITE(dpll_reg, dpll); 5778 I915_WRITE(dpll_reg, dpll);
5780 POSTING_READ(dpll_reg);
5781 intel_wait_for_vblank(dev, pipe); 5779 intel_wait_for_vblank(dev, pipe);
5782 5780
5783 dpll = I915_READ(dpll_reg); 5781 dpll = I915_READ(dpll_reg);
@@ -5821,7 +5819,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
5821 5819
5822 dpll |= DISPLAY_RATE_SELECT_FPA1; 5820 dpll |= DISPLAY_RATE_SELECT_FPA1;
5823 I915_WRITE(dpll_reg, dpll); 5821 I915_WRITE(dpll_reg, dpll);
5824 dpll = I915_READ(dpll_reg);
5825 intel_wait_for_vblank(dev, pipe); 5822 intel_wait_for_vblank(dev, pipe);
5826 dpll = I915_READ(dpll_reg); 5823 dpll = I915_READ(dpll_reg);
5827 if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) 5824 if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
@@ -6933,7 +6930,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
6933 DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); 6930 DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
6934 if (pcu_mbox & (1<<31)) { /* OC supported */ 6931 if (pcu_mbox & (1<<31)) { /* OC supported */
6935 max_freq = pcu_mbox & 0xff; 6932 max_freq = pcu_mbox & 0xff;
6936 DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 100); 6933 DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50);
6937 } 6934 }
6938 6935
6939 /* In units of 100MHz */ 6936 /* In units of 100MHz */
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d29e33f815d7..0daefca5cbb8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1957,9 +1957,9 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1957 DP_NO_AUX_HANDSHAKE_LINK_TRAINING; 1957 DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
1958 } else { 1958 } else {
1959 /* if this fails, presume the device is a ghost */ 1959 /* if this fails, presume the device is a ghost */
1960 DRM_ERROR("failed to retrieve link info\n"); 1960 DRM_INFO("failed to retrieve link info, disabling eDP\n");
1961 intel_dp_destroy(&intel_connector->base);
1962 intel_dp_encoder_destroy(&intel_dp->base.base); 1961 intel_dp_encoder_destroy(&intel_dp->base.base);
1962 intel_dp_destroy(&intel_connector->base);
1963 return; 1963 return;
1964 } 1964 }
1965 } 1965 }
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 789c47801ba8..e9e6f71418a4 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -65,62 +65,60 @@ render_ring_flush(struct intel_ring_buffer *ring,
65 u32 cmd; 65 u32 cmd;
66 int ret; 66 int ret;
67 67
68 if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { 68 /*
69 * read/write caches:
70 *
71 * I915_GEM_DOMAIN_RENDER is always invalidated, but is
72 * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
73 * also flushed at 2d versus 3d pipeline switches.
74 *
75 * read-only caches:
76 *
77 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
78 * MI_READ_FLUSH is set, and is always flushed on 965.
79 *
80 * I915_GEM_DOMAIN_COMMAND may not exist?
81 *
82 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
83 * invalidated when MI_EXE_FLUSH is set.
84 *
85 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
86 * invalidated with every MI_FLUSH.
87 *
88 * TLBs:
89 *
90 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
91 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
92 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
93 * are flushed at any MI_FLUSH.
94 */
95
96 cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
97 if ((invalidate_domains|flush_domains) &
98 I915_GEM_DOMAIN_RENDER)
99 cmd &= ~MI_NO_WRITE_FLUSH;
100 if (INTEL_INFO(dev)->gen < 4) {
69 /* 101 /*
70 * read/write caches: 102 * On the 965, the sampler cache always gets flushed
71 * 103 * and this bit is reserved.
72 * I915_GEM_DOMAIN_RENDER is always invalidated, but is
73 * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
74 * also flushed at 2d versus 3d pipeline switches.
75 *
76 * read-only caches:
77 *
78 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
79 * MI_READ_FLUSH is set, and is always flushed on 965.
80 *
81 * I915_GEM_DOMAIN_COMMAND may not exist?
82 *
83 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
84 * invalidated when MI_EXE_FLUSH is set.
85 *
86 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
87 * invalidated with every MI_FLUSH.
88 *
89 * TLBs:
90 *
91 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
92 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
93 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
94 * are flushed at any MI_FLUSH.
95 */ 104 */
105 if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
106 cmd |= MI_READ_FLUSH;
107 }
108 if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
109 cmd |= MI_EXE_FLUSH;
96 110
97 cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; 111 if (invalidate_domains & I915_GEM_DOMAIN_COMMAND &&
98 if ((invalidate_domains|flush_domains) & 112 (IS_G4X(dev) || IS_GEN5(dev)))
99 I915_GEM_DOMAIN_RENDER) 113 cmd |= MI_INVALIDATE_ISP;
100 cmd &= ~MI_NO_WRITE_FLUSH;
101 if (INTEL_INFO(dev)->gen < 4) {
102 /*
103 * On the 965, the sampler cache always gets flushed
104 * and this bit is reserved.
105 */
106 if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
107 cmd |= MI_READ_FLUSH;
108 }
109 if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
110 cmd |= MI_EXE_FLUSH;
111
112 if (invalidate_domains & I915_GEM_DOMAIN_COMMAND &&
113 (IS_G4X(dev) || IS_GEN5(dev)))
114 cmd |= MI_INVALIDATE_ISP;
115 114
116 ret = intel_ring_begin(ring, 2); 115 ret = intel_ring_begin(ring, 2);
117 if (ret) 116 if (ret)
118 return ret; 117 return ret;
119 118
120 intel_ring_emit(ring, cmd); 119 intel_ring_emit(ring, cmd);
121 intel_ring_emit(ring, MI_NOOP); 120 intel_ring_emit(ring, MI_NOOP);
122 intel_ring_advance(ring); 121 intel_ring_advance(ring);
123 }
124 122
125 return 0; 123 return 0;
126} 124}
@@ -568,9 +566,6 @@ bsd_ring_flush(struct intel_ring_buffer *ring,
568{ 566{
569 int ret; 567 int ret;
570 568
571 if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0)
572 return 0;
573
574 ret = intel_ring_begin(ring, 2); 569 ret = intel_ring_begin(ring, 2);
575 if (ret) 570 if (ret)
576 return ret; 571 return ret;
@@ -1056,9 +1051,6 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring,
1056 uint32_t cmd; 1051 uint32_t cmd;
1057 int ret; 1052 int ret;
1058 1053
1059 if (((invalidate | flush) & I915_GEM_GPU_DOMAINS) == 0)
1060 return 0;
1061
1062 ret = intel_ring_begin(ring, 4); 1054 ret = intel_ring_begin(ring, 4);
1063 if (ret) 1055 if (ret)
1064 return ret; 1056 return ret;
@@ -1230,9 +1222,6 @@ static int blt_ring_flush(struct intel_ring_buffer *ring,
1230 uint32_t cmd; 1222 uint32_t cmd;
1231 int ret; 1223 int ret;
1232 1224
1233 if (((invalidate | flush) & I915_GEM_DOMAIN_RENDER) == 0)
1234 return 0;
1235
1236 ret = blt_ring_begin(ring, 4); 1225 ret = blt_ring_begin(ring, 4);
1237 if (ret) 1226 if (ret)
1238 return ret; 1227 return ret;
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 3cd3234ba0af..10e41af6b026 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -957,7 +957,11 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
957 /* adjust pixel clock as needed */ 957 /* adjust pixel clock as needed */
958 adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); 958 adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
959 959
960 if (ASIC_IS_AVIVO(rdev)) 960 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
961 /* TV seems to prefer the legacy algo on some boards */
962 radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
963 &ref_div, &post_div);
964 else if (ASIC_IS_AVIVO(rdev))
961 radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, 965 radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
962 &ref_div, &post_div); 966 &ref_div, &post_div);
963 else 967 else
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index cf7c8d5b4ec2..cf602e2d0718 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -448,7 +448,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev,
448 448
449bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) 449bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
450{ 450{
451 int edid_info; 451 int edid_info, size;
452 struct edid *edid; 452 struct edid *edid;
453 unsigned char *raw; 453 unsigned char *raw;
454 edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); 454 edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
@@ -456,11 +456,12 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
456 return false; 456 return false;
457 457
458 raw = rdev->bios + edid_info; 458 raw = rdev->bios + edid_info;
459 edid = kmalloc(EDID_LENGTH * (raw[0x7e] + 1), GFP_KERNEL); 459 size = EDID_LENGTH * (raw[0x7e] + 1);
460 edid = kmalloc(size, GFP_KERNEL);
460 if (edid == NULL) 461 if (edid == NULL)
461 return false; 462 return false;
462 463
463 memcpy((unsigned char *)edid, raw, EDID_LENGTH * (raw[0x7e] + 1)); 464 memcpy((unsigned char *)edid, raw, size);
464 465
465 if (!drm_edid_is_valid(edid)) { 466 if (!drm_edid_is_valid(edid)) {
466 kfree(edid); 467 kfree(edid);
@@ -468,6 +469,7 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
468 } 469 }
469 470
470 rdev->mode_info.bios_hardcoded_edid = edid; 471 rdev->mode_info.bios_hardcoded_edid = edid;
472 rdev->mode_info.bios_hardcoded_edid_size = size;
471 return true; 473 return true;
472} 474}
473 475
@@ -475,8 +477,17 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
475struct edid * 477struct edid *
476radeon_bios_get_hardcoded_edid(struct radeon_device *rdev) 478radeon_bios_get_hardcoded_edid(struct radeon_device *rdev)
477{ 479{
478 if (rdev->mode_info.bios_hardcoded_edid) 480 struct edid *edid;
479 return rdev->mode_info.bios_hardcoded_edid; 481
482 if (rdev->mode_info.bios_hardcoded_edid) {
483 edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL);
484 if (edid) {
485 memcpy((unsigned char *)edid,
486 (unsigned char *)rdev->mode_info.bios_hardcoded_edid,
487 rdev->mode_info.bios_hardcoded_edid_size);
488 return edid;
489 }
490 }
480 return NULL; 491 return NULL;
481} 492}
482 493
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 28c7961cd19b..2ef6d5135064 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -633,6 +633,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector,
633static enum drm_connector_status 633static enum drm_connector_status
634radeon_vga_detect(struct drm_connector *connector, bool force) 634radeon_vga_detect(struct drm_connector *connector, bool force)
635{ 635{
636 struct drm_device *dev = connector->dev;
637 struct radeon_device *rdev = dev->dev_private;
636 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 638 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
637 struct drm_encoder *encoder; 639 struct drm_encoder *encoder;
638 struct drm_encoder_helper_funcs *encoder_funcs; 640 struct drm_encoder_helper_funcs *encoder_funcs;
@@ -683,6 +685,17 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
683 685
684 if (ret == connector_status_connected) 686 if (ret == connector_status_connected)
685 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); 687 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
688
689 /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the
690 * vbios to deal with KVMs. If we have one and are not able to detect a monitor
691 * by other means, assume the CRT is connected and use that EDID.
692 */
693 if ((!rdev->is_atom_bios) &&
694 (ret == connector_status_disconnected) &&
695 rdev->mode_info.bios_hardcoded_edid_size) {
696 ret = connector_status_connected;
697 }
698
686 radeon_connector_update_scratch_regs(connector, ret); 699 radeon_connector_update_scratch_regs(connector, ret);
687 return ret; 700 return ret;
688} 701}
@@ -794,6 +807,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector)
794static enum drm_connector_status 807static enum drm_connector_status
795radeon_dvi_detect(struct drm_connector *connector, bool force) 808radeon_dvi_detect(struct drm_connector *connector, bool force)
796{ 809{
810 struct drm_device *dev = connector->dev;
811 struct radeon_device *rdev = dev->dev_private;
797 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 812 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
798 struct drm_encoder *encoder = NULL; 813 struct drm_encoder *encoder = NULL;
799 struct drm_encoder_helper_funcs *encoder_funcs; 814 struct drm_encoder_helper_funcs *encoder_funcs;
@@ -833,8 +848,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
833 * you don't really know what's connected to which port as both are digital. 848 * you don't really know what's connected to which port as both are digital.
834 */ 849 */
835 if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { 850 if (radeon_connector->shared_ddc && (ret == connector_status_connected)) {
836 struct drm_device *dev = connector->dev;
837 struct radeon_device *rdev = dev->dev_private;
838 struct drm_connector *list_connector; 851 struct drm_connector *list_connector;
839 struct radeon_connector *list_radeon_connector; 852 struct radeon_connector *list_radeon_connector;
840 list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { 853 list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
@@ -899,6 +912,19 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
899 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); 912 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
900 } 913 }
901 914
915 /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the
916 * vbios to deal with KVMs. If we have one and are not able to detect a monitor
917 * by other means, assume the DFP is connected and use that EDID. In most
918 * cases the DVI port is actually a virtual KVM port connected to the service
919 * processor.
920 */
921 if ((!rdev->is_atom_bios) &&
922 (ret == connector_status_disconnected) &&
923 rdev->mode_info.bios_hardcoded_edid_size) {
924 radeon_connector->use_digital = true;
925 ret = connector_status_connected;
926 }
927
902out: 928out:
903 /* updated in get modes as well since we need to know if it's analog or digital */ 929 /* updated in get modes as well since we need to know if it's analog or digital */
904 radeon_connector_update_scratch_regs(connector, ret); 930 radeon_connector_update_scratch_regs(connector, ret);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 66c9af1b3d96..41a5d48e657b 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -889,7 +889,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
889 } 889 }
890 890
891 if (rdev->flags & RADEON_IS_MOBILITY) { 891 if (rdev->flags & RADEON_IS_MOBILITY) {
892 /* A temporal workaround for the occational blanking on certain laptop panels. 892 /* A temporal workaround for the occasional blanking on certain laptop panels.
893 This appears to related to the PLL divider registers (fail to lock?). 893 This appears to related to the PLL divider registers (fail to lock?).
894 It occurs even when all dividers are the same with their old settings. 894 It occurs even when all dividers are the same with their old settings.
895 In this case we really don't need to fiddle with PLL registers. 895 In this case we really don't need to fiddle with PLL registers.
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index e4582814bb78..9c57538231d5 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -239,6 +239,7 @@ struct radeon_mode_info {
239 struct drm_property *underscan_vborder_property; 239 struct drm_property *underscan_vborder_property;
240 /* hardcoded DFP edid from BIOS */ 240 /* hardcoded DFP edid from BIOS */
241 struct edid *bios_hardcoded_edid; 241 struct edid *bios_hardcoded_edid;
242 int bios_hardcoded_edid_size;
242 243
243 /* pointer to fbdev info structure */ 244 /* pointer to fbdev info structure */
244 struct radeon_fbdev *rfbdev; 245 struct radeon_fbdev *rfbdev;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 2aed03bde4b2..08de669e025a 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -365,12 +365,14 @@ static ssize_t radeon_set_pm_profile(struct device *dev,
365 else if (strncmp("high", buf, strlen("high")) == 0) 365 else if (strncmp("high", buf, strlen("high")) == 0)
366 rdev->pm.profile = PM_PROFILE_HIGH; 366 rdev->pm.profile = PM_PROFILE_HIGH;
367 else { 367 else {
368 DRM_ERROR("invalid power profile!\n"); 368 count = -EINVAL;
369 goto fail; 369 goto fail;
370 } 370 }
371 radeon_pm_update_profile(rdev); 371 radeon_pm_update_profile(rdev);
372 radeon_pm_set_clocks(rdev); 372 radeon_pm_set_clocks(rdev);
373 } 373 } else
374 count = -EINVAL;
375
374fail: 376fail:
375 mutex_unlock(&rdev->pm.mutex); 377 mutex_unlock(&rdev->pm.mutex);
376 378
@@ -413,7 +415,7 @@ static ssize_t radeon_set_pm_method(struct device *dev,
413 mutex_unlock(&rdev->pm.mutex); 415 mutex_unlock(&rdev->pm.mutex);
414 cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); 416 cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
415 } else { 417 } else {
416 DRM_ERROR("invalid power method!\n"); 418 count = -EINVAL;
417 goto fail; 419 goto fail;
418 } 420 }
419 radeon_pm_compute_clocks(rdev); 421 radeon_pm_compute_clocks(rdev);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e4bd13b3cd8b..81131eda5544 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1047,6 +1047,16 @@ config SENSORS_TMP421
1047 This driver can also be built as a module. If so, the module 1047 This driver can also be built as a module. If so, the module
1048 will be called tmp421. 1048 will be called tmp421.
1049 1049
1050config SENSORS_TWL4030_MADC
1051 tristate "Texas Instruments TWL4030 MADC Hwmon"
1052 depends on TWL4030_MADC
1053 help
1054 If you say yes here you get hwmon support for triton
1055 TWL4030-MADC.
1056
1057 This driver can also be built as a module. If so it will be called
1058 twl4030-madc-hwmon.
1059
1050config SENSORS_VIA_CPUTEMP 1060config SENSORS_VIA_CPUTEMP
1051 tristate "VIA CPU temperature sensor" 1061 tristate "VIA CPU temperature sensor"
1052 depends on X86 1062 depends on X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 54ca5939d028..967d0ea9447f 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
104obj-$(CONFIG_SENSORS_TMP102) += tmp102.o 104obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
105obj-$(CONFIG_SENSORS_TMP401) += tmp401.o 105obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
106obj-$(CONFIG_SENSORS_TMP421) += tmp421.o 106obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
107obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
107obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o 108obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
108obj-$(CONFIG_SENSORS_VIA686A) += via686a.o 109obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
109obj-$(CONFIG_SENSORS_VT1211) += vt1211.o 110obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c
index 1c8b3d9e2051..fea292d43407 100644
--- a/drivers/hwmon/jz4740-hwmon.c
+++ b/drivers/hwmon/jz4740-hwmon.c
@@ -32,7 +32,7 @@ struct jz4740_hwmon {
32 32
33 int irq; 33 int irq;
34 34
35 struct mfd_cell *cell; 35 const struct mfd_cell *cell;
36 struct device *hwmon; 36 struct device *hwmon;
37 37
38 struct completion read_completion; 38 struct completion read_completion;
@@ -112,7 +112,7 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev)
112 return -ENOMEM; 112 return -ENOMEM;
113 } 113 }
114 114
115 hwmon->cell = pdev->dev.platform_data; 115 hwmon->cell = mfd_get_cell(pdev);
116 116
117 hwmon->irq = platform_get_irq(pdev, 0); 117 hwmon->irq = platform_get_irq(pdev, 0);
118 if (hwmon->irq < 0) { 118 if (hwmon->irq < 0) {
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c
new file mode 100644
index 000000000000..97e22bef85ab
--- /dev/null
+++ b/drivers/hwmon/twl4030-madc-hwmon.c
@@ -0,0 +1,157 @@
1/*
2 *
3 * TWL4030 MADC Hwmon driver-This driver monitors the real time
4 * conversion of analog signals like battery temperature,
5 * battery type, battery level etc. User can ask for the conversion on a
6 * particular channel using the sysfs nodes.
7 *
8 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
9 * J Keerthy <j-keerthy@ti.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 */
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/i2c/twl.h>
30#include <linux/device.h>
31#include <linux/platform_device.h>
32#include <linux/i2c/twl4030-madc.h>
33#include <linux/hwmon.h>
34#include <linux/hwmon-sysfs.h>
35#include <linux/stddef.h>
36#include <linux/sysfs.h>
37#include <linux/err.h>
38#include <linux/types.h>
39
40/*
41 * sysfs hook function
42 */
43static ssize_t madc_read(struct device *dev,
44 struct device_attribute *devattr, char *buf)
45{
46 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
47 struct twl4030_madc_request req;
48 long val;
49
50 req.channels = (1 << attr->index);
51 req.method = TWL4030_MADC_SW2;
52 req.func_cb = NULL;
53 val = twl4030_madc_conversion(&req);
54 if (val < 0)
55 return val;
56
57 return sprintf(buf, "%d\n", req.rbuf[attr->index]);
58}
59
60/* sysfs nodes to read individual channels from user side */
61static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, madc_read, NULL, 0);
62static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, madc_read, NULL, 1);
63static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, madc_read, NULL, 2);
64static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, madc_read, NULL, 3);
65static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, madc_read, NULL, 4);
66static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, madc_read, NULL, 5);
67static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, madc_read, NULL, 6);
68static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, madc_read, NULL, 7);
69static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, madc_read, NULL, 8);
70static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, madc_read, NULL, 9);
71static SENSOR_DEVICE_ATTR(curr10_input, S_IRUGO, madc_read, NULL, 10);
72static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11);
73static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12);
74static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15);
75
76static struct attribute *twl4030_madc_attributes[] = {
77 &sensor_dev_attr_in0_input.dev_attr.attr,
78 &sensor_dev_attr_temp1_input.dev_attr.attr,
79 &sensor_dev_attr_in2_input.dev_attr.attr,
80 &sensor_dev_attr_in3_input.dev_attr.attr,
81 &sensor_dev_attr_in4_input.dev_attr.attr,
82 &sensor_dev_attr_in5_input.dev_attr.attr,
83 &sensor_dev_attr_in6_input.dev_attr.attr,
84 &sensor_dev_attr_in7_input.dev_attr.attr,
85 &sensor_dev_attr_in8_input.dev_attr.attr,
86 &sensor_dev_attr_in9_input.dev_attr.attr,
87 &sensor_dev_attr_curr10_input.dev_attr.attr,
88 &sensor_dev_attr_in11_input.dev_attr.attr,
89 &sensor_dev_attr_in12_input.dev_attr.attr,
90 &sensor_dev_attr_in15_input.dev_attr.attr,
91 NULL
92};
93
94static const struct attribute_group twl4030_madc_group = {
95 .attrs = twl4030_madc_attributes,
96};
97
98static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev)
99{
100 int ret;
101 int status;
102 struct device *hwmon;
103
104 ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group);
105 if (ret)
106 goto err_sysfs;
107 hwmon = hwmon_device_register(&pdev->dev);
108 if (IS_ERR(hwmon)) {
109 dev_err(&pdev->dev, "hwmon_device_register failed.\n");
110 status = PTR_ERR(hwmon);
111 goto err_reg;
112 }
113
114 return 0;
115
116err_reg:
117 sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
118err_sysfs:
119
120 return ret;
121}
122
123static int __devexit twl4030_madc_hwmon_remove(struct platform_device *pdev)
124{
125 hwmon_device_unregister(&pdev->dev);
126 sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
127
128 return 0;
129}
130
131static struct platform_driver twl4030_madc_hwmon_driver = {
132 .probe = twl4030_madc_hwmon_probe,
133 .remove = __exit_p(twl4030_madc_hwmon_remove),
134 .driver = {
135 .name = "twl4030_madc_hwmon",
136 .owner = THIS_MODULE,
137 },
138};
139
140static int __init twl4030_madc_hwmon_init(void)
141{
142 return platform_driver_register(&twl4030_madc_hwmon_driver);
143}
144
145module_init(twl4030_madc_hwmon_init);
146
147static void __exit twl4030_madc_hwmon_exit(void)
148{
149 platform_driver_unregister(&twl4030_madc_hwmon_driver);
150}
151
152module_exit(twl4030_madc_hwmon_exit);
153
154MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver");
155MODULE_LICENSE("GPL");
156MODULE_AUTHOR("J Keerthy");
157MODULE_ALIAS("twl4030_madc_hwmon");
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 1b46a9d9f907..fee1a2613861 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -49,6 +49,7 @@
49#include <linux/init.h> 49#include <linux/init.h>
50#include <linux/errno.h> 50#include <linux/errno.h>
51#include <linux/platform_device.h> 51#include <linux/platform_device.h>
52#include <linux/mfd/core.h>
52#include <linux/i2c.h> 53#include <linux/i2c.h>
53#include <linux/interrupt.h> 54#include <linux/interrupt.h>
54#include <linux/wait.h> 55#include <linux/wait.h>
@@ -305,7 +306,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
305 return -EIO; 306 return -EIO;
306 } 307 }
307 308
308 pdata = pdev->dev.platform_data; 309 pdata = mfd_get_data(pdev);
309 if (pdata) { 310 if (pdata) {
310 i2c->regstep = pdata->regstep; 311 i2c->regstep = pdata->regstep;
311 i2c->clock_khz = pdata->clock_khz; 312 i2c->clock_khz = pdata->clock_khz;
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index a9c419e075a5..9fbd7e6fe32e 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -34,6 +34,7 @@
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/mfd/core.h>
37#include <linux/i2c.h> 38#include <linux/i2c.h>
38#include <linux/interrupt.h> 39#include <linux/interrupt.h>
39#include <linux/wait.h> 40#include <linux/wait.h>
@@ -704,7 +705,7 @@ static int __devinit xiic_i2c_probe(struct platform_device *pdev)
704 if (irq < 0) 705 if (irq < 0)
705 goto resource_missing; 706 goto resource_missing;
706 707
707 pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data; 708 pdata = mfd_get_data(pdev);
708 if (!pdata) 709 if (!pdata)
709 return -EINVAL; 710 return -EINVAL;
710 711
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index e88a2cf17711..6f218e014e99 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -233,8 +233,7 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special)
233 233
234 drive->hwif->rq = NULL; 234 drive->hwif->rq = NULL;
235 235
236 elv_add_request(drive->queue, &drive->sense_rq, 236 elv_add_request(drive->queue, &drive->sense_rq, ELEVATOR_INSERT_FRONT);
237 ELEVATOR_INSERT_FRONT, 0);
238 return 0; 237 return 0;
239} 238}
240EXPORT_SYMBOL_GPL(ide_queue_sense_rq); 239EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 0c73fe39a236..fd1e11799137 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -258,17 +258,10 @@ static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
258 if (time_after(jiffies, info->write_timeout)) 258 if (time_after(jiffies, info->write_timeout))
259 return 0; 259 return 0;
260 else { 260 else {
261 struct request_queue *q = drive->queue;
262 unsigned long flags;
263
264 /* 261 /*
265 * take a breather relying on the unplug timer to kick us again 262 * take a breather
266 */ 263 */
267 264 blk_delay_queue(drive->queue, 1);
268 spin_lock_irqsave(q->queue_lock, flags);
269 blk_plug_device(q);
270 spin_unlock_irqrestore(q->queue_lock, flags);
271
272 return 1; 265 return 1;
273 } 266 }
274} 267}
@@ -1177,7 +1170,7 @@ static struct cdrom_device_ops ide_cdrom_dops = {
1177 .open = ide_cdrom_open_real, 1170 .open = ide_cdrom_open_real,
1178 .release = ide_cdrom_release_real, 1171 .release = ide_cdrom_release_real,
1179 .drive_status = ide_cdrom_drive_status, 1172 .drive_status = ide_cdrom_drive_status,
1180 .media_changed = ide_cdrom_check_media_change_real, 1173 .check_events = ide_cdrom_check_events_real,
1181 .tray_move = ide_cdrom_tray_move, 1174 .tray_move = ide_cdrom_tray_move,
1182 .lock_door = ide_cdrom_lock_door, 1175 .lock_door = ide_cdrom_lock_door,
1183 .select_speed = ide_cdrom_select_speed, 1176 .select_speed = ide_cdrom_select_speed,
@@ -1514,8 +1507,6 @@ static int ide_cdrom_setup(ide_drive_t *drive)
1514 blk_queue_dma_alignment(q, 31); 1507 blk_queue_dma_alignment(q, 31);
1515 blk_queue_update_dma_pad(q, 15); 1508 blk_queue_update_dma_pad(q, 15);
1516 1509
1517 q->unplug_delay = max((1 * HZ) / 1000, 1);
1518
1519 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; 1510 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
1520 drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); 1511 drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
1521 1512
@@ -1702,10 +1693,11 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
1702} 1693}
1703 1694
1704 1695
1705static int idecd_media_changed(struct gendisk *disk) 1696static unsigned int idecd_check_events(struct gendisk *disk,
1697 unsigned int clearing)
1706{ 1698{
1707 struct cdrom_info *info = ide_drv_g(disk, cdrom_info); 1699 struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
1708 return cdrom_media_changed(&info->devinfo); 1700 return cdrom_check_events(&info->devinfo, clearing);
1709} 1701}
1710 1702
1711static int idecd_revalidate_disk(struct gendisk *disk) 1703static int idecd_revalidate_disk(struct gendisk *disk)
@@ -1723,7 +1715,7 @@ static const struct block_device_operations idecd_ops = {
1723 .open = idecd_open, 1715 .open = idecd_open,
1724 .release = idecd_release, 1716 .release = idecd_release,
1725 .ioctl = idecd_ioctl, 1717 .ioctl = idecd_ioctl,
1726 .media_changed = idecd_media_changed, 1718 .check_events = idecd_check_events,
1727 .revalidate_disk = idecd_revalidate_disk 1719 .revalidate_disk = idecd_revalidate_disk
1728}; 1720};
1729 1721
@@ -1790,6 +1782,7 @@ static int ide_cd_probe(ide_drive_t *drive)
1790 ide_cd_read_toc(drive, &sense); 1782 ide_cd_read_toc(drive, &sense);
1791 g->fops = &idecd_ops; 1783 g->fops = &idecd_ops;
1792 g->flags |= GENHD_FL_REMOVABLE; 1784 g->flags |= GENHD_FL_REMOVABLE;
1785 g->events = DISK_EVENT_MEDIA_CHANGE;
1793 add_disk(g); 1786 add_disk(g);
1794 return 0; 1787 return 0;
1795 1788
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 93a3cf1b0f3f..1efc936f5b66 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -111,7 +111,8 @@ int cdrom_check_status(ide_drive_t *, struct request_sense *);
111int ide_cdrom_open_real(struct cdrom_device_info *, int); 111int ide_cdrom_open_real(struct cdrom_device_info *, int);
112void ide_cdrom_release_real(struct cdrom_device_info *); 112void ide_cdrom_release_real(struct cdrom_device_info *);
113int ide_cdrom_drive_status(struct cdrom_device_info *, int); 113int ide_cdrom_drive_status(struct cdrom_device_info *, int);
114int ide_cdrom_check_media_change_real(struct cdrom_device_info *, int); 114unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *,
115 unsigned int clearing, int slot_nr);
115int ide_cdrom_tray_move(struct cdrom_device_info *, int); 116int ide_cdrom_tray_move(struct cdrom_device_info *, int);
116int ide_cdrom_lock_door(struct cdrom_device_info *, int); 117int ide_cdrom_lock_door(struct cdrom_device_info *, int);
117int ide_cdrom_select_speed(struct cdrom_device_info *, int); 118int ide_cdrom_select_speed(struct cdrom_device_info *, int);
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index 766b3deeb23c..2a6bc50e8a41 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -79,8 +79,8 @@ int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr)
79 return CDS_DRIVE_NOT_READY; 79 return CDS_DRIVE_NOT_READY;
80} 80}
81 81
82int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi, 82unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi,
83 int slot_nr) 83 unsigned int clearing, int slot_nr)
84{ 84{
85 ide_drive_t *drive = cdi->handle; 85 ide_drive_t *drive = cdi->handle;
86 int retval; 86 int retval;
@@ -89,9 +89,9 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
89 (void) cdrom_check_status(drive, NULL); 89 (void) cdrom_check_status(drive, NULL);
90 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0; 90 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
91 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; 91 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
92 return retval; 92 return retval ? DISK_EVENT_MEDIA_CHANGE : 0;
93 } else { 93 } else {
94 return -EINVAL; 94 return 0;
95 } 95 }
96} 96}
97 97
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 35c4b43585e3..c4ffd4888939 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -285,11 +285,12 @@ static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
285 return 0; 285 return 0;
286} 286}
287 287
288static int ide_gd_media_changed(struct gendisk *disk) 288static unsigned int ide_gd_check_events(struct gendisk *disk,
289 unsigned int clearing)
289{ 290{
290 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 291 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
291 ide_drive_t *drive = idkp->drive; 292 ide_drive_t *drive = idkp->drive;
292 int ret; 293 bool ret;
293 294
294 /* do not scan partitions twice if this is a removable device */ 295 /* do not scan partitions twice if this is a removable device */
295 if (drive->dev_flags & IDE_DFLAG_ATTACH) { 296 if (drive->dev_flags & IDE_DFLAG_ATTACH) {
@@ -297,10 +298,10 @@ static int ide_gd_media_changed(struct gendisk *disk)
297 return 0; 298 return 0;
298 } 299 }
299 300
300 ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); 301 ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED;
301 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; 302 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
302 303
303 return ret; 304 return ret ? DISK_EVENT_MEDIA_CHANGE : 0;
304} 305}
305 306
306static void ide_gd_unlock_native_capacity(struct gendisk *disk) 307static void ide_gd_unlock_native_capacity(struct gendisk *disk)
@@ -318,7 +319,7 @@ static int ide_gd_revalidate_disk(struct gendisk *disk)
318 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 319 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
319 ide_drive_t *drive = idkp->drive; 320 ide_drive_t *drive = idkp->drive;
320 321
321 if (ide_gd_media_changed(disk)) 322 if (ide_gd_check_events(disk, 0))
322 drive->disk_ops->get_capacity(drive); 323 drive->disk_ops->get_capacity(drive);
323 324
324 set_capacity(disk, ide_gd_capacity(drive)); 325 set_capacity(disk, ide_gd_capacity(drive));
@@ -340,7 +341,7 @@ static const struct block_device_operations ide_gd_ops = {
340 .release = ide_gd_release, 341 .release = ide_gd_release,
341 .ioctl = ide_gd_ioctl, 342 .ioctl = ide_gd_ioctl,
342 .getgeo = ide_gd_getgeo, 343 .getgeo = ide_gd_getgeo,
343 .media_changed = ide_gd_media_changed, 344 .check_events = ide_gd_check_events,
344 .unlock_native_capacity = ide_gd_unlock_native_capacity, 345 .unlock_native_capacity = ide_gd_unlock_native_capacity,
345 .revalidate_disk = ide_gd_revalidate_disk 346 .revalidate_disk = ide_gd_revalidate_disk
346}; 347};
@@ -412,6 +413,7 @@ static int ide_gd_probe(ide_drive_t *drive)
412 if (drive->dev_flags & IDE_DFLAG_REMOVABLE) 413 if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
413 g->flags = GENHD_FL_REMOVABLE; 414 g->flags = GENHD_FL_REMOVABLE;
414 g->fops = &ide_gd_ops; 415 g->fops = &ide_gd_ops;
416 g->events = DISK_EVENT_MEDIA_CHANGE;
415 add_disk(g); 417 add_disk(g);
416 return 0; 418 return 0;
417 419
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 999dac054bcc..f4077840d3ab 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -549,8 +549,6 @@ plug_device_2:
549 549
550 if (rq) 550 if (rq)
551 blk_requeue_request(q, rq); 551 blk_requeue_request(q, rq);
552 if (!elv_queue_empty(q))
553 blk_plug_device(q);
554} 552}
555 553
556void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) 554void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
@@ -562,8 +560,6 @@ void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
562 560
563 if (rq) 561 if (rq)
564 blk_requeue_request(q, rq); 562 blk_requeue_request(q, rq);
565 if (!elv_queue_empty(q))
566 blk_plug_device(q);
567 563
568 spin_unlock_irqrestore(q->queue_lock, flags); 564 spin_unlock_irqrestore(q->queue_lock, flags);
569} 565}
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 88a380c5a470..6ab9ab2a5081 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -52,7 +52,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
52 rq->cmd[0] = REQ_UNPARK_HEADS; 52 rq->cmd[0] = REQ_UNPARK_HEADS;
53 rq->cmd_len = 1; 53 rq->cmd_len = 1;
54 rq->cmd_type = REQ_TYPE_SPECIAL; 54 rq->cmd_type = REQ_TYPE_SPECIAL;
55 elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 1); 55 elv_add_request(q, rq, ELEVATOR_INSERT_FRONT);
56 56
57out: 57out:
58 return; 58 return;
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 4a5c4a44ffb1..a46dddf61078 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -107,7 +107,7 @@ static unsigned long long auto_demotion_disable_flags;
107static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { 107static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
108 { /* MWAIT C0 */ }, 108 { /* MWAIT C0 */ },
109 { /* MWAIT C1 */ 109 { /* MWAIT C1 */
110 .name = "NHM-C1", 110 .name = "C1-NHM",
111 .desc = "MWAIT 0x00", 111 .desc = "MWAIT 0x00",
112 .driver_data = (void *) 0x00, 112 .driver_data = (void *) 0x00,
113 .flags = CPUIDLE_FLAG_TIME_VALID, 113 .flags = CPUIDLE_FLAG_TIME_VALID,
@@ -115,7 +115,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
115 .target_residency = 6, 115 .target_residency = 6,
116 .enter = &intel_idle }, 116 .enter = &intel_idle },
117 { /* MWAIT C2 */ 117 { /* MWAIT C2 */
118 .name = "NHM-C3", 118 .name = "C3-NHM",
119 .desc = "MWAIT 0x10", 119 .desc = "MWAIT 0x10",
120 .driver_data = (void *) 0x10, 120 .driver_data = (void *) 0x10,
121 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 121 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
@@ -123,7 +123,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
123 .target_residency = 80, 123 .target_residency = 80,
124 .enter = &intel_idle }, 124 .enter = &intel_idle },
125 { /* MWAIT C3 */ 125 { /* MWAIT C3 */
126 .name = "NHM-C6", 126 .name = "C6-NHM",
127 .desc = "MWAIT 0x20", 127 .desc = "MWAIT 0x20",
128 .driver_data = (void *) 0x20, 128 .driver_data = (void *) 0x20,
129 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 129 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
@@ -135,7 +135,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
135static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { 135static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
136 { /* MWAIT C0 */ }, 136 { /* MWAIT C0 */ },
137 { /* MWAIT C1 */ 137 { /* MWAIT C1 */
138 .name = "SNB-C1", 138 .name = "C1-SNB",
139 .desc = "MWAIT 0x00", 139 .desc = "MWAIT 0x00",
140 .driver_data = (void *) 0x00, 140 .driver_data = (void *) 0x00,
141 .flags = CPUIDLE_FLAG_TIME_VALID, 141 .flags = CPUIDLE_FLAG_TIME_VALID,
@@ -143,7 +143,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
143 .target_residency = 1, 143 .target_residency = 1,
144 .enter = &intel_idle }, 144 .enter = &intel_idle },
145 { /* MWAIT C2 */ 145 { /* MWAIT C2 */
146 .name = "SNB-C3", 146 .name = "C3-SNB",
147 .desc = "MWAIT 0x10", 147 .desc = "MWAIT 0x10",
148 .driver_data = (void *) 0x10, 148 .driver_data = (void *) 0x10,
149 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 149 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
@@ -151,7 +151,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
151 .target_residency = 211, 151 .target_residency = 211,
152 .enter = &intel_idle }, 152 .enter = &intel_idle },
153 { /* MWAIT C3 */ 153 { /* MWAIT C3 */
154 .name = "SNB-C6", 154 .name = "C6-SNB",
155 .desc = "MWAIT 0x20", 155 .desc = "MWAIT 0x20",
156 .driver_data = (void *) 0x20, 156 .driver_data = (void *) 0x20,
157 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 157 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
@@ -159,7 +159,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
159 .target_residency = 345, 159 .target_residency = 345,
160 .enter = &intel_idle }, 160 .enter = &intel_idle },
161 { /* MWAIT C4 */ 161 { /* MWAIT C4 */
162 .name = "SNB-C7", 162 .name = "C7-SNB",
163 .desc = "MWAIT 0x30", 163 .desc = "MWAIT 0x30",
164 .driver_data = (void *) 0x30, 164 .driver_data = (void *) 0x30,
165 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 165 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
@@ -171,7 +171,7 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
171static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { 171static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
172 { /* MWAIT C0 */ }, 172 { /* MWAIT C0 */ },
173 { /* MWAIT C1 */ 173 { /* MWAIT C1 */
174 .name = "ATM-C1", 174 .name = "C1-ATM",
175 .desc = "MWAIT 0x00", 175 .desc = "MWAIT 0x00",
176 .driver_data = (void *) 0x00, 176 .driver_data = (void *) 0x00,
177 .flags = CPUIDLE_FLAG_TIME_VALID, 177 .flags = CPUIDLE_FLAG_TIME_VALID,
@@ -179,7 +179,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
179 .target_residency = 4, 179 .target_residency = 4,
180 .enter = &intel_idle }, 180 .enter = &intel_idle },
181 { /* MWAIT C2 */ 181 { /* MWAIT C2 */
182 .name = "ATM-C2", 182 .name = "C2-ATM",
183 .desc = "MWAIT 0x10", 183 .desc = "MWAIT 0x10",
184 .driver_data = (void *) 0x10, 184 .driver_data = (void *) 0x10,
185 .flags = CPUIDLE_FLAG_TIME_VALID, 185 .flags = CPUIDLE_FLAG_TIME_VALID,
@@ -188,7 +188,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
188 .enter = &intel_idle }, 188 .enter = &intel_idle },
189 { /* MWAIT C3 */ }, 189 { /* MWAIT C3 */ },
190 { /* MWAIT C4 */ 190 { /* MWAIT C4 */
191 .name = "ATM-C4", 191 .name = "C4-ATM",
192 .desc = "MWAIT 0x30", 192 .desc = "MWAIT 0x30",
193 .driver_data = (void *) 0x30, 193 .driver_data = (void *) 0x30,
194 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 194 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
@@ -197,7 +197,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
197 .enter = &intel_idle }, 197 .enter = &intel_idle },
198 { /* MWAIT C5 */ }, 198 { /* MWAIT C5 */ },
199 { /* MWAIT C6 */ 199 { /* MWAIT C6 */
200 .name = "ATM-C6", 200 .name = "C6-ATM",
201 .desc = "MWAIT 0x52", 201 .desc = "MWAIT 0x52",
202 .driver_data = (void *) 0x52, 202 .driver_data = (void *) 0x52,
203 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 203 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index e0ef5fdc361e..4ffc224faa7f 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -204,7 +204,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
204 204
205 /* If the device does ARP internally, return 'done' */ 205 /* If the device does ARP internally, return 'done' */
206 if (rt->dst.dev->flags & IFF_NOARP) { 206 if (rt->dst.dev->flags & IFF_NOARP) {
207 rdma_copy_addr(addr, rt->dst.dev, NULL); 207 ret = rdma_copy_addr(addr, rt->dst.dev, NULL);
208 goto put; 208 goto put;
209 } 209 }
210 210
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index 91916a8d5de4..2bc7f5af64f4 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -101,7 +101,8 @@ void agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
101 agent = port_priv->agent[qpn]; 101 agent = port_priv->agent[qpn];
102 ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); 102 ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num);
103 if (IS_ERR(ah)) { 103 if (IS_ERR(ah)) {
104 printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n"); 104 printk(KERN_ERR SPFX "ib_create_ah_from_wc error %ld\n",
105 PTR_ERR(ah));
105 return; 106 return;
106 } 107 }
107 108
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 8a40cd539ab1..f24b79b805f2 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -1043,6 +1043,9 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
1043 } 1043 }
1044 } 1044 }
1045 1045
1046 /* We can handle large RDMA requests, so allow larger segments. */
1047 dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
1048
1046 mdev = (struct mthca_dev *) ib_alloc_device(sizeof *mdev); 1049 mdev = (struct mthca_dev *) ib_alloc_device(sizeof *mdev);
1047 if (!mdev) { 1050 if (!mdev) {
1048 dev_err(&pdev->dev, "Device struct alloc failed, " 1051 dev_err(&pdev->dev, "Device struct alloc failed, "
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 3d7f3664b67b..13de1192927c 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -694,7 +694,7 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
694 nesdev->netdev_count++; 694 nesdev->netdev_count++;
695 nesdev->nesadapter->netdev_count++; 695 nesdev->nesadapter->netdev_count++;
696 696
697 printk(KERN_ERR PFX "%s: NetEffect RNIC driver successfully loaded.\n", 697 printk(KERN_INFO PFX "%s: NetEffect RNIC driver successfully loaded.\n",
698 pci_name(pcidev)); 698 pci_name(pcidev));
699 return 0; 699 return 0;
700 700
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 83664ed2804f..376d640487d2 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -59,25 +59,31 @@ MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator "
59 "v" DRV_VERSION " (" DRV_RELDATE ")"); 59 "v" DRV_VERSION " (" DRV_RELDATE ")");
60MODULE_LICENSE("Dual BSD/GPL"); 60MODULE_LICENSE("Dual BSD/GPL");
61 61
62static int srp_sg_tablesize = SRP_DEF_SG_TABLESIZE; 62static unsigned int srp_sg_tablesize;
63static int srp_max_iu_len; 63static unsigned int cmd_sg_entries;
64static unsigned int indirect_sg_entries;
65static bool allow_ext_sg;
66static int topspin_workarounds = 1;
64 67
65module_param(srp_sg_tablesize, int, 0444); 68module_param(srp_sg_tablesize, uint, 0444);
66MODULE_PARM_DESC(srp_sg_tablesize, 69MODULE_PARM_DESC(srp_sg_tablesize, "Deprecated name for cmd_sg_entries");
67 "Max number of gather/scatter entries per I/O (default is 12, max 255)");
68 70
69static int topspin_workarounds = 1; 71module_param(cmd_sg_entries, uint, 0444);
72MODULE_PARM_DESC(cmd_sg_entries,
73 "Default number of gather/scatter entries in the SRP command (default is 12, max 255)");
74
75module_param(indirect_sg_entries, uint, 0444);
76MODULE_PARM_DESC(indirect_sg_entries,
77 "Default max number of gather/scatter entries (default is 12, max is " __stringify(SCSI_MAX_SG_CHAIN_SEGMENTS) ")");
78
79module_param(allow_ext_sg, bool, 0444);
80MODULE_PARM_DESC(allow_ext_sg,
81 "Default behavior when there are more than cmd_sg_entries S/G entries after mapping; fails the request when false (default false)");
70 82
71module_param(topspin_workarounds, int, 0444); 83module_param(topspin_workarounds, int, 0444);
72MODULE_PARM_DESC(topspin_workarounds, 84MODULE_PARM_DESC(topspin_workarounds,
73 "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); 85 "Enable workarounds for Topspin/Cisco SRP target bugs if != 0");
74 86
75static int mellanox_workarounds = 1;
76
77module_param(mellanox_workarounds, int, 0444);
78MODULE_PARM_DESC(mellanox_workarounds,
79 "Enable workarounds for Mellanox SRP target bugs if != 0");
80
81static void srp_add_one(struct ib_device *device); 87static void srp_add_one(struct ib_device *device);
82static void srp_remove_one(struct ib_device *device); 88static void srp_remove_one(struct ib_device *device);
83static void srp_recv_completion(struct ib_cq *cq, void *target_ptr); 89static void srp_recv_completion(struct ib_cq *cq, void *target_ptr);
@@ -114,14 +120,6 @@ static int srp_target_is_topspin(struct srp_target_port *target)
114 !memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui)); 120 !memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui));
115} 121}
116 122
117static int srp_target_is_mellanox(struct srp_target_port *target)
118{
119 static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 };
120
121 return mellanox_workarounds &&
122 !memcmp(&target->ioc_guid, mellanox_oui, sizeof mellanox_oui);
123}
124
125static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, 123static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size,
126 gfp_t gfp_mask, 124 gfp_t gfp_mask,
127 enum dma_data_direction direction) 125 enum dma_data_direction direction)
@@ -378,7 +376,7 @@ static int srp_send_req(struct srp_target_port *target)
378 376
379 req->priv.opcode = SRP_LOGIN_REQ; 377 req->priv.opcode = SRP_LOGIN_REQ;
380 req->priv.tag = 0; 378 req->priv.tag = 0;
381 req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len); 379 req->priv.req_it_iu_len = cpu_to_be32(target->max_iu_len);
382 req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 380 req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
383 SRP_BUF_FORMAT_INDIRECT); 381 SRP_BUF_FORMAT_INDIRECT);
384 /* 382 /*
@@ -456,6 +454,24 @@ static bool srp_change_state(struct srp_target_port *target,
456 return changed; 454 return changed;
457} 455}
458 456
457static void srp_free_req_data(struct srp_target_port *target)
458{
459 struct ib_device *ibdev = target->srp_host->srp_dev->dev;
460 struct srp_request *req;
461 int i;
462
463 for (i = 0, req = target->req_ring; i < SRP_CMD_SQ_SIZE; ++i, ++req) {
464 kfree(req->fmr_list);
465 kfree(req->map_page);
466 if (req->indirect_dma_addr) {
467 ib_dma_unmap_single(ibdev, req->indirect_dma_addr,
468 target->indirect_size,
469 DMA_TO_DEVICE);
470 }
471 kfree(req->indirect_desc);
472 }
473}
474
459static void srp_remove_work(struct work_struct *work) 475static void srp_remove_work(struct work_struct *work)
460{ 476{
461 struct srp_target_port *target = 477 struct srp_target_port *target =
@@ -472,6 +488,7 @@ static void srp_remove_work(struct work_struct *work)
472 scsi_remove_host(target->scsi_host); 488 scsi_remove_host(target->scsi_host);
473 ib_destroy_cm_id(target->cm_id); 489 ib_destroy_cm_id(target->cm_id);
474 srp_free_target_ib(target); 490 srp_free_target_ib(target);
491 srp_free_req_data(target);
475 scsi_host_put(target->scsi_host); 492 scsi_host_put(target->scsi_host);
476} 493}
477 494
@@ -535,18 +552,20 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
535 struct srp_target_port *target, 552 struct srp_target_port *target,
536 struct srp_request *req) 553 struct srp_request *req)
537{ 554{
555 struct ib_device *ibdev = target->srp_host->srp_dev->dev;
556 struct ib_pool_fmr **pfmr;
557
538 if (!scsi_sglist(scmnd) || 558 if (!scsi_sglist(scmnd) ||
539 (scmnd->sc_data_direction != DMA_TO_DEVICE && 559 (scmnd->sc_data_direction != DMA_TO_DEVICE &&
540 scmnd->sc_data_direction != DMA_FROM_DEVICE)) 560 scmnd->sc_data_direction != DMA_FROM_DEVICE))
541 return; 561 return;
542 562
543 if (req->fmr) { 563 pfmr = req->fmr_list;
544 ib_fmr_pool_unmap(req->fmr); 564 while (req->nfmr--)
545 req->fmr = NULL; 565 ib_fmr_pool_unmap(*pfmr++);
546 }
547 566
548 ib_dma_unmap_sg(target->srp_host->srp_dev->dev, scsi_sglist(scmnd), 567 ib_dma_unmap_sg(ibdev, scsi_sglist(scmnd), scsi_sg_count(scmnd),
549 scsi_sg_count(scmnd), scmnd->sc_data_direction); 568 scmnd->sc_data_direction);
550} 569}
551 570
552static void srp_remove_req(struct srp_target_port *target, 571static void srp_remove_req(struct srp_target_port *target,
@@ -645,96 +664,151 @@ err:
645 return ret; 664 return ret;
646} 665}
647 666
648static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat, 667static void srp_map_desc(struct srp_map_state *state, dma_addr_t dma_addr,
649 int sg_cnt, struct srp_request *req, 668 unsigned int dma_len, u32 rkey)
650 struct srp_direct_buf *buf)
651{ 669{
652 u64 io_addr = 0; 670 struct srp_direct_buf *desc = state->desc;
653 u64 *dma_pages;
654 u32 len;
655 int page_cnt;
656 int i, j;
657 int ret;
658 struct srp_device *dev = target->srp_host->srp_dev;
659 struct ib_device *ibdev = dev->dev;
660 struct scatterlist *sg;
661 671
662 if (!dev->fmr_pool) 672 desc->va = cpu_to_be64(dma_addr);
663 return -ENODEV; 673 desc->key = cpu_to_be32(rkey);
674 desc->len = cpu_to_be32(dma_len);
664 675
665 if (srp_target_is_mellanox(target) && 676 state->total_len += dma_len;
666 (ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask)) 677 state->desc++;
667 return -EINVAL; 678 state->ndesc++;
679}
668 680
669 len = page_cnt = 0; 681static int srp_map_finish_fmr(struct srp_map_state *state,
670 scsi_for_each_sg(req->scmnd, sg, sg_cnt, i) { 682 struct srp_target_port *target)
671 unsigned int dma_len = ib_sg_dma_len(ibdev, sg); 683{
684 struct srp_device *dev = target->srp_host->srp_dev;
685 struct ib_pool_fmr *fmr;
686 u64 io_addr = 0;
672 687
673 if (ib_sg_dma_address(ibdev, sg) & ~dev->fmr_page_mask) { 688 if (!state->npages)
674 if (i > 0) 689 return 0;
675 return -EINVAL;
676 else
677 ++page_cnt;
678 }
679 if ((ib_sg_dma_address(ibdev, sg) + dma_len) &
680 ~dev->fmr_page_mask) {
681 if (i < sg_cnt - 1)
682 return -EINVAL;
683 else
684 ++page_cnt;
685 }
686 690
687 len += dma_len; 691 if (state->npages == 1) {
692 srp_map_desc(state, state->base_dma_addr, state->fmr_len,
693 target->rkey);
694 state->npages = state->fmr_len = 0;
695 return 0;
688 } 696 }
689 697
690 page_cnt += len >> dev->fmr_page_shift; 698 fmr = ib_fmr_pool_map_phys(dev->fmr_pool, state->pages,
691 if (page_cnt > SRP_FMR_SIZE) 699 state->npages, io_addr);
692 return -ENOMEM; 700 if (IS_ERR(fmr))
701 return PTR_ERR(fmr);
693 702
694 dma_pages = kmalloc(sizeof (u64) * page_cnt, GFP_ATOMIC); 703 *state->next_fmr++ = fmr;
695 if (!dma_pages) 704 state->nfmr++;
696 return -ENOMEM;
697 705
698 page_cnt = 0; 706 srp_map_desc(state, 0, state->fmr_len, fmr->fmr->rkey);
699 scsi_for_each_sg(req->scmnd, sg, sg_cnt, i) { 707 state->npages = state->fmr_len = 0;
700 unsigned int dma_len = ib_sg_dma_len(ibdev, sg); 708 return 0;
709}
701 710
702 for (j = 0; j < dma_len; j += dev->fmr_page_size) 711static void srp_map_update_start(struct srp_map_state *state,
703 dma_pages[page_cnt++] = 712 struct scatterlist *sg, int sg_index,
704 (ib_sg_dma_address(ibdev, sg) & 713 dma_addr_t dma_addr)
705 dev->fmr_page_mask) + j; 714{
715 state->unmapped_sg = sg;
716 state->unmapped_index = sg_index;
717 state->unmapped_addr = dma_addr;
718}
719
720static int srp_map_sg_entry(struct srp_map_state *state,
721 struct srp_target_port *target,
722 struct scatterlist *sg, int sg_index,
723 int use_fmr)
724{
725 struct srp_device *dev = target->srp_host->srp_dev;
726 struct ib_device *ibdev = dev->dev;
727 dma_addr_t dma_addr = ib_sg_dma_address(ibdev, sg);
728 unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
729 unsigned int len;
730 int ret;
731
732 if (!dma_len)
733 return 0;
734
735 if (use_fmr == SRP_MAP_NO_FMR) {
736 /* Once we're in direct map mode for a request, we don't
737 * go back to FMR mode, so no need to update anything
738 * other than the descriptor.
739 */
740 srp_map_desc(state, dma_addr, dma_len, target->rkey);
741 return 0;
706 } 742 }
707 743
708 req->fmr = ib_fmr_pool_map_phys(dev->fmr_pool, 744 /* If we start at an offset into the FMR page, don't merge into
709 dma_pages, page_cnt, io_addr); 745 * the current FMR. Finish it out, and use the kernel's MR for this
710 if (IS_ERR(req->fmr)) { 746 * sg entry. This is to avoid potential bugs on some SRP targets
711 ret = PTR_ERR(req->fmr); 747 * that were never quite defined, but went away when the initiator
712 req->fmr = NULL; 748 * avoided using FMR on such page fragments.
713 goto out; 749 */
750 if (dma_addr & ~dev->fmr_page_mask || dma_len > dev->fmr_max_size) {
751 ret = srp_map_finish_fmr(state, target);
752 if (ret)
753 return ret;
754
755 srp_map_desc(state, dma_addr, dma_len, target->rkey);
756 srp_map_update_start(state, NULL, 0, 0);
757 return 0;
714 } 758 }
715 759
716 buf->va = cpu_to_be64(ib_sg_dma_address(ibdev, &scat[0]) & 760 /* If this is the first sg to go into the FMR, save our position.
717 ~dev->fmr_page_mask); 761 * We need to know the first unmapped entry, its index, and the
718 buf->key = cpu_to_be32(req->fmr->fmr->rkey); 762 * first unmapped address within that entry to be able to restart
719 buf->len = cpu_to_be32(len); 763 * mapping after an error.
764 */
765 if (!state->unmapped_sg)
766 srp_map_update_start(state, sg, sg_index, dma_addr);
720 767
721 ret = 0; 768 while (dma_len) {
769 if (state->npages == SRP_FMR_SIZE) {
770 ret = srp_map_finish_fmr(state, target);
771 if (ret)
772 return ret;
722 773
723out: 774 srp_map_update_start(state, sg, sg_index, dma_addr);
724 kfree(dma_pages); 775 }
776
777 len = min_t(unsigned int, dma_len, dev->fmr_page_size);
725 778
779 if (!state->npages)
780 state->base_dma_addr = dma_addr;
781 state->pages[state->npages++] = dma_addr;
782 state->fmr_len += len;
783 dma_addr += len;
784 dma_len -= len;
785 }
786
787 /* If the last entry of the FMR wasn't a full page, then we need to
788 * close it out and start a new one -- we can only merge at page
789 * boundries.
790 */
791 ret = 0;
792 if (len != dev->fmr_page_size) {
793 ret = srp_map_finish_fmr(state, target);
794 if (!ret)
795 srp_map_update_start(state, NULL, 0, 0);
796 }
726 return ret; 797 return ret;
727} 798}
728 799
729static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, 800static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
730 struct srp_request *req) 801 struct srp_request *req)
731{ 802{
732 struct scatterlist *scat; 803 struct scatterlist *scat, *sg;
733 struct srp_cmd *cmd = req->cmd->buf; 804 struct srp_cmd *cmd = req->cmd->buf;
734 int len, nents, count; 805 int i, len, nents, count, use_fmr;
735 u8 fmt = SRP_DATA_DESC_DIRECT;
736 struct srp_device *dev; 806 struct srp_device *dev;
737 struct ib_device *ibdev; 807 struct ib_device *ibdev;
808 struct srp_map_state state;
809 struct srp_indirect_buf *indirect_hdr;
810 u32 table_len;
811 u8 fmt;
738 812
739 if (!scsi_sglist(scmnd) || scmnd->sc_data_direction == DMA_NONE) 813 if (!scsi_sglist(scmnd) || scmnd->sc_data_direction == DMA_NONE)
740 return sizeof (struct srp_cmd); 814 return sizeof (struct srp_cmd);
@@ -754,6 +828,8 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
754 ibdev = dev->dev; 828 ibdev = dev->dev;
755 829
756 count = ib_dma_map_sg(ibdev, scat, nents, scmnd->sc_data_direction); 830 count = ib_dma_map_sg(ibdev, scat, nents, scmnd->sc_data_direction);
831 if (unlikely(count == 0))
832 return -EIO;
757 833
758 fmt = SRP_DATA_DESC_DIRECT; 834 fmt = SRP_DATA_DESC_DIRECT;
759 len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf); 835 len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf);
@@ -770,49 +846,99 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
770 buf->va = cpu_to_be64(ib_sg_dma_address(ibdev, scat)); 846 buf->va = cpu_to_be64(ib_sg_dma_address(ibdev, scat));
771 buf->key = cpu_to_be32(target->rkey); 847 buf->key = cpu_to_be32(target->rkey);
772 buf->len = cpu_to_be32(ib_sg_dma_len(ibdev, scat)); 848 buf->len = cpu_to_be32(ib_sg_dma_len(ibdev, scat));
773 } else if (srp_map_fmr(target, scat, count, req, 849
774 (void *) cmd->add_data)) { 850 req->nfmr = 0;
775 /* 851 goto map_complete;
776 * FMR mapping failed, and the scatterlist has more 852 }
777 * than one entry. Generate an indirect memory 853
778 * descriptor. 854 /* We have more than one scatter/gather entry, so build our indirect
779 */ 855 * descriptor table, trying to merge as many entries with FMR as we
780 struct srp_indirect_buf *buf = (void *) cmd->add_data; 856 * can.
781 struct scatterlist *sg; 857 */
782 u32 datalen = 0; 858 indirect_hdr = (void *) cmd->add_data;
783 int i; 859
784 860 ib_dma_sync_single_for_cpu(ibdev, req->indirect_dma_addr,
785 fmt = SRP_DATA_DESC_INDIRECT; 861 target->indirect_size, DMA_TO_DEVICE);
786 len = sizeof (struct srp_cmd) + 862
787 sizeof (struct srp_indirect_buf) + 863 memset(&state, 0, sizeof(state));
788 count * sizeof (struct srp_direct_buf); 864 state.desc = req->indirect_desc;
789 865 state.pages = req->map_page;
790 scsi_for_each_sg(scmnd, sg, count, i) { 866 state.next_fmr = req->fmr_list;
791 unsigned int dma_len = ib_sg_dma_len(ibdev, sg); 867
792 868 use_fmr = dev->fmr_pool ? SRP_MAP_ALLOW_FMR : SRP_MAP_NO_FMR;
793 buf->desc_list[i].va = 869
794 cpu_to_be64(ib_sg_dma_address(ibdev, sg)); 870 for_each_sg(scat, sg, count, i) {
795 buf->desc_list[i].key = 871 if (srp_map_sg_entry(&state, target, sg, i, use_fmr)) {
796 cpu_to_be32(target->rkey); 872 /* FMR mapping failed, so backtrack to the first
797 buf->desc_list[i].len = cpu_to_be32(dma_len); 873 * unmapped entry and continue on without using FMR.
798 datalen += dma_len; 874 */
875 dma_addr_t dma_addr;
876 unsigned int dma_len;
877
878backtrack:
879 sg = state.unmapped_sg;
880 i = state.unmapped_index;
881
882 dma_addr = ib_sg_dma_address(ibdev, sg);
883 dma_len = ib_sg_dma_len(ibdev, sg);
884 dma_len -= (state.unmapped_addr - dma_addr);
885 dma_addr = state.unmapped_addr;
886 use_fmr = SRP_MAP_NO_FMR;
887 srp_map_desc(&state, dma_addr, dma_len, target->rkey);
799 } 888 }
889 }
800 890
801 if (scmnd->sc_data_direction == DMA_TO_DEVICE) 891 if (use_fmr == SRP_MAP_ALLOW_FMR && srp_map_finish_fmr(&state, target))
802 cmd->data_out_desc_cnt = count; 892 goto backtrack;
803 else
804 cmd->data_in_desc_cnt = count;
805 893
806 buf->table_desc.va = 894 /* We've mapped the request, now pull as much of the indirect
807 cpu_to_be64(req->cmd->dma + sizeof *cmd + sizeof *buf); 895 * descriptor table as we can into the command buffer. If this
808 buf->table_desc.key = 896 * target is not using an external indirect table, we are
809 cpu_to_be32(target->rkey); 897 * guaranteed to fit into the command, as the SCSI layer won't
810 buf->table_desc.len = 898 * give us more S/G entries than we allow.
811 cpu_to_be32(count * sizeof (struct srp_direct_buf)); 899 */
900 req->nfmr = state.nfmr;
901 if (state.ndesc == 1) {
902 /* FMR mapping was able to collapse this to one entry,
903 * so use a direct descriptor.
904 */
905 struct srp_direct_buf *buf = (void *) cmd->add_data;
812 906
813 buf->len = cpu_to_be32(datalen); 907 *buf = req->indirect_desc[0];
908 goto map_complete;
909 }
910
911 if (unlikely(target->cmd_sg_cnt < state.ndesc &&
912 !target->allow_ext_sg)) {
913 shost_printk(KERN_ERR, target->scsi_host,
914 "Could not fit S/G list into SRP_CMD\n");
915 return -EIO;
814 } 916 }
815 917
918 count = min(state.ndesc, target->cmd_sg_cnt);
919 table_len = state.ndesc * sizeof (struct srp_direct_buf);
920
921 fmt = SRP_DATA_DESC_INDIRECT;
922 len = sizeof(struct srp_cmd) + sizeof (struct srp_indirect_buf);
923 len += count * sizeof (struct srp_direct_buf);
924
925 memcpy(indirect_hdr->desc_list, req->indirect_desc,
926 count * sizeof (struct srp_direct_buf));
927
928 indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr);
929 indirect_hdr->table_desc.key = cpu_to_be32(target->rkey);
930 indirect_hdr->table_desc.len = cpu_to_be32(table_len);
931 indirect_hdr->len = cpu_to_be32(state.total_len);
932
933 if (scmnd->sc_data_direction == DMA_TO_DEVICE)
934 cmd->data_out_desc_cnt = count;
935 else
936 cmd->data_in_desc_cnt = count;
937
938 ib_dma_sync_single_for_device(ibdev, req->indirect_dma_addr, table_len,
939 DMA_TO_DEVICE);
940
941map_complete:
816 if (scmnd->sc_data_direction == DMA_TO_DEVICE) 942 if (scmnd->sc_data_direction == DMA_TO_DEVICE)
817 cmd->buf_fmt = fmt << 4; 943 cmd->buf_fmt = fmt << 4;
818 else 944 else
@@ -1140,7 +1266,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
1140 spin_unlock_irqrestore(&target->lock, flags); 1266 spin_unlock_irqrestore(&target->lock, flags);
1141 1267
1142 dev = target->srp_host->srp_dev->dev; 1268 dev = target->srp_host->srp_dev->dev;
1143 ib_dma_sync_single_for_cpu(dev, iu->dma, srp_max_iu_len, 1269 ib_dma_sync_single_for_cpu(dev, iu->dma, target->max_iu_len,
1144 DMA_TO_DEVICE); 1270 DMA_TO_DEVICE);
1145 1271
1146 scmnd->result = 0; 1272 scmnd->result = 0;
@@ -1164,7 +1290,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
1164 goto err_iu; 1290 goto err_iu;
1165 } 1291 }
1166 1292
1167 ib_dma_sync_single_for_device(dev, iu->dma, srp_max_iu_len, 1293 ib_dma_sync_single_for_device(dev, iu->dma, target->max_iu_len,
1168 DMA_TO_DEVICE); 1294 DMA_TO_DEVICE);
1169 1295
1170 if (srp_post_send(target, iu, len)) { 1296 if (srp_post_send(target, iu, len)) {
@@ -1204,7 +1330,7 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target)
1204 1330
1205 for (i = 0; i < SRP_SQ_SIZE; ++i) { 1331 for (i = 0; i < SRP_SQ_SIZE; ++i) {
1206 target->tx_ring[i] = srp_alloc_iu(target->srp_host, 1332 target->tx_ring[i] = srp_alloc_iu(target->srp_host,
1207 srp_max_iu_len, 1333 target->max_iu_len,
1208 GFP_KERNEL, DMA_TO_DEVICE); 1334 GFP_KERNEL, DMA_TO_DEVICE);
1209 if (!target->tx_ring[i]) 1335 if (!target->tx_ring[i])
1210 goto err; 1336 goto err;
@@ -1228,6 +1354,78 @@ err:
1228 return -ENOMEM; 1354 return -ENOMEM;
1229} 1355}
1230 1356
1357static void srp_cm_rep_handler(struct ib_cm_id *cm_id,
1358 struct srp_login_rsp *lrsp,
1359 struct srp_target_port *target)
1360{
1361 struct ib_qp_attr *qp_attr = NULL;
1362 int attr_mask = 0;
1363 int ret;
1364 int i;
1365
1366 if (lrsp->opcode == SRP_LOGIN_RSP) {
1367 target->max_ti_iu_len = be32_to_cpu(lrsp->max_ti_iu_len);
1368 target->req_lim = be32_to_cpu(lrsp->req_lim_delta);
1369
1370 /*
1371 * Reserve credits for task management so we don't
1372 * bounce requests back to the SCSI mid-layer.
1373 */
1374 target->scsi_host->can_queue
1375 = min(target->req_lim - SRP_TSK_MGMT_SQ_SIZE,
1376 target->scsi_host->can_queue);
1377 } else {
1378 shost_printk(KERN_WARNING, target->scsi_host,
1379 PFX "Unhandled RSP opcode %#x\n", lrsp->opcode);
1380 ret = -ECONNRESET;
1381 goto error;
1382 }
1383
1384 if (!target->rx_ring[0]) {
1385 ret = srp_alloc_iu_bufs(target);
1386 if (ret)
1387 goto error;
1388 }
1389
1390 ret = -ENOMEM;
1391 qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL);
1392 if (!qp_attr)
1393 goto error;
1394
1395 qp_attr->qp_state = IB_QPS_RTR;
1396 ret = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
1397 if (ret)
1398 goto error_free;
1399
1400 ret = ib_modify_qp(target->qp, qp_attr, attr_mask);
1401 if (ret)
1402 goto error_free;
1403
1404 for (i = 0; i < SRP_RQ_SIZE; i++) {
1405 struct srp_iu *iu = target->rx_ring[i];
1406 ret = srp_post_recv(target, iu);
1407 if (ret)
1408 goto error_free;
1409 }
1410
1411 qp_attr->qp_state = IB_QPS_RTS;
1412 ret = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
1413 if (ret)
1414 goto error_free;
1415
1416 ret = ib_modify_qp(target->qp, qp_attr, attr_mask);
1417 if (ret)
1418 goto error_free;
1419
1420 ret = ib_send_cm_rtu(cm_id, NULL, 0);
1421
1422error_free:
1423 kfree(qp_attr);
1424
1425error:
1426 target->status = ret;
1427}
1428
1231static void srp_cm_rej_handler(struct ib_cm_id *cm_id, 1429static void srp_cm_rej_handler(struct ib_cm_id *cm_id,
1232 struct ib_cm_event *event, 1430 struct ib_cm_event *event,
1233 struct srp_target_port *target) 1431 struct srp_target_port *target)
@@ -1311,11 +1509,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id,
1311static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) 1509static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
1312{ 1510{
1313 struct srp_target_port *target = cm_id->context; 1511 struct srp_target_port *target = cm_id->context;
1314 struct ib_qp_attr *qp_attr = NULL;
1315 int attr_mask = 0;
1316 int comp = 0; 1512 int comp = 0;
1317 int opcode = 0;
1318 int i;
1319 1513
1320 switch (event->event) { 1514 switch (event->event) {
1321 case IB_CM_REQ_ERROR: 1515 case IB_CM_REQ_ERROR:
@@ -1327,71 +1521,7 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
1327 1521
1328 case IB_CM_REP_RECEIVED: 1522 case IB_CM_REP_RECEIVED:
1329 comp = 1; 1523 comp = 1;
1330 opcode = *(u8 *) event->private_data; 1524 srp_cm_rep_handler(cm_id, event->private_data, target);
1331
1332 if (opcode == SRP_LOGIN_RSP) {
1333 struct srp_login_rsp *rsp = event->private_data;
1334
1335 target->max_ti_iu_len = be32_to_cpu(rsp->max_ti_iu_len);
1336 target->req_lim = be32_to_cpu(rsp->req_lim_delta);
1337
1338 /*
1339 * Reserve credits for task management so we don't
1340 * bounce requests back to the SCSI mid-layer.
1341 */
1342 target->scsi_host->can_queue
1343 = min(target->req_lim - SRP_TSK_MGMT_SQ_SIZE,
1344 target->scsi_host->can_queue);
1345 } else {
1346 shost_printk(KERN_WARNING, target->scsi_host,
1347 PFX "Unhandled RSP opcode %#x\n", opcode);
1348 target->status = -ECONNRESET;
1349 break;
1350 }
1351
1352 if (!target->rx_ring[0]) {
1353 target->status = srp_alloc_iu_bufs(target);
1354 if (target->status)
1355 break;
1356 }
1357
1358 qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL);
1359 if (!qp_attr) {
1360 target->status = -ENOMEM;
1361 break;
1362 }
1363
1364 qp_attr->qp_state = IB_QPS_RTR;
1365 target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
1366 if (target->status)
1367 break;
1368
1369 target->status = ib_modify_qp(target->qp, qp_attr, attr_mask);
1370 if (target->status)
1371 break;
1372
1373 for (i = 0; i < SRP_RQ_SIZE; i++) {
1374 struct srp_iu *iu = target->rx_ring[i];
1375 target->status = srp_post_recv(target, iu);
1376 if (target->status)
1377 break;
1378 }
1379 if (target->status)
1380 break;
1381
1382 qp_attr->qp_state = IB_QPS_RTS;
1383 target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
1384 if (target->status)
1385 break;
1386
1387 target->status = ib_modify_qp(target->qp, qp_attr, attr_mask);
1388 if (target->status)
1389 break;
1390
1391 target->status = ib_send_cm_rtu(cm_id, NULL, 0);
1392 if (target->status)
1393 break;
1394
1395 break; 1525 break;
1396 1526
1397 case IB_CM_REJ_RECEIVED: 1527 case IB_CM_REJ_RECEIVED:
@@ -1431,8 +1561,6 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
1431 if (comp) 1561 if (comp)
1432 complete(&target->done); 1562 complete(&target->done);
1433 1563
1434 kfree(qp_attr);
1435
1436 return 0; 1564 return 0;
1437} 1565}
1438 1566
@@ -1658,6 +1786,22 @@ static ssize_t show_local_ib_device(struct device *dev,
1658 return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name); 1786 return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name);
1659} 1787}
1660 1788
1789static ssize_t show_cmd_sg_entries(struct device *dev,
1790 struct device_attribute *attr, char *buf)
1791{
1792 struct srp_target_port *target = host_to_target(class_to_shost(dev));
1793
1794 return sprintf(buf, "%u\n", target->cmd_sg_cnt);
1795}
1796
1797static ssize_t show_allow_ext_sg(struct device *dev,
1798 struct device_attribute *attr, char *buf)
1799{
1800 struct srp_target_port *target = host_to_target(class_to_shost(dev));
1801
1802 return sprintf(buf, "%s\n", target->allow_ext_sg ? "true" : "false");
1803}
1804
1661static DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); 1805static DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL);
1662static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); 1806static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL);
1663static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); 1807static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL);
@@ -1668,6 +1812,8 @@ static DEVICE_ATTR(req_lim, S_IRUGO, show_req_lim, NULL);
1668static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); 1812static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL);
1669static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); 1813static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL);
1670static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); 1814static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
1815static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL);
1816static DEVICE_ATTR(allow_ext_sg, S_IRUGO, show_allow_ext_sg, NULL);
1671 1817
1672static struct device_attribute *srp_host_attrs[] = { 1818static struct device_attribute *srp_host_attrs[] = {
1673 &dev_attr_id_ext, 1819 &dev_attr_id_ext,
@@ -1680,6 +1826,8 @@ static struct device_attribute *srp_host_attrs[] = {
1680 &dev_attr_zero_req_lim, 1826 &dev_attr_zero_req_lim,
1681 &dev_attr_local_ib_port, 1827 &dev_attr_local_ib_port,
1682 &dev_attr_local_ib_device, 1828 &dev_attr_local_ib_device,
1829 &dev_attr_cmd_sg_entries,
1830 &dev_attr_allow_ext_sg,
1683 NULL 1831 NULL
1684}; 1832};
1685 1833
@@ -1692,6 +1840,7 @@ static struct scsi_host_template srp_template = {
1692 .eh_abort_handler = srp_abort, 1840 .eh_abort_handler = srp_abort,
1693 .eh_device_reset_handler = srp_reset_device, 1841 .eh_device_reset_handler = srp_reset_device,
1694 .eh_host_reset_handler = srp_reset_host, 1842 .eh_host_reset_handler = srp_reset_host,
1843 .sg_tablesize = SRP_DEF_SG_TABLESIZE,
1695 .can_queue = SRP_CMD_SQ_SIZE, 1844 .can_queue = SRP_CMD_SQ_SIZE,
1696 .this_id = -1, 1845 .this_id = -1,
1697 .cmd_per_lun = SRP_CMD_SQ_SIZE, 1846 .cmd_per_lun = SRP_CMD_SQ_SIZE,
@@ -1763,6 +1912,9 @@ enum {
1763 SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, 1912 SRP_OPT_MAX_CMD_PER_LUN = 1 << 6,
1764 SRP_OPT_IO_CLASS = 1 << 7, 1913 SRP_OPT_IO_CLASS = 1 << 7,
1765 SRP_OPT_INITIATOR_EXT = 1 << 8, 1914 SRP_OPT_INITIATOR_EXT = 1 << 8,
1915 SRP_OPT_CMD_SG_ENTRIES = 1 << 9,
1916 SRP_OPT_ALLOW_EXT_SG = 1 << 10,
1917 SRP_OPT_SG_TABLESIZE = 1 << 11,
1766 SRP_OPT_ALL = (SRP_OPT_ID_EXT | 1918 SRP_OPT_ALL = (SRP_OPT_ID_EXT |
1767 SRP_OPT_IOC_GUID | 1919 SRP_OPT_IOC_GUID |
1768 SRP_OPT_DGID | 1920 SRP_OPT_DGID |
@@ -1780,6 +1932,9 @@ static const match_table_t srp_opt_tokens = {
1780 { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, 1932 { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" },
1781 { SRP_OPT_IO_CLASS, "io_class=%x" }, 1933 { SRP_OPT_IO_CLASS, "io_class=%x" },
1782 { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" }, 1934 { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" },
1935 { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" },
1936 { SRP_OPT_ALLOW_EXT_SG, "allow_ext_sg=%u" },
1937 { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" },
1783 { SRP_OPT_ERR, NULL } 1938 { SRP_OPT_ERR, NULL }
1784}; 1939};
1785 1940
@@ -1907,6 +2062,31 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
1907 kfree(p); 2062 kfree(p);
1908 break; 2063 break;
1909 2064
2065 case SRP_OPT_CMD_SG_ENTRIES:
2066 if (match_int(args, &token) || token < 1 || token > 255) {
2067 printk(KERN_WARNING PFX "bad max cmd_sg_entries parameter '%s'\n", p);
2068 goto out;
2069 }
2070 target->cmd_sg_cnt = token;
2071 break;
2072
2073 case SRP_OPT_ALLOW_EXT_SG:
2074 if (match_int(args, &token)) {
2075 printk(KERN_WARNING PFX "bad allow_ext_sg parameter '%s'\n", p);
2076 goto out;
2077 }
2078 target->allow_ext_sg = !!token;
2079 break;
2080
2081 case SRP_OPT_SG_TABLESIZE:
2082 if (match_int(args, &token) || token < 1 ||
2083 token > SCSI_MAX_SG_CHAIN_SEGMENTS) {
2084 printk(KERN_WARNING PFX "bad max sg_tablesize parameter '%s'\n", p);
2085 goto out;
2086 }
2087 target->sg_tablesize = token;
2088 break;
2089
1910 default: 2090 default:
1911 printk(KERN_WARNING PFX "unknown parameter or missing value " 2091 printk(KERN_WARNING PFX "unknown parameter or missing value "
1912 "'%s' in target creation request\n", p); 2092 "'%s' in target creation request\n", p);
@@ -1937,39 +2117,73 @@ static ssize_t srp_create_target(struct device *dev,
1937 container_of(dev, struct srp_host, dev); 2117 container_of(dev, struct srp_host, dev);
1938 struct Scsi_Host *target_host; 2118 struct Scsi_Host *target_host;
1939 struct srp_target_port *target; 2119 struct srp_target_port *target;
1940 int ret; 2120 struct ib_device *ibdev = host->srp_dev->dev;
1941 int i; 2121 dma_addr_t dma_addr;
2122 int i, ret;
1942 2123
1943 target_host = scsi_host_alloc(&srp_template, 2124 target_host = scsi_host_alloc(&srp_template,
1944 sizeof (struct srp_target_port)); 2125 sizeof (struct srp_target_port));
1945 if (!target_host) 2126 if (!target_host)
1946 return -ENOMEM; 2127 return -ENOMEM;
1947 2128
1948 target_host->transportt = ib_srp_transport_template; 2129 target_host->transportt = ib_srp_transport_template;
1949 target_host->max_lun = SRP_MAX_LUN; 2130 target_host->max_lun = SRP_MAX_LUN;
1950 target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; 2131 target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
1951 2132
1952 target = host_to_target(target_host); 2133 target = host_to_target(target_host);
1953 2134
1954 target->io_class = SRP_REV16A_IB_IO_CLASS; 2135 target->io_class = SRP_REV16A_IB_IO_CLASS;
1955 target->scsi_host = target_host; 2136 target->scsi_host = target_host;
1956 target->srp_host = host; 2137 target->srp_host = host;
1957 target->lkey = host->srp_dev->mr->lkey; 2138 target->lkey = host->srp_dev->mr->lkey;
1958 target->rkey = host->srp_dev->mr->rkey; 2139 target->rkey = host->srp_dev->mr->rkey;
2140 target->cmd_sg_cnt = cmd_sg_entries;
2141 target->sg_tablesize = indirect_sg_entries ? : cmd_sg_entries;
2142 target->allow_ext_sg = allow_ext_sg;
2143
2144 ret = srp_parse_options(buf, target);
2145 if (ret)
2146 goto err;
2147
2148 if (!host->srp_dev->fmr_pool && !target->allow_ext_sg &&
2149 target->cmd_sg_cnt < target->sg_tablesize) {
2150 printk(KERN_WARNING PFX "No FMR pool and no external indirect descriptors, limiting sg_tablesize to cmd_sg_cnt\n");
2151 target->sg_tablesize = target->cmd_sg_cnt;
2152 }
2153
2154 target_host->sg_tablesize = target->sg_tablesize;
2155 target->indirect_size = target->sg_tablesize *
2156 sizeof (struct srp_direct_buf);
2157 target->max_iu_len = sizeof (struct srp_cmd) +
2158 sizeof (struct srp_indirect_buf) +
2159 target->cmd_sg_cnt * sizeof (struct srp_direct_buf);
1959 2160
1960 spin_lock_init(&target->lock); 2161 spin_lock_init(&target->lock);
1961 INIT_LIST_HEAD(&target->free_tx); 2162 INIT_LIST_HEAD(&target->free_tx);
1962 INIT_LIST_HEAD(&target->free_reqs); 2163 INIT_LIST_HEAD(&target->free_reqs);
1963 for (i = 0; i < SRP_CMD_SQ_SIZE; ++i) { 2164 for (i = 0; i < SRP_CMD_SQ_SIZE; ++i) {
1964 target->req_ring[i].index = i; 2165 struct srp_request *req = &target->req_ring[i];
1965 list_add_tail(&target->req_ring[i].list, &target->free_reqs);
1966 }
1967 2166
1968 ret = srp_parse_options(buf, target); 2167 req->fmr_list = kmalloc(target->cmd_sg_cnt * sizeof (void *),
1969 if (ret) 2168 GFP_KERNEL);
1970 goto err; 2169 req->map_page = kmalloc(SRP_FMR_SIZE * sizeof (void *),
2170 GFP_KERNEL);
2171 req->indirect_desc = kmalloc(target->indirect_size, GFP_KERNEL);
2172 if (!req->fmr_list || !req->map_page || !req->indirect_desc)
2173 goto err_free_mem;
2174
2175 dma_addr = ib_dma_map_single(ibdev, req->indirect_desc,
2176 target->indirect_size,
2177 DMA_TO_DEVICE);
2178 if (ib_dma_mapping_error(ibdev, dma_addr))
2179 goto err_free_mem;
2180
2181 req->indirect_dma_addr = dma_addr;
2182 req->index = i;
2183 list_add_tail(&req->list, &target->free_reqs);
2184 }
1971 2185
1972 ib_query_gid(host->srp_dev->dev, host->port, 0, &target->path.sgid); 2186 ib_query_gid(ibdev, host->port, 0, &target->path.sgid);
1973 2187
1974 shost_printk(KERN_DEBUG, target->scsi_host, PFX 2188 shost_printk(KERN_DEBUG, target->scsi_host, PFX
1975 "new target: id_ext %016llx ioc_guid %016llx pkey %04x " 2189 "new target: id_ext %016llx ioc_guid %016llx pkey %04x "
@@ -1982,11 +2196,11 @@ static ssize_t srp_create_target(struct device *dev,
1982 2196
1983 ret = srp_create_target_ib(target); 2197 ret = srp_create_target_ib(target);
1984 if (ret) 2198 if (ret)
1985 goto err; 2199 goto err_free_mem;
1986 2200
1987 ret = srp_new_cm_id(target); 2201 ret = srp_new_cm_id(target);
1988 if (ret) 2202 if (ret)
1989 goto err_free; 2203 goto err_free_ib;
1990 2204
1991 target->qp_in_error = 0; 2205 target->qp_in_error = 0;
1992 ret = srp_connect_target(target); 2206 ret = srp_connect_target(target);
@@ -2008,9 +2222,12 @@ err_disconnect:
2008err_cm_id: 2222err_cm_id:
2009 ib_destroy_cm_id(target->cm_id); 2223 ib_destroy_cm_id(target->cm_id);
2010 2224
2011err_free: 2225err_free_ib:
2012 srp_free_target_ib(target); 2226 srp_free_target_ib(target);
2013 2227
2228err_free_mem:
2229 srp_free_req_data(target);
2230
2014err: 2231err:
2015 scsi_host_put(target_host); 2232 scsi_host_put(target_host);
2016 2233
@@ -2083,7 +2300,7 @@ static void srp_add_one(struct ib_device *device)
2083 struct ib_device_attr *dev_attr; 2300 struct ib_device_attr *dev_attr;
2084 struct ib_fmr_pool_param fmr_param; 2301 struct ib_fmr_pool_param fmr_param;
2085 struct srp_host *host; 2302 struct srp_host *host;
2086 int s, e, p; 2303 int max_pages_per_fmr, fmr_page_shift, s, e, p;
2087 2304
2088 dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); 2305 dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL);
2089 if (!dev_attr) 2306 if (!dev_attr)
@@ -2101,12 +2318,13 @@ static void srp_add_one(struct ib_device *device)
2101 2318
2102 /* 2319 /*
2103 * Use the smallest page size supported by the HCA, down to a 2320 * Use the smallest page size supported by the HCA, down to a
2104 * minimum of 512 bytes (which is the smallest sector that a 2321 * minimum of 4096 bytes. We're unlikely to build large sglists
2105 * SCSI command will ever carry). 2322 * out of smaller entries.
2106 */ 2323 */
2107 srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1); 2324 fmr_page_shift = max(12, ffs(dev_attr->page_size_cap) - 1);
2108 srp_dev->fmr_page_size = 1 << srp_dev->fmr_page_shift; 2325 srp_dev->fmr_page_size = 1 << fmr_page_shift;
2109 srp_dev->fmr_page_mask = ~((u64) srp_dev->fmr_page_size - 1); 2326 srp_dev->fmr_page_mask = ~((u64) srp_dev->fmr_page_size - 1);
2327 srp_dev->fmr_max_size = srp_dev->fmr_page_size * SRP_FMR_SIZE;
2110 2328
2111 INIT_LIST_HEAD(&srp_dev->dev_list); 2329 INIT_LIST_HEAD(&srp_dev->dev_list);
2112 2330
@@ -2122,17 +2340,24 @@ static void srp_add_one(struct ib_device *device)
2122 if (IS_ERR(srp_dev->mr)) 2340 if (IS_ERR(srp_dev->mr))
2123 goto err_pd; 2341 goto err_pd;
2124 2342
2125 memset(&fmr_param, 0, sizeof fmr_param); 2343 for (max_pages_per_fmr = SRP_FMR_SIZE;
2126 fmr_param.pool_size = SRP_FMR_POOL_SIZE; 2344 max_pages_per_fmr >= SRP_FMR_MIN_SIZE;
2127 fmr_param.dirty_watermark = SRP_FMR_DIRTY_SIZE; 2345 max_pages_per_fmr /= 2, srp_dev->fmr_max_size /= 2) {
2128 fmr_param.cache = 1; 2346 memset(&fmr_param, 0, sizeof fmr_param);
2129 fmr_param.max_pages_per_fmr = SRP_FMR_SIZE; 2347 fmr_param.pool_size = SRP_FMR_POOL_SIZE;
2130 fmr_param.page_shift = srp_dev->fmr_page_shift; 2348 fmr_param.dirty_watermark = SRP_FMR_DIRTY_SIZE;
2131 fmr_param.access = (IB_ACCESS_LOCAL_WRITE | 2349 fmr_param.cache = 1;
2132 IB_ACCESS_REMOTE_WRITE | 2350 fmr_param.max_pages_per_fmr = max_pages_per_fmr;
2133 IB_ACCESS_REMOTE_READ); 2351 fmr_param.page_shift = fmr_page_shift;
2134 2352 fmr_param.access = (IB_ACCESS_LOCAL_WRITE |
2135 srp_dev->fmr_pool = ib_create_fmr_pool(srp_dev->pd, &fmr_param); 2353 IB_ACCESS_REMOTE_WRITE |
2354 IB_ACCESS_REMOTE_READ);
2355
2356 srp_dev->fmr_pool = ib_create_fmr_pool(srp_dev->pd, &fmr_param);
2357 if (!IS_ERR(srp_dev->fmr_pool))
2358 break;
2359 }
2360
2136 if (IS_ERR(srp_dev->fmr_pool)) 2361 if (IS_ERR(srp_dev->fmr_pool))
2137 srp_dev->fmr_pool = NULL; 2362 srp_dev->fmr_pool = NULL;
2138 2363
@@ -2207,6 +2432,7 @@ static void srp_remove_one(struct ib_device *device)
2207 srp_disconnect_target(target); 2432 srp_disconnect_target(target);
2208 ib_destroy_cm_id(target->cm_id); 2433 ib_destroy_cm_id(target->cm_id);
2209 srp_free_target_ib(target); 2434 srp_free_target_ib(target);
2435 srp_free_req_data(target);
2210 scsi_host_put(target->scsi_host); 2436 scsi_host_put(target->scsi_host);
2211 } 2437 }
2212 2438
@@ -2230,9 +2456,25 @@ static int __init srp_init_module(void)
2230 2456
2231 BUILD_BUG_ON(FIELD_SIZEOF(struct ib_wc, wr_id) < sizeof(void *)); 2457 BUILD_BUG_ON(FIELD_SIZEOF(struct ib_wc, wr_id) < sizeof(void *));
2232 2458
2233 if (srp_sg_tablesize > 255) { 2459 if (srp_sg_tablesize) {
2234 printk(KERN_WARNING PFX "Clamping srp_sg_tablesize to 255\n"); 2460 printk(KERN_WARNING PFX "srp_sg_tablesize is deprecated, please use cmd_sg_entries\n");
2235 srp_sg_tablesize = 255; 2461 if (!cmd_sg_entries)
2462 cmd_sg_entries = srp_sg_tablesize;
2463 }
2464
2465 if (!cmd_sg_entries)
2466 cmd_sg_entries = SRP_DEF_SG_TABLESIZE;
2467
2468 if (cmd_sg_entries > 255) {
2469 printk(KERN_WARNING PFX "Clamping cmd_sg_entries to 255\n");
2470 cmd_sg_entries = 255;
2471 }
2472
2473 if (!indirect_sg_entries)
2474 indirect_sg_entries = cmd_sg_entries;
2475 else if (indirect_sg_entries < cmd_sg_entries) {
2476 printk(KERN_WARNING PFX "Bumping up indirect_sg_entries to match cmd_sg_entries (%u)\n", cmd_sg_entries);
2477 indirect_sg_entries = cmd_sg_entries;
2236 } 2478 }
2237 2479
2238 ib_srp_transport_template = 2480 ib_srp_transport_template =
@@ -2240,11 +2482,6 @@ static int __init srp_init_module(void)
2240 if (!ib_srp_transport_template) 2482 if (!ib_srp_transport_template)
2241 return -ENOMEM; 2483 return -ENOMEM;
2242 2484
2243 srp_template.sg_tablesize = srp_sg_tablesize;
2244 srp_max_iu_len = (sizeof (struct srp_cmd) +
2245 sizeof (struct srp_indirect_buf) +
2246 srp_sg_tablesize * 16);
2247
2248 ret = class_register(&srp_class); 2485 ret = class_register(&srp_class);
2249 if (ret) { 2486 if (ret) {
2250 printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); 2487 printk(KERN_ERR PFX "couldn't register class infiniband_srp\n");
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 9dc6fc3fd894..020caf0c3789 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -69,9 +69,13 @@ enum {
69 SRP_TAG_NO_REQ = ~0U, 69 SRP_TAG_NO_REQ = ~0U,
70 SRP_TAG_TSK_MGMT = 1U << 31, 70 SRP_TAG_TSK_MGMT = 1U << 31,
71 71
72 SRP_FMR_SIZE = 256, 72 SRP_FMR_SIZE = 512,
73 SRP_FMR_MIN_SIZE = 128,
73 SRP_FMR_POOL_SIZE = 1024, 74 SRP_FMR_POOL_SIZE = 1024,
74 SRP_FMR_DIRTY_SIZE = SRP_FMR_POOL_SIZE / 4 75 SRP_FMR_DIRTY_SIZE = SRP_FMR_POOL_SIZE / 4,
76
77 SRP_MAP_ALLOW_FMR = 0,
78 SRP_MAP_NO_FMR = 1,
75}; 79};
76 80
77enum srp_target_state { 81enum srp_target_state {
@@ -93,9 +97,9 @@ struct srp_device {
93 struct ib_pd *pd; 97 struct ib_pd *pd;
94 struct ib_mr *mr; 98 struct ib_mr *mr;
95 struct ib_fmr_pool *fmr_pool; 99 struct ib_fmr_pool *fmr_pool;
96 int fmr_page_shift;
97 int fmr_page_size;
98 u64 fmr_page_mask; 100 u64 fmr_page_mask;
101 int fmr_page_size;
102 int fmr_max_size;
99}; 103};
100 104
101struct srp_host { 105struct srp_host {
@@ -112,7 +116,11 @@ struct srp_request {
112 struct list_head list; 116 struct list_head list;
113 struct scsi_cmnd *scmnd; 117 struct scsi_cmnd *scmnd;
114 struct srp_iu *cmd; 118 struct srp_iu *cmd;
115 struct ib_pool_fmr *fmr; 119 struct ib_pool_fmr **fmr_list;
120 u64 *map_page;
121 struct srp_direct_buf *indirect_desc;
122 dma_addr_t indirect_dma_addr;
123 short nfmr;
116 short index; 124 short index;
117}; 125};
118 126
@@ -130,6 +138,10 @@ struct srp_target_port {
130 u32 lkey; 138 u32 lkey;
131 u32 rkey; 139 u32 rkey;
132 enum srp_target_state state; 140 enum srp_target_state state;
141 unsigned int max_iu_len;
142 unsigned int cmd_sg_cnt;
143 unsigned int indirect_size;
144 bool allow_ext_sg;
133 145
134 /* Everything above this point is used in the hot path of 146 /* Everything above this point is used in the hot path of
135 * command processing. Try to keep them packed into cachelines. 147 * command processing. Try to keep them packed into cachelines.
@@ -144,6 +156,7 @@ struct srp_target_port {
144 struct Scsi_Host *scsi_host; 156 struct Scsi_Host *scsi_host;
145 char target_name[32]; 157 char target_name[32];
146 unsigned int scsi_id; 158 unsigned int scsi_id;
159 unsigned int sg_tablesize;
147 160
148 struct ib_sa_path_rec path; 161 struct ib_sa_path_rec path;
149 __be16 orig_dgid[8]; 162 __be16 orig_dgid[8];
@@ -179,4 +192,19 @@ struct srp_iu {
179 enum dma_data_direction direction; 192 enum dma_data_direction direction;
180}; 193};
181 194
195struct srp_map_state {
196 struct ib_pool_fmr **next_fmr;
197 struct srp_direct_buf *desc;
198 u64 *pages;
199 dma_addr_t base_dma_addr;
200 u32 fmr_len;
201 u32 total_len;
202 unsigned int npages;
203 unsigned int nfmr;
204 unsigned int ndesc;
205 struct scatterlist *unmapped_sg;
206 int unmapped_index;
207 dma_addr_t unmapped_addr;
208};
209
182#endif /* IB_SRP_H */ 210#endif /* IB_SRP_H */
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c
index 4cc82826ea6b..3dca3c14510e 100644
--- a/drivers/input/misc/88pm860x_onkey.c
+++ b/drivers/input/misc/88pm860x_onkey.c
@@ -74,7 +74,7 @@ static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
74 info->chip = chip; 74 info->chip = chip;
75 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 75 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
76 info->dev = &pdev->dev; 76 info->dev = &pdev->dev;
77 info->irq = irq + chip->irq_base; 77 info->irq = irq;
78 78
79 info->idev = input_allocate_device(); 79 info->idev = input_allocate_device();
80 if (!info->idev) { 80 if (!info->idev) {
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index 014dd4ad0d4f..6a11694e3fc7 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -29,6 +29,7 @@
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <linux/i2c/twl.h> 30#include <linux/i2c/twl.h>
31#include <linux/mfd/twl4030-codec.h> 31#include <linux/mfd/twl4030-codec.h>
32#include <linux/mfd/core.h>
32#include <linux/input.h> 33#include <linux/input.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34 35
@@ -196,7 +197,7 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
196 197
197static int __devinit twl4030_vibra_probe(struct platform_device *pdev) 198static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
198{ 199{
199 struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; 200 struct twl4030_codec_vibra_data *pdata = mfd_get_data(pdev);
200 struct vibra_info *info; 201 struct vibra_info *info;
201 int ret; 202 int ret;
202 203
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index e672b44ee172..416def84d045 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -17,6 +17,7 @@
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/mfd/core.h>
20#include <linux/mfd/88pm860x.h> 21#include <linux/mfd/88pm860x.h>
21 22
22#define LED_PWM_SHIFT (3) 23#define LED_PWM_SHIFT (3)
@@ -118,7 +119,8 @@ static void pm860x_led_work(struct work_struct *work)
118 119
119 struct pm860x_led *led; 120 struct pm860x_led *led;
120 struct pm860x_chip *chip; 121 struct pm860x_chip *chip;
121 int mask; 122 unsigned char buf[3];
123 int mask, ret;
122 124
123 led = container_of(work, struct pm860x_led, work); 125 led = container_of(work, struct pm860x_led, work);
124 chip = led->chip; 126 chip = led->chip;
@@ -128,16 +130,27 @@ static void pm860x_led_work(struct work_struct *work)
128 pm860x_set_bits(led->i2c, __led_off(led->port), 130 pm860x_set_bits(led->i2c, __led_off(led->port),
129 LED_CURRENT_MASK, led->iset); 131 LED_CURRENT_MASK, led->iset);
130 } 132 }
133 pm860x_set_bits(led->i2c, __blink_off(led->port),
134 LED_BLINK_MASK, LED_ON_CONTINUOUS);
131 mask = __blink_ctl_mask(led->port); 135 mask = __blink_ctl_mask(led->port);
132 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask); 136 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
133 } else if (led->brightness == 0) {
134 pm860x_set_bits(led->i2c, __led_off(led->port),
135 LED_CURRENT_MASK, 0);
136 mask = __blink_ctl_mask(led->port);
137 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
138 } 137 }
139 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK, 138 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK,
140 led->brightness); 139 led->brightness);
140
141 if (led->brightness == 0) {
142 pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf);
143 ret = buf[0] & LED_PWM_MASK;
144 ret |= buf[1] & LED_PWM_MASK;
145 ret |= buf[2] & LED_PWM_MASK;
146 if (ret == 0) {
147 /* unset current since no led is lighting */
148 pm860x_set_bits(led->i2c, __led_off(led->port),
149 LED_CURRENT_MASK, 0);
150 mask = __blink_ctl_mask(led->port);
151 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
152 }
153 }
141 led->current_brightness = led->brightness; 154 led->current_brightness = led->brightness;
142 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", 155 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
143 __led_off(led->port), led->brightness); 156 __led_off(led->port), led->brightness);
@@ -153,31 +166,12 @@ static void pm860x_led_set(struct led_classdev *cdev,
153 schedule_work(&data->work); 166 schedule_work(&data->work);
154} 167}
155 168
156static int __check_device(struct pm860x_led_pdata *pdata, char *name)
157{
158 struct pm860x_led_pdata *p = pdata;
159 int ret = -EINVAL;
160
161 while (p && p->id) {
162 if ((p->id != PM8606_ID_LED) || (p->flags < 0))
163 break;
164
165 if (!strncmp(name, pm860x_led_name[p->flags],
166 MFD_NAME_SIZE)) {
167 ret = (int)p->flags;
168 break;
169 }
170 p++;
171 }
172 return ret;
173}
174
175static int pm860x_led_probe(struct platform_device *pdev) 169static int pm860x_led_probe(struct platform_device *pdev)
176{ 170{
177 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 171 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
178 struct pm860x_platform_data *pm860x_pdata;
179 struct pm860x_led_pdata *pdata; 172 struct pm860x_led_pdata *pdata;
180 struct pm860x_led *data; 173 struct pm860x_led *data;
174 struct mfd_cell *cell;
181 struct resource *res; 175 struct resource *res;
182 int ret; 176 int ret;
183 177
@@ -187,10 +181,11 @@ static int pm860x_led_probe(struct platform_device *pdev)
187 return -EINVAL; 181 return -EINVAL;
188 } 182 }
189 183
190 if (pdev->dev.parent->platform_data) { 184 cell = pdev->dev.platform_data;
191 pm860x_pdata = pdev->dev.parent->platform_data; 185 if (cell == NULL)
192 pdata = pm860x_pdata->led; 186 return -ENODEV;
193 } else { 187 pdata = cell->mfd_data;
188 if (pdata == NULL) {
194 dev_err(&pdev->dev, "No platform data!\n"); 189 dev_err(&pdev->dev, "No platform data!\n");
195 return -EINVAL; 190 return -EINVAL;
196 } 191 }
@@ -198,12 +193,12 @@ static int pm860x_led_probe(struct platform_device *pdev)
198 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); 193 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
199 if (data == NULL) 194 if (data == NULL)
200 return -ENOMEM; 195 return -ENOMEM;
201 strncpy(data->name, res->name, MFD_NAME_SIZE); 196 strncpy(data->name, res->name, MFD_NAME_SIZE - 1);
202 dev_set_drvdata(&pdev->dev, data); 197 dev_set_drvdata(&pdev->dev, data);
203 data->chip = chip; 198 data->chip = chip;
204 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 199 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
205 data->iset = pdata->iset; 200 data->iset = pdata->iset;
206 data->port = __check_device(pdata, data->name); 201 data->port = pdata->flags;
207 if (data->port < 0) { 202 if (data->port < 0) {
208 dev_err(&pdev->dev, "check device failed\n"); 203 dev_err(&pdev->dev, "check device failed\n");
209 kfree(data); 204 kfree(data);
@@ -221,6 +216,7 @@ static int pm860x_led_probe(struct platform_device *pdev)
221 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 216 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
222 goto out; 217 goto out;
223 } 218 }
219 pm860x_led_set(&data->cdev, 0);
224 return 0; 220 return 0;
225out: 221out:
226 kfree(data); 222 kfree(data);
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index f05bb08d0f09..06a5bb484707 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -22,6 +22,7 @@
22#include <linux/leds.h> 22#include <linux/leds.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/mfd/mc13783.h> 24#include <linux/mfd/mc13783.h>
25#include <linux/mfd/core.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26 27
27struct mc13783_led { 28struct mc13783_led {
@@ -183,7 +184,7 @@ static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
183 184
184static int __devinit mc13783_leds_prepare(struct platform_device *pdev) 185static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
185{ 186{
186 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 187 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
187 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 188 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
188 int ret = 0; 189 int ret = 0;
189 int reg = 0; 190 int reg = 0;
@@ -264,7 +265,7 @@ out:
264 265
265static int __devinit mc13783_led_probe(struct platform_device *pdev) 266static int __devinit mc13783_led_probe(struct platform_device *pdev)
266{ 267{
267 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 268 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
268 struct mc13783_led_platform_data *led_cur; 269 struct mc13783_led_platform_data *led_cur;
269 struct mc13783_led *led, *led_dat; 270 struct mc13783_led *led, *led_dat;
270 int ret, i; 271 int ret, i;
@@ -351,7 +352,7 @@ err_free:
351 352
352static int __devexit mc13783_led_remove(struct platform_device *pdev) 353static int __devexit mc13783_led_remove(struct platform_device *pdev)
353{ 354{
354 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 355 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
355 struct mc13783_led *led = platform_get_drvdata(pdev); 356 struct mc13783_led *led = platform_get_drvdata(pdev);
356 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 357 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
357 int i; 358 int i;
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index a2ce0b2da281..5c9362792f1d 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -347,7 +347,7 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait)
347 atomic_inc(&bitmap->pending_writes); 347 atomic_inc(&bitmap->pending_writes);
348 set_buffer_locked(bh); 348 set_buffer_locked(bh);
349 set_buffer_mapped(bh); 349 set_buffer_mapped(bh);
350 submit_bh(WRITE | REQ_UNPLUG | REQ_SYNC, bh); 350 submit_bh(WRITE | REQ_SYNC, bh);
351 bh = bh->b_this_page; 351 bh = bh->b_this_page;
352 } 352 }
353 353
@@ -1339,8 +1339,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
1339 prepare_to_wait(&bitmap->overflow_wait, &__wait, 1339 prepare_to_wait(&bitmap->overflow_wait, &__wait,
1340 TASK_UNINTERRUPTIBLE); 1340 TASK_UNINTERRUPTIBLE);
1341 spin_unlock_irq(&bitmap->lock); 1341 spin_unlock_irq(&bitmap->lock);
1342 md_unplug(bitmap->mddev); 1342 io_schedule();
1343 schedule();
1344 finish_wait(&bitmap->overflow_wait, &__wait); 1343 finish_wait(&bitmap->overflow_wait, &__wait);
1345 continue; 1344 continue;
1346 } 1345 }
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 4e054bd91664..2c62c1169f78 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -991,11 +991,6 @@ static void clone_init(struct dm_crypt_io *io, struct bio *clone)
991 clone->bi_destructor = dm_crypt_bio_destructor; 991 clone->bi_destructor = dm_crypt_bio_destructor;
992} 992}
993 993
994static void kcryptd_unplug(struct crypt_config *cc)
995{
996 blk_unplug(bdev_get_queue(cc->dev->bdev));
997}
998
999static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp) 994static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
1000{ 995{
1001 struct crypt_config *cc = io->target->private; 996 struct crypt_config *cc = io->target->private;
@@ -1008,10 +1003,8 @@ static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
1008 * one in order to decrypt the whole bio data *afterwards*. 1003 * one in order to decrypt the whole bio data *afterwards*.
1009 */ 1004 */
1010 clone = bio_alloc_bioset(gfp, bio_segments(base_bio), cc->bs); 1005 clone = bio_alloc_bioset(gfp, bio_segments(base_bio), cc->bs);
1011 if (!clone) { 1006 if (!clone)
1012 kcryptd_unplug(cc);
1013 return 1; 1007 return 1;
1014 }
1015 1008
1016 crypt_inc_pending(io); 1009 crypt_inc_pending(io);
1017 1010
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 136d4f71a116..76a5af00a26b 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -352,7 +352,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
352 BUG_ON(num_regions > DM_IO_MAX_REGIONS); 352 BUG_ON(num_regions > DM_IO_MAX_REGIONS);
353 353
354 if (sync) 354 if (sync)
355 rw |= REQ_SYNC | REQ_UNPLUG; 355 rw |= REQ_SYNC;
356 356
357 /* 357 /*
358 * For multiple regions we need to be careful to rewind 358 * For multiple regions we need to be careful to rewind
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 924f5f0084c2..1bb73a13ca40 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -37,13 +37,6 @@ struct dm_kcopyd_client {
37 unsigned int nr_pages; 37 unsigned int nr_pages;
38 unsigned int nr_free_pages; 38 unsigned int nr_free_pages;
39 39
40 /*
41 * Block devices to unplug.
42 * Non-NULL pointer means that a block device has some pending requests
43 * and needs to be unplugged.
44 */
45 struct block_device *unplug[2];
46
47 struct dm_io_client *io_client; 40 struct dm_io_client *io_client;
48 41
49 wait_queue_head_t destroyq; 42 wait_queue_head_t destroyq;
@@ -315,31 +308,6 @@ static int run_complete_job(struct kcopyd_job *job)
315 return 0; 308 return 0;
316} 309}
317 310
318/*
319 * Unplug the block device at the specified index.
320 */
321static void unplug(struct dm_kcopyd_client *kc, int rw)
322{
323 if (kc->unplug[rw] != NULL) {
324 blk_unplug(bdev_get_queue(kc->unplug[rw]));
325 kc->unplug[rw] = NULL;
326 }
327}
328
329/*
330 * Prepare block device unplug. If there's another device
331 * to be unplugged at the same array index, we unplug that
332 * device first.
333 */
334static void prepare_unplug(struct dm_kcopyd_client *kc, int rw,
335 struct block_device *bdev)
336{
337 if (likely(kc->unplug[rw] == bdev))
338 return;
339 unplug(kc, rw);
340 kc->unplug[rw] = bdev;
341}
342
343static void complete_io(unsigned long error, void *context) 311static void complete_io(unsigned long error, void *context)
344{ 312{
345 struct kcopyd_job *job = (struct kcopyd_job *) context; 313 struct kcopyd_job *job = (struct kcopyd_job *) context;
@@ -386,16 +354,10 @@ static int run_io_job(struct kcopyd_job *job)
386 .client = job->kc->io_client, 354 .client = job->kc->io_client,
387 }; 355 };
388 356
389 if (job->rw == READ) { 357 if (job->rw == READ)
390 r = dm_io(&io_req, 1, &job->source, NULL); 358 r = dm_io(&io_req, 1, &job->source, NULL);
391 prepare_unplug(job->kc, READ, job->source.bdev); 359 else
392 } else {
393 if (job->num_dests > 1)
394 io_req.bi_rw |= REQ_UNPLUG;
395 r = dm_io(&io_req, job->num_dests, job->dests, NULL); 360 r = dm_io(&io_req, job->num_dests, job->dests, NULL);
396 if (!(io_req.bi_rw & REQ_UNPLUG))
397 prepare_unplug(job->kc, WRITE, job->dests[0].bdev);
398 }
399 361
400 return r; 362 return r;
401} 363}
@@ -466,6 +428,7 @@ static void do_work(struct work_struct *work)
466{ 428{
467 struct dm_kcopyd_client *kc = container_of(work, 429 struct dm_kcopyd_client *kc = container_of(work,
468 struct dm_kcopyd_client, kcopyd_work); 430 struct dm_kcopyd_client, kcopyd_work);
431 struct blk_plug plug;
469 432
470 /* 433 /*
471 * The order that these are called is *very* important. 434 * The order that these are called is *very* important.
@@ -473,18 +436,12 @@ static void do_work(struct work_struct *work)
473 * Pages jobs when successful will jump onto the io jobs 436 * Pages jobs when successful will jump onto the io jobs
474 * list. io jobs call wake when they complete and it all 437 * list. io jobs call wake when they complete and it all
475 * starts again. 438 * starts again.
476 *
477 * Note that io_jobs add block devices to the unplug array,
478 * this array is cleared with "unplug" calls. It is thus
479 * forbidden to run complete_jobs after io_jobs and before
480 * unplug because the block device could be destroyed in
481 * job completion callback.
482 */ 439 */
440 blk_start_plug(&plug);
483 process_jobs(&kc->complete_jobs, kc, run_complete_job); 441 process_jobs(&kc->complete_jobs, kc, run_complete_job);
484 process_jobs(&kc->pages_jobs, kc, run_pages_job); 442 process_jobs(&kc->pages_jobs, kc, run_pages_job);
485 process_jobs(&kc->io_jobs, kc, run_io_job); 443 process_jobs(&kc->io_jobs, kc, run_io_job);
486 unplug(kc, READ); 444 blk_finish_plug(&plug);
487 unplug(kc, WRITE);
488} 445}
489 446
490/* 447/*
@@ -665,8 +622,6 @@ int dm_kcopyd_client_create(unsigned int nr_pages,
665 INIT_LIST_HEAD(&kc->io_jobs); 622 INIT_LIST_HEAD(&kc->io_jobs);
666 INIT_LIST_HEAD(&kc->pages_jobs); 623 INIT_LIST_HEAD(&kc->pages_jobs);
667 624
668 memset(kc->unplug, 0, sizeof(kc->unplug));
669
670 kc->job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache); 625 kc->job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache);
671 if (!kc->job_pool) 626 if (!kc->job_pool)
672 goto bad_slab; 627 goto bad_slab;
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index b9e1e15ef11c..5ef136cdba91 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -394,7 +394,7 @@ static void raid_unplug(struct dm_target_callbacks *cb)
394{ 394{
395 struct raid_set *rs = container_of(cb, struct raid_set, callbacks); 395 struct raid_set *rs = container_of(cb, struct raid_set, callbacks);
396 396
397 md_raid5_unplug_device(rs->md.private); 397 md_raid5_kick_device(rs->md.private);
398} 398}
399 399
400/* 400/*
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index dee326775c60..976ad4688afc 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -842,8 +842,6 @@ static void do_mirror(struct work_struct *work)
842 do_reads(ms, &reads); 842 do_reads(ms, &reads);
843 do_writes(ms, &writes); 843 do_writes(ms, &writes);
844 do_failures(ms, &failures); 844 do_failures(ms, &failures);
845
846 dm_table_unplug_all(ms->ti->table);
847} 845}
848 846
849/*----------------------------------------------------------------- 847/*-----------------------------------------------------------------
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 38e4eb1bb965..416d4e258df6 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -55,6 +55,7 @@ struct dm_table {
55 struct dm_target *targets; 55 struct dm_target *targets;
56 56
57 unsigned discards_supported:1; 57 unsigned discards_supported:1;
58 unsigned integrity_supported:1;
58 59
59 /* 60 /*
60 * Indicates the rw permissions for the new logical 61 * Indicates the rw permissions for the new logical
@@ -859,7 +860,7 @@ int dm_table_alloc_md_mempools(struct dm_table *t)
859 return -EINVAL; 860 return -EINVAL;
860 } 861 }
861 862
862 t->mempools = dm_alloc_md_mempools(type); 863 t->mempools = dm_alloc_md_mempools(type, t->integrity_supported);
863 if (!t->mempools) 864 if (!t->mempools)
864 return -ENOMEM; 865 return -ENOMEM;
865 866
@@ -935,8 +936,10 @@ static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device
935 struct dm_dev_internal *dd; 936 struct dm_dev_internal *dd;
936 937
937 list_for_each_entry(dd, devices, list) 938 list_for_each_entry(dd, devices, list)
938 if (bdev_get_integrity(dd->dm_dev.bdev)) 939 if (bdev_get_integrity(dd->dm_dev.bdev)) {
940 t->integrity_supported = 1;
939 return blk_integrity_register(dm_disk(md), NULL); 941 return blk_integrity_register(dm_disk(md), NULL);
942 }
940 943
941 return 0; 944 return 0;
942} 945}
@@ -1275,29 +1278,6 @@ int dm_table_any_busy_target(struct dm_table *t)
1275 return 0; 1278 return 0;
1276} 1279}
1277 1280
1278void dm_table_unplug_all(struct dm_table *t)
1279{
1280 struct dm_dev_internal *dd;
1281 struct list_head *devices = dm_table_get_devices(t);
1282 struct dm_target_callbacks *cb;
1283
1284 list_for_each_entry(dd, devices, list) {
1285 struct request_queue *q = bdev_get_queue(dd->dm_dev.bdev);
1286 char b[BDEVNAME_SIZE];
1287
1288 if (likely(q))
1289 blk_unplug(q);
1290 else
1291 DMWARN_LIMIT("%s: Cannot unplug nonexistent device %s",
1292 dm_device_name(t->md),
1293 bdevname(dd->dm_dev.bdev, b));
1294 }
1295
1296 list_for_each_entry(cb, &t->target_callbacks, list)
1297 if (cb->unplug_fn)
1298 cb->unplug_fn(cb);
1299}
1300
1301struct mapped_device *dm_table_get_md(struct dm_table *t) 1281struct mapped_device *dm_table_get_md(struct dm_table *t)
1302{ 1282{
1303 return t->md; 1283 return t->md;
@@ -1345,4 +1325,3 @@ EXPORT_SYMBOL(dm_table_get_mode);
1345EXPORT_SYMBOL(dm_table_get_md); 1325EXPORT_SYMBOL(dm_table_get_md);
1346EXPORT_SYMBOL(dm_table_put); 1326EXPORT_SYMBOL(dm_table_put);
1347EXPORT_SYMBOL(dm_table_get); 1327EXPORT_SYMBOL(dm_table_get);
1348EXPORT_SYMBOL(dm_table_unplug_all);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index eaa3af0e0632..0cf68b478878 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -477,7 +477,8 @@ static void start_io_acct(struct dm_io *io)
477 cpu = part_stat_lock(); 477 cpu = part_stat_lock();
478 part_round_stats(cpu, &dm_disk(md)->part0); 478 part_round_stats(cpu, &dm_disk(md)->part0);
479 part_stat_unlock(); 479 part_stat_unlock();
480 dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]); 480 atomic_set(&dm_disk(md)->part0.in_flight[rw],
481 atomic_inc_return(&md->pending[rw]));
481} 482}
482 483
483static void end_io_acct(struct dm_io *io) 484static void end_io_acct(struct dm_io *io)
@@ -497,8 +498,8 @@ static void end_io_acct(struct dm_io *io)
497 * After this is decremented the bio must not be touched if it is 498 * After this is decremented the bio must not be touched if it is
498 * a flush. 499 * a flush.
499 */ 500 */
500 dm_disk(md)->part0.in_flight[rw] = pending = 501 pending = atomic_dec_return(&md->pending[rw]);
501 atomic_dec_return(&md->pending[rw]); 502 atomic_set(&dm_disk(md)->part0.in_flight[rw], pending);
502 pending += atomic_read(&md->pending[rw^0x1]); 503 pending += atomic_read(&md->pending[rw^0x1]);
503 504
504 /* nudge anyone waiting on suspend queue */ 505 /* nudge anyone waiting on suspend queue */
@@ -807,8 +808,6 @@ void dm_requeue_unmapped_request(struct request *clone)
807 dm_unprep_request(rq); 808 dm_unprep_request(rq);
808 809
809 spin_lock_irqsave(q->queue_lock, flags); 810 spin_lock_irqsave(q->queue_lock, flags);
810 if (elv_queue_empty(q))
811 blk_plug_device(q);
812 blk_requeue_request(q, rq); 811 blk_requeue_request(q, rq);
813 spin_unlock_irqrestore(q->queue_lock, flags); 812 spin_unlock_irqrestore(q->queue_lock, flags);
814 813
@@ -1613,10 +1612,10 @@ static void dm_request_fn(struct request_queue *q)
1613 * number of in-flight I/Os after the queue is stopped in 1612 * number of in-flight I/Os after the queue is stopped in
1614 * dm_suspend(). 1613 * dm_suspend().
1615 */ 1614 */
1616 while (!blk_queue_plugged(q) && !blk_queue_stopped(q)) { 1615 while (!blk_queue_stopped(q)) {
1617 rq = blk_peek_request(q); 1616 rq = blk_peek_request(q);
1618 if (!rq) 1617 if (!rq)
1619 goto plug_and_out; 1618 goto delay_and_out;
1620 1619
1621 /* always use block 0 to find the target for flushes for now */ 1620 /* always use block 0 to find the target for flushes for now */
1622 pos = 0; 1621 pos = 0;
@@ -1627,7 +1626,7 @@ static void dm_request_fn(struct request_queue *q)
1627 BUG_ON(!dm_target_is_valid(ti)); 1626 BUG_ON(!dm_target_is_valid(ti));
1628 1627
1629 if (ti->type->busy && ti->type->busy(ti)) 1628 if (ti->type->busy && ti->type->busy(ti))
1630 goto plug_and_out; 1629 goto delay_and_out;
1631 1630
1632 blk_start_request(rq); 1631 blk_start_request(rq);
1633 clone = rq->special; 1632 clone = rq->special;
@@ -1647,11 +1646,8 @@ requeued:
1647 BUG_ON(!irqs_disabled()); 1646 BUG_ON(!irqs_disabled());
1648 spin_lock(q->queue_lock); 1647 spin_lock(q->queue_lock);
1649 1648
1650plug_and_out: 1649delay_and_out:
1651 if (!elv_queue_empty(q)) 1650 blk_delay_queue(q, HZ / 10);
1652 /* Some requests still remain, retry later */
1653 blk_plug_device(q);
1654
1655out: 1651out:
1656 dm_table_put(map); 1652 dm_table_put(map);
1657 1653
@@ -1680,20 +1676,6 @@ static int dm_lld_busy(struct request_queue *q)
1680 return r; 1676 return r;
1681} 1677}
1682 1678
1683static void dm_unplug_all(struct request_queue *q)
1684{
1685 struct mapped_device *md = q->queuedata;
1686 struct dm_table *map = dm_get_live_table(md);
1687
1688 if (map) {
1689 if (dm_request_based(md))
1690 generic_unplug_device(q);
1691
1692 dm_table_unplug_all(map);
1693 dm_table_put(map);
1694 }
1695}
1696
1697static int dm_any_congested(void *congested_data, int bdi_bits) 1679static int dm_any_congested(void *congested_data, int bdi_bits)
1698{ 1680{
1699 int r = bdi_bits; 1681 int r = bdi_bits;
@@ -1817,7 +1799,6 @@ static void dm_init_md_queue(struct mapped_device *md)
1817 md->queue->backing_dev_info.congested_data = md; 1799 md->queue->backing_dev_info.congested_data = md;
1818 blk_queue_make_request(md->queue, dm_request); 1800 blk_queue_make_request(md->queue, dm_request);
1819 blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); 1801 blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
1820 md->queue->unplug_fn = dm_unplug_all;
1821 blk_queue_merge_bvec(md->queue, dm_merge_bvec); 1802 blk_queue_merge_bvec(md->queue, dm_merge_bvec);
1822 blk_queue_flush(md->queue, REQ_FLUSH | REQ_FUA); 1803 blk_queue_flush(md->queue, REQ_FLUSH | REQ_FUA);
1823} 1804}
@@ -2263,8 +2244,6 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
2263 int r = 0; 2244 int r = 0;
2264 DECLARE_WAITQUEUE(wait, current); 2245 DECLARE_WAITQUEUE(wait, current);
2265 2246
2266 dm_unplug_all(md->queue);
2267
2268 add_wait_queue(&md->wait, &wait); 2247 add_wait_queue(&md->wait, &wait);
2269 2248
2270 while (1) { 2249 while (1) {
@@ -2539,7 +2518,6 @@ int dm_resume(struct mapped_device *md)
2539 2518
2540 clear_bit(DMF_SUSPENDED, &md->flags); 2519 clear_bit(DMF_SUSPENDED, &md->flags);
2541 2520
2542 dm_table_unplug_all(map);
2543 r = 0; 2521 r = 0;
2544out: 2522out:
2545 dm_table_put(map); 2523 dm_table_put(map);
@@ -2643,9 +2621,10 @@ int dm_noflush_suspending(struct dm_target *ti)
2643} 2621}
2644EXPORT_SYMBOL_GPL(dm_noflush_suspending); 2622EXPORT_SYMBOL_GPL(dm_noflush_suspending);
2645 2623
2646struct dm_md_mempools *dm_alloc_md_mempools(unsigned type) 2624struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity)
2647{ 2625{
2648 struct dm_md_mempools *pools = kmalloc(sizeof(*pools), GFP_KERNEL); 2626 struct dm_md_mempools *pools = kmalloc(sizeof(*pools), GFP_KERNEL);
2627 unsigned int pool_size = (type == DM_TYPE_BIO_BASED) ? 16 : MIN_IOS;
2649 2628
2650 if (!pools) 2629 if (!pools)
2651 return NULL; 2630 return NULL;
@@ -2662,13 +2641,18 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type)
2662 if (!pools->tio_pool) 2641 if (!pools->tio_pool)
2663 goto free_io_pool_and_out; 2642 goto free_io_pool_and_out;
2664 2643
2665 pools->bs = (type == DM_TYPE_BIO_BASED) ? 2644 pools->bs = bioset_create(pool_size, 0);
2666 bioset_create(16, 0) : bioset_create(MIN_IOS, 0);
2667 if (!pools->bs) 2645 if (!pools->bs)
2668 goto free_tio_pool_and_out; 2646 goto free_tio_pool_and_out;
2669 2647
2648 if (integrity && bioset_integrity_create(pools->bs, pool_size))
2649 goto free_bioset_and_out;
2650
2670 return pools; 2651 return pools;
2671 2652
2653free_bioset_and_out:
2654 bioset_free(pools->bs);
2655
2672free_tio_pool_and_out: 2656free_tio_pool_and_out:
2673 mempool_destroy(pools->tio_pool); 2657 mempool_destroy(pools->tio_pool);
2674 2658
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 0c2dd5f4af76..1aaf16746da8 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -149,7 +149,7 @@ void dm_kcopyd_exit(void);
149/* 149/*
150 * Mempool operations 150 * Mempool operations
151 */ 151 */
152struct dm_md_mempools *dm_alloc_md_mempools(unsigned type); 152struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity);
153void dm_free_md_mempools(struct dm_md_mempools *pools); 153void dm_free_md_mempools(struct dm_md_mempools *pools);
154 154
155#endif 155#endif
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 0ed7f6bc2a7f..abfb59a61ede 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -87,22 +87,6 @@ static int linear_mergeable_bvec(struct request_queue *q,
87 return maxsectors << 9; 87 return maxsectors << 9;
88} 88}
89 89
90static void linear_unplug(struct request_queue *q)
91{
92 mddev_t *mddev = q->queuedata;
93 linear_conf_t *conf;
94 int i;
95
96 rcu_read_lock();
97 conf = rcu_dereference(mddev->private);
98
99 for (i=0; i < mddev->raid_disks; i++) {
100 struct request_queue *r_queue = bdev_get_queue(conf->disks[i].rdev->bdev);
101 blk_unplug(r_queue);
102 }
103 rcu_read_unlock();
104}
105
106static int linear_congested(void *data, int bits) 90static int linear_congested(void *data, int bits)
107{ 91{
108 mddev_t *mddev = data; 92 mddev_t *mddev = data;
@@ -224,11 +208,9 @@ static int linear_run (mddev_t *mddev)
224 md_set_array_sectors(mddev, linear_size(mddev, 0, 0)); 208 md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
225 209
226 blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); 210 blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
227 mddev->queue->unplug_fn = linear_unplug;
228 mddev->queue->backing_dev_info.congested_fn = linear_congested; 211 mddev->queue->backing_dev_info.congested_fn = linear_congested;
229 mddev->queue->backing_dev_info.congested_data = mddev; 212 mddev->queue->backing_dev_info.congested_data = mddev;
230 md_integrity_register(mddev); 213 return md_integrity_register(mddev);
231 return 0;
232} 214}
233 215
234static void free_conf(struct rcu_head *head) 216static void free_conf(struct rcu_head *head)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index d5ad7723b172..06ecea751a39 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -780,8 +780,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
780 bio->bi_end_io = super_written; 780 bio->bi_end_io = super_written;
781 781
782 atomic_inc(&mddev->pending_writes); 782 atomic_inc(&mddev->pending_writes);
783 submit_bio(REQ_WRITE | REQ_SYNC | REQ_UNPLUG | REQ_FLUSH | REQ_FUA, 783 submit_bio(REQ_WRITE | REQ_SYNC | REQ_FLUSH | REQ_FUA, bio);
784 bio);
785} 784}
786 785
787void md_super_wait(mddev_t *mddev) 786void md_super_wait(mddev_t *mddev)
@@ -809,7 +808,7 @@ int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size,
809 struct completion event; 808 struct completion event;
810 int ret; 809 int ret;
811 810
812 rw |= REQ_SYNC | REQ_UNPLUG; 811 rw |= REQ_SYNC;
813 812
814 bio->bi_bdev = (metadata_op && rdev->meta_bdev) ? 813 bio->bi_bdev = (metadata_op && rdev->meta_bdev) ?
815 rdev->meta_bdev : rdev->bdev; 814 rdev->meta_bdev : rdev->bdev;
@@ -1804,8 +1803,12 @@ int md_integrity_register(mddev_t *mddev)
1804 mdname(mddev)); 1803 mdname(mddev));
1805 return -EINVAL; 1804 return -EINVAL;
1806 } 1805 }
1807 printk(KERN_NOTICE "md: data integrity on %s enabled\n", 1806 printk(KERN_NOTICE "md: data integrity enabled on %s\n", mdname(mddev));
1808 mdname(mddev)); 1807 if (bioset_integrity_create(mddev->bio_set, BIO_POOL_SIZE)) {
1808 printk(KERN_ERR "md: failed to create integrity pool for %s\n",
1809 mdname(mddev));
1810 return -EINVAL;
1811 }
1809 return 0; 1812 return 0;
1810} 1813}
1811EXPORT_SYMBOL(md_integrity_register); 1814EXPORT_SYMBOL(md_integrity_register);
@@ -4817,7 +4820,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
4817 __md_stop_writes(mddev); 4820 __md_stop_writes(mddev);
4818 md_stop(mddev); 4821 md_stop(mddev);
4819 mddev->queue->merge_bvec_fn = NULL; 4822 mddev->queue->merge_bvec_fn = NULL;
4820 mddev->queue->unplug_fn = NULL;
4821 mddev->queue->backing_dev_info.congested_fn = NULL; 4823 mddev->queue->backing_dev_info.congested_fn = NULL;
4822 4824
4823 /* tell userspace to handle 'inactive' */ 4825 /* tell userspace to handle 'inactive' */
@@ -6692,8 +6694,6 @@ EXPORT_SYMBOL_GPL(md_allow_write);
6692 6694
6693void md_unplug(mddev_t *mddev) 6695void md_unplug(mddev_t *mddev)
6694{ 6696{
6695 if (mddev->queue)
6696 blk_unplug(mddev->queue);
6697 if (mddev->plug) 6697 if (mddev->plug)
6698 mddev->plug->unplug_fn(mddev->plug); 6698 mddev->plug->unplug_fn(mddev->plug);
6699} 6699}
@@ -6876,7 +6876,6 @@ void md_do_sync(mddev_t *mddev)
6876 >= mddev->resync_max - mddev->curr_resync_completed 6876 >= mddev->resync_max - mddev->curr_resync_completed
6877 )) { 6877 )) {
6878 /* time to update curr_resync_completed */ 6878 /* time to update curr_resync_completed */
6879 md_unplug(mddev);
6880 wait_event(mddev->recovery_wait, 6879 wait_event(mddev->recovery_wait,
6881 atomic_read(&mddev->recovery_active) == 0); 6880 atomic_read(&mddev->recovery_active) == 0);
6882 mddev->curr_resync_completed = j; 6881 mddev->curr_resync_completed = j;
@@ -6952,7 +6951,6 @@ void md_do_sync(mddev_t *mddev)
6952 * about not overloading the IO subsystem. (things like an 6951 * about not overloading the IO subsystem. (things like an
6953 * e2fsck being done on the RAID array should execute fast) 6952 * e2fsck being done on the RAID array should execute fast)
6954 */ 6953 */
6955 md_unplug(mddev);
6956 cond_resched(); 6954 cond_resched();
6957 6955
6958 currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2 6956 currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2
@@ -6971,8 +6969,6 @@ void md_do_sync(mddev_t *mddev)
6971 * this also signals 'finished resyncing' to md_stop 6969 * this also signals 'finished resyncing' to md_stop
6972 */ 6970 */
6973 out: 6971 out:
6974 md_unplug(mddev);
6975
6976 wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); 6972 wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
6977 6973
6978 /* tell personality that we are finished */ 6974 /* tell personality that we are finished */
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 3a62d440e27b..c35890990985 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -106,36 +106,6 @@ static void multipath_end_request(struct bio *bio, int error)
106 rdev_dec_pending(rdev, conf->mddev); 106 rdev_dec_pending(rdev, conf->mddev);
107} 107}
108 108
109static void unplug_slaves(mddev_t *mddev)
110{
111 multipath_conf_t *conf = mddev->private;
112 int i;
113
114 rcu_read_lock();
115 for (i=0; i<mddev->raid_disks; i++) {
116 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
117 if (rdev && !test_bit(Faulty, &rdev->flags)
118 && atomic_read(&rdev->nr_pending)) {
119 struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
120
121 atomic_inc(&rdev->nr_pending);
122 rcu_read_unlock();
123
124 blk_unplug(r_queue);
125
126 rdev_dec_pending(rdev, mddev);
127 rcu_read_lock();
128 }
129 }
130 rcu_read_unlock();
131}
132
133static void multipath_unplug(struct request_queue *q)
134{
135 unplug_slaves(q->queuedata);
136}
137
138
139static int multipath_make_request(mddev_t *mddev, struct bio * bio) 109static int multipath_make_request(mddev_t *mddev, struct bio * bio)
140{ 110{
141 multipath_conf_t *conf = mddev->private; 111 multipath_conf_t *conf = mddev->private;
@@ -345,7 +315,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
345 p->rdev = rdev; 315 p->rdev = rdev;
346 goto abort; 316 goto abort;
347 } 317 }
348 md_integrity_register(mddev); 318 err = md_integrity_register(mddev);
349 } 319 }
350abort: 320abort:
351 321
@@ -517,10 +487,12 @@ static int multipath_run (mddev_t *mddev)
517 */ 487 */
518 md_set_array_sectors(mddev, multipath_size(mddev, 0, 0)); 488 md_set_array_sectors(mddev, multipath_size(mddev, 0, 0));
519 489
520 mddev->queue->unplug_fn = multipath_unplug;
521 mddev->queue->backing_dev_info.congested_fn = multipath_congested; 490 mddev->queue->backing_dev_info.congested_fn = multipath_congested;
522 mddev->queue->backing_dev_info.congested_data = mddev; 491 mddev->queue->backing_dev_info.congested_data = mddev;
523 md_integrity_register(mddev); 492
493 if (md_integrity_register(mddev))
494 goto out_free_conf;
495
524 return 0; 496 return 0;
525 497
526out_free_conf: 498out_free_conf:
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c0ac457f1218..e86bf3682e1e 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -25,21 +25,6 @@
25#include "raid0.h" 25#include "raid0.h"
26#include "raid5.h" 26#include "raid5.h"
27 27
28static void raid0_unplug(struct request_queue *q)
29{
30 mddev_t *mddev = q->queuedata;
31 raid0_conf_t *conf = mddev->private;
32 mdk_rdev_t **devlist = conf->devlist;
33 int raid_disks = conf->strip_zone[0].nb_dev;
34 int i;
35
36 for (i=0; i < raid_disks; i++) {
37 struct request_queue *r_queue = bdev_get_queue(devlist[i]->bdev);
38
39 blk_unplug(r_queue);
40 }
41}
42
43static int raid0_congested(void *data, int bits) 28static int raid0_congested(void *data, int bits)
44{ 29{
45 mddev_t *mddev = data; 30 mddev_t *mddev = data;
@@ -272,7 +257,6 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf)
272 mdname(mddev), 257 mdname(mddev),
273 (unsigned long long)smallest->sectors); 258 (unsigned long long)smallest->sectors);
274 } 259 }
275 mddev->queue->unplug_fn = raid0_unplug;
276 mddev->queue->backing_dev_info.congested_fn = raid0_congested; 260 mddev->queue->backing_dev_info.congested_fn = raid0_congested;
277 mddev->queue->backing_dev_info.congested_data = mddev; 261 mddev->queue->backing_dev_info.congested_data = mddev;
278 262
@@ -395,8 +379,7 @@ static int raid0_run(mddev_t *mddev)
395 379
396 blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec); 380 blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec);
397 dump_zones(mddev); 381 dump_zones(mddev);
398 md_integrity_register(mddev); 382 return md_integrity_register(mddev);
399 return 0;
400} 383}
401 384
402static int raid0_stop(mddev_t *mddev) 385static int raid0_stop(mddev_t *mddev)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 06cd712807d0..c2a21ae56d97 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -52,23 +52,16 @@
52#define NR_RAID1_BIOS 256 52#define NR_RAID1_BIOS 256
53 53
54 54
55static void unplug_slaves(mddev_t *mddev);
56
57static void allow_barrier(conf_t *conf); 55static void allow_barrier(conf_t *conf);
58static void lower_barrier(conf_t *conf); 56static void lower_barrier(conf_t *conf);
59 57
60static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data) 58static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
61{ 59{
62 struct pool_info *pi = data; 60 struct pool_info *pi = data;
63 r1bio_t *r1_bio;
64 int size = offsetof(r1bio_t, bios[pi->raid_disks]); 61 int size = offsetof(r1bio_t, bios[pi->raid_disks]);
65 62
66 /* allocate a r1bio with room for raid_disks entries in the bios array */ 63 /* allocate a r1bio with room for raid_disks entries in the bios array */
67 r1_bio = kzalloc(size, gfp_flags); 64 return kzalloc(size, gfp_flags);
68 if (!r1_bio && pi->mddev)
69 unplug_slaves(pi->mddev);
70
71 return r1_bio;
72} 65}
73 66
74static void r1bio_pool_free(void *r1_bio, void *data) 67static void r1bio_pool_free(void *r1_bio, void *data)
@@ -91,10 +84,8 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
91 int i, j; 84 int i, j;
92 85
93 r1_bio = r1bio_pool_alloc(gfp_flags, pi); 86 r1_bio = r1bio_pool_alloc(gfp_flags, pi);
94 if (!r1_bio) { 87 if (!r1_bio)
95 unplug_slaves(pi->mddev);
96 return NULL; 88 return NULL;
97 }
98 89
99 /* 90 /*
100 * Allocate bios : 1 for reading, n-1 for writing 91 * Allocate bios : 1 for reading, n-1 for writing
@@ -520,37 +511,6 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
520 return new_disk; 511 return new_disk;
521} 512}
522 513
523static void unplug_slaves(mddev_t *mddev)
524{
525 conf_t *conf = mddev->private;
526 int i;
527
528 rcu_read_lock();
529 for (i=0; i<mddev->raid_disks; i++) {
530 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
531 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
532 struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
533
534 atomic_inc(&rdev->nr_pending);
535 rcu_read_unlock();
536
537 blk_unplug(r_queue);
538
539 rdev_dec_pending(rdev, mddev);
540 rcu_read_lock();
541 }
542 }
543 rcu_read_unlock();
544}
545
546static void raid1_unplug(struct request_queue *q)
547{
548 mddev_t *mddev = q->queuedata;
549
550 unplug_slaves(mddev);
551 md_wakeup_thread(mddev->thread);
552}
553
554static int raid1_congested(void *data, int bits) 514static int raid1_congested(void *data, int bits)
555{ 515{
556 mddev_t *mddev = data; 516 mddev_t *mddev = data;
@@ -580,23 +540,16 @@ static int raid1_congested(void *data, int bits)
580} 540}
581 541
582 542
583static int flush_pending_writes(conf_t *conf) 543static void flush_pending_writes(conf_t *conf)
584{ 544{
585 /* Any writes that have been queued but are awaiting 545 /* Any writes that have been queued but are awaiting
586 * bitmap updates get flushed here. 546 * bitmap updates get flushed here.
587 * We return 1 if any requests were actually submitted.
588 */ 547 */
589 int rv = 0;
590
591 spin_lock_irq(&conf->device_lock); 548 spin_lock_irq(&conf->device_lock);
592 549
593 if (conf->pending_bio_list.head) { 550 if (conf->pending_bio_list.head) {
594 struct bio *bio; 551 struct bio *bio;
595 bio = bio_list_get(&conf->pending_bio_list); 552 bio = bio_list_get(&conf->pending_bio_list);
596 /* Only take the spinlock to quiet a warning */
597 spin_lock(conf->mddev->queue->queue_lock);
598 blk_remove_plug(conf->mddev->queue);
599 spin_unlock(conf->mddev->queue->queue_lock);
600 spin_unlock_irq(&conf->device_lock); 553 spin_unlock_irq(&conf->device_lock);
601 /* flush any pending bitmap writes to 554 /* flush any pending bitmap writes to
602 * disk before proceeding w/ I/O */ 555 * disk before proceeding w/ I/O */
@@ -608,10 +561,14 @@ static int flush_pending_writes(conf_t *conf)
608 generic_make_request(bio); 561 generic_make_request(bio);
609 bio = next; 562 bio = next;
610 } 563 }
611 rv = 1;
612 } else 564 } else
613 spin_unlock_irq(&conf->device_lock); 565 spin_unlock_irq(&conf->device_lock);
614 return rv; 566}
567
568static void md_kick_device(mddev_t *mddev)
569{
570 blk_flush_plug(current);
571 md_wakeup_thread(mddev->thread);
615} 572}
616 573
617/* Barriers.... 574/* Barriers....
@@ -643,8 +600,7 @@ static void raise_barrier(conf_t *conf)
643 600
644 /* Wait until no block IO is waiting */ 601 /* Wait until no block IO is waiting */
645 wait_event_lock_irq(conf->wait_barrier, !conf->nr_waiting, 602 wait_event_lock_irq(conf->wait_barrier, !conf->nr_waiting,
646 conf->resync_lock, 603 conf->resync_lock, md_kick_device(conf->mddev));
647 raid1_unplug(conf->mddev->queue));
648 604
649 /* block any new IO from starting */ 605 /* block any new IO from starting */
650 conf->barrier++; 606 conf->barrier++;
@@ -652,8 +608,7 @@ static void raise_barrier(conf_t *conf)
652 /* Now wait for all pending IO to complete */ 608 /* Now wait for all pending IO to complete */
653 wait_event_lock_irq(conf->wait_barrier, 609 wait_event_lock_irq(conf->wait_barrier,
654 !conf->nr_pending && conf->barrier < RESYNC_DEPTH, 610 !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
655 conf->resync_lock, 611 conf->resync_lock, md_kick_device(conf->mddev));
656 raid1_unplug(conf->mddev->queue));
657 612
658 spin_unlock_irq(&conf->resync_lock); 613 spin_unlock_irq(&conf->resync_lock);
659} 614}
@@ -675,7 +630,7 @@ static void wait_barrier(conf_t *conf)
675 conf->nr_waiting++; 630 conf->nr_waiting++;
676 wait_event_lock_irq(conf->wait_barrier, !conf->barrier, 631 wait_event_lock_irq(conf->wait_barrier, !conf->barrier,
677 conf->resync_lock, 632 conf->resync_lock,
678 raid1_unplug(conf->mddev->queue)); 633 md_kick_device(conf->mddev));
679 conf->nr_waiting--; 634 conf->nr_waiting--;
680 } 635 }
681 conf->nr_pending++; 636 conf->nr_pending++;
@@ -712,7 +667,7 @@ static void freeze_array(conf_t *conf)
712 conf->nr_pending == conf->nr_queued+1, 667 conf->nr_pending == conf->nr_queued+1,
713 conf->resync_lock, 668 conf->resync_lock,
714 ({ flush_pending_writes(conf); 669 ({ flush_pending_writes(conf);
715 raid1_unplug(conf->mddev->queue); })); 670 md_kick_device(conf->mddev); }));
716 spin_unlock_irq(&conf->resync_lock); 671 spin_unlock_irq(&conf->resync_lock);
717} 672}
718static void unfreeze_array(conf_t *conf) 673static void unfreeze_array(conf_t *conf)
@@ -962,7 +917,6 @@ static int make_request(mddev_t *mddev, struct bio * bio)
962 atomic_inc(&r1_bio->remaining); 917 atomic_inc(&r1_bio->remaining);
963 spin_lock_irqsave(&conf->device_lock, flags); 918 spin_lock_irqsave(&conf->device_lock, flags);
964 bio_list_add(&conf->pending_bio_list, mbio); 919 bio_list_add(&conf->pending_bio_list, mbio);
965 blk_plug_device_unlocked(mddev->queue);
966 spin_unlock_irqrestore(&conf->device_lock, flags); 920 spin_unlock_irqrestore(&conf->device_lock, flags);
967 } 921 }
968 r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL); 922 r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL);
@@ -971,7 +925,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
971 /* In case raid1d snuck in to freeze_array */ 925 /* In case raid1d snuck in to freeze_array */
972 wake_up(&conf->wait_barrier); 926 wake_up(&conf->wait_barrier);
973 927
974 if (do_sync) 928 if (do_sync || !bitmap)
975 md_wakeup_thread(mddev->thread); 929 md_wakeup_thread(mddev->thread);
976 930
977 return 0; 931 return 0;
@@ -1178,7 +1132,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
1178 p->rdev = rdev; 1132 p->rdev = rdev;
1179 goto abort; 1133 goto abort;
1180 } 1134 }
1181 md_integrity_register(mddev); 1135 err = md_integrity_register(mddev);
1182 } 1136 }
1183abort: 1137abort:
1184 1138
@@ -1561,7 +1515,6 @@ static void raid1d(mddev_t *mddev)
1561 unsigned long flags; 1515 unsigned long flags;
1562 conf_t *conf = mddev->private; 1516 conf_t *conf = mddev->private;
1563 struct list_head *head = &conf->retry_list; 1517 struct list_head *head = &conf->retry_list;
1564 int unplug=0;
1565 mdk_rdev_t *rdev; 1518 mdk_rdev_t *rdev;
1566 1519
1567 md_check_recovery(mddev); 1520 md_check_recovery(mddev);
@@ -1569,7 +1522,7 @@ static void raid1d(mddev_t *mddev)
1569 for (;;) { 1522 for (;;) {
1570 char b[BDEVNAME_SIZE]; 1523 char b[BDEVNAME_SIZE];
1571 1524
1572 unplug += flush_pending_writes(conf); 1525 flush_pending_writes(conf);
1573 1526
1574 spin_lock_irqsave(&conf->device_lock, flags); 1527 spin_lock_irqsave(&conf->device_lock, flags);
1575 if (list_empty(head)) { 1528 if (list_empty(head)) {
@@ -1583,10 +1536,9 @@ static void raid1d(mddev_t *mddev)
1583 1536
1584 mddev = r1_bio->mddev; 1537 mddev = r1_bio->mddev;
1585 conf = mddev->private; 1538 conf = mddev->private;
1586 if (test_bit(R1BIO_IsSync, &r1_bio->state)) { 1539 if (test_bit(R1BIO_IsSync, &r1_bio->state))
1587 sync_request_write(mddev, r1_bio); 1540 sync_request_write(mddev, r1_bio);
1588 unplug = 1; 1541 else {
1589 } else {
1590 int disk; 1542 int disk;
1591 1543
1592 /* we got a read error. Maybe the drive is bad. Maybe just 1544 /* we got a read error. Maybe the drive is bad. Maybe just
@@ -1636,14 +1588,11 @@ static void raid1d(mddev_t *mddev)
1636 bio->bi_end_io = raid1_end_read_request; 1588 bio->bi_end_io = raid1_end_read_request;
1637 bio->bi_rw = READ | do_sync; 1589 bio->bi_rw = READ | do_sync;
1638 bio->bi_private = r1_bio; 1590 bio->bi_private = r1_bio;
1639 unplug = 1;
1640 generic_make_request(bio); 1591 generic_make_request(bio);
1641 } 1592 }
1642 } 1593 }
1643 cond_resched(); 1594 cond_resched();
1644 } 1595 }
1645 if (unplug)
1646 unplug_slaves(mddev);
1647} 1596}
1648 1597
1649 1598
@@ -2066,11 +2015,9 @@ static int run(mddev_t *mddev)
2066 2015
2067 md_set_array_sectors(mddev, raid1_size(mddev, 0, 0)); 2016 md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
2068 2017
2069 mddev->queue->unplug_fn = raid1_unplug;
2070 mddev->queue->backing_dev_info.congested_fn = raid1_congested; 2018 mddev->queue->backing_dev_info.congested_fn = raid1_congested;
2071 mddev->queue->backing_dev_info.congested_data = mddev; 2019 mddev->queue->backing_dev_info.congested_data = mddev;
2072 md_integrity_register(mddev); 2020 return md_integrity_register(mddev);
2073 return 0;
2074} 2021}
2075 2022
2076static int stop(mddev_t *mddev) 2023static int stop(mddev_t *mddev)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 747d061d8e05..f7b62370b374 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -57,23 +57,16 @@
57 */ 57 */
58#define NR_RAID10_BIOS 256 58#define NR_RAID10_BIOS 256
59 59
60static void unplug_slaves(mddev_t *mddev);
61
62static void allow_barrier(conf_t *conf); 60static void allow_barrier(conf_t *conf);
63static void lower_barrier(conf_t *conf); 61static void lower_barrier(conf_t *conf);
64 62
65static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data) 63static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
66{ 64{
67 conf_t *conf = data; 65 conf_t *conf = data;
68 r10bio_t *r10_bio;
69 int size = offsetof(struct r10bio_s, devs[conf->copies]); 66 int size = offsetof(struct r10bio_s, devs[conf->copies]);
70 67
71 /* allocate a r10bio with room for raid_disks entries in the bios array */ 68 /* allocate a r10bio with room for raid_disks entries in the bios array */
72 r10_bio = kzalloc(size, gfp_flags); 69 return kzalloc(size, gfp_flags);
73 if (!r10_bio && conf->mddev)
74 unplug_slaves(conf->mddev);
75
76 return r10_bio;
77} 70}
78 71
79static void r10bio_pool_free(void *r10_bio, void *data) 72static void r10bio_pool_free(void *r10_bio, void *data)
@@ -106,10 +99,8 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data)
106 int nalloc; 99 int nalloc;
107 100
108 r10_bio = r10bio_pool_alloc(gfp_flags, conf); 101 r10_bio = r10bio_pool_alloc(gfp_flags, conf);
109 if (!r10_bio) { 102 if (!r10_bio)
110 unplug_slaves(conf->mddev);
111 return NULL; 103 return NULL;
112 }
113 104
114 if (test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery)) 105 if (test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery))
115 nalloc = conf->copies; /* resync */ 106 nalloc = conf->copies; /* resync */
@@ -597,37 +588,6 @@ rb_out:
597 return disk; 588 return disk;
598} 589}
599 590
600static void unplug_slaves(mddev_t *mddev)
601{
602 conf_t *conf = mddev->private;
603 int i;
604
605 rcu_read_lock();
606 for (i=0; i < conf->raid_disks; i++) {
607 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
608 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
609 struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
610
611 atomic_inc(&rdev->nr_pending);
612 rcu_read_unlock();
613
614 blk_unplug(r_queue);
615
616 rdev_dec_pending(rdev, mddev);
617 rcu_read_lock();
618 }
619 }
620 rcu_read_unlock();
621}
622
623static void raid10_unplug(struct request_queue *q)
624{
625 mddev_t *mddev = q->queuedata;
626
627 unplug_slaves(q->queuedata);
628 md_wakeup_thread(mddev->thread);
629}
630
631static int raid10_congested(void *data, int bits) 591static int raid10_congested(void *data, int bits)
632{ 592{
633 mddev_t *mddev = data; 593 mddev_t *mddev = data;
@@ -649,23 +609,16 @@ static int raid10_congested(void *data, int bits)
649 return ret; 609 return ret;
650} 610}
651 611
652static int flush_pending_writes(conf_t *conf) 612static void flush_pending_writes(conf_t *conf)
653{ 613{
654 /* Any writes that have been queued but are awaiting 614 /* Any writes that have been queued but are awaiting
655 * bitmap updates get flushed here. 615 * bitmap updates get flushed here.
656 * We return 1 if any requests were actually submitted.
657 */ 616 */
658 int rv = 0;
659
660 spin_lock_irq(&conf->device_lock); 617 spin_lock_irq(&conf->device_lock);
661 618
662 if (conf->pending_bio_list.head) { 619 if (conf->pending_bio_list.head) {
663 struct bio *bio; 620 struct bio *bio;
664 bio = bio_list_get(&conf->pending_bio_list); 621 bio = bio_list_get(&conf->pending_bio_list);
665 /* Spinlock only taken to quiet a warning */
666 spin_lock(conf->mddev->queue->queue_lock);
667 blk_remove_plug(conf->mddev->queue);
668 spin_unlock(conf->mddev->queue->queue_lock);
669 spin_unlock_irq(&conf->device_lock); 622 spin_unlock_irq(&conf->device_lock);
670 /* flush any pending bitmap writes to disk 623 /* flush any pending bitmap writes to disk
671 * before proceeding w/ I/O */ 624 * before proceeding w/ I/O */
@@ -677,11 +630,16 @@ static int flush_pending_writes(conf_t *conf)
677 generic_make_request(bio); 630 generic_make_request(bio);
678 bio = next; 631 bio = next;
679 } 632 }
680 rv = 1;
681 } else 633 } else
682 spin_unlock_irq(&conf->device_lock); 634 spin_unlock_irq(&conf->device_lock);
683 return rv;
684} 635}
636
637static void md_kick_device(mddev_t *mddev)
638{
639 blk_flush_plug(current);
640 md_wakeup_thread(mddev->thread);
641}
642
685/* Barriers.... 643/* Barriers....
686 * Sometimes we need to suspend IO while we do something else, 644 * Sometimes we need to suspend IO while we do something else,
687 * either some resync/recovery, or reconfigure the array. 645 * either some resync/recovery, or reconfigure the array.
@@ -711,8 +669,7 @@ static void raise_barrier(conf_t *conf, int force)
711 669
712 /* Wait until no block IO is waiting (unless 'force') */ 670 /* Wait until no block IO is waiting (unless 'force') */
713 wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting, 671 wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting,
714 conf->resync_lock, 672 conf->resync_lock, md_kick_device(conf->mddev));
715 raid10_unplug(conf->mddev->queue));
716 673
717 /* block any new IO from starting */ 674 /* block any new IO from starting */
718 conf->barrier++; 675 conf->barrier++;
@@ -720,8 +677,7 @@ static void raise_barrier(conf_t *conf, int force)
720 /* No wait for all pending IO to complete */ 677 /* No wait for all pending IO to complete */
721 wait_event_lock_irq(conf->wait_barrier, 678 wait_event_lock_irq(conf->wait_barrier,
722 !conf->nr_pending && conf->barrier < RESYNC_DEPTH, 679 !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
723 conf->resync_lock, 680 conf->resync_lock, md_kick_device(conf->mddev));
724 raid10_unplug(conf->mddev->queue));
725 681
726 spin_unlock_irq(&conf->resync_lock); 682 spin_unlock_irq(&conf->resync_lock);
727} 683}
@@ -742,7 +698,7 @@ static void wait_barrier(conf_t *conf)
742 conf->nr_waiting++; 698 conf->nr_waiting++;
743 wait_event_lock_irq(conf->wait_barrier, !conf->barrier, 699 wait_event_lock_irq(conf->wait_barrier, !conf->barrier,
744 conf->resync_lock, 700 conf->resync_lock,
745 raid10_unplug(conf->mddev->queue)); 701 md_kick_device(conf->mddev));
746 conf->nr_waiting--; 702 conf->nr_waiting--;
747 } 703 }
748 conf->nr_pending++; 704 conf->nr_pending++;
@@ -779,7 +735,7 @@ static void freeze_array(conf_t *conf)
779 conf->nr_pending == conf->nr_queued+1, 735 conf->nr_pending == conf->nr_queued+1,
780 conf->resync_lock, 736 conf->resync_lock,
781 ({ flush_pending_writes(conf); 737 ({ flush_pending_writes(conf);
782 raid10_unplug(conf->mddev->queue); })); 738 md_kick_device(conf->mddev); }));
783 spin_unlock_irq(&conf->resync_lock); 739 spin_unlock_irq(&conf->resync_lock);
784} 740}
785 741
@@ -974,7 +930,6 @@ static int make_request(mddev_t *mddev, struct bio * bio)
974 atomic_inc(&r10_bio->remaining); 930 atomic_inc(&r10_bio->remaining);
975 spin_lock_irqsave(&conf->device_lock, flags); 931 spin_lock_irqsave(&conf->device_lock, flags);
976 bio_list_add(&conf->pending_bio_list, mbio); 932 bio_list_add(&conf->pending_bio_list, mbio);
977 blk_plug_device_unlocked(mddev->queue);
978 spin_unlock_irqrestore(&conf->device_lock, flags); 933 spin_unlock_irqrestore(&conf->device_lock, flags);
979 } 934 }
980 935
@@ -991,7 +946,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
991 /* In case raid10d snuck in to freeze_array */ 946 /* In case raid10d snuck in to freeze_array */
992 wake_up(&conf->wait_barrier); 947 wake_up(&conf->wait_barrier);
993 948
994 if (do_sync) 949 if (do_sync || !mddev->bitmap)
995 md_wakeup_thread(mddev->thread); 950 md_wakeup_thread(mddev->thread);
996 951
997 return 0; 952 return 0;
@@ -1233,7 +1188,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
1233 p->rdev = rdev; 1188 p->rdev = rdev;
1234 goto abort; 1189 goto abort;
1235 } 1190 }
1236 md_integrity_register(mddev); 1191 err = md_integrity_register(mddev);
1237 } 1192 }
1238abort: 1193abort:
1239 1194
@@ -1684,7 +1639,6 @@ static void raid10d(mddev_t *mddev)
1684 unsigned long flags; 1639 unsigned long flags;
1685 conf_t *conf = mddev->private; 1640 conf_t *conf = mddev->private;
1686 struct list_head *head = &conf->retry_list; 1641 struct list_head *head = &conf->retry_list;
1687 int unplug=0;
1688 mdk_rdev_t *rdev; 1642 mdk_rdev_t *rdev;
1689 1643
1690 md_check_recovery(mddev); 1644 md_check_recovery(mddev);
@@ -1692,7 +1646,7 @@ static void raid10d(mddev_t *mddev)
1692 for (;;) { 1646 for (;;) {
1693 char b[BDEVNAME_SIZE]; 1647 char b[BDEVNAME_SIZE];
1694 1648
1695 unplug += flush_pending_writes(conf); 1649 flush_pending_writes(conf);
1696 1650
1697 spin_lock_irqsave(&conf->device_lock, flags); 1651 spin_lock_irqsave(&conf->device_lock, flags);
1698 if (list_empty(head)) { 1652 if (list_empty(head)) {
@@ -1706,13 +1660,11 @@ static void raid10d(mddev_t *mddev)
1706 1660
1707 mddev = r10_bio->mddev; 1661 mddev = r10_bio->mddev;
1708 conf = mddev->private; 1662 conf = mddev->private;
1709 if (test_bit(R10BIO_IsSync, &r10_bio->state)) { 1663 if (test_bit(R10BIO_IsSync, &r10_bio->state))
1710 sync_request_write(mddev, r10_bio); 1664 sync_request_write(mddev, r10_bio);
1711 unplug = 1; 1665 else if (test_bit(R10BIO_IsRecover, &r10_bio->state))
1712 } else if (test_bit(R10BIO_IsRecover, &r10_bio->state)) {
1713 recovery_request_write(mddev, r10_bio); 1666 recovery_request_write(mddev, r10_bio);
1714 unplug = 1; 1667 else {
1715 } else {
1716 int mirror; 1668 int mirror;
1717 /* we got a read error. Maybe the drive is bad. Maybe just 1669 /* we got a read error. Maybe the drive is bad. Maybe just
1718 * the block and we can fix it. 1670 * the block and we can fix it.
@@ -1759,14 +1711,11 @@ static void raid10d(mddev_t *mddev)
1759 bio->bi_rw = READ | do_sync; 1711 bio->bi_rw = READ | do_sync;
1760 bio->bi_private = r10_bio; 1712 bio->bi_private = r10_bio;
1761 bio->bi_end_io = raid10_end_read_request; 1713 bio->bi_end_io = raid10_end_read_request;
1762 unplug = 1;
1763 generic_make_request(bio); 1714 generic_make_request(bio);
1764 } 1715 }
1765 } 1716 }
1766 cond_resched(); 1717 cond_resched();
1767 } 1718 }
1768 if (unplug)
1769 unplug_slaves(mddev);
1770} 1719}
1771 1720
1772 1721
@@ -2377,7 +2326,6 @@ static int run(mddev_t *mddev)
2377 md_set_array_sectors(mddev, size); 2326 md_set_array_sectors(mddev, size);
2378 mddev->resync_max_sectors = size; 2327 mddev->resync_max_sectors = size;
2379 2328
2380 mddev->queue->unplug_fn = raid10_unplug;
2381 mddev->queue->backing_dev_info.congested_fn = raid10_congested; 2329 mddev->queue->backing_dev_info.congested_fn = raid10_congested;
2382 mddev->queue->backing_dev_info.congested_data = mddev; 2330 mddev->queue->backing_dev_info.congested_data = mddev;
2383 2331
@@ -2395,7 +2343,10 @@ static int run(mddev_t *mddev)
2395 2343
2396 if (conf->near_copies < conf->raid_disks) 2344 if (conf->near_copies < conf->raid_disks)
2397 blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec); 2345 blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec);
2398 md_integrity_register(mddev); 2346
2347 if (md_integrity_register(mddev))
2348 goto out_free_conf;
2349
2399 return 0; 2350 return 0;
2400 2351
2401out_free_conf: 2352out_free_conf:
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 78536fdbd87f..e867ee42b152 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -433,8 +433,6 @@ static int has_failed(raid5_conf_t *conf)
433 return 0; 433 return 0;
434} 434}
435 435
436static void unplug_slaves(mddev_t *mddev);
437
438static struct stripe_head * 436static struct stripe_head *
439get_active_stripe(raid5_conf_t *conf, sector_t sector, 437get_active_stripe(raid5_conf_t *conf, sector_t sector,
440 int previous, int noblock, int noquiesce) 438 int previous, int noblock, int noquiesce)
@@ -463,8 +461,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector,
463 < (conf->max_nr_stripes *3/4) 461 < (conf->max_nr_stripes *3/4)
464 || !conf->inactive_blocked), 462 || !conf->inactive_blocked),
465 conf->device_lock, 463 conf->device_lock,
466 md_raid5_unplug_device(conf) 464 md_raid5_kick_device(conf));
467 );
468 conf->inactive_blocked = 0; 465 conf->inactive_blocked = 0;
469 } else 466 } else
470 init_stripe(sh, sector, previous); 467 init_stripe(sh, sector, previous);
@@ -1473,8 +1470,7 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
1473 wait_event_lock_irq(conf->wait_for_stripe, 1470 wait_event_lock_irq(conf->wait_for_stripe,
1474 !list_empty(&conf->inactive_list), 1471 !list_empty(&conf->inactive_list),
1475 conf->device_lock, 1472 conf->device_lock,
1476 unplug_slaves(conf->mddev) 1473 blk_flush_plug(current));
1477 );
1478 osh = get_free_stripe(conf); 1474 osh = get_free_stripe(conf);
1479 spin_unlock_irq(&conf->device_lock); 1475 spin_unlock_irq(&conf->device_lock);
1480 atomic_set(&nsh->count, 1); 1476 atomic_set(&nsh->count, 1);
@@ -3645,58 +3641,19 @@ static void activate_bit_delay(raid5_conf_t *conf)
3645 } 3641 }
3646} 3642}
3647 3643
3648static void unplug_slaves(mddev_t *mddev) 3644void md_raid5_kick_device(raid5_conf_t *conf)
3649{ 3645{
3650 raid5_conf_t *conf = mddev->private; 3646 blk_flush_plug(current);
3651 int i; 3647 raid5_activate_delayed(conf);
3652 int devs = max(conf->raid_disks, conf->previous_raid_disks);
3653
3654 rcu_read_lock();
3655 for (i = 0; i < devs; i++) {
3656 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
3657 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
3658 struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
3659
3660 atomic_inc(&rdev->nr_pending);
3661 rcu_read_unlock();
3662
3663 blk_unplug(r_queue);
3664
3665 rdev_dec_pending(rdev, mddev);
3666 rcu_read_lock();
3667 }
3668 }
3669 rcu_read_unlock();
3670}
3671
3672void md_raid5_unplug_device(raid5_conf_t *conf)
3673{
3674 unsigned long flags;
3675
3676 spin_lock_irqsave(&conf->device_lock, flags);
3677
3678 if (plugger_remove_plug(&conf->plug)) {
3679 conf->seq_flush++;
3680 raid5_activate_delayed(conf);
3681 }
3682 md_wakeup_thread(conf->mddev->thread); 3648 md_wakeup_thread(conf->mddev->thread);
3683
3684 spin_unlock_irqrestore(&conf->device_lock, flags);
3685
3686 unplug_slaves(conf->mddev);
3687} 3649}
3688EXPORT_SYMBOL_GPL(md_raid5_unplug_device); 3650EXPORT_SYMBOL_GPL(md_raid5_kick_device);
3689 3651
3690static void raid5_unplug(struct plug_handle *plug) 3652static void raid5_unplug(struct plug_handle *plug)
3691{ 3653{
3692 raid5_conf_t *conf = container_of(plug, raid5_conf_t, plug); 3654 raid5_conf_t *conf = container_of(plug, raid5_conf_t, plug);
3693 md_raid5_unplug_device(conf);
3694}
3695 3655
3696static void raid5_unplug_queue(struct request_queue *q) 3656 md_raid5_kick_device(conf);
3697{
3698 mddev_t *mddev = q->queuedata;
3699 md_raid5_unplug_device(mddev->private);
3700} 3657}
3701 3658
3702int md_raid5_congested(mddev_t *mddev, int bits) 3659int md_raid5_congested(mddev_t *mddev, int bits)
@@ -4100,7 +4057,7 @@ static int make_request(mddev_t *mddev, struct bio * bi)
4100 * add failed due to overlap. Flush everything 4057 * add failed due to overlap. Flush everything
4101 * and wait a while 4058 * and wait a while
4102 */ 4059 */
4103 md_raid5_unplug_device(conf); 4060 md_raid5_kick_device(conf);
4104 release_stripe(sh); 4061 release_stripe(sh);
4105 schedule(); 4062 schedule();
4106 goto retry; 4063 goto retry;
@@ -4365,7 +4322,6 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
4365 4322
4366 if (sector_nr >= max_sector) { 4323 if (sector_nr >= max_sector) {
4367 /* just being told to finish up .. nothing much to do */ 4324 /* just being told to finish up .. nothing much to do */
4368 unplug_slaves(mddev);
4369 4325
4370 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { 4326 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
4371 end_reshape(conf); 4327 end_reshape(conf);
@@ -4569,7 +4525,6 @@ static void raid5d(mddev_t *mddev)
4569 spin_unlock_irq(&conf->device_lock); 4525 spin_unlock_irq(&conf->device_lock);
4570 4526
4571 async_tx_issue_pending_all(); 4527 async_tx_issue_pending_all();
4572 unplug_slaves(mddev);
4573 4528
4574 pr_debug("--- raid5d inactive\n"); 4529 pr_debug("--- raid5d inactive\n");
4575} 4530}
@@ -5204,7 +5159,7 @@ static int run(mddev_t *mddev)
5204 5159
5205 mddev->queue->backing_dev_info.congested_data = mddev; 5160 mddev->queue->backing_dev_info.congested_data = mddev;
5206 mddev->queue->backing_dev_info.congested_fn = raid5_congested; 5161 mddev->queue->backing_dev_info.congested_fn = raid5_congested;
5207 mddev->queue->unplug_fn = raid5_unplug_queue; 5162 mddev->queue->queue_lock = &conf->device_lock;
5208 5163
5209 chunk_size = mddev->chunk_sectors << 9; 5164 chunk_size = mddev->chunk_sectors << 9;
5210 blk_queue_io_min(mddev->queue, chunk_size); 5165 blk_queue_io_min(mddev->queue, chunk_size);
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 2ace0582b409..8d563a4f022a 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -503,6 +503,6 @@ static inline int algorithm_is_DDF(int layout)
503} 503}
504 504
505extern int md_raid5_congested(mddev_t *mddev, int bits); 505extern int md_raid5_congested(mddev_t *mddev, int bits);
506extern void md_raid5_unplug_device(raid5_conf_t *conf); 506extern void md_raid5_kick_device(raid5_conf_t *conf);
507extern int raid5_set_cache_size(mddev_t *mddev, int size); 507extern int raid5_set_cache_size(mddev_t *mddev, int size);
508#endif 508#endif
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 81b3ba83cc65..6995940b633a 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -14,6 +14,19 @@ if MEDIA_SUPPORT
14comment "Multimedia core support" 14comment "Multimedia core support"
15 15
16# 16#
17# Media controller
18#
19
20config MEDIA_CONTROLLER
21 bool "Media Controller API (EXPERIMENTAL)"
22 depends on EXPERIMENTAL
23 ---help---
24 Enable the media controller API used to query media devices internal
25 topology and configure it dynamically.
26
27 This API is mostly used by camera interfaces in embedded platforms.
28
29#
17# V4L core and enabled API's 30# V4L core and enabled API's
18# 31#
19 32
@@ -40,6 +53,15 @@ config VIDEO_V4L2_COMMON
40 depends on (I2C || I2C=n) && VIDEO_DEV 53 depends on (I2C || I2C=n) && VIDEO_DEV
41 default (I2C || I2C=n) && VIDEO_DEV 54 default (I2C || I2C=n) && VIDEO_DEV
42 55
56config VIDEO_V4L2_SUBDEV_API
57 bool "V4L2 sub-device userspace API (EXPERIMENTAL)"
58 depends on VIDEO_DEV && MEDIA_CONTROLLER && EXPERIMENTAL
59 ---help---
60 Enables the V4L2 sub-device pad-level userspace API used to configure
61 video format, size and frame rate between hardware blocks.
62
63 This API is mostly used by camera interfaces in embedded platforms.
64
43# 65#
44# DVB Core 66# DVB Core
45# 67#
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index b603ea645ede..64755c99ded2 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,6 +2,12 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5media-objs := media-device.o media-devnode.o media-entity.o
6
7ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
8 obj-$(CONFIG_MEDIA_SUPPORT) += media.o
9endif
10
5obj-y += common/ rc/ video/ 11obj-y += common/ rc/ video/
6 12
7obj-$(CONFIG_VIDEO_DEV) += radio/ 13obj-$(CONFIG_VIDEO_DEV) += radio/
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index bf14bd79e2fc..cdb645d57438 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -36,6 +36,8 @@ struct tda9887_priv {
36 unsigned int mode; 36 unsigned int mode;
37 unsigned int audmode; 37 unsigned int audmode;
38 v4l2_std_id std; 38 v4l2_std_id std;
39
40 bool standby;
39}; 41};
40 42
41/* ---------------------------------------------------------------------- */ 43/* ---------------------------------------------------------------------- */
@@ -568,7 +570,7 @@ static void tda9887_configure(struct dvb_frontend *fe)
568 tda9887_do_config(fe); 570 tda9887_do_config(fe);
569 tda9887_set_insmod(fe); 571 tda9887_set_insmod(fe);
570 572
571 if (priv->mode == T_STANDBY) 573 if (priv->standby)
572 priv->data[1] |= cForcedMuteAudioON; 574 priv->data[1] |= cForcedMuteAudioON;
573 575
574 tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", 576 tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
@@ -616,7 +618,7 @@ static void tda9887_standby(struct dvb_frontend *fe)
616{ 618{
617 struct tda9887_priv *priv = fe->analog_demod_priv; 619 struct tda9887_priv *priv = fe->analog_demod_priv;
618 620
619 priv->mode = T_STANDBY; 621 priv->standby = true;
620 622
621 tda9887_configure(fe); 623 tda9887_configure(fe);
622} 624}
@@ -626,6 +628,7 @@ static void tda9887_set_params(struct dvb_frontend *fe,
626{ 628{
627 struct tda9887_priv *priv = fe->analog_demod_priv; 629 struct tda9887_priv *priv = fe->analog_demod_priv;
628 630
631 priv->standby = false;
629 priv->mode = params->mode; 632 priv->mode = params->mode;
630 priv->audmode = params->audmode; 633 priv->audmode = params->audmode;
631 priv->std = params->std; 634 priv->std = params->std;
@@ -686,7 +689,7 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
686 return NULL; 689 return NULL;
687 case 1: 690 case 1:
688 fe->analog_demod_priv = priv; 691 fe->analog_demod_priv = priv;
689 priv->mode = T_STANDBY; 692 priv->standby = true;
690 tuner_info("tda988[5/6/7] found\n"); 693 tuner_info("tda988[5/6/7] found\n");
691 break; 694 break;
692 default: 695 default:
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c
index 925399dffbed..bf78cb9fc52c 100644
--- a/drivers/media/common/tuners/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
@@ -23,6 +23,7 @@ struct tea5761_priv {
23 struct tuner_i2c_props i2c_props; 23 struct tuner_i2c_props i2c_props;
24 24
25 u32 frequency; 25 u32 frequency;
26 bool standby;
26}; 27};
27 28
28/*****************************************************************************/ 29/*****************************************************************************/
@@ -135,18 +136,19 @@ static void tea5761_status_dump(unsigned char *buffer)
135} 136}
136 137
137/* Freq should be specifyed at 62.5 Hz */ 138/* Freq should be specifyed at 62.5 Hz */
138static int set_radio_freq(struct dvb_frontend *fe, 139static int __set_radio_freq(struct dvb_frontend *fe,
139 struct analog_parameters *params) 140 unsigned int freq,
141 bool mono)
140{ 142{
141 struct tea5761_priv *priv = fe->tuner_priv; 143 struct tea5761_priv *priv = fe->tuner_priv;
142 unsigned int frq = params->frequency; 144 unsigned int frq = freq;
143 unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 }; 145 unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
144 unsigned div; 146 unsigned div;
145 int rc; 147 int rc;
146 148
147 tuner_dbg("radio freq counter %d\n", frq); 149 tuner_dbg("radio freq counter %d\n", frq);
148 150
149 if (params->mode == T_STANDBY) { 151 if (priv->standby) {
150 tuner_dbg("TEA5761 set to standby mode\n"); 152 tuner_dbg("TEA5761 set to standby mode\n");
151 buffer[5] |= TEA5761_TNCTRL_MU; 153 buffer[5] |= TEA5761_TNCTRL_MU;
152 } else { 154 } else {
@@ -154,7 +156,7 @@ static int set_radio_freq(struct dvb_frontend *fe,
154 } 156 }
155 157
156 158
157 if (params->audmode == V4L2_TUNER_MODE_MONO) { 159 if (mono) {
158 tuner_dbg("TEA5761 set to mono\n"); 160 tuner_dbg("TEA5761 set to mono\n");
159 buffer[5] |= TEA5761_TNCTRL_MST; 161 buffer[5] |= TEA5761_TNCTRL_MST;
160 } else { 162 } else {
@@ -176,6 +178,26 @@ static int set_radio_freq(struct dvb_frontend *fe,
176 return 0; 178 return 0;
177} 179}
178 180
181static int set_radio_freq(struct dvb_frontend *fe,
182 struct analog_parameters *params)
183{
184 struct tea5761_priv *priv = fe->analog_demod_priv;
185
186 priv->standby = false;
187
188 return __set_radio_freq(fe, params->frequency,
189 params->audmode == V4L2_TUNER_MODE_MONO);
190}
191
192static int set_radio_sleep(struct dvb_frontend *fe)
193{
194 struct tea5761_priv *priv = fe->analog_demod_priv;
195
196 priv->standby = true;
197
198 return __set_radio_freq(fe, priv->frequency, false);
199}
200
179static int tea5761_read_status(struct dvb_frontend *fe, char *buffer) 201static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
180{ 202{
181 struct tea5761_priv *priv = fe->tuner_priv; 203 struct tea5761_priv *priv = fe->tuner_priv;
@@ -284,6 +306,7 @@ static struct dvb_tuner_ops tea5761_tuner_ops = {
284 .name = "tea5761", // Philips TEA5761HN FM Radio 306 .name = "tea5761", // Philips TEA5761HN FM Radio
285 }, 307 },
286 .set_analog_params = set_radio_freq, 308 .set_analog_params = set_radio_freq,
309 .sleep = set_radio_sleep,
287 .release = tea5761_release, 310 .release = tea5761_release,
288 .get_frequency = tea5761_get_frequency, 311 .get_frequency = tea5761_get_frequency,
289 .get_status = tea5761_get_status, 312 .get_status = tea5761_get_status,
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 58a513bcd747..afba6dc5e080 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -971,6 +971,22 @@ static struct tuner_params tuner_tena_9533_di_params[] = {
971 }, 971 },
972}; 972};
973 973
974/* ------------ TUNER_TENA_TNF_5337 - Tena tnf5337MFD STD M/N ------------ */
975
976static struct tuner_range tuner_tena_tnf_5337_ntsc_ranges[] = {
977 { 16 * 166.25 /*MHz*/, 0x86, 0x01, },
978 { 16 * 466.25 /*MHz*/, 0x86, 0x02, },
979 { 16 * 999.99 , 0x86, 0x08, },
980};
981
982static struct tuner_params tuner_tena_tnf_5337_params[] = {
983 {
984 .type = TUNER_PARAM_TYPE_NTSC,
985 .ranges = tuner_tena_tnf_5337_ntsc_ranges,
986 .count = ARRAY_SIZE(tuner_tena_tnf_5337_ntsc_ranges),
987 },
988};
989
974/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */ 990/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
975 991
976static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { 992static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
@@ -1842,6 +1858,11 @@ struct tunertype tuners[] = {
1842 .params = tuner_philips_fq1236_mk5_params, 1858 .params = tuner_philips_fq1236_mk5_params,
1843 .count = ARRAY_SIZE(tuner_philips_fq1236_mk5_params), 1859 .count = ARRAY_SIZE(tuner_philips_fq1236_mk5_params),
1844 }, 1860 },
1861 [TUNER_TENA_TNF_5337] = { /* Tena 5337 MFD */
1862 .name = "Tena TNF5337 MFD",
1863 .params = tuner_tena_tnf_5337_params,
1864 .count = ARRAY_SIZE(tuner_tena_tnf_5337_params),
1865 },
1845}; 1866};
1846EXPORT_SYMBOL(tuners); 1867EXPORT_SYMBOL(tuners);
1847 1868
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index b6ce528e1889..16fba6b59616 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -685,7 +685,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
685{ 685{
686 struct xc2028_data *priv = fe->tuner_priv; 686 struct xc2028_data *priv = fe->tuner_priv;
687 struct firmware_properties new_fw; 687 struct firmware_properties new_fw;
688 int rc = 0, is_retry = 0; 688 int rc = 0, retry_count = 0;
689 u16 version, hwmodel; 689 u16 version, hwmodel;
690 v4l2_std_id std0; 690 v4l2_std_id std0;
691 691
@@ -855,9 +855,9 @@ read_not_reliable:
855 855
856fail: 856fail:
857 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 857 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
858 if (!is_retry) { 858 if (retry_count < 8) {
859 msleep(50); 859 msleep(50);
860 is_retry = 1; 860 retry_count++;
861 tuner_dbg("Retrying firmware load\n"); 861 tuner_dbg("Retrying firmware load\n");
862 goto retry; 862 goto retry;
863 } 863 }
@@ -907,7 +907,7 @@ ret:
907#define DIV 15625 907#define DIV 15625
908 908
909static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, 909static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
910 enum tuner_mode new_mode, 910 enum v4l2_tuner_type new_type,
911 unsigned int type, 911 unsigned int type,
912 v4l2_std_id std, 912 v4l2_std_id std,
913 u16 int_freq) 913 u16 int_freq)
@@ -933,7 +933,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
933 * that xc2028 will be in a safe state. 933 * that xc2028 will be in a safe state.
934 * Maybe this might also be needed for DTV. 934 * Maybe this might also be needed for DTV.
935 */ 935 */
936 if (new_mode == T_ANALOG_TV) { 936 if (new_type == V4L2_TUNER_ANALOG_TV) {
937 rc = send_seq(priv, {0x00, 0x00}); 937 rc = send_seq(priv, {0x00, 0x00});
938 938
939 /* Analog modes require offset = 0 */ 939 /* Analog modes require offset = 0 */
@@ -1054,7 +1054,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
1054 if (priv->ctrl.input1) 1054 if (priv->ctrl.input1)
1055 type |= INPUT1; 1055 type |= INPUT1;
1056 return generic_set_freq(fe, (625l * p->frequency) / 10, 1056 return generic_set_freq(fe, (625l * p->frequency) / 10,
1057 T_RADIO, type, 0, 0); 1057 V4L2_TUNER_RADIO, type, 0, 0);
1058 } 1058 }
1059 1059
1060 /* if std is not defined, choose one */ 1060 /* if std is not defined, choose one */
@@ -1069,7 +1069,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
1069 p->std |= parse_audio_std_option(); 1069 p->std |= parse_audio_std_option();
1070 1070
1071 return generic_set_freq(fe, 62500l * p->frequency, 1071 return generic_set_freq(fe, 62500l * p->frequency,
1072 T_ANALOG_TV, type, p->std, 0); 1072 V4L2_TUNER_ANALOG_TV, type, p->std, 0);
1073} 1073}
1074 1074
1075static int xc2028_set_params(struct dvb_frontend *fe, 1075static int xc2028_set_params(struct dvb_frontend *fe,
@@ -1174,7 +1174,7 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1174 } 1174 }
1175 1175
1176 return generic_set_freq(fe, p->frequency, 1176 return generic_set_freq(fe, p->frequency,
1177 T_DIGITAL_TV, type, 0, demod); 1177 V4L2_TUNER_DIGITAL_TV, type, 0, demod);
1178} 1178}
1179 1179
1180static int xc2028_sleep(struct dvb_frontend *fe) 1180static int xc2028_sleep(struct dvb_frontend *fe)
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 76ac5cd84af7..1e28f7dcb26b 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -65,7 +65,7 @@ struct xc5000_priv {
65}; 65};
66 66
67/* Misc Defines */ 67/* Misc Defines */
68#define MAX_TV_STANDARD 23 68#define MAX_TV_STANDARD 24
69#define XC_MAX_I2C_WRITE_LENGTH 64 69#define XC_MAX_I2C_WRITE_LENGTH 64
70 70
71/* Signal Types */ 71/* Signal Types */
@@ -92,6 +92,8 @@ struct xc5000_priv {
92#define XREG_IF_OUT 0x05 92#define XREG_IF_OUT 0x05
93#define XREG_SEEK_MODE 0x07 93#define XREG_SEEK_MODE 0x07
94#define XREG_POWER_DOWN 0x0A /* Obsolete */ 94#define XREG_POWER_DOWN 0x0A /* Obsolete */
95/* Set the output amplitude - SIF for analog, DTVP/DTVN for digital */
96#define XREG_OUTPUT_AMP 0x0B
95#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ 97#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
96#define XREG_SMOOTHEDCVBS 0x0E 98#define XREG_SMOOTHEDCVBS 0x0E
97#define XREG_XTALFREQ 0x0F 99#define XREG_XTALFREQ 0x0F
@@ -173,6 +175,7 @@ struct XC_TV_STANDARD {
173#define DTV7 20 175#define DTV7 20
174#define FM_Radio_INPUT2 21 176#define FM_Radio_INPUT2 21
175#define FM_Radio_INPUT1 22 177#define FM_Radio_INPUT1 22
178#define FM_Radio_INPUT1_MONO 23
176 179
177static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { 180static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
178 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, 181 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
@@ -197,7 +200,8 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
197 {"DTV7/8", 0x00C0, 0x801B}, 200 {"DTV7/8", 0x00C0, 0x801B},
198 {"DTV7", 0x00C0, 0x8007}, 201 {"DTV7", 0x00C0, 0x8007},
199 {"FM Radio-INPUT2", 0x9802, 0x9002}, 202 {"FM Radio-INPUT2", 0x9802, 0x9002},
200 {"FM Radio-INPUT1", 0x0208, 0x9002} 203 {"FM Radio-INPUT1", 0x0208, 0x9002},
204 {"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
201}; 205};
202 206
203static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); 207static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
@@ -683,6 +687,24 @@ static int xc5000_set_params(struct dvb_frontend *fe,
683 return -EINVAL; 687 return -EINVAL;
684 } 688 }
685 priv->rf_mode = XC_RF_MODE_AIR; 689 priv->rf_mode = XC_RF_MODE_AIR;
690 } else if (fe->ops.info.type == FE_QAM) {
691 dprintk(1, "%s() QAM\n", __func__);
692 switch (params->u.qam.modulation) {
693 case QAM_16:
694 case QAM_32:
695 case QAM_64:
696 case QAM_128:
697 case QAM_256:
698 case QAM_AUTO:
699 dprintk(1, "%s() QAM modulation\n", __func__);
700 priv->bandwidth = BANDWIDTH_8_MHZ;
701 priv->video_standard = DTV7_8;
702 priv->freq_hz = params->frequency - 2750000;
703 priv->rf_mode = XC_RF_MODE_CABLE;
704 break;
705 default:
706 return -EINVAL;
707 }
686 } else { 708 } else {
687 printk(KERN_ERR "xc5000 modulation type not supported!\n"); 709 printk(KERN_ERR "xc5000 modulation type not supported!\n");
688 return -EINVAL; 710 return -EINVAL;
@@ -714,6 +736,8 @@ static int xc5000_set_params(struct dvb_frontend *fe,
714 return -EIO; 736 return -EIO;
715 } 737 }
716 738
739 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
740
717 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); 741 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
718 742
719 if (debug) 743 if (debug)
@@ -818,6 +842,8 @@ tune_channel:
818 return -EREMOTEIO; 842 return -EREMOTEIO;
819 } 843 }
820 844
845 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
846
821 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); 847 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
822 848
823 if (debug) 849 if (debug)
@@ -845,6 +871,8 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
845 radio_input = FM_Radio_INPUT1; 871 radio_input = FM_Radio_INPUT1;
846 else if (priv->radio_input == XC5000_RADIO_FM2) 872 else if (priv->radio_input == XC5000_RADIO_FM2)
847 radio_input = FM_Radio_INPUT2; 873 radio_input = FM_Radio_INPUT2;
874 else if (priv->radio_input == XC5000_RADIO_FM1_MONO)
875 radio_input = FM_Radio_INPUT1_MONO;
848 else { 876 else {
849 dprintk(1, "%s() unknown radio input %d\n", __func__, 877 dprintk(1, "%s() unknown radio input %d\n", __func__,
850 priv->radio_input); 878 priv->radio_input);
@@ -871,6 +899,12 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
871 return -EREMOTEIO; 899 return -EREMOTEIO;
872 } 900 }
873 901
902 if ((priv->radio_input == XC5000_RADIO_FM1) ||
903 (priv->radio_input == XC5000_RADIO_FM2))
904 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
905 else if (priv->radio_input == XC5000_RADIO_FM1_MONO)
906 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x06);
907
874 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); 908 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
875 909
876 return 0; 910 return 0;
@@ -1021,6 +1055,23 @@ static int xc5000_release(struct dvb_frontend *fe)
1021 return 0; 1055 return 0;
1022} 1056}
1023 1057
1058static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg)
1059{
1060 struct xc5000_priv *priv = fe->tuner_priv;
1061 struct xc5000_config *p = priv_cfg;
1062
1063 dprintk(1, "%s()\n", __func__);
1064
1065 if (p->if_khz)
1066 priv->if_khz = p->if_khz;
1067
1068 if (p->radio_input)
1069 priv->radio_input = p->radio_input;
1070
1071 return 0;
1072}
1073
1074
1024static const struct dvb_tuner_ops xc5000_tuner_ops = { 1075static const struct dvb_tuner_ops xc5000_tuner_ops = {
1025 .info = { 1076 .info = {
1026 .name = "Xceive XC5000", 1077 .name = "Xceive XC5000",
@@ -1033,6 +1084,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
1033 .init = xc5000_init, 1084 .init = xc5000_init,
1034 .sleep = xc5000_sleep, 1085 .sleep = xc5000_sleep,
1035 1086
1087 .set_config = xc5000_set_config,
1036 .set_params = xc5000_set_params, 1088 .set_params = xc5000_set_params,
1037 .set_analog_params = xc5000_set_analog_params, 1089 .set_analog_params = xc5000_set_analog_params,
1038 .get_frequency = xc5000_get_frequency, 1090 .get_frequency = xc5000_get_frequency,
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index 3756e73649be..e2957451b532 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -40,6 +40,7 @@ struct xc5000_config {
40#define XC5000_RADIO_NOT_CONFIGURED 0 40#define XC5000_RADIO_NOT_CONFIGURED 0
41#define XC5000_RADIO_FM1 1 41#define XC5000_RADIO_FM1 1
42#define XC5000_RADIO_FM2 2 42#define XC5000_RADIO_FM2 2
43#define XC5000_RADIO_FM1_MONO 3
43 44
44/* For each bridge framework, when it attaches either analog or digital, 45/* For each bridge framework, when it attaches either analog or digital,
45 * it has to store a reference back to its _core equivalent structure, 46 * it has to store a reference back to its _core equivalent structure,
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 161ccfd471cb..ee214c3b63d7 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -65,7 +65,7 @@ comment "Supported SDMC DM1105 Adapters"
65source "drivers/media/dvb/dm1105/Kconfig" 65source "drivers/media/dvb/dm1105/Kconfig"
66 66
67comment "Supported FireWire (IEEE 1394) Adapters" 67comment "Supported FireWire (IEEE 1394) Adapters"
68 depends on DVB_CORE && IEEE1394 68 depends on DVB_CORE && FIREWIRE
69source "drivers/media/dvb/firewire/Kconfig" 69source "drivers/media/dvb/firewire/Kconfig"
70 70
71comment "Supported Earthsoft PT1 Adapters" 71comment "Supported Earthsoft PT1 Adapters"
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index f9f19be77181..3b860504bf04 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -239,7 +239,6 @@ struct analog_demod_ops {
239 void (*set_params)(struct dvb_frontend *fe, 239 void (*set_params)(struct dvb_frontend *fe,
240 struct analog_parameters *params); 240 struct analog_parameters *params);
241 int (*has_signal)(struct dvb_frontend *fe); 241 int (*has_signal)(struct dvb_frontend *fe);
242 int (*is_stereo)(struct dvb_frontend *fe);
243 int (*get_afc)(struct dvb_frontend *fe); 242 int (*get_afc)(struct dvb_frontend *fe);
244 void (*tuner_status)(struct dvb_frontend *fe); 243 void (*tuner_status)(struct dvb_frontend *fe);
245 void (*standby)(struct dvb_frontend *fe); 244 void (*standby)(struct dvb_frontend *fe);
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 3d48ba019342..fe4f894183ff 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -358,3 +358,11 @@ config DVB_USB_LME2510
358 select DVB_IX2505V if !DVB_FE_CUSTOMISE 358 select DVB_IX2505V if !DVB_FE_CUSTOMISE
359 help 359 help
360 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . 360 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
361
362config DVB_USB_TECHNISAT_USB2
363 tristate "Technisat DVB-S/S2 USB2.0 support"
364 depends on DVB_USB
365 select DVB_STB0899 if !DVB_FE_CUSTOMISE
366 select DVB_STB6100 if !DVB_FE_CUSTOMISE
367 help
368 Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 5b1d12f2d591..4bac13da0c39 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -91,6 +91,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
91dvb-usb-lmedm04-objs = lmedm04.o 91dvb-usb-lmedm04-objs = lmedm04.o
92obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o 92obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
93 93
94dvb-usb-technisat-usb2-objs = technisat-usb2.o
95obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
96
94EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 97EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
95# due to tuner-xc3028 98# due to tuner-xc3028
96EXTRA_CFLAGS += -Idrivers/media/common/tuners 99EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index 53b93a4b6f8a..f8e9bf116f21 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
38} 38}
39 39
40static struct rc_map_table rc_map_a800_table[] = { 40static struct rc_map_table rc_map_a800_table[] = {
41 { 0x0201, KEY_PROG1 }, /* SOURCE */ 41 { 0x0201, KEY_MODE }, /* SOURCE */
42 { 0x0200, KEY_POWER }, /* POWER */ 42 { 0x0200, KEY_POWER2 }, /* POWER */
43 { 0x0205, KEY_1 }, /* 1 */ 43 { 0x0205, KEY_1 }, /* 1 */
44 { 0x0206, KEY_2 }, /* 2 */ 44 { 0x0206, KEY_2 }, /* 2 */
45 { 0x0207, KEY_3 }, /* 3 */ 45 { 0x0207, KEY_3 }, /* 3 */
@@ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = {
52 { 0x0212, KEY_LEFT }, /* L / DISPLAY */ 52 { 0x0212, KEY_LEFT }, /* L / DISPLAY */
53 { 0x0211, KEY_0 }, /* 0 */ 53 { 0x0211, KEY_0 }, /* 0 */
54 { 0x0213, KEY_RIGHT }, /* R / CH RTN */ 54 { 0x0213, KEY_RIGHT }, /* R / CH RTN */
55 { 0x0217, KEY_PROG2 }, /* SNAP SHOT */ 55 { 0x0217, KEY_CAMERA }, /* SNAP SHOT */
56 { 0x0210, KEY_PROG3 }, /* 16-CH PREV */ 56 { 0x0210, KEY_LAST }, /* 16-CH PREV */
57 { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */ 57 { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
58 { 0x020c, KEY_ZOOM }, /* FULL SCREEN */ 58 { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
59 { 0x021f, KEY_VOLUMEUP }, /* VOL UP */ 59 { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 8671ca362c81..100ebc37e99e 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -479,6 +479,7 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
479 ret = af9015_set_reg_bit(d, 0xd50b, 0); 479 ret = af9015_set_reg_bit(d, 0xd50b, 0);
480 else 480 else
481 ret = af9015_clear_reg_bit(d, 0xd50b, 0); 481 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
482
482error: 483error:
483 if (ret) 484 if (ret)
484 err("endpoint init failed:%d", ret); 485 err("endpoint init failed:%d", ret);
@@ -611,6 +612,11 @@ static int af9015_init(struct dvb_usb_device *d)
611 int ret; 612 int ret;
612 deb_info("%s:\n", __func__); 613 deb_info("%s:\n", __func__);
613 614
615 /* init RC canary */
616 ret = af9015_write_reg(d, 0x98e9, 0xff);
617 if (ret)
618 goto error;
619
614 ret = af9015_init_endpoint(d); 620 ret = af9015_init_endpoint(d);
615 if (ret) 621 if (ret)
616 goto error; 622 goto error;
@@ -659,9 +665,8 @@ error:
659static int af9015_download_firmware(struct usb_device *udev, 665static int af9015_download_firmware(struct usb_device *udev,
660 const struct firmware *fw) 666 const struct firmware *fw)
661{ 667{
662 int i, len, packets, remainder, ret; 668 int i, len, remaining, ret;
663 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; 669 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
664 u16 addr = 0x5100; /* firmware start address */
665 u16 checksum = 0; 670 u16 checksum = 0;
666 671
667 deb_info("%s:\n", __func__); 672 deb_info("%s:\n", __func__);
@@ -673,24 +678,20 @@ static int af9015_download_firmware(struct usb_device *udev,
673 af9015_config.firmware_size = fw->size; 678 af9015_config.firmware_size = fw->size;
674 af9015_config.firmware_checksum = checksum; 679 af9015_config.firmware_checksum = checksum;
675 680
676 #define FW_PACKET_MAX_DATA 55 681 #define FW_ADDR 0x5100 /* firmware start address */
677 682 #define LEN_MAX 55 /* max packet size */
678 packets = fw->size / FW_PACKET_MAX_DATA; 683 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
679 remainder = fw->size % FW_PACKET_MAX_DATA; 684 len = remaining;
680 len = FW_PACKET_MAX_DATA; 685 if (len > LEN_MAX)
681 for (i = 0; i <= packets; i++) { 686 len = LEN_MAX;
682 if (i == packets) /* set size of the last packet */
683 len = remainder;
684 687
685 req.data_len = len; 688 req.data_len = len;
686 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); 689 req.data = (u8 *) &fw->data[fw->size - remaining];
687 req.addr = addr; 690 req.addr = FW_ADDR + fw->size - remaining;
688 addr += FW_PACKET_MAX_DATA;
689 691
690 ret = af9015_rw_udev(udev, &req); 692 ret = af9015_rw_udev(udev, &req);
691 if (ret) { 693 if (ret) {
692 err("firmware download failed at packet %d with " \ 694 err("firmware download failed:%d", ret);
693 "code %d", i, ret);
694 goto error; 695 goto error;
695 } 696 }
696 } 697 }
@@ -738,6 +739,8 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
738}; 739};
739 740
740static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { 741static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
742 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC,
743 RC_MAP_TERRATEC_SLIM_2 },
741 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, 744 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
742 RC_MAP_TERRATEC_SLIM }, 745 RC_MAP_TERRATEC_SLIM },
743 { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, 746 { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700,
@@ -1016,22 +1019,38 @@ static int af9015_rc_query(struct dvb_usb_device *d)
1016{ 1019{
1017 struct af9015_state *priv = d->priv; 1020 struct af9015_state *priv = d->priv;
1018 int ret; 1021 int ret;
1019 u8 buf[16]; 1022 u8 buf[17];
1020 1023
1021 /* read registers needed to detect remote controller code */ 1024 /* read registers needed to detect remote controller code */
1022 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); 1025 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
1023 if (ret) 1026 if (ret)
1024 goto error; 1027 goto error;
1025 1028
1026 if (buf[14] || buf[15]) { 1029 /* If any of these are non-zero, assume invalid data */
1030 if (buf[1] || buf[2] || buf[3])
1031 return ret;
1032
1033 /* Check for repeat of previous code */
1034 if ((priv->rc_repeat != buf[6] || buf[0]) &&
1035 !memcmp(&buf[12], priv->rc_last, 4)) {
1036 deb_rc("%s: key repeated\n", __func__);
1037 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1038 priv->rc_repeat = buf[6];
1039 return ret;
1040 }
1041
1042 /* Only process key if canary killed */
1043 if (buf[16] != 0xff && buf[0] != 0x01) {
1027 deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, 1044 deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
1028 buf[12], buf[13], buf[14], buf[15]); 1045 buf[12], buf[13], buf[14], buf[15]);
1029 1046
1030 /* clean IR code from mem */ 1047 /* Reset the canary */
1031 ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); 1048 ret = af9015_write_reg(d, 0x98e9, 0xff);
1032 if (ret) 1049 if (ret)
1033 goto error; 1050 goto error;
1034 1051
1052 /* Remember this key */
1053 memcpy(priv->rc_last, &buf[12], 4);
1035 if (buf[14] == (u8) ~buf[15]) { 1054 if (buf[14] == (u8) ~buf[15]) {
1036 if (buf[12] == (u8) ~buf[13]) { 1055 if (buf[12] == (u8) ~buf[13]) {
1037 /* NEC */ 1056 /* NEC */
@@ -1041,15 +1060,17 @@ static int af9015_rc_query(struct dvb_usb_device *d)
1041 priv->rc_keycode = buf[12] << 16 | 1060 priv->rc_keycode = buf[12] << 16 |
1042 buf[13] << 8 | buf[14]; 1061 buf[13] << 8 | buf[14];
1043 } 1062 }
1044 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1045 } else { 1063 } else {
1046 priv->rc_keycode = 0; /* clear just for sure */ 1064 /* 32 bit NEC */
1065 priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
1066 buf[14] << 8 | buf[15];
1047 } 1067 }
1048 } else if (priv->rc_repeat != buf[6] || buf[0]) {
1049 deb_rc("%s: key repeated\n", __func__);
1050 rc_keydown(d->rc_dev, priv->rc_keycode, 0); 1068 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1051 } else { 1069 } else {
1052 deb_rc("%s: no key press\n", __func__); 1070 deb_rc("%s: no key press\n", __func__);
1071 /* Invalidate last keypress */
1072 /* Not really needed, but helps with debug */
1073 priv->rc_last[2] = priv->rc_last[3];
1053 } 1074 }
1054 1075
1055 priv->rc_repeat = buf[6]; 1076 priv->rc_repeat = buf[6];
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index f20cfa6ed690..beb3004f00ba 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -102,6 +102,7 @@ struct af9015_state {
102 struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ 102 struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
103 u8 rc_repeat; 103 u8 rc_repeat;
104 u32 rc_keycode; 104 u32 rc_keycode;
105 u8 rc_last[4];
105}; 106};
106 107
107struct af9015_config { 108struct af9015_config {
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 3537d65c04bc..b2a87f2c2c3e 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -32,6 +32,7 @@ extern int dvb_usb_dib0700_debug;
32 // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) 32 // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
33 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) 33 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
34 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) 34 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
35#define REQUEST_SET_I2C_PARAM 0x10
35#define REQUEST_SET_RC 0x11 36#define REQUEST_SET_RC 0x11
36#define REQUEST_NEW_I2C_READ 0x12 37#define REQUEST_NEW_I2C_READ 0x12
37#define REQUEST_NEW_I2C_WRITE 0x13 38#define REQUEST_NEW_I2C_WRITE 0x13
@@ -61,6 +62,7 @@ extern struct i2c_algorithm dib0700_i2c_algo;
61extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, 62extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
62 struct dvb_usb_device_description **desc, int *cold); 63 struct dvb_usb_device_description **desc, int *cold);
63extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); 64extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
65extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
64 66
65extern int dib0700_device_count; 67extern int dib0700_device_count;
66extern int dvb_usb_dib0700_ir_proto; 68extern int dvb_usb_dib0700_ir_proto;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 98ffb40728e3..b79af68c54ae 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -186,7 +186,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
186 msg[i].len, 186 msg[i].len,
187 USB_CTRL_GET_TIMEOUT); 187 USB_CTRL_GET_TIMEOUT);
188 if (result < 0) { 188 if (result < 0) {
189 err("i2c read error (status = %d)\n", result); 189 deb_info("i2c read error (status = %d)\n", result);
190 break; 190 break;
191 } 191 }
192 192
@@ -215,7 +215,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
215 0, 0, buf, msg[i].len + 4, 215 0, 0, buf, msg[i].len + 4,
216 USB_CTRL_GET_TIMEOUT); 216 USB_CTRL_GET_TIMEOUT);
217 if (result < 0) { 217 if (result < 0) {
218 err("i2c write error (status = %d)\n", result); 218 deb_info("i2c write error (status = %d)\n", result);
219 break; 219 break;
220 } 220 }
221 } 221 }
@@ -328,6 +328,31 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
328 return dib0700_ctrl_wr(d, b, 10); 328 return dib0700_ctrl_wr(d, b, 10);
329} 329}
330 330
331int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
332{
333 u16 divider;
334 u8 b[8];
335
336 if (scl_kHz == 0)
337 return -EINVAL;
338
339 b[0] = REQUEST_SET_I2C_PARAM;
340 divider = (u16) (30000 / scl_kHz);
341 b[2] = (u8) (divider >> 8);
342 b[3] = (u8) (divider & 0xff);
343 divider = (u16) (72000 / scl_kHz);
344 b[4] = (u8) (divider >> 8);
345 b[5] = (u8) (divider & 0xff);
346 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
347 b[6] = (u8) (divider >> 8);
348 b[7] = (u8) (divider & 0xff);
349
350 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
351 (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz);
352 return dib0700_ctrl_wr(d, b, 8);
353}
354
355
331int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) 356int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
332{ 357{
333 switch (clk_MHz) { 358 switch (clk_MHz) {
@@ -459,10 +484,20 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
459 484
460 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); 485 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
461 486
462 if (onoff) 487 st->channel_state &= ~0x3;
463 st->channel_state |= 1 << adap->id; 488 if ((adap->stream.props.endpoint != 2)
464 else 489 && (adap->stream.props.endpoint != 3)) {
465 st->channel_state &= ~(1 << adap->id); 490 deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint);
491 if (onoff)
492 st->channel_state |= 1 << (adap->id);
493 else
494 st->channel_state |= 1 << ~(adap->id);
495 } else {
496 if (onoff)
497 st->channel_state |= 1 << (adap->stream.props.endpoint-2);
498 else
499 st->channel_state |= 1 << (3-adap->stream.props.endpoint);
500 }
466 501
467 b[2] |= st->channel_state; 502 b[2] |= st->channel_state;
468 503
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 193cdb77b76a..97af266d7f1d 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -12,6 +12,7 @@
12#include "dib7000m.h" 12#include "dib7000m.h"
13#include "dib7000p.h" 13#include "dib7000p.h"
14#include "dib8000.h" 14#include "dib8000.h"
15#include "dib9000.h"
15#include "mt2060.h" 16#include "mt2060.h"
16#include "mt2266.h" 17#include "mt2266.h"
17#include "tuner-xc2028.h" 18#include "tuner-xc2028.h"
@@ -29,6 +30,7 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif
29 30
30struct dib0700_adapter_state { 31struct dib0700_adapter_state {
31 int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); 32 int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
33 const struct firmware *frontend_firmware;
32}; 34};
33 35
34/* Hauppauge Nova-T 500 (aka Bristol) 36/* Hauppauge Nova-T 500 (aka Bristol)
@@ -1243,13 +1245,13 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1243static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, 1245static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
1244 u16 pid, int onoff) 1246 u16 pid, int onoff)
1245{ 1247{
1246 return dib8000_pid_filter(adapter->fe, index, pid, onoff); 1248 return dib8000_pid_filter(adapter->fe, index, pid, onoff);
1247} 1249}
1248 1250
1249static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, 1251static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
1250 int onoff) 1252 int onoff)
1251{ 1253{
1252 return dib8000_pid_filter_ctrl(adapter->fe, onoff); 1254 return dib8000_pid_filter_ctrl(adapter->fe, onoff);
1253} 1255}
1254 1256
1255/* STK807x */ 1257/* STK807x */
@@ -1321,11 +1323,11 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1321 1323
1322/* STK8096GP */ 1324/* STK8096GP */
1323struct dibx000_agc_config dib8090_agc_config[2] = { 1325struct dibx000_agc_config dib8090_agc_config[2] = {
1324 { 1326 {
1325 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, 1327 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1326 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, 1328 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1327 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, 1329 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1328 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ 1330 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1329 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) 1331 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1330 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), 1332 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1331 1333
@@ -1362,12 +1364,12 @@ struct dibx000_agc_config dib8090_agc_config[2] = {
1362 51, 1364 51,
1363 1365
1364 0, 1366 0,
1365 }, 1367 },
1366 { 1368 {
1367 BAND_CBAND, 1369 BAND_CBAND,
1368 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, 1370 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1369 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, 1371 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1370 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ 1372 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1371 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) 1373 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1372 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), 1374 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1373 1375
@@ -1404,135 +1406,153 @@ struct dibx000_agc_config dib8090_agc_config[2] = {
1404 51, 1406 51,
1405 1407
1406 0, 1408 0,
1407 } 1409 }
1408}; 1410};
1409 1411
1410static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { 1412static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
1411 54000, 13500, 1413 54000, 13500,
1412 1, 18, 3, 1, 0, 1414 1, 18, 3, 1, 0,
1413 0, 0, 1, 1, 2, 1415 0, 0, 1, 1, 2,
1414 (3 << 14) | (1 << 12) | (599 << 0), 1416 (3 << 14) | (1 << 12) | (599 << 0),
1415 (0 << 25) | 0, 1417 (0 << 25) | 0,
1416 20199727, 1418 20199727,
1417 12000000, 1419 12000000,
1418}; 1420};
1419 1421
1420static int dib8090_get_adc_power(struct dvb_frontend *fe) 1422static int dib8090_get_adc_power(struct dvb_frontend *fe)
1421{ 1423{
1422 return dib8000_get_adc_power(fe, 1); 1424 return dib8000_get_adc_power(fe, 1);
1423} 1425}
1424 1426
1425static struct dib8000_config dib809x_dib8000_config = { 1427static struct dib8000_config dib809x_dib8000_config[2] = {
1426 .output_mpeg2_in_188_bytes = 1, 1428 {
1427 1429 .output_mpeg2_in_188_bytes = 1,
1428 .agc_config_count = 2, 1430
1429 .agc = dib8090_agc_config, 1431 .agc_config_count = 2,
1430 .agc_control = dib0090_dcc_freq, 1432 .agc = dib8090_agc_config,
1431 .pll = &dib8090_pll_config_12mhz, 1433 .agc_control = dib0090_dcc_freq,
1432 .tuner_is_baseband = 1, 1434 .pll = &dib8090_pll_config_12mhz,
1433 1435 .tuner_is_baseband = 1,
1434 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, 1436
1435 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, 1437 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1436 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, 1438 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1437 1439 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1438 .hostbus_diversity = 1, 1440
1439 .div_cfg = 0x31, 1441 .hostbus_diversity = 1,
1440 .output_mode = OUTMODE_MPEG2_FIFO, 1442 .div_cfg = 0x31,
1441 .drives = 0x2d98, 1443 .output_mode = OUTMODE_MPEG2_FIFO,
1442 .diversity_delay = 144, 1444 .drives = 0x2d98,
1443 .refclksel = 3, 1445 .diversity_delay = 48,
1446 .refclksel = 3,
1447 }, {
1448 .output_mpeg2_in_188_bytes = 1,
1449
1450 .agc_config_count = 2,
1451 .agc = dib8090_agc_config,
1452 .agc_control = dib0090_dcc_freq,
1453 .pll = &dib8090_pll_config_12mhz,
1454 .tuner_is_baseband = 1,
1455
1456 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1457 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1458 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1459
1460 .hostbus_diversity = 1,
1461 .div_cfg = 0x31,
1462 .output_mode = OUTMODE_DIVERSITY,
1463 .drives = 0x2d08,
1464 .diversity_delay = 1,
1465 .refclksel = 3,
1466 }
1467};
1468
1469static struct dib0090_wbd_slope dib8090_wbd_table[] = {
1470 /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
1471 { 120, 0, 500, 0, 500, 4 }, /* CBAND */
1472 { 170, 0, 450, 0, 450, 4 }, /* CBAND */
1473 { 380, 48, 373, 28, 259, 6 }, /* VHF */
1474 { 860, 34, 700, 36, 616, 6 }, /* high UHF */
1475 { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */
1444}; 1476};
1445 1477
1446static struct dib0090_config dib809x_dib0090_config = { 1478static struct dib0090_config dib809x_dib0090_config = {
1447 .io.pll_bypass = 1, 1479 .io.pll_bypass = 1,
1448 .io.pll_range = 1, 1480 .io.pll_range = 1,
1449 .io.pll_prediv = 1, 1481 .io.pll_prediv = 1,
1450 .io.pll_loopdiv = 20, 1482 .io.pll_loopdiv = 20,
1451 .io.adc_clock_ratio = 8, 1483 .io.adc_clock_ratio = 8,
1452 .io.pll_int_loop_filt = 0, 1484 .io.pll_int_loop_filt = 0,
1453 .io.clock_khz = 12000, 1485 .io.clock_khz = 12000,
1454 .reset = dib80xx_tuner_reset, 1486 .reset = dib80xx_tuner_reset,
1455 .sleep = dib80xx_tuner_sleep, 1487 .sleep = dib80xx_tuner_sleep,
1456 .clkouttobamse = 1, 1488 .clkouttobamse = 1,
1457 .analog_output = 1, 1489 .analog_output = 1,
1458 .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, 1490 .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
1459 .wbd_vhf_offset = 100, 1491 .use_pwm_agc = 1,
1460 .wbd_cband_offset = 450, 1492 .clkoutdrive = 1,
1461 .use_pwm_agc = 1, 1493 .get_adc_power = dib8090_get_adc_power,
1462 .clkoutdrive = 1, 1494 .freq_offset_khz_uhf = -63,
1463 .get_adc_power = dib8090_get_adc_power,
1464 .freq_offset_khz_uhf = 0,
1465 .freq_offset_khz_vhf = -143, 1495 .freq_offset_khz_vhf = -143,
1496 .wbd = dib8090_wbd_table,
1497 .fref_clock_ratio = 6,
1466}; 1498};
1467 1499
1468static int dib8096_set_param_override(struct dvb_frontend *fe, 1500static int dib8096_set_param_override(struct dvb_frontend *fe,
1469 struct dvb_frontend_parameters *fep) 1501 struct dvb_frontend_parameters *fep)
1470{ 1502{
1471 struct dvb_usb_adapter *adap = fe->dvb->priv; 1503 struct dvb_usb_adapter *adap = fe->dvb->priv;
1472 struct dib0700_adapter_state *state = adap->priv; 1504 struct dib0700_adapter_state *state = adap->priv;
1473 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); 1505 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1474 u16 offset; 1506 u16 target;
1475 int ret = 0; 1507 int ret = 0;
1476 enum frontend_tune_state tune_state = CT_SHUTDOWN; 1508 enum frontend_tune_state tune_state = CT_SHUTDOWN;
1477 u16 ltgain, rf_gain_limit; 1509 u16 ltgain, rf_gain_limit;
1478 1510
1479 ret = state->set_param_save(fe, fep); 1511 ret = state->set_param_save(fe, fep);
1480 if (ret < 0) 1512 if (ret < 0)
1481 return ret; 1513 return ret;
1482 1514
1483 switch (band) { 1515 target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
1484 case BAND_VHF: 1516 dib8000_set_wbd_ref(fe, target);
1485 offset = 100; 1517
1486 break; 1518
1487 case BAND_UHF: 1519 if (band == BAND_CBAND) {
1488 offset = 550; 1520 deb_info("tuning in CBAND - soft-AGC startup\n");
1489 break; 1521 dib0090_set_tune_state(fe, CT_AGC_START);
1490 default: 1522 do {
1491 offset = 0; 1523 ret = dib0090_gain_control(fe);
1492 break; 1524 msleep(ret);
1493 } 1525 tune_state = dib0090_get_tune_state(fe);
1494 offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; 1526 if (tune_state == CT_AGC_STEP_0)
1495 dib8000_set_wbd_ref(fe, offset); 1527 dib8000_set_gpio(fe, 6, 0, 1);
1496 1528 else if (tune_state == CT_AGC_STEP_1) {
1497 1529 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1498 if (band == BAND_CBAND) { 1530 if (rf_gain_limit == 0)
1499 deb_info("tuning in CBAND - soft-AGC startup\n"); 1531 dib8000_set_gpio(fe, 6, 0, 0);
1500 /* TODO specific wbd target for dib0090 - needed for startup ? */ 1532 }
1501 dib0090_set_tune_state(fe, CT_AGC_START); 1533 } while (tune_state < CT_AGC_STOP);
1502 do { 1534 dib0090_pwm_gain_reset(fe);
1503 ret = dib0090_gain_control(fe); 1535 dib8000_pwm_agc_reset(fe);
1504 msleep(ret); 1536 dib8000_set_tune_state(fe, CT_DEMOD_START);
1505 tune_state = dib0090_get_tune_state(fe); 1537 } else {
1506 if (tune_state == CT_AGC_STEP_0) 1538 deb_info("not tuning in CBAND - standard AGC startup\n");
1507 dib8000_set_gpio(fe, 6, 0, 1); 1539 dib0090_pwm_gain_reset(fe);
1508 else if (tune_state == CT_AGC_STEP_1) { 1540 }
1509 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1510 if (rf_gain_limit == 0)
1511 dib8000_set_gpio(fe, 6, 0, 0);
1512 }
1513 } while (tune_state < CT_AGC_STOP);
1514 dib0090_pwm_gain_reset(fe);
1515 dib8000_pwm_agc_reset(fe);
1516 dib8000_set_tune_state(fe, CT_DEMOD_START);
1517 } else {
1518 deb_info("not tuning in CBAND - standard AGC startup\n");
1519 dib0090_pwm_gain_reset(fe);
1520 }
1521 1541
1522 return 0; 1542 return 0;
1523} 1543}
1524 1544
1525static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) 1545static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
1526{ 1546{
1527 struct dib0700_adapter_state *st = adap->priv; 1547 struct dib0700_adapter_state *st = adap->priv;
1528 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); 1548 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1529 1549
1530 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) 1550 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1531 return -ENODEV; 1551 return -ENODEV;
1532 1552
1533 st->set_param_save = adap->fe->ops.tuner_ops.set_params; 1553 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1534 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; 1554 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1535 return 0; 1555 return 0;
1536} 1556}
1537 1557
1538static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) 1558static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
@@ -1554,11 +1574,931 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
1554 1574
1555 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); 1575 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
1556 1576
1557 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config); 1577 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1578
1579 return adap->fe == NULL ? -ENODEV : 0;
1580}
1581
1582static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
1583{
1584 struct dib0700_adapter_state *st = adap->priv;
1585 struct i2c_adapter *tun_i2c;
1586 struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe, 1);
1587
1588 if (fe_slave) {
1589 tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
1590 if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
1591 return -ENODEV;
1592 fe_slave->dvb = adap->fe->dvb;
1593 fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
1594 }
1595 tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1596 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1597 return -ENODEV;
1598
1599 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1600 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1601
1602 return 0;
1603}
1604
1605static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
1606{
1607 struct dvb_frontend *fe_slave;
1608
1609 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1610 msleep(20);
1611 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1612 msleep(1000);
1613 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1614 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1615 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1616
1617 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1618
1619 dib0700_ctrl_clock(adap->dev, 72, 1);
1620
1621 msleep(20);
1622 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1623 msleep(20);
1624 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1625
1626 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80);
1627
1628 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1629 if (adap->fe == NULL)
1630 return -ENODEV;
1631
1632 fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
1633 dib8000_set_slave_frontend(adap->fe, fe_slave);
1634
1635 return fe_slave == NULL ? -ENODEV : 0;
1636}
1637
1638/* STK9090M */
1639static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
1640{
1641 return dib9000_fw_pid_filter(adapter->fe, index, pid, onoff);
1642}
1643
1644static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
1645{
1646 return dib9000_fw_pid_filter_ctrl(adapter->fe, onoff);
1647}
1648
1649static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
1650{
1651 return dib9000_set_gpio(fe, 5, 0, !onoff);
1652}
1653
1654static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
1655{
1656 return dib9000_set_gpio(fe, 0, 0, onoff);
1657}
1658
1659static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
1660{
1661 u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
1662 u8 rb[2];
1663 struct i2c_msg msg[2] = {
1664 {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2},
1665 {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
1666 };
1667 u8 index_data;
1668
1669 dibx000_i2c_set_speed(i2c, 250);
1670
1671 if (i2c_transfer(i2c, msg, 2) != 2)
1672 return -EIO;
1673
1674 switch (rb[0] << 8 | rb[1]) {
1675 case 0:
1676 deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
1677 return -EIO;
1678 case 1:
1679 deb_info("Found DiB0170 rev2");
1680 break;
1681 case 2:
1682 deb_info("Found DiB0190 rev2");
1683 break;
1684 default:
1685 deb_info("DiB01x0 not found");
1686 return -EIO;
1687 }
1688
1689 for (index_data = 0; index_data < len; index_data += 2) {
1690 wb[2] = (data[index_data + 1] >> 8) & 0xff;
1691 wb[3] = (data[index_data + 1]) & 0xff;
1692
1693 if (data[index_data] == 0) {
1694 wb[0] = (data[index_data] >> 8) & 0xff;
1695 wb[1] = (data[index_data]) & 0xff;
1696 msg[0].len = 2;
1697 if (i2c_transfer(i2c, msg, 2) != 2)
1698 return -EIO;
1699 wb[2] |= rb[0];
1700 wb[3] |= rb[1] & ~(3 << 4);
1701 }
1702
1703 wb[0] = (data[index_data] >> 8)&0xff;
1704 wb[1] = (data[index_data])&0xff;
1705 msg[0].len = 4;
1706 if (i2c_transfer(i2c, &msg[0], 1) != 1)
1707 return -EIO;
1708 }
1709 return 0;
1710}
1711
1712static struct dib9000_config stk9090m_config = {
1713 .output_mpeg2_in_188_bytes = 1,
1714 .output_mode = OUTMODE_MPEG2_FIFO,
1715 .vcxo_timer = 279620,
1716 .timing_frequency = 20452225,
1717 .demod_clock_khz = 60000,
1718 .xtal_clock_khz = 30000,
1719 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1720 .subband = {
1721 2,
1722 {
1723 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
1724 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
1725 { 0 },
1726 },
1727 },
1728 .gpio_function = {
1729 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1730 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1731 },
1732};
1733
1734static struct dib9000_config nim9090md_config[2] = {
1735 {
1736 .output_mpeg2_in_188_bytes = 1,
1737 .output_mode = OUTMODE_MPEG2_FIFO,
1738 .vcxo_timer = 279620,
1739 .timing_frequency = 20452225,
1740 .demod_clock_khz = 60000,
1741 .xtal_clock_khz = 30000,
1742 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1743 }, {
1744 .output_mpeg2_in_188_bytes = 1,
1745 .output_mode = OUTMODE_DIVERSITY,
1746 .vcxo_timer = 279620,
1747 .timing_frequency = 20452225,
1748 .demod_clock_khz = 60000,
1749 .xtal_clock_khz = 30000,
1750 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1751 .subband = {
1752 2,
1753 {
1754 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
1755 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
1756 { 0 },
1757 },
1758 },
1759 .gpio_function = {
1760 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1761 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1762 },
1763 }
1764};
1765
1766static struct dib0090_config dib9090_dib0090_config = {
1767 .io.pll_bypass = 0,
1768 .io.pll_range = 1,
1769 .io.pll_prediv = 1,
1770 .io.pll_loopdiv = 8,
1771 .io.adc_clock_ratio = 8,
1772 .io.pll_int_loop_filt = 0,
1773 .io.clock_khz = 30000,
1774 .reset = dib90x0_tuner_reset,
1775 .sleep = dib90x0_tuner_sleep,
1776 .clkouttobamse = 0,
1777 .analog_output = 0,
1778 .use_pwm_agc = 0,
1779 .clkoutdrive = 0,
1780 .freq_offset_khz_uhf = 0,
1781 .freq_offset_khz_vhf = 0,
1782};
1783
1784static struct dib0090_config nim9090md_dib0090_config[2] = {
1785 {
1786 .io.pll_bypass = 0,
1787 .io.pll_range = 1,
1788 .io.pll_prediv = 1,
1789 .io.pll_loopdiv = 8,
1790 .io.adc_clock_ratio = 8,
1791 .io.pll_int_loop_filt = 0,
1792 .io.clock_khz = 30000,
1793 .reset = dib90x0_tuner_reset,
1794 .sleep = dib90x0_tuner_sleep,
1795 .clkouttobamse = 1,
1796 .analog_output = 0,
1797 .use_pwm_agc = 0,
1798 .clkoutdrive = 0,
1799 .freq_offset_khz_uhf = 0,
1800 .freq_offset_khz_vhf = 0,
1801 }, {
1802 .io.pll_bypass = 0,
1803 .io.pll_range = 1,
1804 .io.pll_prediv = 1,
1805 .io.pll_loopdiv = 8,
1806 .io.adc_clock_ratio = 8,
1807 .io.pll_int_loop_filt = 0,
1808 .io.clock_khz = 30000,
1809 .reset = dib90x0_tuner_reset,
1810 .sleep = dib90x0_tuner_sleep,
1811 .clkouttobamse = 0,
1812 .analog_output = 0,
1813 .use_pwm_agc = 0,
1814 .clkoutdrive = 0,
1815 .freq_offset_khz_uhf = 0,
1816 .freq_offset_khz_vhf = 0,
1817 }
1818};
1819
1820
1821static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
1822{
1823 struct dib0700_adapter_state *state = adap->priv;
1824 struct dib0700_state *st = adap->dev->priv;
1825 u32 fw_version;
1826
1827 /* Make use of the new i2c functions from FW 1.20 */
1828 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
1829 if (fw_version >= 0x10200)
1830 st->fw_use_new_i2c_api = 1;
1831 dib0700_set_i2c_speed(adap->dev, 340);
1832
1833 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1834 msleep(20);
1835 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1836 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1837 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1838 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1839
1840 dib0700_ctrl_clock(adap->dev, 72, 1);
1841
1842 msleep(20);
1843 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1844 msleep(20);
1845 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1846
1847 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
1848
1849 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
1850 deb_info("%s: Upload failed. (file not found?)\n", __func__);
1851 return -ENODEV;
1852 } else {
1853 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
1854 }
1855 stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
1856 stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
1857
1858 adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
1859
1860 return adap->fe == NULL ? -ENODEV : 0;
1861}
1862
1863static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
1864{
1865 struct dib0700_adapter_state *state = adap->priv;
1866 struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe);
1867 u16 data_dib190[10] = {
1868 1, 0x1374,
1869 2, 0x01a2,
1870 7, 0x0020,
1871 0, 0x00ef,
1872 8, 0x0486,
1873 };
1874
1875 if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &dib9090_dib0090_config) == NULL)
1876 return -ENODEV;
1877 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
1878 if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
1879 return -ENODEV;
1880 dib0700_set_i2c_speed(adap->dev, 2000);
1881 if (dib9000_firmware_post_pll_init(adap->fe) < 0)
1882 return -ENODEV;
1883 release_firmware(state->frontend_firmware);
1884 return 0;
1885}
1886
1887static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
1888{
1889 struct dib0700_adapter_state *state = adap->priv;
1890 struct dib0700_state *st = adap->dev->priv;
1891 struct i2c_adapter *i2c;
1892 struct dvb_frontend *fe_slave;
1893 u32 fw_version;
1894
1895 /* Make use of the new i2c functions from FW 1.20 */
1896 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
1897 if (fw_version >= 0x10200)
1898 st->fw_use_new_i2c_api = 1;
1899 dib0700_set_i2c_speed(adap->dev, 340);
1900
1901 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1902 msleep(20);
1903 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1904 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1905 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1906 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1907
1908 dib0700_ctrl_clock(adap->dev, 72, 1);
1909
1910 msleep(20);
1911 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1912 msleep(20);
1913 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1914
1915 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
1916 deb_info("%s: Upload failed. (file not found?)\n", __func__);
1917 return -EIO;
1918 } else {
1919 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
1920 }
1921 nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
1922 nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
1923 nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
1924 nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
1925
1926 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
1927 adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
1928
1929 if (adap->fe == NULL)
1930 return -ENODEV;
1931
1932 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
1933 dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
1934
1935 fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
1936 dib9000_set_slave_frontend(adap->fe, fe_slave);
1937
1938 return fe_slave == NULL ? -ENODEV : 0;
1939}
1940
1941static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
1942{
1943 struct dib0700_adapter_state *state = adap->priv;
1944 struct i2c_adapter *i2c;
1945 struct dvb_frontend *fe_slave;
1946 u16 data_dib190[10] = {
1947 1, 0x5374,
1948 2, 0x01ae,
1949 7, 0x0020,
1950 0, 0x00ef,
1951 8, 0x0406,
1952 };
1953 i2c = dib9000_get_tuner_interface(adap->fe);
1954 if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
1955 return -ENODEV;
1956 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
1957 if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
1958 return -ENODEV;
1959 dib0700_set_i2c_speed(adap->dev, 2000);
1960 if (dib9000_firmware_post_pll_init(adap->fe) < 0)
1961 return -ENODEV;
1962
1963 fe_slave = dib9000_get_slave_frontend(adap->fe, 1);
1964 if (fe_slave != NULL) {
1965 i2c = dib9000_get_component_bus_interface(adap->fe);
1966 dib9000_set_i2c_adapter(fe_slave, i2c);
1967
1968 i2c = dib9000_get_tuner_interface(fe_slave);
1969 if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
1970 return -ENODEV;
1971 fe_slave->dvb = adap->fe->dvb;
1972 dib9000_fw_set_component_bus_speed(adap->fe, 2000);
1973 if (dib9000_firmware_post_pll_init(fe_slave) < 0)
1974 return -ENODEV;
1975 }
1976 release_firmware(state->frontend_firmware);
1977
1978 return 0;
1979}
1980
1981/* NIM7090 */
1982struct dib7090p_best_adc {
1983 u32 timf;
1984 u32 pll_loopdiv;
1985 u32 pll_prediv;
1986};
1987
1988static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
1989{
1990 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
1991
1992 u16 xtal = 12000;
1993 u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */
1994 u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
1995 u32 fdem_max = 76000;
1996 u32 fdem_min = 69500;
1997 u32 fcp = 0, fs = 0, fdem = 0;
1998 u32 harmonic_id = 0;
1999
2000 adc->pll_loopdiv = loopdiv;
2001 adc->pll_prediv = prediv;
2002 adc->timf = 0;
2003
2004 deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
2005
2006 /* Find Min and Max prediv */
2007 while ((xtal/max_prediv) >= fcp_min)
2008 max_prediv++;
2009
2010 max_prediv--;
2011 min_prediv = max_prediv;
2012 while ((xtal/min_prediv) <= fcp_max) {
2013 min_prediv--;
2014 if (min_prediv == 1)
2015 break;
2016 }
2017 deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
2018
2019 min_prediv = 2;
2020
2021 for (prediv = min_prediv ; prediv < max_prediv; prediv++) {
2022 fcp = xtal / prediv;
2023 if (fcp > fcp_min && fcp < fcp_max) {
2024 for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
2025 fdem = ((xtal/prediv) * loopdiv);
2026 fs = fdem / 4;
2027 /* test min/max system restrictions */
2028
2029 if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
2030 spur = 0;
2031 /* test fs harmonics positions */
2032 for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
2033 if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) {
2034 spur = 1;
2035 break;
2036 }
2037 }
2038
2039 if (!spur) {
2040 adc->pll_loopdiv = loopdiv;
2041 adc->pll_prediv = prediv;
2042 adc->timf = 2396745143UL/fdem*(1 << 9);
2043 adc->timf += ((2396745143UL%fdem) << 9)/fdem;
2044 deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
2045 break;
2046 }
2047 }
2048 }
2049 }
2050 if (!spur)
2051 break;
2052 }
2053
2054
2055 if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
2056 return -EINVAL;
2057 else
2058 return 0;
2059}
2060
2061static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2062{
2063 struct dvb_usb_adapter *adap = fe->dvb->priv;
2064 struct dib0700_adapter_state *state = adap->priv;
2065 struct dibx000_bandwidth_config pll;
2066 u16 target;
2067 struct dib7090p_best_adc adc;
2068 int ret;
2069
2070 ret = state->set_param_save(fe, fep);
2071 if (ret < 0)
2072 return ret;
2073
2074 memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
2075 dib0090_pwm_gain_reset(fe);
2076 target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2;
2077 dib7000p_set_wbd_ref(fe, target);
2078
2079 if (dib7090p_get_best_sampling(fe, &adc) == 0) {
2080 pll.pll_ratio = adc.pll_loopdiv;
2081 pll.pll_prediv = adc.pll_prediv;
2082
2083 dib7000p_update_pll(fe, &pll);
2084 dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
2085 }
2086 return 0;
2087}
2088
2089static struct dib0090_wbd_slope dib7090_wbd_table[] = {
2090 { 380, 81, 850, 64, 540, 4},
2091 { 860, 51, 866, 21, 375, 4},
2092 {1700, 0, 250, 0, 100, 6},
2093 {2600, 0, 250, 0, 100, 6},
2094 { 0xFFFF, 0, 0, 0, 0, 0},
2095};
2096
2097struct dibx000_agc_config dib7090_agc_config[2] = {
2098 {
2099 .band_caps = BAND_UHF,
2100 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2101 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2102 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2103
2104 .inv_gain = 687,
2105 .time_stabiliz = 10,
2106
2107 .alpha_level = 0,
2108 .thlock = 118,
2109
2110 .wbd_inv = 0,
2111 .wbd_ref = 1200,
2112 .wbd_sel = 3,
2113 .wbd_alpha = 5,
2114
2115 .agc1_max = 65535,
2116 .agc1_min = 0,
2117
2118 .agc2_max = 65535,
2119 .agc2_min = 0,
2120
2121 .agc1_pt1 = 0,
2122 .agc1_pt2 = 32,
2123 .agc1_pt3 = 114,
2124 .agc1_slope1 = 143,
2125 .agc1_slope2 = 144,
2126 .agc2_pt1 = 114,
2127 .agc2_pt2 = 227,
2128 .agc2_slope1 = 116,
2129 .agc2_slope2 = 117,
2130
2131 .alpha_mant = 18,
2132 .alpha_exp = 0,
2133 .beta_mant = 20,
2134 .beta_exp = 59,
2135
2136 .perform_agc_softsplit = 0,
2137 } , {
2138 .band_caps = BAND_FM | BAND_VHF | BAND_CBAND,
2139 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2140 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2141 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2142
2143 .inv_gain = 732,
2144 .time_stabiliz = 10,
2145
2146 .alpha_level = 0,
2147 .thlock = 118,
2148
2149 .wbd_inv = 0,
2150 .wbd_ref = 1200,
2151 .wbd_sel = 3,
2152 .wbd_alpha = 5,
2153
2154 .agc1_max = 65535,
2155 .agc1_min = 0,
2156
2157 .agc2_max = 65535,
2158 .agc2_min = 0,
2159
2160 .agc1_pt1 = 0,
2161 .agc1_pt2 = 0,
2162 .agc1_pt3 = 98,
2163 .agc1_slope1 = 0,
2164 .agc1_slope2 = 167,
2165 .agc1_pt1 = 98,
2166 .agc2_pt2 = 255,
2167 .agc2_slope1 = 104,
2168 .agc2_slope2 = 0,
2169
2170 .alpha_mant = 18,
2171 .alpha_exp = 0,
2172 .beta_mant = 20,
2173 .beta_exp = 59,
2174
2175 .perform_agc_softsplit = 0,
2176 }
2177};
2178
2179static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
2180 60000, 15000,
2181 1, 5, 0, 0, 0,
2182 0, 0, 1, 1, 2,
2183 (3 << 14) | (1 << 12) | (524 << 0),
2184 (0 << 25) | 0,
2185 20452225,
2186 15000000,
2187};
2188
2189static struct dib7000p_config nim7090_dib7000p_config = {
2190 .output_mpeg2_in_188_bytes = 1,
2191 .hostbus_diversity = 1,
2192 .tuner_is_baseband = 1,
2193 .update_lna = NULL,
2194
2195 .agc_config_count = 2,
2196 .agc = dib7090_agc_config,
2197
2198 .bw = &dib7090_clock_config_12_mhz,
2199
2200 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2201 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2202 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2203
2204 .pwm_freq_div = 0,
2205
2206 .agc_control = dib7090_agc_restart,
2207
2208 .spur_protect = 0,
2209 .disable_sample_and_hold = 0,
2210 .enable_current_mirror = 0,
2211 .diversity_delay = 0,
2212
2213 .output_mode = OUTMODE_MPEG2_FIFO,
2214 .enMpegOutput = 1,
2215};
2216
2217static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
2218 {
2219 .output_mpeg2_in_188_bytes = 1,
2220 .hostbus_diversity = 1,
2221 .tuner_is_baseband = 1,
2222 .update_lna = NULL,
2223
2224 .agc_config_count = 2,
2225 .agc = dib7090_agc_config,
2226
2227 .bw = &dib7090_clock_config_12_mhz,
2228
2229 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2230 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2231 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2232
2233 .pwm_freq_div = 0,
2234
2235 .agc_control = dib7090_agc_restart,
2236
2237 .spur_protect = 0,
2238 .disable_sample_and_hold = 0,
2239 .enable_current_mirror = 0,
2240 .diversity_delay = 0,
2241
2242 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2243 .default_i2c_addr = 0x90,
2244 .enMpegOutput = 1,
2245 }, {
2246 .output_mpeg2_in_188_bytes = 1,
2247 .hostbus_diversity = 1,
2248 .tuner_is_baseband = 1,
2249 .update_lna = NULL,
2250
2251 .agc_config_count = 2,
2252 .agc = dib7090_agc_config,
2253
2254 .bw = &dib7090_clock_config_12_mhz,
2255
2256 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2257 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2258 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2259
2260 .pwm_freq_div = 0,
2261
2262 .agc_control = dib7090_agc_restart,
2263
2264 .spur_protect = 0,
2265 .disable_sample_and_hold = 0,
2266 .enable_current_mirror = 0,
2267 .diversity_delay = 0,
2268
2269 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2270 .default_i2c_addr = 0x92,
2271 .enMpegOutput = 0,
2272 }
2273};
2274
2275static const struct dib0090_config nim7090_dib0090_config = {
2276 .io.clock_khz = 12000,
2277 .io.pll_bypass = 0,
2278 .io.pll_range = 0,
2279 .io.pll_prediv = 3,
2280 .io.pll_loopdiv = 6,
2281 .io.adc_clock_ratio = 0,
2282 .io.pll_int_loop_filt = 0,
2283 .reset = dib7090_tuner_sleep,
2284 .sleep = dib7090_tuner_sleep,
2285
2286 .freq_offset_khz_uhf = 0,
2287 .freq_offset_khz_vhf = 0,
2288
2289 .get_adc_power = dib7090_get_adc_power,
2290
2291 .clkouttobamse = 1,
2292 .analog_output = 0,
2293
2294 .wbd_vhf_offset = 0,
2295 .wbd_cband_offset = 0,
2296 .use_pwm_agc = 1,
2297 .clkoutdrive = 0,
2298
2299 .fref_clock_ratio = 0,
2300
2301 .wbd = dib7090_wbd_table,
2302
2303 .ls_cfg_pad_drv = 0,
2304 .data_tx_drv = 0,
2305 .low_if = NULL,
2306 .in_soc = 1,
2307};
2308
2309static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
2310 {
2311 .io.clock_khz = 12000,
2312 .io.pll_bypass = 0,
2313 .io.pll_range = 0,
2314 .io.pll_prediv = 3,
2315 .io.pll_loopdiv = 6,
2316 .io.adc_clock_ratio = 0,
2317 .io.pll_int_loop_filt = 0,
2318 .reset = dib7090_tuner_sleep,
2319 .sleep = dib7090_tuner_sleep,
2320
2321 .freq_offset_khz_uhf = 50,
2322 .freq_offset_khz_vhf = 70,
2323
2324 .get_adc_power = dib7090_get_adc_power,
2325
2326 .clkouttobamse = 1,
2327 .analog_output = 0,
2328
2329 .wbd_vhf_offset = 0,
2330 .wbd_cband_offset = 0,
2331 .use_pwm_agc = 1,
2332 .clkoutdrive = 0,
2333
2334 .fref_clock_ratio = 0,
2335
2336 .wbd = dib7090_wbd_table,
2337
2338 .ls_cfg_pad_drv = 0,
2339 .data_tx_drv = 0,
2340 .low_if = NULL,
2341 .in_soc = 1,
2342 }, {
2343 .io.clock_khz = 12000,
2344 .io.pll_bypass = 0,
2345 .io.pll_range = 0,
2346 .io.pll_prediv = 3,
2347 .io.pll_loopdiv = 6,
2348 .io.adc_clock_ratio = 0,
2349 .io.pll_int_loop_filt = 0,
2350 .reset = dib7090_tuner_sleep,
2351 .sleep = dib7090_tuner_sleep,
2352
2353 .freq_offset_khz_uhf = -50,
2354 .freq_offset_khz_vhf = -70,
2355
2356 .get_adc_power = dib7090_get_adc_power,
2357
2358 .clkouttobamse = 1,
2359 .analog_output = 0,
2360
2361 .wbd_vhf_offset = 0,
2362 .wbd_cband_offset = 0,
2363 .use_pwm_agc = 1,
2364 .clkoutdrive = 0,
2365
2366 .fref_clock_ratio = 0,
2367
2368 .wbd = dib7090_wbd_table,
2369
2370 .ls_cfg_pad_drv = 0,
2371 .data_tx_drv = 0,
2372 .low_if = NULL,
2373 .in_soc = 1,
2374 }
2375};
2376
2377static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
2378{
2379 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2380 msleep(20);
2381 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2382 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2383 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2384 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2385
2386 msleep(20);
2387 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2388 msleep(20);
2389 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2390
2391 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
2392 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2393 return -ENODEV;
2394 }
2395 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
1558 2396
1559 return adap->fe == NULL ? -ENODEV : 0; 2397 return adap->fe == NULL ? -ENODEV : 0;
1560} 2398}
1561 2399
2400static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
2401{
2402 struct dib0700_adapter_state *st = adap->priv;
2403 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2404
2405 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &nim7090_dib0090_config) == NULL)
2406 return -ENODEV;
2407
2408 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2409
2410 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2411 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2412 return 0;
2413}
2414
2415static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
2416{
2417 struct dib0700_state *st = adap->dev->priv;
2418
2419 /* The TFE7090 requires the dib0700 to not be in master mode */
2420 st->disable_streaming_master_mode = 1;
2421
2422 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2423 msleep(20);
2424 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2425 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2426 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2427 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2428
2429 msleep(20);
2430 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2431 msleep(20);
2432 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2433
2434 /* initialize IC 0 */
2435 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
2436 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2437 return -ENODEV;
2438 }
2439
2440 dib0700_set_i2c_speed(adap->dev, 340);
2441 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
2442
2443 dib7090_slave_reset(adap->fe);
2444
2445 if (adap->fe == NULL)
2446 return -ENODEV;
2447
2448 return 0;
2449}
2450
2451static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
2452{
2453 struct i2c_adapter *i2c;
2454
2455 if (adap->dev->adapter[0].fe == NULL) {
2456 err("the master dib7090 has to be initialized first");
2457 return -ENODEV; /* the master device has not been initialized */
2458 }
2459
2460 i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
2461 if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
2462 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2463 return -ENODEV;
2464 }
2465
2466 adap->fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
2467 dib0700_set_i2c_speed(adap->dev, 200);
2468
2469 return adap->fe == NULL ? -ENODEV : 0;
2470}
2471
2472static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
2473{
2474 struct dib0700_adapter_state *st = adap->priv;
2475 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2476
2477 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
2478 return -ENODEV;
2479
2480 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2481
2482 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2483 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2484 return 0;
2485}
2486
2487static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
2488{
2489 struct dib0700_adapter_state *st = adap->priv;
2490 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2491
2492 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
2493 return -ENODEV;
2494
2495 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2496
2497 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2498 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2499 return 0;
2500}
2501
1562/* STK7070PD */ 2502/* STK7070PD */
1563static struct dib7000p_config stk7070pd_dib7000p_config[2] = { 2503static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1564 { 2504 {
@@ -1856,6 +2796,12 @@ struct usb_device_id dib0700_usb_id_table[] = {
1856 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, 2796 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
1857 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, 2797 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
1858 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) }, 2798 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) },
2799 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) },
2800/* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) },
2801 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) },
2802 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
2803 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
2804 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
1859 { 0 } /* Terminating entry */ 2805 { 0 } /* Terminating entry */
1860}; 2806};
1861MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 2807MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -2465,7 +3411,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2465 }, 3411 },
2466 }, 3412 },
2467 3413
2468 .num_device_descs = 2, 3414 .num_device_descs = 3,
2469 .devices = { 3415 .devices = {
2470 { "DiBcom STK7770P reference design", 3416 { "DiBcom STK7770P reference design",
2471 { &dib0700_usb_id_table[59], NULL }, 3417 { &dib0700_usb_id_table[59], NULL },
@@ -2477,6 +3423,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2477 &dib0700_usb_id_table[60], NULL}, 3423 &dib0700_usb_id_table[60], NULL},
2478 { NULL }, 3424 { NULL },
2479 }, 3425 },
3426 { "TechniSat AirStar TeleStick 2",
3427 { &dib0700_usb_id_table[74], NULL },
3428 { NULL },
3429 },
2480 }, 3430 },
2481 3431
2482 .rc.core = { 3432 .rc.core = {
@@ -2619,6 +3569,205 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2619 RC_TYPE_NEC, 3569 RC_TYPE_NEC,
2620 .change_protocol = dib0700_change_protocol, 3570 .change_protocol = dib0700_change_protocol,
2621 }, 3571 },
3572 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3573 .num_adapters = 1,
3574 .adapter = {
3575 {
3576 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3577 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3578 .pid_filter_count = 32,
3579 .pid_filter = dib90x0_pid_filter,
3580 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
3581 .frontend_attach = stk9090m_frontend_attach,
3582 .tuner_attach = dib9090_tuner_attach,
3583
3584 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3585
3586 .size_of_priv =
3587 sizeof(struct dib0700_adapter_state),
3588 },
3589 },
3590
3591 .num_device_descs = 1,
3592 .devices = {
3593 { "DiBcom STK9090M reference design",
3594 { &dib0700_usb_id_table[69], NULL },
3595 { NULL },
3596 },
3597 },
3598
3599 .rc.core = {
3600 .rc_interval = DEFAULT_RC_INTERVAL,
3601 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3602 .module_name = "dib0700",
3603 .rc_query = dib0700_rc_query_old_firmware,
3604 .allowed_protos = RC_TYPE_RC5 |
3605 RC_TYPE_RC6 |
3606 RC_TYPE_NEC,
3607 .change_protocol = dib0700_change_protocol,
3608 },
3609 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3610 .num_adapters = 1,
3611 .adapter = {
3612 {
3613 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3614 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3615 .pid_filter_count = 32,
3616 .pid_filter = stk80xx_pid_filter,
3617 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
3618 .frontend_attach = nim8096md_frontend_attach,
3619 .tuner_attach = nim8096md_tuner_attach,
3620
3621 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3622
3623 .size_of_priv =
3624 sizeof(struct dib0700_adapter_state),
3625 },
3626 },
3627
3628 .num_device_descs = 1,
3629 .devices = {
3630 { "DiBcom NIM8096MD reference design",
3631 { &dib0700_usb_id_table[70], NULL },
3632 { NULL },
3633 },
3634 },
3635
3636 .rc.core = {
3637 .rc_interval = DEFAULT_RC_INTERVAL,
3638 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3639 .module_name = "dib0700",
3640 .rc_query = dib0700_rc_query_old_firmware,
3641 .allowed_protos = RC_TYPE_RC5 |
3642 RC_TYPE_RC6 |
3643 RC_TYPE_NEC,
3644 .change_protocol = dib0700_change_protocol,
3645 },
3646 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3647 .num_adapters = 1,
3648 .adapter = {
3649 {
3650 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3651 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3652 .pid_filter_count = 32,
3653 .pid_filter = dib90x0_pid_filter,
3654 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
3655 .frontend_attach = nim9090md_frontend_attach,
3656 .tuner_attach = nim9090md_tuner_attach,
3657
3658 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3659
3660 .size_of_priv =
3661 sizeof(struct dib0700_adapter_state),
3662 },
3663 },
3664
3665 .num_device_descs = 1,
3666 .devices = {
3667 { "DiBcom NIM9090MD reference design",
3668 { &dib0700_usb_id_table[71], NULL },
3669 { NULL },
3670 },
3671 },
3672
3673 .rc.core = {
3674 .rc_interval = DEFAULT_RC_INTERVAL,
3675 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3676 .module_name = "dib0700",
3677 .rc_query = dib0700_rc_query_old_firmware,
3678 .allowed_protos = RC_TYPE_RC5 |
3679 RC_TYPE_RC6 |
3680 RC_TYPE_NEC,
3681 .change_protocol = dib0700_change_protocol,
3682 },
3683 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3684 .num_adapters = 1,
3685 .adapter = {
3686 {
3687 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3688 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3689 .pid_filter_count = 32,
3690 .pid_filter = stk70x0p_pid_filter,
3691 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3692 .frontend_attach = nim7090_frontend_attach,
3693 .tuner_attach = nim7090_tuner_attach,
3694
3695 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3696
3697 .size_of_priv =
3698 sizeof(struct dib0700_adapter_state),
3699 },
3700 },
3701
3702 .num_device_descs = 1,
3703 .devices = {
3704 { "DiBcom NIM7090 reference design",
3705 { &dib0700_usb_id_table[72], NULL },
3706 { NULL },
3707 },
3708 },
3709
3710 .rc.core = {
3711 .rc_interval = DEFAULT_RC_INTERVAL,
3712 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3713 .module_name = "dib0700",
3714 .rc_query = dib0700_rc_query_old_firmware,
3715 .allowed_protos = RC_TYPE_RC5 |
3716 RC_TYPE_RC6 |
3717 RC_TYPE_NEC,
3718 .change_protocol = dib0700_change_protocol,
3719 },
3720 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3721 .num_adapters = 2,
3722 .adapter = {
3723 {
3724 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3725 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3726 .pid_filter_count = 32,
3727 .pid_filter = stk70x0p_pid_filter,
3728 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3729 .frontend_attach = tfe7090pvr_frontend0_attach,
3730 .tuner_attach = tfe7090pvr_tuner0_attach,
3731
3732 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3733
3734 .size_of_priv =
3735 sizeof(struct dib0700_adapter_state),
3736 },
3737 {
3738 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3739 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3740 .pid_filter_count = 32,
3741 .pid_filter = stk70x0p_pid_filter,
3742 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3743 .frontend_attach = tfe7090pvr_frontend1_attach,
3744 .tuner_attach = tfe7090pvr_tuner1_attach,
3745
3746 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3747
3748 .size_of_priv =
3749 sizeof(struct dib0700_adapter_state),
3750 },
3751 },
3752
3753 .num_device_descs = 1,
3754 .devices = {
3755 { "DiBcom TFE7090PVR reference design",
3756 { &dib0700_usb_id_table[73], NULL },
3757 { NULL },
3758 },
3759 },
3760
3761 .rc.core = {
3762 .rc_interval = DEFAULT_RC_INTERVAL,
3763 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3764 .module_name = "dib0700",
3765 .rc_query = dib0700_rc_query_old_firmware,
3766 .allowed_protos = RC_TYPE_RC5 |
3767 RC_TYPE_RC6 |
3768 RC_TYPE_NEC,
3769 .change_protocol = dib0700_change_protocol,
3770 },
2622 }, 3771 },
2623}; 3772};
2624 3773
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index f2dbce7edb3b..f6344cdd360f 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = {
176 { 0xaf59, KEY_AUX }, 176 { 0xaf59, KEY_AUX },
177 { 0x5f5a, KEY_DVD }, 177 { 0x5f5a, KEY_DVD },
178 { 0x6f5a, KEY_POWER }, 178 { 0x6f5a, KEY_POWER },
179 { 0x9f5a, KEY_MHP }, /* labelled 'Picture' */ 179 { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */
180 { 0xaf5a, KEY_AUDIO }, 180 { 0xaf5a, KEY_AUDIO },
181 { 0x5f65, KEY_INFO }, 181 { 0x5f65, KEY_INFO },
182 { 0x6f65, KEY_F13 }, /* 16:9 */ 182 { 0x6f65, KEY_F13 }, /* 16:9 */
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 1a6310b61923..3a8b7446b7b0 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -106,8 +106,13 @@
106#define USB_PID_DIBCOM_STK807XP 0x1f90 106#define USB_PID_DIBCOM_STK807XP 0x1f90
107#define USB_PID_DIBCOM_STK807XPVR 0x1f98 107#define USB_PID_DIBCOM_STK807XPVR 0x1f98
108#define USB_PID_DIBCOM_STK8096GP 0x1fa0 108#define USB_PID_DIBCOM_STK8096GP 0x1fa0
109#define USB_PID_DIBCOM_NIM8096MD 0x1fa8
109#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 110#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
110#define USB_PID_DIBCOM_STK7770P 0x1e80 111#define USB_PID_DIBCOM_STK7770P 0x1e80
112#define USB_PID_DIBCOM_NIM7090 0x1bb2
113#define USB_PID_DIBCOM_TFE7090PVR 0x1bb4
114#define USB_PID_DIBCOM_NIM9090M 0x2383
115#define USB_PID_DIBCOM_NIM9090MD 0x2384
111#define USB_PID_DPOSH_M9206_COLD 0x9206 116#define USB_PID_DPOSH_M9206_COLD 0x9206
112#define USB_PID_DPOSH_M9206_WARM 0xa090 117#define USB_PID_DPOSH_M9206_WARM 0xa090
113#define USB_PID_E3C_EC168 0x1689 118#define USB_PID_E3C_EC168 0x1689
@@ -312,4 +317,6 @@
312#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac 317#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac
313#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001 318#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001
314#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002 319#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
320#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004
321#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
315#endif 322#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index b2b9415d874d..41bacff24960 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -273,7 +273,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
273 dev->map_name = d->props.rc.core.rc_codes; 273 dev->map_name = d->props.rc.core.rc_codes;
274 dev->change_protocol = d->props.rc.core.change_protocol; 274 dev->change_protocol = d->props.rc.core.change_protocol;
275 dev->allowed_protos = d->props.rc.core.allowed_protos; 275 dev->allowed_protos = d->props.rc.core.allowed_protos;
276 dev->driver_type = RC_DRIVER_SCANCODE; 276 dev->driver_type = d->props.rc.core.driver_type;
277 usb_to_input_id(d->udev, &dev->input_id); 277 usb_to_input_id(d->udev, &dev->input_id);
278 dev->input_name = "IR-receiver inside an USB DVB receiver"; 278 dev->input_name = "IR-receiver inside an USB DVB receiver";
279 dev->input_phys = d->rc_phys; 279 dev->input_phys = d->rc_phys;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 65fa9268e7f7..76a80968482a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -181,6 +181,7 @@ struct dvb_rc_legacy {
181 * @rc_codes: name of rc codes table 181 * @rc_codes: name of rc codes table
182 * @protocol: type of protocol(s) currently used by the driver 182 * @protocol: type of protocol(s) currently used by the driver
183 * @allowed_protos: protocol(s) supported by the driver 183 * @allowed_protos: protocol(s) supported by the driver
184 * @driver_type: Used to point if a device supports raw mode
184 * @change_protocol: callback to change protocol 185 * @change_protocol: callback to change protocol
185 * @rc_query: called to query an event event. 186 * @rc_query: called to query an event event.
186 * @rc_interval: time in ms between two queries. 187 * @rc_interval: time in ms between two queries.
@@ -190,6 +191,7 @@ struct dvb_rc {
190 char *rc_codes; 191 char *rc_codes;
191 u64 protocol; 192 u64 protocol;
192 u64 allowed_protos; 193 u64 allowed_protos;
194 enum rc_driver_type driver_type;
193 int (*change_protocol)(struct rc_dev *dev, u64 rc_type); 195 int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
194 char *module_name; 196 char *module_name;
195 int (*rc_query) (struct dvb_usb_device *d); 197 int (*rc_query) (struct dvb_usb_device *d);
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 2c307ba0d28b..f5b9da18f611 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,15 +1,16 @@
1/* DVB USB framework compliant Linux driver for the 1/* DVB USB framework compliant Linux driver for the
2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, 2 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3* TeVii S600, S630, S650, 3 * TeVii S600, S630, S650, S660, S480,
4* Prof 1100, 7500 Cards 4 * Prof 1100, 7500,
5* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) 5 * Geniatech SU3000 Cards
6* 6 * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by)
7* This program is free software; you can redistribute it and/or modify it 7 *
8* under the terms of the GNU General Public License as published by the 8 * This program is free software; you can redistribute it and/or modify it
9* Free Software Foundation, version 2. 9 * under the terms of the GNU General Public License as published by the
10* 10 * Free Software Foundation, version 2.
11* see Documentation/dvb/README.dvb-usb for more information 11 *
12*/ 12 * see Documentation/dvb/README.dvb-usb for more information
13 */
13#include "dw2102.h" 14#include "dw2102.h"
14#include "si21xx.h" 15#include "si21xx.h"
15#include "stv0299.h" 16#include "stv0299.h"
@@ -55,6 +56,14 @@
55#define USB_PID_TEVII_S660 0xd660 56#define USB_PID_TEVII_S660 0xd660
56#endif 57#endif
57 58
59#ifndef USB_PID_TEVII_S480_1
60#define USB_PID_TEVII_S480_1 0xd481
61#endif
62
63#ifndef USB_PID_TEVII_S480_2
64#define USB_PID_TEVII_S480_2 0xd482
65#endif
66
58#ifndef USB_PID_PROF_1100 67#ifndef USB_PID_PROF_1100
59#define USB_PID_PROF_1100 0xb012 68#define USB_PID_PROF_1100 0xb012
60#endif 69#endif
@@ -67,7 +76,9 @@
67#define REG_21_SYMBOLRATE_BYTE2 0x21 76#define REG_21_SYMBOLRATE_BYTE2 0x21
68/* on my own*/ 77/* on my own*/
69#define DW2102_VOLTAGE_CTRL (0x1800) 78#define DW2102_VOLTAGE_CTRL (0x1800)
79#define SU3000_STREAM_CTRL (0x1900)
70#define DW2102_RC_QUERY (0x1a00) 80#define DW2102_RC_QUERY (0x1a00)
81#define DW2102_LED_CTRL (0x1b00)
71 82
72#define err_str "did not find the firmware file. (%s) " \ 83#define err_str "did not find the firmware file. (%s) " \
73 "Please see linux/Documentation/dvb/ for more details " \ 84 "Please see linux/Documentation/dvb/ for more details " \
@@ -78,6 +89,14 @@ struct rc_map_dvb_usb_table_table {
78 int rc_keys_size; 89 int rc_keys_size;
79}; 90};
80 91
92struct su3000_state {
93 u8 initialized;
94};
95
96struct s6x0_state {
97 int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
98};
99
81/* debug */ 100/* debug */
82static int dvb_usb_dw2102_debug; 101static int dvb_usb_dw2102_debug;
83module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); 102module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
@@ -87,7 +106,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
87/* keymaps */ 106/* keymaps */
88static int ir_keymap; 107static int ir_keymap;
89module_param_named(keymap, ir_keymap, int, 0644); 108module_param_named(keymap, ir_keymap, int, 0644);
90MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); 109MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."
110 " 256=none");
91 111
92/* demod probe */ 112/* demod probe */
93static int demod_probe = 1; 113static int demod_probe = 1;
@@ -136,8 +156,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
136 /* read stv0299 register */ 156 /* read stv0299 register */
137 value = msg[0].buf[0];/* register */ 157 value = msg[0].buf[0];/* register */
138 for (i = 0; i < msg[1].len; i++) { 158 for (i = 0; i < msg[1].len; i++) {
139 value = value + i; 159 ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0,
140 ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
141 buf6, 2, DW210X_READ_MSG); 160 buf6, 2, DW210X_READ_MSG);
142 msg[1].buf[i] = buf6[0]; 161 msg[1].buf[i] = buf6[0];
143 } 162 }
@@ -483,10 +502,10 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
483 for (j = 0; j < num; j++) { 502 for (j = 0; j < num; j++) {
484 switch (msg[j].addr) { 503 switch (msg[j].addr) {
485 case (DW2102_RC_QUERY): { 504 case (DW2102_RC_QUERY): {
486 u8 ibuf[4]; 505 u8 ibuf[5];
487 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 506 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
488 ibuf, 4, DW210X_READ_MSG); 507 ibuf, 5, DW210X_READ_MSG);
489 memcpy(msg[j].buf, ibuf + 1, 2); 508 memcpy(msg[j].buf, ibuf + 3, 2);
490 break; 509 break;
491 } 510 }
492 case (DW2102_VOLTAGE_CTRL): { 511 case (DW2102_VOLTAGE_CTRL): {
@@ -502,6 +521,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
502 obuf, 2, DW210X_WRITE_MSG); 521 obuf, 2, DW210X_WRITE_MSG);
503 break; 522 break;
504 } 523 }
524 case (DW2102_LED_CTRL): {
525 u8 obuf[2];
526
527 obuf[0] = 5;
528 obuf[1] = msg[j].buf[0];
529 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
530 obuf, 2, DW210X_WRITE_MSG);
531 break;
532 }
505 /*case 0x55: cx24116 533 /*case 0x55: cx24116
506 case 0x6a: stv0903 534 case 0x6a: stv0903
507 case 0x68: ds3000, stv0903 535 case 0x68: ds3000, stv0903
@@ -535,14 +563,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
535 i += 16; 563 i += 16;
536 len -= 16; 564 len -= 16;
537 } while (len > 0); 565 } while (len > 0);
538 } else if ((udev->descriptor.idProduct == 0x7500) 566 } else if (j < (num - 1)) {
539 && (j < (num - 1))) {
540 /* write register addr before read */ 567 /* write register addr before read */
541 u8 obuf[msg[j].len + 2]; 568 u8 obuf[msg[j].len + 2];
542 obuf[0] = msg[j + 1].len; 569 obuf[0] = msg[j + 1].len;
543 obuf[1] = (msg[j].addr << 1); 570 obuf[1] = (msg[j].addr << 1);
544 memcpy(obuf + 2, msg[j].buf, msg[j].len); 571 memcpy(obuf + 2, msg[j].buf, msg[j].len);
545 ret = dw210x_op_rw(d->udev, 0x92, 0, 0, 572 ret = dw210x_op_rw(d->udev,
573 udev->descriptor.idProduct ==
574 0x7500 ? 0x92 : 0x90, 0, 0,
546 obuf, msg[j].len + 2, 575 obuf, msg[j].len + 2,
547 DW210X_WRITE_MSG); 576 DW210X_WRITE_MSG);
548 break; 577 break;
@@ -552,8 +581,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
552 obuf[0] = msg[j].len + 1; 581 obuf[0] = msg[j].len + 1;
553 obuf[1] = (msg[j].addr << 1); 582 obuf[1] = (msg[j].addr << 1);
554 memcpy(obuf + 2, msg[j].buf, msg[j].len); 583 memcpy(obuf + 2, msg[j].buf, msg[j].len);
555 ret = dw210x_op_rw(d->udev, 584 ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
556 (num > 1 ? 0x90 : 0x80), 0, 0,
557 obuf, msg[j].len + 2, 585 obuf, msg[j].len + 2,
558 DW210X_WRITE_MSG); 586 DW210X_WRITE_MSG);
559 break; 587 break;
@@ -561,14 +589,76 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
561 break; 589 break;
562 } 590 }
563 } 591 }
564
565 msleep(3);
566 } 592 }
567 593
568 mutex_unlock(&d->i2c_mutex); 594 mutex_unlock(&d->i2c_mutex);
569 return num; 595 return num;
570} 596}
571 597
598static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
599 int num)
600{
601 struct dvb_usb_device *d = i2c_get_adapdata(adap);
602 u8 obuf[0x40], ibuf[0x40];
603
604 if (!d)
605 return -ENODEV;
606 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
607 return -EAGAIN;
608
609 switch (num) {
610 case 1:
611 switch (msg[0].addr) {
612 case SU3000_STREAM_CTRL:
613 obuf[0] = msg[0].buf[0] + 0x36;
614 obuf[1] = 3;
615 obuf[2] = 0;
616 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
617 err("i2c transfer failed.");
618 break;
619 case DW2102_RC_QUERY:
620 obuf[0] = 0x10;
621 if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
622 err("i2c transfer failed.");
623 msg[0].buf[1] = ibuf[0];
624 msg[0].buf[0] = ibuf[1];
625 break;
626 default:
627 /* always i2c write*/
628 obuf[0] = 0x08;
629 obuf[1] = msg[0].addr;
630 obuf[2] = msg[0].len;
631
632 memcpy(&obuf[3], msg[0].buf, msg[0].len);
633
634 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
635 ibuf, 1, 0) < 0)
636 err("i2c transfer failed.");
637
638 }
639 break;
640 case 2:
641 /* always i2c read */
642 obuf[0] = 0x09;
643 obuf[1] = msg[0].len;
644 obuf[2] = msg[1].len;
645 obuf[3] = msg[0].addr;
646 memcpy(&obuf[4], msg[0].buf, msg[0].len);
647
648 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
649 ibuf, msg[1].len + 1, 0) < 0)
650 err("i2c transfer failed.");
651
652 memcpy(msg[1].buf, &ibuf[1], msg[1].len);
653 break;
654 default:
655 warn("more than 2 i2c messages at a time is not handled yet.");
656 break;
657 }
658 mutex_unlock(&d->i2c_mutex);
659 return num;
660}
661
572static u32 dw210x_i2c_func(struct i2c_adapter *adapter) 662static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
573{ 663{
574 return I2C_FUNC_I2C; 664 return I2C_FUNC_I2C;
@@ -604,6 +694,11 @@ static struct i2c_algorithm s6x0_i2c_algo = {
604 .functionality = dw210x_i2c_func, 694 .functionality = dw210x_i2c_func,
605}; 695};
606 696
697static struct i2c_algorithm su3000_i2c_algo = {
698 .master_xfer = su3000_i2c_transfer,
699 .functionality = dw210x_i2c_func,
700};
701
607static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 702static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
608{ 703{
609 int i; 704 int i;
@@ -668,6 +763,82 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
668 return 0; 763 return 0;
669}; 764};
670 765
766static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
767{
768 static u8 command_start[] = {0x00};
769 static u8 command_stop[] = {0x01};
770 struct i2c_msg msg = {
771 .addr = SU3000_STREAM_CTRL,
772 .flags = 0,
773 .buf = onoff ? command_start : command_stop,
774 .len = 1
775 };
776
777 i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
778
779 return 0;
780}
781
782static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
783{
784 struct su3000_state *state = (struct su3000_state *)d->priv;
785 u8 obuf[] = {0xde, 0};
786
787 info("%s: %d, initialized %d\n", __func__, i, state->initialized);
788
789 if (i && !state->initialized) {
790 state->initialized = 1;
791 /* reset board */
792 dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
793 }
794
795 return 0;
796}
797
798static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
799{
800 int i;
801 u8 obuf[] = { 0x1f, 0xf0 };
802 u8 ibuf[] = { 0 };
803 struct i2c_msg msg[] = {
804 {
805 .addr = 0x51,
806 .flags = 0,
807 .buf = obuf,
808 .len = 2,
809 }, {
810 .addr = 0x51,
811 .flags = I2C_M_RD,
812 .buf = ibuf,
813 .len = 1,
814
815 }
816 };
817
818 for (i = 0; i < 6; i++) {
819 obuf[1] = 0xf0 + i;
820 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
821 break;
822 else
823 mac[i] = ibuf[0];
824
825 debug_dump(mac, 6, printk);
826 }
827
828 return 0;
829}
830
831static int su3000_identify_state(struct usb_device *udev,
832 struct dvb_usb_device_properties *props,
833 struct dvb_usb_device_description **desc,
834 int *cold)
835{
836 info("%s\n", __func__);
837
838 *cold = 0;
839 return 0;
840}
841
671static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 842static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
672{ 843{
673 static u8 command_13v[] = {0x00, 0x01}; 844 static u8 command_13v[] = {0x00, 0x01};
@@ -692,6 +863,37 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
692 return 0; 863 return 0;
693} 864}
694 865
866static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
867{
868 struct dvb_usb_adapter *d =
869 (struct dvb_usb_adapter *)(fe->dvb->priv);
870 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
871
872 dw210x_set_voltage(fe, voltage);
873 if (st->old_set_voltage)
874 st->old_set_voltage(fe, voltage);
875
876 return 0;
877}
878
879static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
880{
881 static u8 led_off[] = { 0 };
882 static u8 led_on[] = { 1 };
883 struct i2c_msg msg = {
884 .addr = DW2102_LED_CTRL,
885 .flags = 0,
886 .buf = led_off,
887 .len = 1
888 };
889 struct dvb_usb_adapter *udev_adap =
890 (struct dvb_usb_adapter *)(fe->dvb->priv);
891
892 if (offon)
893 msg.buf = led_on;
894 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
895}
896
695static struct stv0299_config sharp_z0194a_config = { 897static struct stv0299_config sharp_z0194a_config = {
696 .demod_address = 0x68, 898 .demod_address = 0x68,
697 .inittab = sharp_z0194a_inittab, 899 .inittab = sharp_z0194a_inittab,
@@ -771,6 +973,12 @@ static struct stv0900_config prof_7500_stv0900_config = {
771 .tun1_adc = 0,/* 2 Vpp */ 973 .tun1_adc = 0,/* 2 Vpp */
772 .path1_mode = 3, 974 .path1_mode = 3,
773 .tun1_type = 3, 975 .tun1_type = 3,
976 .set_lock_led = dw210x_led_ctrl,
977};
978
979static struct ds3000_config su3000_ds3000_config = {
980 .demod_address = 0x68,
981 .ci_mode = 1,
774}; 982};
775 983
776static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 984static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
@@ -885,7 +1093,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
885 return -EIO; 1093 return -EIO;
886} 1094}
887 1095
888static int s6x0_frontend_attach(struct dvb_usb_adapter *d) 1096static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
889{ 1097{
890 d->fe = dvb_attach(mt312_attach, &zl313_config, 1098 d->fe = dvb_attach(mt312_attach, &zl313_config,
891 &d->dev->i2c_adap); 1099 &d->dev->i2c_adap);
@@ -898,41 +1106,108 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
898 } 1106 }
899 } 1107 }
900 1108
1109 return -EIO;
1110}
1111
1112static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
1113{
1114 u8 obuf[] = {7, 1};
1115
901 d->fe = dvb_attach(stv0288_attach, &earda_config, 1116 d->fe = dvb_attach(stv0288_attach, &earda_config,
902 &d->dev->i2c_adap); 1117 &d->dev->i2c_adap);
903 if (d->fe != NULL) { 1118
904 if (dvb_attach(stb6000_attach, d->fe, 0x61, 1119 if (d->fe == NULL)
905 &d->dev->i2c_adap)) { 1120 return -EIO;
906 d->fe->ops.set_voltage = dw210x_set_voltage; 1121
907 info("Attached stv0288+stb6000!\n"); 1122 if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap))
908 return 0; 1123 return -EIO;
909 } 1124
910 } 1125 d->fe->ops.set_voltage = dw210x_set_voltage;
1126
1127 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1128
1129 info("Attached stv0288+stb6000!\n");
1130
1131 return 0;
1132
1133}
1134
1135static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
1136{
1137 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
1138 u8 obuf[] = {7, 1};
911 1139
912 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, 1140 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
913 &d->dev->i2c_adap); 1141 &d->dev->i2c_adap);
914 if (d->fe != NULL) {
915 d->fe->ops.set_voltage = dw210x_set_voltage;
916 info("Attached ds3000+ds2020!\n");
917 return 0;
918 }
919 1142
920 return -EIO; 1143 if (d->fe == NULL)
1144 return -EIO;
1145
1146 st->old_set_voltage = d->fe->ops.set_voltage;
1147 d->fe->ops.set_voltage = s660_set_voltage;
1148
1149 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1150
1151 info("Attached ds3000+ds2020!\n");
1152
1153 return 0;
921} 1154}
922 1155
923static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) 1156static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
924{ 1157{
1158 u8 obuf[] = {7, 1};
1159
925 d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, 1160 d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
926 &d->dev->i2c_adap, 0); 1161 &d->dev->i2c_adap, 0);
927 if (d->fe == NULL) 1162 if (d->fe == NULL)
928 return -EIO; 1163 return -EIO;
1164
929 d->fe->ops.set_voltage = dw210x_set_voltage; 1165 d->fe->ops.set_voltage = dw210x_set_voltage;
930 1166
1167 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1168
931 info("Attached STV0900+STB6100A!\n"); 1169 info("Attached STV0900+STB6100A!\n");
932 1170
933 return 0; 1171 return 0;
934} 1172}
935 1173
1174static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1175{
1176 u8 obuf[3] = { 0xe, 0x80, 0 };
1177 u8 ibuf[] = { 0 };
1178
1179 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1180 err("command 0x0e transfer failed.");
1181
1182 obuf[0] = 0xe;
1183 obuf[1] = 0x83;
1184 obuf[2] = 0;
1185
1186 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1187 err("command 0x0e transfer failed.");
1188
1189 obuf[0] = 0xe;
1190 obuf[1] = 0x83;
1191 obuf[2] = 1;
1192
1193 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1194 err("command 0x0e transfer failed.");
1195
1196 obuf[0] = 0x51;
1197
1198 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1199 err("command 0x51 transfer failed.");
1200
1201 d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
1202 &d->dev->i2c_adap);
1203 if (d->fe == NULL)
1204 return -EIO;
1205
1206 info("Attached DS3000!\n");
1207
1208 return 0;
1209}
1210
936static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 1211static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
937{ 1212{
938 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 1213 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -949,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
949} 1224}
950 1225
951static struct rc_map_table rc_map_dw210x_table[] = { 1226static struct rc_map_table rc_map_dw210x_table[] = {
952 { 0xf80a, KEY_Q }, /*power*/ 1227 { 0xf80a, KEY_POWER2 }, /*power*/
953 { 0xf80c, KEY_M }, /*mute*/ 1228 { 0xf80c, KEY_MUTE }, /*mute*/
954 { 0xf811, KEY_1 }, 1229 { 0xf811, KEY_1 },
955 { 0xf812, KEY_2 }, 1230 { 0xf812, KEY_2 },
956 { 0xf813, KEY_3 }, 1231 { 0xf813, KEY_3 },
@@ -961,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = {
961 { 0xf818, KEY_8 }, 1236 { 0xf818, KEY_8 },
962 { 0xf819, KEY_9 }, 1237 { 0xf819, KEY_9 },
963 { 0xf810, KEY_0 }, 1238 { 0xf810, KEY_0 },
964 { 0xf81c, KEY_PAGEUP }, /*ch+*/ 1239 { 0xf81c, KEY_CHANNELUP }, /*ch+*/
965 { 0xf80f, KEY_PAGEDOWN }, /*ch-*/ 1240 { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/
966 { 0xf81a, KEY_O }, /*vol+*/ 1241 { 0xf81a, KEY_VOLUMEUP }, /*vol+*/
967 { 0xf80e, KEY_Z }, /*vol-*/ 1242 { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/
968 { 0xf804, KEY_R }, /*rec*/ 1243 { 0xf804, KEY_RECORD }, /*rec*/
969 { 0xf809, KEY_D }, /*fav*/ 1244 { 0xf809, KEY_FAVORITES }, /*fav*/
970 { 0xf808, KEY_BACKSPACE }, /*rewind*/ 1245 { 0xf808, KEY_REWIND }, /*rewind*/
971 { 0xf807, KEY_A }, /*fast*/ 1246 { 0xf807, KEY_FASTFORWARD }, /*fast*/
972 { 0xf80b, KEY_P }, /*pause*/ 1247 { 0xf80b, KEY_PAUSE }, /*pause*/
973 { 0xf802, KEY_ESC }, /*cancel*/ 1248 { 0xf802, KEY_ESC }, /*cancel*/
974 { 0xf803, KEY_G }, /*tab*/ 1249 { 0xf803, KEY_TAB }, /*tab*/
975 { 0xf800, KEY_UP }, /*up*/ 1250 { 0xf800, KEY_UP }, /*up*/
976 { 0xf81f, KEY_ENTER }, /*ok*/ 1251 { 0xf81f, KEY_OK }, /*ok*/
977 { 0xf801, KEY_DOWN }, /*down*/ 1252 { 0xf801, KEY_DOWN }, /*down*/
978 { 0xf805, KEY_C }, /*cap*/ 1253 { 0xf805, KEY_CAMERA }, /*cap*/
979 { 0xf806, KEY_S }, /*stop*/ 1254 { 0xf806, KEY_STOP }, /*stop*/
980 { 0xf840, KEY_F }, /*full*/ 1255 { 0xf840, KEY_ZOOM }, /*full*/
981 { 0xf81e, KEY_W }, /*tvmode*/ 1256 { 0xf81e, KEY_TV }, /*tvmode*/
982 { 0xf81b, KEY_B }, /*recall*/ 1257 { 0xf81b, KEY_LAST }, /*recall*/
983}; 1258};
984 1259
985static struct rc_map_table rc_map_tevii_table[] = { 1260static struct rc_map_table rc_map_tevii_table[] = {
@@ -1067,10 +1342,49 @@ static struct rc_map_table rc_map_tbs_table[] = {
1067 { 0xf89b, KEY_MODE } 1342 { 0xf89b, KEY_MODE }
1068}; 1343};
1069 1344
1345static struct rc_map_table rc_map_su3000_table[] = {
1346 { 0x25, KEY_POWER }, /* right-bottom Red */
1347 { 0x0a, KEY_MUTE }, /* -/-- */
1348 { 0x01, KEY_1 },
1349 { 0x02, KEY_2 },
1350 { 0x03, KEY_3 },
1351 { 0x04, KEY_4 },
1352 { 0x05, KEY_5 },
1353 { 0x06, KEY_6 },
1354 { 0x07, KEY_7 },
1355 { 0x08, KEY_8 },
1356 { 0x09, KEY_9 },
1357 { 0x00, KEY_0 },
1358 { 0x20, KEY_UP }, /* CH+ */
1359 { 0x21, KEY_DOWN }, /* CH+ */
1360 { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
1361 { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
1362 { 0x1f, KEY_RECORD },
1363 { 0x17, KEY_PLAY },
1364 { 0x16, KEY_PAUSE },
1365 { 0x0b, KEY_STOP },
1366 { 0x27, KEY_FASTFORWARD },/* >> */
1367 { 0x26, KEY_REWIND }, /* << */
1368 { 0x0d, KEY_OK }, /* Mute */
1369 { 0x11, KEY_LEFT }, /* VOL- */
1370 { 0x10, KEY_RIGHT }, /* VOL+ */
1371 { 0x29, KEY_BACK }, /* button under 9 */
1372 { 0x2c, KEY_MENU }, /* TTX */
1373 { 0x2b, KEY_EPG }, /* EPG */
1374 { 0x1e, KEY_RED }, /* OSD */
1375 { 0x0e, KEY_GREEN }, /* Window */
1376 { 0x2d, KEY_YELLOW }, /* button under << */
1377 { 0x0f, KEY_BLUE }, /* bottom yellow button */
1378 { 0x14, KEY_AUDIO }, /* Snapshot */
1379 { 0x38, KEY_TV }, /* TV/Radio */
1380 { 0x0c, KEY_ESC } /* upper Red buttton */
1381};
1382
1070static struct rc_map_dvb_usb_table_table keys_tables[] = { 1383static struct rc_map_dvb_usb_table_table keys_tables[] = {
1071 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, 1384 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
1072 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, 1385 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
1073 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, 1386 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
1387 { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
1074}; 1388};
1075 1389
1076static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 1390static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -1089,7 +1403,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1089 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { 1403 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
1090 keymap = keys_tables[ir_keymap - 1].rc_keys ; 1404 keymap = keys_tables[ir_keymap - 1].rc_keys ;
1091 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; 1405 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
1092 } 1406 } else if (ir_keymap > ARRAY_SIZE(keys_tables))
1407 return 0; /* none */
1093 1408
1094 *state = REMOTE_NO_KEY_PRESSED; 1409 *state = REMOTE_NO_KEY_PRESSED;
1095 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 1410 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
@@ -1125,6 +1440,11 @@ static struct usb_device_id dw2102_table[] = {
1125 {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, 1440 {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1126 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, 1441 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1127 {USB_DEVICE(0x3034, 0x7500)}, 1442 {USB_DEVICE(0x3034, 0x7500)},
1443 {USB_DEVICE(0x1f4d, 0x3000)},
1444 {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
1445 {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
1446 {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
1447 {USB_DEVICE(0x1f4d, 0x3100)},
1128 { } 1448 { }
1129}; 1449};
1130 1450
@@ -1184,11 +1504,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
1184 } 1504 }
1185 /* init registers */ 1505 /* init registers */
1186 switch (dev->descriptor.idProduct) { 1506 switch (dev->descriptor.idProduct) {
1187 case USB_PID_PROF_1100:
1188 s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table;
1189 s6x0_properties.rc.legacy.rc_map_size =
1190 ARRAY_SIZE(rc_map_tbs_table);
1191 break;
1192 case USB_PID_TEVII_S650: 1507 case USB_PID_TEVII_S650:
1193 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table; 1508 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
1194 dw2104_properties.rc.legacy.rc_map_size = 1509 dw2104_properties.rc.legacy.rc_map_size =
@@ -1271,8 +1586,6 @@ static struct dvb_usb_device_properties dw2102_properties = {
1271 .adapter = { 1586 .adapter = {
1272 { 1587 {
1273 .frontend_attach = dw2102_frontend_attach, 1588 .frontend_attach = dw2102_frontend_attach,
1274 .streaming_ctrl = NULL,
1275 .tuner_attach = NULL,
1276 .stream = { 1589 .stream = {
1277 .type = USB_BULK, 1590 .type = USB_BULK,
1278 .count = 8, 1591 .count = 8,
@@ -1324,8 +1637,6 @@ static struct dvb_usb_device_properties dw2104_properties = {
1324 .adapter = { 1637 .adapter = {
1325 { 1638 {
1326 .frontend_attach = dw2104_frontend_attach, 1639 .frontend_attach = dw2104_frontend_attach,
1327 .streaming_ctrl = NULL,
1328 /*.tuner_attach = dw2104_tuner_attach,*/
1329 .stream = { 1640 .stream = {
1330 .type = USB_BULK, 1641 .type = USB_BULK,
1331 .count = 8, 1642 .count = 8,
@@ -1373,7 +1684,6 @@ static struct dvb_usb_device_properties dw3101_properties = {
1373 .adapter = { 1684 .adapter = {
1374 { 1685 {
1375 .frontend_attach = dw3101_frontend_attach, 1686 .frontend_attach = dw3101_frontend_attach,
1376 .streaming_ctrl = NULL,
1377 .tuner_attach = dw3101_tuner_attach, 1687 .tuner_attach = dw3101_tuner_attach,
1378 .stream = { 1688 .stream = {
1379 .type = USB_BULK, 1689 .type = USB_BULK,
@@ -1399,6 +1709,7 @@ static struct dvb_usb_device_properties dw3101_properties = {
1399static struct dvb_usb_device_properties s6x0_properties = { 1709static struct dvb_usb_device_properties s6x0_properties = {
1400 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1710 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1401 .usb_ctrl = DEVICE_SPECIFIC, 1711 .usb_ctrl = DEVICE_SPECIFIC,
1712 .size_of_priv = sizeof(struct s6x0_state),
1402 .firmware = "dvb-usb-s630.fw", 1713 .firmware = "dvb-usb-s630.fw",
1403 .no_reconnect = 1, 1714 .no_reconnect = 1,
1404 1715
@@ -1416,9 +1727,7 @@ static struct dvb_usb_device_properties s6x0_properties = {
1416 .read_mac_address = s6x0_read_mac_address, 1727 .read_mac_address = s6x0_read_mac_address,
1417 .adapter = { 1728 .adapter = {
1418 { 1729 {
1419 .frontend_attach = s6x0_frontend_attach, 1730 .frontend_attach = zl100313_frontend_attach,
1420 .streaming_ctrl = NULL,
1421 .tuner_attach = NULL,
1422 .stream = { 1731 .stream = {
1423 .type = USB_BULK, 1732 .type = USB_BULK,
1424 .count = 8, 1733 .count = 8,
@@ -1431,23 +1740,41 @@ static struct dvb_usb_device_properties s6x0_properties = {
1431 }, 1740 },
1432 } 1741 }
1433 }, 1742 },
1434 .num_device_descs = 3, 1743 .num_device_descs = 1,
1435 .devices = { 1744 .devices = {
1436 {"TeVii S630 USB", 1745 {"TeVii S630 USB",
1437 {&dw2102_table[6], NULL}, 1746 {&dw2102_table[6], NULL},
1438 {NULL}, 1747 {NULL},
1439 }, 1748 },
1440 {"Prof 1100 USB ",
1441 {&dw2102_table[7], NULL},
1442 {NULL},
1443 },
1444 {"TeVii S660 USB",
1445 {&dw2102_table[8], NULL},
1446 {NULL},
1447 },
1448 } 1749 }
1449}; 1750};
1450 1751
1752struct dvb_usb_device_properties *p1100;
1753static struct dvb_usb_device_description d1100 = {
1754 "Prof 1100 USB ",
1755 {&dw2102_table[7], NULL},
1756 {NULL},
1757};
1758
1759struct dvb_usb_device_properties *s660;
1760static struct dvb_usb_device_description d660 = {
1761 "TeVii S660 USB",
1762 {&dw2102_table[8], NULL},
1763 {NULL},
1764};
1765
1766static struct dvb_usb_device_description d480_1 = {
1767 "TeVii S480.1 USB",
1768 {&dw2102_table[12], NULL},
1769 {NULL},
1770};
1771
1772static struct dvb_usb_device_description d480_2 = {
1773 "TeVii S480.2 USB",
1774 {&dw2102_table[13], NULL},
1775 {NULL},
1776};
1777
1451struct dvb_usb_device_properties *p7500; 1778struct dvb_usb_device_properties *p7500;
1452static struct dvb_usb_device_description d7500 = { 1779static struct dvb_usb_device_description d7500 = {
1453 "Prof 7500 USB DVB-S2", 1780 "Prof 7500 USB DVB-S2",
@@ -1455,17 +1782,97 @@ static struct dvb_usb_device_description d7500 = {
1455 {NULL}, 1782 {NULL},
1456}; 1783};
1457 1784
1785static struct dvb_usb_device_properties su3000_properties = {
1786 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1787 .usb_ctrl = DEVICE_SPECIFIC,
1788 .size_of_priv = sizeof(struct su3000_state),
1789 .power_ctrl = su3000_power_ctrl,
1790 .num_adapters = 1,
1791 .identify_state = su3000_identify_state,
1792 .i2c_algo = &su3000_i2c_algo,
1793
1794 .rc.legacy = {
1795 .rc_map_table = rc_map_su3000_table,
1796 .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
1797 .rc_interval = 150,
1798 .rc_query = dw2102_rc_query,
1799 },
1800
1801 .read_mac_address = su3000_read_mac_address,
1802
1803 .generic_bulk_ctrl_endpoint = 0x01,
1804
1805 .adapter = {
1806 {
1807 .streaming_ctrl = su3000_streaming_ctrl,
1808 .frontend_attach = su3000_frontend_attach,
1809 .stream = {
1810 .type = USB_BULK,
1811 .count = 8,
1812 .endpoint = 0x82,
1813 .u = {
1814 .bulk = {
1815 .buffersize = 4096,
1816 }
1817 }
1818 }
1819 }
1820 },
1821 .num_device_descs = 3,
1822 .devices = {
1823 { "SU3000HD DVB-S USB2.0",
1824 { &dw2102_table[10], NULL },
1825 { NULL },
1826 },
1827 { "Terratec Cinergy S2 USB HD",
1828 { &dw2102_table[11], NULL },
1829 { NULL },
1830 },
1831 { "X3M TV SPC1400HD PCI",
1832 { &dw2102_table[14], NULL },
1833 { NULL },
1834 },
1835 }
1836};
1837
1458static int dw2102_probe(struct usb_interface *intf, 1838static int dw2102_probe(struct usb_interface *intf,
1459 const struct usb_device_id *id) 1839 const struct usb_device_id *id)
1460{ 1840{
1841 p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1842 if (!p1100)
1843 return -ENOMEM;
1844 /* copy default structure */
1845 memcpy(p1100, &s6x0_properties,
1846 sizeof(struct dvb_usb_device_properties));
1847 /* fill only different fields */
1848 p1100->firmware = "dvb-usb-p1100.fw";
1849 p1100->devices[0] = d1100;
1850 p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
1851 p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1852 p1100->adapter->frontend_attach = stv0288_frontend_attach;
1853
1854 s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1855 if (!s660) {
1856 kfree(p1100);
1857 return -ENOMEM;
1858 }
1859 memcpy(s660, &s6x0_properties,
1860 sizeof(struct dvb_usb_device_properties));
1861 s660->firmware = "dvb-usb-s660.fw";
1862 s660->num_device_descs = 3;
1863 s660->devices[0] = d660;
1864 s660->devices[1] = d480_1;
1865 s660->devices[2] = d480_2;
1866 s660->adapter->frontend_attach = ds3000_frontend_attach;
1461 1867
1462 p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); 1868 p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1463 if (!p7500) 1869 if (!p7500) {
1870 kfree(p1100);
1871 kfree(s660);
1464 return -ENOMEM; 1872 return -ENOMEM;
1465 /* copy default structure */ 1873 }
1466 memcpy(p7500, &s6x0_properties, 1874 memcpy(p7500, &s6x0_properties,
1467 sizeof(struct dvb_usb_device_properties)); 1875 sizeof(struct dvb_usb_device_properties));
1468 /* fill only different fields */
1469 p7500->firmware = "dvb-usb-p7500.fw"; 1876 p7500->firmware = "dvb-usb-p7500.fw";
1470 p7500->devices[0] = d7500; 1877 p7500->devices[0] = d7500;
1471 p7500->rc.legacy.rc_map_table = rc_map_tbs_table; 1878 p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
@@ -1480,8 +1887,14 @@ static int dw2102_probe(struct usb_interface *intf,
1480 THIS_MODULE, NULL, adapter_nr) || 1887 THIS_MODULE, NULL, adapter_nr) ||
1481 0 == dvb_usb_device_init(intf, &s6x0_properties, 1888 0 == dvb_usb_device_init(intf, &s6x0_properties,
1482 THIS_MODULE, NULL, adapter_nr) || 1889 THIS_MODULE, NULL, adapter_nr) ||
1890 0 == dvb_usb_device_init(intf, p1100,
1891 THIS_MODULE, NULL, adapter_nr) ||
1892 0 == dvb_usb_device_init(intf, s660,
1893 THIS_MODULE, NULL, adapter_nr) ||
1483 0 == dvb_usb_device_init(intf, p7500, 1894 0 == dvb_usb_device_init(intf, p7500,
1484 THIS_MODULE, NULL, adapter_nr)) 1895 THIS_MODULE, NULL, adapter_nr) ||
1896 0 == dvb_usb_device_init(intf, &su3000_properties,
1897 THIS_MODULE, NULL, adapter_nr))
1485 return 0; 1898 return 0;
1486 1899
1487 return -ENODEV; 1900 return -ENODEV;
@@ -1514,7 +1927,8 @@ module_exit(dw2102_module_exit);
1514MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 1927MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1515MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," 1928MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1516 " DVB-C 3101 USB2.0," 1929 " DVB-C 3101 USB2.0,"
1517 " TeVii S600, S630, S650, S660 USB2.0," 1930 " TeVii S600, S630, S650, S660, S480,"
1518 " Prof 1100, 7500 USB2.0 devices"); 1931 " Prof 1100, 7500 USB2.0,"
1932 " Geniatech SU3000 devices");
1519MODULE_VERSION("0.1"); 1933MODULE_VERSION("0.1");
1520MODULE_LICENSE("GPL"); 1934MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index 46ccd01a7696..cd26e7c1536a 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -2,7 +2,9 @@
2 * 2 *
3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395 3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
4 * LME2510C + LG TDQY-P001F 4 * LME2510C + LG TDQY-P001F
5 * LME2510C + BS2F7HZ0194
5 * LME2510 + LG TDQY-P001F 6 * LME2510 + LG TDQY-P001F
7 * LME2510 + BS2F7HZ0194
6 * 8 *
7 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) 9 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
8 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) 10 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
@@ -12,20 +14,22 @@
12 * 14 *
13 * MVB0001F (LME2510C+LGTDQT-P001F) 15 * MVB0001F (LME2510C+LGTDQT-P001F)
14 * 16 *
17 * MV0194 (LME2510+SHARP:BS2F7HZ0194)
18 * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
19 *
20 * MVB0194 (LME2510C+SHARP0194)
21 *
15 * For firmware see Documentation/dvb/lmedm04.txt 22 * For firmware see Documentation/dvb/lmedm04.txt
16 * 23 *
17 * I2C addresses: 24 * I2C addresses:
18 * 0xd0 - STV0288 - Demodulator 25 * 0xd0 - STV0288 - Demodulator
19 * 0xc0 - Sharp IX2505V - Tuner 26 * 0xc0 - Sharp IX2505V - Tuner
20 * --or-- 27 * --
21 * 0x1c - TDA10086 - Demodulator 28 * 0x1c - TDA10086 - Demodulator
22 * 0xc0 - TDA8263 - Tuner 29 * 0xc0 - TDA8263 - Tuner
23 * 30 * --
24 * ***Please Note*** 31 * 0xd0 - STV0299 - Demodulator
25 * There are other variants of the DM04 32 * 0xc0 - IX2410 - Tuner
26 * ***NOT SUPPORTED***
27 * MV0194 (LME2510+SHARP0194)
28 * MVB0194 (LME2510C+SHARP0194)
29 * 33 *
30 * 34 *
31 * VID = 3344 PID LME2510=1122 LME2510C=1120 35 * VID = 3344 PID LME2510=1122 LME2510C=1120
@@ -55,6 +59,9 @@
55 * 59 *
56 * QQbox suffers from noise on LNB voltage. 60 * QQbox suffers from noise on LNB voltage.
57 * 61 *
62 * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
63 * with other tuners. After a cold reset streaming will not start.
64 *
58 * PID functions have been removed from this driver version due to 65 * PID functions have been removed from this driver version due to
59 * problems with different firmware and application versions. 66 * problems with different firmware and application versions.
60 */ 67 */
@@ -69,6 +76,9 @@
69#include "tda10086.h" 76#include "tda10086.h"
70#include "stv0288.h" 77#include "stv0288.h"
71#include "ix2505v.h" 78#include "ix2505v.h"
79#include "stv0299.h"
80#include "dvb-pll.h"
81#include "z0194a.h"
72 82
73 83
74 84
@@ -96,8 +106,11 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
96 106
97 107
98DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 108DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
109
110#define TUNER_DEFAULT 0x0
99#define TUNER_LG 0x1 111#define TUNER_LG 0x1
100#define TUNER_S7395 0x2 112#define TUNER_S7395 0x2
113#define TUNER_S0194 0x3
101 114
102struct lme2510_state { 115struct lme2510_state {
103 u8 id; 116 u8 id;
@@ -191,7 +204,7 @@ static int lme2510_stream_restart(struct dvb_usb_device *d)
191 rbuff, sizeof(rbuff)); 204 rbuff, sizeof(rbuff));
192 return ret; 205 return ret;
193} 206}
194static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress) 207static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress)
195{ 208{
196 struct dvb_usb_device *d = adap->dev; 209 struct dvb_usb_device *d = adap->dev;
197 210
@@ -237,7 +250,8 @@ static void lme2510_int_response(struct urb *lme_urb)
237 case 0xaa: 250 case 0xaa:
238 debug_data_snipet(1, "INT Remote data snipet in", ibuf); 251 debug_data_snipet(1, "INT Remote data snipet in", ibuf);
239 lme2510_remote_keypress(adap, 252 lme2510_remote_keypress(adap,
240 (u16)(ibuf[4]<<8)+ibuf[5]); 253 (u32)(ibuf[2] << 24) + (ibuf[3] << 16) +
254 (ibuf[4] << 8) + ibuf[5]);
241 break; 255 break;
242 case 0xbb: 256 case 0xbb:
243 switch (st->tuner_config) { 257 switch (st->tuner_config) {
@@ -249,6 +263,7 @@ static void lme2510_int_response(struct urb *lme_urb)
249 st->time_key = ibuf[7]; 263 st->time_key = ibuf[7];
250 break; 264 break;
251 case TUNER_S7395: 265 case TUNER_S7395:
266 case TUNER_S0194:
252 /* Tweak for earlier firmware*/ 267 /* Tweak for earlier firmware*/
253 if (ibuf[1] == 0x03) { 268 if (ibuf[1] == 0x03) {
254 if (ibuf[2] > 1) 269 if (ibuf[2] > 1)
@@ -364,6 +379,18 @@ static int lme2510_msg(struct dvb_usb_device *d,
364 msleep(5); 379 msleep(5);
365 } 380 }
366 break; 381 break;
382 case TUNER_S0194:
383 if (wbuf[2] == 0xd0) {
384 if (wbuf[3] == 0x1b) {
385 st->signal_lock = rbuf[1];
386 if ((st->stream_on & 1) &&
387 (st->signal_lock & 0x8)) {
388 lme2510_stream_restart(d);
389 st->i2c_talk_onoff = 0;
390 }
391 }
392 }
393 break;
367 default: 394 default:
368 break; 395 break;
369 } 396 }
@@ -423,6 +450,34 @@ static int lme2510_msg(struct dvb_usb_device *d,
423 break; 450 break;
424 } 451 }
425 break; 452 break;
453 case TUNER_S0194:
454 switch (wbuf[3]) {
455 case 0x18:
456 rbuf[0] = 0x55;
457 rbuf[1] = (st->signal_level & 0x80)
458 ? 0 : (st->signal_level * 2);
459 break;
460 case 0x24:
461 rbuf[0] = 0x55;
462 rbuf[1] = st->signal_sn;
463 break;
464 case 0x1b:
465 rbuf[0] = 0x55;
466 rbuf[1] = st->signal_lock;
467 break;
468 case 0x19:
469 case 0x25:
470 case 0x1e:
471 case 0x1d:
472 rbuf[0] = 0x55;
473 rbuf[1] = 0x00;
474 break;
475 default:
476 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
477 st->i2c_talk_onoff = 1;
478 break;
479 }
480 break;
426 default: 481 default:
427 break; 482 break;
428 } 483 }
@@ -517,17 +572,14 @@ static int lme2510_identify_state(struct usb_device *udev,
517 struct dvb_usb_device_description **desc, 572 struct dvb_usb_device_description **desc,
518 int *cold) 573 int *cold)
519{ 574{
520 if (lme2510_return_status(udev) == 0x44) 575 *cold = 0;
521 *cold = 1;
522 else
523 *cold = 0;
524 return 0; 576 return 0;
525} 577}
526 578
527static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 579static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
528{ 580{
529 struct lme2510_state *st = adap->dev->priv; 581 struct lme2510_state *st = adap->dev->priv;
530 static u8 clear_reg_3[] = LME_CLEAR_PID; 582 static u8 clear_reg_3[] = LME_CLEAR_PID;
531 static u8 rbuf[1]; 583 static u8 rbuf[1];
532 int ret = 0, rlen = sizeof(rbuf); 584 int ret = 0, rlen = sizeof(rbuf);
533 585
@@ -658,9 +710,6 @@ static int lme2510_download_firmware(struct usb_device *dev,
658 return (ret < 0) ? -ENODEV : 0; 710 return (ret < 0) ? -ENODEV : 0;
659} 711}
660 712
661/* Default firmware for LME2510C */
662char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw";
663
664static void lme_coldreset(struct usb_device *dev) 713static void lme_coldreset(struct usb_device *dev)
665{ 714{
666 int ret = 0, len_in; 715 int ret = 0, len_in;
@@ -678,49 +727,83 @@ static void lme_coldreset(struct usb_device *dev)
678static int lme_firmware_switch(struct usb_device *udev, int cold) 727static int lme_firmware_switch(struct usb_device *udev, int cold)
679{ 728{
680 const struct firmware *fw = NULL; 729 const struct firmware *fw = NULL;
681 char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; 730 const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
682 char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw"; 731 const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
683 char *firm_msg[] = {"Loading", "Switching to"}; 732 const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
684 int ret; 733 const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
734 const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
735 const char *fw_lme;
736 int ret, cold_fw;
685 737
686 cold = (cold > 0) ? (cold & 1) : 0; 738 cold = (cold > 0) ? (cold & 1) : 0;
687 739
688 if (udev->descriptor.idProduct == 0x1122) 740 cold_fw = !cold;
689 return 0;
690 741
691 switch (dvb_usb_lme2510_firmware) { 742 if (udev->descriptor.idProduct == 0x1122) {
692 case 0: 743 switch (dvb_usb_lme2510_firmware) {
693 default: 744 default:
694 memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395)); 745 dvb_usb_lme2510_firmware = TUNER_S0194;
695 ret = request_firmware(&fw, lme_firmware, &udev->dev); 746 case TUNER_S0194:
696 if (ret == 0) { 747 fw_lme = fw_s0194;
697 info("FRM %s S7395 Firmware", firm_msg[cold]); 748 ret = request_firmware(&fw, fw_lme, &udev->dev);
749 if (ret == 0) {
750 cold = 0;/*lme2510-s0194 cannot cold reset*/
751 break;
752 }
753 dvb_usb_lme2510_firmware = TUNER_LG;
754 case TUNER_LG:
755 fw_lme = fw_lg;
756 ret = request_firmware(&fw, fw_lme, &udev->dev);
757 if (ret == 0)
758 break;
759 info("FRM No Firmware Found - please install");
760 dvb_usb_lme2510_firmware = TUNER_DEFAULT;
761 cold = 0;
762 cold_fw = 0;
698 break; 763 break;
699 } 764 }
700 if (cold == 0) 765 } else {
701 dvb_usb_lme2510_firmware = 1; 766 switch (dvb_usb_lme2510_firmware) {
702 else 767 default:
768 dvb_usb_lme2510_firmware = TUNER_S7395;
769 case TUNER_S7395:
770 fw_lme = fw_c_s7395;
771 ret = request_firmware(&fw, fw_lme, &udev->dev);
772 if (ret == 0)
773 break;
774 dvb_usb_lme2510_firmware = TUNER_LG;
775 case TUNER_LG:
776 fw_lme = fw_c_lg;
777 ret = request_firmware(&fw, fw_lme, &udev->dev);
778 if (ret == 0)
779 break;
780 dvb_usb_lme2510_firmware = TUNER_S0194;
781 case TUNER_S0194:
782 fw_lme = fw_c_s0194;
783 ret = request_firmware(&fw, fw_lme, &udev->dev);
784 if (ret == 0)
785 break;
786 info("FRM No Firmware Found - please install");
787 dvb_usb_lme2510_firmware = TUNER_DEFAULT;
703 cold = 0; 788 cold = 0;
704 case 1: 789 cold_fw = 0;
705 memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg));
706 ret = request_firmware(&fw, lme_firmware, &udev->dev);
707 if (ret == 0) {
708 info("FRM %s LG Firmware", firm_msg[cold]);
709 break; 790 break;
710 } 791 }
711 info("FRM No Firmware Found - please install");
712 dvb_usb_lme2510_firmware = 0;
713 cold = 0;
714 break;
715 } 792 }
716 793
717 release_firmware(fw); 794 if (cold_fw) {
795 info("FRM Loading %s file", fw_lme);
796 ret = lme2510_download_firmware(udev, fw);
797 }
718 798
719 if (cold) { 799 if (cold) {
800 info("FRM Changing to %s firmware", fw_lme);
720 lme_coldreset(udev); 801 lme_coldreset(udev);
721 return -ENODEV; 802 return -ENODEV;
722 } 803 }
723 804
805 release_firmware(fw);
806
724 return ret; 807 return ret;
725} 808}
726 809
@@ -758,6 +841,18 @@ static struct ix2505v_config lme_tuner = {
758 .tuner_chargepump = 0x3, 841 .tuner_chargepump = 0x3,
759}; 842};
760 843
844static struct stv0299_config sharp_z0194_config = {
845 .demod_address = 0xd0,
846 .inittab = sharp_z0194a_inittab,
847 .mclk = 88000000UL,
848 .invert = 0,
849 .skip_reinit = 0,
850 .lock_output = STV0299_LOCKOUTPUT_1,
851 .volt13_op0_op1 = STV0299_VOLT13_OP1,
852 .min_delay_ms = 100,
853 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
854};
855
761static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, 856static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
762 fe_sec_voltage_t voltage) 857 fe_sec_voltage_t voltage)
763{ 858{
@@ -793,7 +888,8 @@ static int lme_name(struct dvb_usb_adapter *adap)
793{ 888{
794 struct lme2510_state *st = adap->dev->priv; 889 struct lme2510_state *st = adap->dev->priv;
795 const char *desc = adap->dev->desc->name; 890 const char *desc = adap->dev->desc->name;
796 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"}; 891 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
892 " SHARP:BS2F7HZ0194"};
797 char *name = adap->fe->ops.info.name; 893 char *name = adap->fe->ops.info.name;
798 894
799 strlcpy(name, desc, 128); 895 strlcpy(name, desc, 128);
@@ -820,26 +916,40 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
820 st->i2c_tuner_gate_r = 4; 916 st->i2c_tuner_gate_r = 4;
821 st->i2c_tuner_addr = 0xc0; 917 st->i2c_tuner_addr = 0xc0;
822 st->tuner_config = TUNER_LG; 918 st->tuner_config = TUNER_LG;
823 if (dvb_usb_lme2510_firmware != 1) { 919 if (dvb_usb_lme2510_firmware != TUNER_LG) {
824 dvb_usb_lme2510_firmware = 1; 920 dvb_usb_lme2510_firmware = TUNER_LG;
825 ret = lme_firmware_switch(adap->dev->udev, 1); 921 ret = lme_firmware_switch(adap->dev->udev, 1);
826 } else /*stops LG/Sharp multi tuner problems*/ 922 }
827 dvb_usb_lme2510_firmware = 0; 923 goto end;
924 }
925
926 st->i2c_gate = 4;
927 adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config,
928 &adap->dev->i2c_adap);
929 if (adap->fe) {
930 info("FE Found Stv0299");
931 st->i2c_tuner_gate_w = 4;
932 st->i2c_tuner_gate_r = 5;
933 st->i2c_tuner_addr = 0xc0;
934 st->tuner_config = TUNER_S0194;
935 if (dvb_usb_lme2510_firmware != TUNER_S0194) {
936 dvb_usb_lme2510_firmware = TUNER_S0194;
937 ret = lme_firmware_switch(adap->dev->udev, 1);
938 }
828 goto end; 939 goto end;
829 } 940 }
830 941
831 st->i2c_gate = 5; 942 st->i2c_gate = 5;
832 adap->fe = dvb_attach(stv0288_attach, &lme_config, 943 adap->fe = dvb_attach(stv0288_attach, &lme_config,
833 &adap->dev->i2c_adap); 944 &adap->dev->i2c_adap);
834
835 if (adap->fe) { 945 if (adap->fe) {
836 info("FE Found Stv0288"); 946 info("FE Found Stv0288");
837 st->i2c_tuner_gate_w = 4; 947 st->i2c_tuner_gate_w = 4;
838 st->i2c_tuner_gate_r = 5; 948 st->i2c_tuner_gate_r = 5;
839 st->i2c_tuner_addr = 0xc0; 949 st->i2c_tuner_addr = 0xc0;
840 st->tuner_config = TUNER_S7395; 950 st->tuner_config = TUNER_S7395;
841 if (dvb_usb_lme2510_firmware != 0) { 951 if (dvb_usb_lme2510_firmware != TUNER_S7395) {
842 dvb_usb_lme2510_firmware = 0; 952 dvb_usb_lme2510_firmware = TUNER_S7395;
843 ret = lme_firmware_switch(adap->dev->udev, 1); 953 ret = lme_firmware_switch(adap->dev->udev, 1);
844 } 954 }
845 } else { 955 } else {
@@ -847,6 +957,7 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
847 return -ENODEV; 957 return -ENODEV;
848 } 958 }
849 959
960
850end: if (ret) { 961end: if (ret) {
851 kfree(adap->fe); 962 kfree(adap->fe);
852 adap->fe = NULL; 963 adap->fe = NULL;
@@ -855,14 +966,13 @@ end: if (ret) {
855 966
856 adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; 967 adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
857 ret = lme_name(adap); 968 ret = lme_name(adap);
858
859 return ret; 969 return ret;
860} 970}
861 971
862static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) 972static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
863{ 973{
864 struct lme2510_state *st = adap->dev->priv; 974 struct lme2510_state *st = adap->dev->priv;
865 char *tun_msg[] = {"", "TDA8263", "IX2505V"}; 975 char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"};
866 int ret = 0; 976 int ret = 0;
867 977
868 switch (st->tuner_config) { 978 switch (st->tuner_config) {
@@ -876,6 +986,11 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
876 &adap->dev->i2c_adap)) 986 &adap->dev->i2c_adap))
877 ret = st->tuner_config; 987 ret = st->tuner_config;
878 break; 988 break;
989 case TUNER_S0194:
990 if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0,
991 &adap->dev->i2c_adap, DVB_PLL_OPERA1))
992 ret = st->tuner_config;
993 break;
879 default: 994 default:
880 break; 995 break;
881 } 996 }
@@ -936,7 +1051,10 @@ static int lme2510_probe(struct usb_interface *intf,
936 return -ENODEV; 1051 return -ENODEV;
937 } 1052 }
938 1053
939 lme_firmware_switch(udev, 0); 1054 if (lme2510_return_status(udev) == 0x44) {
1055 lme_firmware_switch(udev, 0);
1056 return -ENODEV;
1057 }
940 1058
941 if (0 == dvb_usb_device_init(intf, &lme2510_properties, 1059 if (0 == dvb_usb_device_init(intf, &lme2510_properties,
942 THIS_MODULE, NULL, adapter_nr)) { 1060 THIS_MODULE, NULL, adapter_nr)) {
@@ -964,10 +1082,6 @@ MODULE_DEVICE_TABLE(usb, lme2510_table);
964 1082
965static struct dvb_usb_device_properties lme2510_properties = { 1083static struct dvb_usb_device_properties lme2510_properties = {
966 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1084 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
967 .usb_ctrl = DEVICE_SPECIFIC,
968 .download_firmware = lme2510_download_firmware,
969 .firmware = "dvb-usb-lme2510-lg.fw",
970
971 .size_of_priv = sizeof(struct lme2510_state), 1085 .size_of_priv = sizeof(struct lme2510_state),
972 .num_adapters = 1, 1086 .num_adapters = 1,
973 .adapter = { 1087 .adapter = {
@@ -1004,9 +1118,6 @@ static struct dvb_usb_device_properties lme2510_properties = {
1004 1118
1005static struct dvb_usb_device_properties lme2510c_properties = { 1119static struct dvb_usb_device_properties lme2510c_properties = {
1006 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1120 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1007 .usb_ctrl = DEVICE_SPECIFIC,
1008 .download_firmware = lme2510_download_firmware,
1009 .firmware = (const char *)&lme_firmware,
1010 .size_of_priv = sizeof(struct lme2510_state), 1121 .size_of_priv = sizeof(struct lme2510_state),
1011 .num_adapters = 1, 1122 .num_adapters = 1,
1012 .adapter = { 1123 .adapter = {
@@ -1109,5 +1220,5 @@ module_exit(lme2510_module_exit);
1109 1220
1110MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 1221MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1111MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); 1222MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
1112MODULE_VERSION("1.75"); 1223MODULE_VERSION("1.80");
1113MODULE_LICENSE("GPL"); 1224MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 1f1b7d6980a5..7e569f4dd80b 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = {
342 {0x49b6, KEY_8}, 342 {0x49b6, KEY_8},
343 {0x05fa, KEY_9}, 343 {0x05fa, KEY_9},
344 {0x45ba, KEY_0}, 344 {0x45ba, KEY_0},
345 {0x09f6, KEY_UP}, /*chanup */ 345 {0x09f6, KEY_CHANNELUP}, /*chanup */
346 {0x1be5, KEY_DOWN}, /*chandown */ 346 {0x1be5, KEY_CHANNELDOWN}, /*chandown */
347 {0x5da3, KEY_LEFT}, /*voldown */ 347 {0x5da3, KEY_VOLUMEDOWN}, /*voldown */
348 {0x5fa1, KEY_RIGHT}, /*volup */ 348 {0x5fa1, KEY_VOLUMEUP}, /*volup */
349 {0x07f8, KEY_SPACE}, /*tab */ 349 {0x07f8, KEY_SPACE}, /*tab */
350 {0x1fe1, KEY_ENTER}, /*play ok */ 350 {0x1fe1, KEY_OK}, /*play ok */
351 {0x1be4, KEY_Z}, /*zoom */ 351 {0x1be4, KEY_ZOOM}, /*zoom */
352 {0x59a6, KEY_M}, /*mute */ 352 {0x59a6, KEY_MUTE}, /*mute */
353 {0x5ba5, KEY_F}, /*tv/f */ 353 {0x5ba5, KEY_RADIO}, /*tv/f */
354 {0x19e7, KEY_R}, /*rec */ 354 {0x19e7, KEY_RECORD}, /*rec */
355 {0x01fe, KEY_S}, /*Stop */ 355 {0x01fe, KEY_STOP}, /*Stop */
356 {0x03fd, KEY_P}, /*pause */ 356 {0x03fd, KEY_PAUSE}, /*pause */
357 {0x03fc, KEY_W}, /*<- -> */ 357 {0x03fc, KEY_SCREEN}, /*<- -> */
358 {0x07f9, KEY_C}, /*capture */ 358 {0x07f9, KEY_CAMERA}, /*capture */
359 {0x47b9, KEY_Q}, /*exit */ 359 {0x47b9, KEY_ESC}, /*exit */
360 {0x43bc, KEY_O}, /*power */ 360 {0x43bc, KEY_POWER2}, /*power */
361
362}; 361};
363 362
364static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) 363static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c
new file mode 100644
index 000000000000..08f8842ad280
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c
@@ -0,0 +1,807 @@
1/*
2 * Linux driver for Technisat DVB-S/S2 USB 2.0 device
3 *
4 * Copyright (C) 2010 Patrick Boettcher,
5 * Kernel Labs Inc. PO Box 745, St James, NY 11780
6 *
7 * Development was sponsored by Technisat Digital UK Limited, whose
8 * registered office is Witan Gate House 500 - 600 Witan Gate West,
9 * Milton Keynes, MK9 1SH
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
22 * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
24 * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
25 * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
26 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
27 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
28 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
29 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
30 * GNU General Public License for more details.
31 */
32
33#define DVB_USB_LOG_PREFIX "technisat-usb2"
34#include "dvb-usb.h"
35
36#include "stv6110x.h"
37#include "stv090x.h"
38
39/* module parameters */
40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug,
45 "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
46 DVB_USB_DEBUG_STATUS);
47
48/* disables all LED control command and
49 * also does not start the signal polling thread */
50static int disable_led_control;
51module_param(disable_led_control, int, 0444);
52MODULE_PARM_DESC(disable_led_control,
53 "disable LED control of the device "
54 "(default: 0 - LED control is active).");
55
56/* device private data */
57struct technisat_usb2_state {
58 struct dvb_usb_device *dev;
59 struct delayed_work green_led_work;
60 u8 power_state;
61
62 u16 last_scan_code;
63};
64
65/* debug print helpers */
66#define deb_info(args...) dprintk(debug, 0x01, args)
67#define deb_eeprom(args...) dprintk(debug, 0x02, args)
68#define deb_i2c(args...) dprintk(debug, 0x04, args)
69#define deb_rc(args...) dprintk(debug, 0x08, args)
70
71/* vendor requests */
72#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
73#define SET_FRONT_END_RESET_VENDOR_REQUEST 0xB4
74#define GET_VERSION_INFO_VENDOR_REQUEST 0xB5
75#define SET_GREEN_LED_VENDOR_REQUEST 0xB6
76#define SET_RED_LED_VENDOR_REQUEST 0xB7
77#define GET_IR_DATA_VENDOR_REQUEST 0xB8
78#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST 0xB9
79#define SET_USB_REENUMERATION 0xBA
80
81/* i2c-access methods */
82#define I2C_SPEED_100KHZ_BIT 0x40
83
84#define I2C_STATUS_NAK 7
85#define I2C_STATUS_OK 8
86
87static int technisat_usb2_i2c_access(struct usb_device *udev,
88 u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
89{
90 u8 b[64];
91 int ret, actual_length;
92
93 deb_i2c("i2c-access: %02x, tx: ", device_addr);
94 debug_dump(tx, txlen, deb_i2c);
95 deb_i2c(" ");
96
97 if (txlen > 62) {
98 err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
99 device_addr);
100 txlen = 62;
101 }
102 if (rxlen > 62) {
103 err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
104 device_addr);
105 txlen = 62;
106 }
107
108 b[0] = I2C_SPEED_100KHZ_BIT;
109 b[1] = device_addr << 1;
110
111 if (rx != NULL) {
112 b[0] |= rxlen;
113 b[1] |= 1;
114 }
115
116 memcpy(&b[2], tx, txlen);
117 ret = usb_bulk_msg(udev,
118 usb_sndbulkpipe(udev, 0x01),
119 b, 2 + txlen,
120 NULL, 1000);
121
122 if (ret < 0) {
123 err("i2c-error: out failed %02x = %d", device_addr, ret);
124 return -ENODEV;
125 }
126
127 ret = usb_bulk_msg(udev,
128 usb_rcvbulkpipe(udev, 0x01),
129 b, 64, &actual_length, 1000);
130 if (ret < 0) {
131 err("i2c-error: in failed %02x = %d", device_addr, ret);
132 return -ENODEV;
133 }
134
135 if (b[0] != I2C_STATUS_OK) {
136 err("i2c-error: %02x = %d", device_addr, b[0]);
137 /* handle tuner-i2c-nak */
138 if (!(b[0] == I2C_STATUS_NAK &&
139 device_addr == 0x60
140 /* && device_is_technisat_usb2 */))
141 return -ENODEV;
142 }
143
144 deb_i2c("status: %d, ", b[0]);
145
146 if (rx != NULL) {
147 memcpy(rx, &b[2], rxlen);
148
149 deb_i2c("rx (%d): ", rxlen);
150 debug_dump(rx, rxlen, deb_i2c);
151 }
152
153 deb_i2c("\n");
154
155 return 0;
156}
157
158static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
159 int num)
160{
161 int ret = 0, i;
162 struct dvb_usb_device *d = i2c_get_adapdata(adap);
163
164 /* Ensure nobody else hits the i2c bus while we're sending our
165 sequence of messages, (such as the remote control thread) */
166 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
167 return -EAGAIN;
168
169 for (i = 0; i < num; i++) {
170 if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
171 ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
172 msg[i].buf, msg[i].len,
173 msg[i+1].buf, msg[i+1].len);
174 if (ret != 0)
175 break;
176 i++;
177 } else {
178 ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
179 msg[i].buf, msg[i].len,
180 NULL, 0);
181 if (ret != 0)
182 break;
183 }
184 }
185
186 if (ret == 0)
187 ret = i;
188
189 mutex_unlock(&d->i2c_mutex);
190
191 return ret;
192}
193
194static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
195{
196 return I2C_FUNC_I2C;
197}
198
199static struct i2c_algorithm technisat_usb2_i2c_algo = {
200 .master_xfer = technisat_usb2_i2c_xfer,
201 .functionality = technisat_usb2_i2c_func,
202};
203
204#if 0
205static void technisat_usb2_frontend_reset(struct usb_device *udev)
206{
207 usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
208 SET_FRONT_END_RESET_VENDOR_REQUEST,
209 USB_TYPE_VENDOR | USB_DIR_OUT,
210 10, 0,
211 NULL, 0, 500);
212}
213#endif
214
215/* LED control */
216enum technisat_usb2_led_state {
217 LED_OFF,
218 LED_BLINK,
219 LED_ON,
220 LED_UNDEFINED
221};
222
223static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
224{
225 int ret;
226
227 u8 led[8] = {
228 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
229 0
230 };
231
232 if (disable_led_control && state != LED_OFF)
233 return 0;
234
235 switch (state) {
236 case LED_ON:
237 led[1] = 0x82;
238 break;
239 case LED_BLINK:
240 led[1] = 0x82;
241 if (red) {
242 led[2] = 0x02;
243 led[3] = 10;
244 led[4] = 10;
245 } else {
246 led[2] = 0xff;
247 led[3] = 50;
248 led[4] = 50;
249 }
250 led[5] = 1;
251 break;
252
253 default:
254 case LED_OFF:
255 led[1] = 0x80;
256 break;
257 }
258
259 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
260 return -EAGAIN;
261
262 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
263 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
264 USB_TYPE_VENDOR | USB_DIR_OUT,
265 0, 0,
266 led, sizeof(led), 500);
267
268 mutex_unlock(&d->i2c_mutex);
269 return ret;
270}
271
272static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
273{
274 int ret;
275 u8 b = 0;
276
277 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
278 return -EAGAIN;
279
280 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
281 SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
282 USB_TYPE_VENDOR | USB_DIR_OUT,
283 (red << 8) | green, 0,
284 &b, 1, 500);
285
286 mutex_unlock(&d->i2c_mutex);
287
288 return ret;
289}
290
291static void technisat_usb2_green_led_control(struct work_struct *work)
292{
293 struct technisat_usb2_state *state =
294 container_of(work, struct technisat_usb2_state, green_led_work.work);
295 struct dvb_frontend *fe = state->dev->adapter[0].fe;
296
297 if (state->power_state == 0)
298 goto schedule;
299
300 if (fe != NULL) {
301 enum fe_status status;
302
303 if (fe->ops.read_status(fe, &status) != 0)
304 goto schedule;
305
306 if (status & FE_HAS_LOCK) {
307 u32 ber;
308
309 if (fe->ops.read_ber(fe, &ber) != 0)
310 goto schedule;
311
312 if (ber > 1000)
313 technisat_usb2_set_led(state->dev, 0, LED_BLINK);
314 else
315 technisat_usb2_set_led(state->dev, 0, LED_ON);
316 } else
317 technisat_usb2_set_led(state->dev, 0, LED_OFF);
318 }
319
320schedule:
321 schedule_delayed_work(&state->green_led_work,
322 msecs_to_jiffies(500));
323}
324
325/* method to find out whether the firmware has to be downloaded or not */
326static int technisat_usb2_identify_state(struct usb_device *udev,
327 struct dvb_usb_device_properties *props,
328 struct dvb_usb_device_description **desc, int *cold)
329{
330 int ret;
331 u8 version[3];
332
333 /* first select the interface */
334 if (usb_set_interface(udev, 0, 1) != 0)
335 err("could not set alternate setting to 0");
336 else
337 info("set alternate setting");
338
339 *cold = 0; /* by default do not download a firmware - just in case something is wrong */
340
341 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
342 GET_VERSION_INFO_VENDOR_REQUEST,
343 USB_TYPE_VENDOR | USB_DIR_IN,
344 0, 0,
345 version, sizeof(version), 500);
346
347 if (ret < 0)
348 *cold = 1;
349 else {
350 info("firmware version: %d.%d", version[1], version[2]);
351 *cold = 0;
352 }
353
354 return 0;
355}
356
357/* power control */
358static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
359{
360 struct technisat_usb2_state *state = d->priv;
361
362 state->power_state = level;
363
364 if (disable_led_control)
365 return 0;
366
367 /* green led is turned off in any case - will be turned on when tuning */
368 technisat_usb2_set_led(d, 0, LED_OFF);
369 /* red led is turned on all the time */
370 technisat_usb2_set_led(d, 1, LED_ON);
371 return 0;
372}
373
374/* mac address reading - from the eeprom */
375#if 0
376static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
377{
378 u8 reg;
379 u8 b[16];
380 int i, j;
381
382 /* full EEPROM dump */
383 for (j = 0; j < 256 * 4; j += 16) {
384 reg = j;
385 if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
386 break;
387
388 deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
389 for (i = 0; i < 16; i++)
390 deb_eeprom("%02x ", b[i]);
391 deb_eeprom("\n");
392 }
393}
394#endif
395
396static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
397{
398 u8 lrc = 0;
399 while (--length)
400 lrc ^= *b++;
401 return lrc;
402}
403
404static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
405 u16 offset, u8 *b, u16 length, u8 tries)
406{
407 u8 bo = offset & 0xff;
408 struct i2c_msg msg[] = {
409 {
410 .addr = 0x50 | ((offset >> 8) & 0x3),
411 .buf = &bo,
412 .len = 1
413 }, {
414 .addr = 0x50 | ((offset >> 8) & 0x3),
415 .flags = I2C_M_RD,
416 .buf = b,
417 .len = length
418 }
419 };
420
421 while (tries--) {
422 int status;
423
424 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
425 break;
426
427 status =
428 technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
429
430 if (status)
431 return 0;
432 }
433
434 return -EREMOTEIO;
435}
436
437#define EEPROM_MAC_START 0x3f8
438#define EEPROM_MAC_TOTAL 8
439static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
440 u8 mac[])
441{
442 u8 buf[EEPROM_MAC_TOTAL];
443
444 if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
445 buf, EEPROM_MAC_TOTAL, 4) != 0)
446 return -ENODEV;
447
448 memcpy(mac, buf, 6);
449 return 0;
450}
451
452/* frontend attach */
453static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
454 fe_sec_voltage_t voltage)
455{
456 int i;
457 u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
458
459 gpio[2] = 1; /* high - voltage ? */
460
461 switch (voltage) {
462 case SEC_VOLTAGE_13:
463 gpio[0] = 1;
464 break;
465 case SEC_VOLTAGE_18:
466 gpio[0] = 1;
467 gpio[1] = 1;
468 break;
469 default:
470 case SEC_VOLTAGE_OFF:
471 break;
472 }
473
474 for (i = 0; i < 3; i++)
475 if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
476 return -EREMOTEIO;
477 return 0;
478}
479
480static struct stv090x_config technisat_usb2_stv090x_config = {
481 .device = STV0903,
482 .demod_mode = STV090x_SINGLE,
483 .clk_mode = STV090x_CLK_EXT,
484
485 .xtal = 8000000,
486 .address = 0x68,
487
488 .ts1_mode = STV090x_TSMODE_DVBCI,
489 .ts1_clk = 13400000,
490 .ts1_tei = 1,
491
492 .repeater_level = STV090x_RPTLEVEL_64,
493
494 .tuner_bbgain = 6,
495};
496
497static struct stv6110x_config technisat_usb2_stv6110x_config = {
498 .addr = 0x60,
499 .refclk = 16000000,
500 .clk_div = 2,
501};
502
503static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
504{
505 struct usb_device *udev = a->dev->udev;
506 int ret;
507
508 a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
509 &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
510
511 if (a->fe) {
512 struct stv6110x_devctl *ctl;
513
514 ctl = dvb_attach(stv6110x_attach,
515 a->fe,
516 &technisat_usb2_stv6110x_config,
517 &a->dev->i2c_adap);
518
519 if (ctl) {
520 technisat_usb2_stv090x_config.tuner_init = ctl->tuner_init;
521 technisat_usb2_stv090x_config.tuner_sleep = ctl->tuner_sleep;
522 technisat_usb2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
523 technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
524 technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
525 technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
526 technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
527 technisat_usb2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
528 technisat_usb2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
529 technisat_usb2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
530 technisat_usb2_stv090x_config.tuner_get_status = ctl->tuner_get_status;
531
532 /* call the init function once to initialize
533 tuner's clock output divider and demod's
534 master clock */
535 if (a->fe->ops.init)
536 a->fe->ops.init(a->fe);
537
538 if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
539 return -EAGAIN;
540
541 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
542 SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
543 USB_TYPE_VENDOR | USB_DIR_OUT,
544 0, 0,
545 NULL, 0, 500);
546 mutex_unlock(&a->dev->i2c_mutex);
547
548 if (ret != 0)
549 err("could not set IF_CLK to external");
550
551 a->fe->ops.set_voltage = technisat_usb2_set_voltage;
552
553 /* if everything was successful assign a nice name to the frontend */
554 strlcpy(a->fe->ops.info.name, a->dev->desc->name,
555 sizeof(a->fe->ops.info.name));
556 } else {
557 dvb_frontend_detach(a->fe);
558 a->fe = NULL;
559 }
560 }
561
562 technisat_usb2_set_led_timer(a->dev, 1, 1);
563
564 return a->fe == NULL ? -ENODEV : 0;
565}
566
567/* Remote control */
568
569/* the device is giving providing raw IR-signals to the host mapping
570 * it only to one remote control is just the default implementation
571 */
572#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
573#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
574
575#define FIRMWARE_CLOCK_TICK 83333
576#define FIRMWARE_CLOCK_DIVISOR 256
577
578#define IR_PERCENT_TOLERANCE 15
579
580#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
581#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
582
583#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
584#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
585
586#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
587#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
588
589#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
590#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
591
592static int technisat_usb2_get_ir(struct dvb_usb_device *d)
593{
594 u8 buf[62], *b;
595 int ret;
596 struct ir_raw_event ev;
597
598 buf[0] = GET_IR_DATA_VENDOR_REQUEST;
599 buf[1] = 0x08;
600 buf[2] = 0x8f;
601 buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
602 buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
603
604 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
605 return -EAGAIN;
606 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
607 GET_IR_DATA_VENDOR_REQUEST,
608 USB_TYPE_VENDOR | USB_DIR_OUT,
609 0, 0,
610 buf, 5, 500);
611 if (ret < 0)
612 goto unlock;
613
614 buf[1] = 0;
615 buf[2] = 0;
616 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
617 GET_IR_DATA_VENDOR_REQUEST,
618 USB_TYPE_VENDOR | USB_DIR_IN,
619 0x8080, 0,
620 buf, sizeof(buf), 500);
621
622unlock:
623 mutex_unlock(&d->i2c_mutex);
624
625 if (ret < 0)
626 return ret;
627
628 if (ret == 1)
629 return 0; /* no key pressed */
630
631 /* decoding */
632 b = buf+1;
633
634#if 0
635 deb_rc("RC: %d ", ret);
636 debug_dump(b, ret, deb_rc);
637#endif
638
639 ev.pulse = 0;
640 while (1) {
641 ev.pulse = !ev.pulse;
642 ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
643 ir_raw_event_store(d->rc_dev, &ev);
644
645 b++;
646 if (*b == 0xff) {
647 ev.pulse = 0;
648 ev.duration = 888888*2;
649 ir_raw_event_store(d->rc_dev, &ev);
650 break;
651 }
652 }
653
654 ir_raw_event_handle(d->rc_dev);
655
656 return 1;
657}
658
659static int technisat_usb2_rc_query(struct dvb_usb_device *d)
660{
661 int ret = technisat_usb2_get_ir(d);
662
663 if (ret < 0)
664 return ret;
665
666 if (ret == 0)
667 return 0;
668
669 if (!disable_led_control)
670 technisat_usb2_set_led(d, 1, LED_BLINK);
671
672 return 0;
673}
674
675/* DVB-USB and USB stuff follows */
676static struct usb_device_id technisat_usb2_id_table[] = {
677 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
678 { 0 } /* Terminating entry */
679};
680
681/* device description */
682static struct dvb_usb_device_properties technisat_usb2_devices = {
683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
684
685 .usb_ctrl = CYPRESS_FX2,
686
687 .identify_state = technisat_usb2_identify_state,
688 .firmware = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
689
690 .size_of_priv = sizeof(struct technisat_usb2_state),
691
692 .i2c_algo = &technisat_usb2_i2c_algo,
693
694 .power_ctrl = technisat_usb2_power_ctrl,
695 .read_mac_address = technisat_usb2_read_mac_address,
696
697 .num_adapters = 1,
698 .adapter = {
699 {
700 .frontend_attach = technisat_usb2_frontend_attach,
701
702 .stream = {
703 .type = USB_ISOC,
704 .count = 8,
705 .endpoint = 0x2,
706 .u = {
707 .isoc = {
708 .framesperurb = 32,
709 .framesize = 2048,
710 .interval = 3,
711 }
712 }
713 },
714
715 .size_of_priv = 0,
716 },
717 },
718
719 .num_device_descs = 1,
720 .devices = {
721 { "Technisat SkyStar USB HD (DVB-S/S2)",
722 { &technisat_usb2_id_table[0], NULL },
723 { NULL },
724 },
725 },
726
727 .rc.core = {
728 .rc_interval = 100,
729 .rc_codes = RC_MAP_TECHNISAT_USB2,
730 .module_name = "technisat-usb2",
731 .rc_query = technisat_usb2_rc_query,
732 .allowed_protos = RC_TYPE_ALL,
733 .driver_type = RC_DRIVER_IR_RAW,
734 }
735};
736
737static int technisat_usb2_probe(struct usb_interface *intf,
738 const struct usb_device_id *id)
739{
740 struct dvb_usb_device *dev;
741
742 if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
743 &dev, adapter_nr) != 0)
744 return -ENODEV;
745
746 if (dev) {
747 struct technisat_usb2_state *state = dev->priv;
748 state->dev = dev;
749
750 if (!disable_led_control) {
751 INIT_DELAYED_WORK(&state->green_led_work,
752 technisat_usb2_green_led_control);
753 schedule_delayed_work(&state->green_led_work,
754 msecs_to_jiffies(500));
755 }
756 }
757
758 return 0;
759}
760
761static void technisat_usb2_disconnect(struct usb_interface *intf)
762{
763 struct dvb_usb_device *dev = usb_get_intfdata(intf);
764
765 /* work and stuff was only created when the device is is hot-state */
766 if (dev != NULL) {
767 struct technisat_usb2_state *state = dev->priv;
768 if (state != NULL) {
769 cancel_delayed_work_sync(&state->green_led_work);
770 flush_scheduled_work();
771 }
772 }
773
774 dvb_usb_device_exit(intf);
775}
776
777static struct usb_driver technisat_usb2_driver = {
778 .name = "dvb_usb_technisat_usb2",
779 .probe = technisat_usb2_probe,
780 .disconnect = technisat_usb2_disconnect,
781 .id_table = technisat_usb2_id_table,
782};
783
784/* module stuff */
785static int __init technisat_usb2_module_init(void)
786{
787 int result = usb_register(&technisat_usb2_driver);
788 if (result) {
789 err("usb_register failed. Code %d", result);
790 return result;
791 }
792
793 return 0;
794}
795
796static void __exit technisat_usb2_module_exit(void)
797{
798 usb_deregister(&technisat_usb2_driver);
799}
800
801module_init(technisat_usb2_module_init);
802module_exit(technisat_usb2_module_exit);
803
804MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
805MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
806MODULE_VERSION("1.0");
807MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig
index 4afa29256df1..f3e9448c3955 100644
--- a/drivers/media/dvb/firewire/Kconfig
+++ b/drivers/media/dvb/firewire/Kconfig
@@ -1,6 +1,6 @@
1config DVB_FIREDTV 1config DVB_FIREDTV
2 tristate "FireDTV and FloppyDTV" 2 tristate "FireDTV and FloppyDTV"
3 depends on DVB_CORE && (FIREWIRE || IEEE1394) 3 depends on DVB_CORE && FIREWIRE
4 help 4 help
5 Support for DVB receivers from Digital Everywhere 5 Support for DVB receivers from Digital Everywhere
6 which are connected via IEEE 1394 (FireWire). 6 which are connected via IEEE 1394 (FireWire).
@@ -13,12 +13,6 @@ config DVB_FIREDTV
13 13
14if DVB_FIREDTV 14if DVB_FIREDTV
15 15
16config DVB_FIREDTV_FIREWIRE
17 def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m)
18
19config DVB_FIREDTV_IEEE1394
20 def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m)
21
22config DVB_FIREDTV_INPUT 16config DVB_FIREDTV_INPUT
23 def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) 17 def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
24 18
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile
index da84203d51c6..357b3aab186b 100644
--- a/drivers/media/dvb/firewire/Makefile
+++ b/drivers/media/dvb/firewire/Makefile
@@ -1,9 +1,6 @@
1obj-$(CONFIG_DVB_FIREDTV) += firedtv.o 1obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
2 2
3firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o 3firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o
4firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o
5firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
6firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o 4firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
7 5
8ccflags-y += -Idrivers/media/dvb/dvb-core 6ccflags-y += -Idrivers/media/dvb/dvb-core
9ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
deleted file mode 100644
index b34ca7afb0e6..000000000000
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ /dev/null
@@ -1,300 +0,0 @@
1/*
2 * FireDTV driver -- ieee1394 I/O backend
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
6 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/kernel.h>
17#include <linux/list.h>
18#include <linux/slab.h>
19#include <linux/spinlock.h>
20#include <linux/types.h>
21
22#include <dma.h>
23#include <csr1212.h>
24#include <highlevel.h>
25#include <hosts.h>
26#include <ieee1394.h>
27#include <iso.h>
28#include <nodemgr.h>
29
30#include <dvb_demux.h>
31
32#include "firedtv.h"
33
34static LIST_HEAD(node_list);
35static DEFINE_SPINLOCK(node_list_lock);
36
37#define CIP_HEADER_SIZE 8
38#define MPEG2_TS_HEADER_SIZE 4
39#define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188)
40
41static void rawiso_activity_cb(struct hpsb_iso *iso)
42{
43 struct firedtv *f, *fdtv = NULL;
44 unsigned int i, num, packet;
45 unsigned char *buf;
46 unsigned long flags;
47 int count;
48
49 spin_lock_irqsave(&node_list_lock, flags);
50 list_for_each_entry(f, &node_list, list)
51 if (f->backend_data == iso) {
52 fdtv = f;
53 break;
54 }
55 spin_unlock_irqrestore(&node_list_lock, flags);
56
57 packet = iso->first_packet;
58 num = hpsb_iso_n_ready(iso);
59
60 if (!fdtv) {
61 pr_err("received at unknown iso channel\n");
62 goto out;
63 }
64
65 for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
66 buf = dma_region_i(&iso->data_buf, unsigned char,
67 iso->infos[packet].offset + CIP_HEADER_SIZE);
68 count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
69 MPEG2_TS_SOURCE_PACKET_SIZE;
70
71 /* ignore empty packet */
72 if (iso->infos[packet].len <= CIP_HEADER_SIZE)
73 continue;
74
75 while (count--) {
76 if (buf[MPEG2_TS_HEADER_SIZE] == 0x47)
77 dvb_dmx_swfilter_packets(&fdtv->demux,
78 &buf[MPEG2_TS_HEADER_SIZE], 1);
79 else
80 dev_err(fdtv->device,
81 "skipping invalid packet\n");
82 buf += MPEG2_TS_SOURCE_PACKET_SIZE;
83 }
84 }
85out:
86 hpsb_iso_recv_release_packets(iso, num);
87}
88
89static inline struct node_entry *node_of(struct firedtv *fdtv)
90{
91 return container_of(fdtv->device, struct unit_directory, device)->ne;
92}
93
94static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
95{
96 quadlet_t *d = data;
97 int ret;
98
99 ret = hpsb_node_lock(node_of(fdtv), addr,
100 EXTCODE_COMPARE_SWAP, &d[1], d[0]);
101 d[0] = d[1];
102
103 return ret;
104}
105
106static int node_read(struct firedtv *fdtv, u64 addr, void *data)
107{
108 return hpsb_node_read(node_of(fdtv), addr, data, 4);
109}
110
111static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
112{
113 return hpsb_node_write(node_of(fdtv), addr, data, len);
114}
115
116#define FDTV_ISO_BUFFER_PACKETS 256
117#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200)
118
119static int start_iso(struct firedtv *fdtv)
120{
121 struct hpsb_iso *iso_handle;
122 int ret;
123
124 iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host,
125 FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS,
126 fdtv->isochannel, HPSB_ISO_DMA_DEFAULT,
127 -1, /* stat.config.irq_interval */
128 rawiso_activity_cb);
129 if (iso_handle == NULL) {
130 dev_err(fdtv->device, "cannot initialize iso receive\n");
131 return -ENOMEM;
132 }
133 fdtv->backend_data = iso_handle;
134
135 ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0);
136 if (ret != 0) {
137 dev_err(fdtv->device, "cannot start iso receive\n");
138 hpsb_iso_shutdown(iso_handle);
139 fdtv->backend_data = NULL;
140 }
141 return ret;
142}
143
144static void stop_iso(struct firedtv *fdtv)
145{
146 struct hpsb_iso *iso_handle = fdtv->backend_data;
147
148 if (iso_handle != NULL) {
149 hpsb_iso_stop(iso_handle);
150 hpsb_iso_shutdown(iso_handle);
151 }
152 fdtv->backend_data = NULL;
153}
154
155static const struct firedtv_backend fdtv_1394_backend = {
156 .lock = node_lock,
157 .read = node_read,
158 .write = node_write,
159 .start_iso = start_iso,
160 .stop_iso = stop_iso,
161};
162
163static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
164 int cts, u8 *data, size_t length)
165{
166 struct firedtv *f, *fdtv = NULL;
167 unsigned long flags;
168 int su;
169
170 if (length == 0 || (data[0] & 0xf0) != 0)
171 return;
172
173 su = data[1] & 0x7;
174
175 spin_lock_irqsave(&node_list_lock, flags);
176 list_for_each_entry(f, &node_list, list)
177 if (node_of(f)->host == host &&
178 node_of(f)->nodeid == nodeid &&
179 (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
180 fdtv = f;
181 break;
182 }
183 spin_unlock_irqrestore(&node_list_lock, flags);
184
185 if (fdtv)
186 avc_recv(fdtv, data, length);
187}
188
189static int node_probe(struct device *dev)
190{
191 struct unit_directory *ud =
192 container_of(dev, struct unit_directory, device);
193 struct firedtv *fdtv;
194 int kv_len, err;
195 void *kv_str;
196
197 if (ud->model_name_kv) {
198 kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4;
199 kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
200 } else {
201 kv_len = 0;
202 kv_str = NULL;
203 }
204 fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
205 if (!fdtv)
206 return -ENOMEM;
207
208 /*
209 * Work around a bug in udev's path_id script: Use the fw-host's dev
210 * instead of the unit directory's dev as parent of the input device.
211 */
212 err = fdtv_register_rc(fdtv, dev->parent->parent);
213 if (err)
214 goto fail_free;
215
216 spin_lock_irq(&node_list_lock);
217 list_add_tail(&fdtv->list, &node_list);
218 spin_unlock_irq(&node_list_lock);
219
220 err = avc_identify_subunit(fdtv);
221 if (err)
222 goto fail;
223
224 err = fdtv_dvb_register(fdtv);
225 if (err)
226 goto fail;
227
228 avc_register_remote_control(fdtv);
229
230 return 0;
231fail:
232 spin_lock_irq(&node_list_lock);
233 list_del(&fdtv->list);
234 spin_unlock_irq(&node_list_lock);
235 fdtv_unregister_rc(fdtv);
236fail_free:
237 kfree(fdtv);
238
239 return err;
240}
241
242static int node_remove(struct device *dev)
243{
244 struct firedtv *fdtv = dev_get_drvdata(dev);
245
246 fdtv_dvb_unregister(fdtv);
247
248 spin_lock_irq(&node_list_lock);
249 list_del(&fdtv->list);
250 spin_unlock_irq(&node_list_lock);
251
252 fdtv_unregister_rc(fdtv);
253 kfree(fdtv);
254
255 return 0;
256}
257
258static int node_update(struct unit_directory *ud)
259{
260 struct firedtv *fdtv = dev_get_drvdata(&ud->device);
261
262 if (fdtv->isochannel >= 0)
263 cmp_establish_pp_connection(fdtv, fdtv->subunit,
264 fdtv->isochannel);
265 return 0;
266}
267
268static struct hpsb_protocol_driver fdtv_driver = {
269 .name = "firedtv",
270 .id_table = fdtv_id_table,
271 .update = node_update,
272 .driver = {
273 .probe = node_probe,
274 .remove = node_remove,
275 },
276};
277
278static struct hpsb_highlevel fdtv_highlevel = {
279 .name = "firedtv",
280 .fcp_request = fcp_request,
281};
282
283int __init fdtv_1394_init(void)
284{
285 int ret;
286
287 hpsb_register_highlevel(&fdtv_highlevel);
288 ret = hpsb_register_protocol(&fdtv_driver);
289 if (ret) {
290 printk(KERN_ERR "firedtv: failed to register protocol\n");
291 hpsb_unregister_highlevel(&fdtv_highlevel);
292 }
293 return ret;
294}
295
296void __exit fdtv_1394_exit(void)
297{
298 hpsb_unregister_protocol(&fdtv_driver);
299 hpsb_unregister_highlevel(&fdtv_highlevel);
300}
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index f0f1842fab60..fc5ccd8c923a 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -241,8 +241,8 @@ static int avc_write(struct firedtv *fdtv)
241 if (unlikely(avc_debug)) 241 if (unlikely(avc_debug))
242 debug_fcp(fdtv->avc_data, fdtv->avc_data_length); 242 debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
243 243
244 err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, 244 err = fdtv_write(fdtv, FCP_COMMAND_REGISTER,
245 fdtv->avc_data, fdtv->avc_data_length); 245 fdtv->avc_data, fdtv->avc_data_length);
246 if (err) { 246 if (err) {
247 dev_err(fdtv->device, "FCP command write failed\n"); 247 dev_err(fdtv->device, "FCP command write failed\n");
248 248
@@ -1322,7 +1322,7 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
1322 1322
1323 mutex_lock(&fdtv->avc_mutex); 1323 mutex_lock(&fdtv->avc_mutex);
1324 1324
1325 ret = fdtv->backend->read(fdtv, addr, data); 1325 ret = fdtv_read(fdtv, addr, data);
1326 if (ret < 0) 1326 if (ret < 0)
1327 dev_err(fdtv->device, "CMP: read I/O error\n"); 1327 dev_err(fdtv->device, "CMP: read I/O error\n");
1328 1328
@@ -1340,7 +1340,7 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
1340 /* data[] is stack-allocated and should not be DMA-mapped. */ 1340 /* data[] is stack-allocated and should not be DMA-mapped. */
1341 memcpy(fdtv->avc_data, data, 8); 1341 memcpy(fdtv->avc_data, data, 8);
1342 1342
1343 ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data); 1343 ret = fdtv_lock(fdtv, addr, fdtv->avc_data);
1344 if (ret < 0) 1344 if (ret < 0)
1345 dev_err(fdtv->device, "CMP: lock I/O error\n"); 1345 dev_err(fdtv->device, "CMP: lock I/O error\n");
1346 else 1346 else
@@ -1405,10 +1405,7 @@ repeat:
1405 /* FIXME: this is for the worst case - optimize */ 1405 /* FIXME: this is for the worst case - optimize */
1406 set_opcr_overhead_id(opcr, 0); 1406 set_opcr_overhead_id(opcr, 0);
1407 1407
1408 /* 1408 /* FIXME: allocate isochronous channel and bandwidth at IRM */
1409 * FIXME: allocate isochronous channel and bandwidth at IRM
1410 * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
1411 */
1412 } 1409 }
1413 1410
1414 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1); 1411 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
@@ -1424,8 +1421,6 @@ repeat:
1424 /* 1421 /*
1425 * FIXME: if old_opcr.P2P_Connections > 0, 1422 * FIXME: if old_opcr.P2P_Connections > 0,
1426 * deallocate isochronous channel and bandwidth at IRM 1423 * deallocate isochronous channel and bandwidth at IRM
1427 * if (...)
1428 * fdtv->backend->dealloc_resources(fdtv, channel, bw);
1429 */ 1424 */
1430 1425
1431 if (++attempts < 6) /* arbitrary limit */ 1426 if (++attempts < 6) /* arbitrary limit */
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 079e8c5b0475..fd8bbbfa5c59 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -14,14 +14,9 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/mod_devicetable.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/mutex.h> 18#include <linux/mutex.h>
20#include <linux/slab.h>
21#include <linux/string.h>
22#include <linux/types.h> 19#include <linux/types.h>
23#include <linux/wait.h>
24#include <linux/workqueue.h>
25 20
26#include <dmxdev.h> 21#include <dmxdev.h>
27#include <dvb_demux.h> 22#include <dvb_demux.h>
@@ -166,11 +161,11 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
166 161
167DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 162DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
168 163
169int fdtv_dvb_register(struct firedtv *fdtv) 164int fdtv_dvb_register(struct firedtv *fdtv, const char *name)
170{ 165{
171 int err; 166 int err;
172 167
173 err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], 168 err = dvb_register_adapter(&fdtv->adapter, name,
174 THIS_MODULE, fdtv->device, adapter_nr); 169 THIS_MODULE, fdtv->device, adapter_nr);
175 if (err < 0) 170 if (err < 0)
176 goto fail_log; 171 goto fail_log;
@@ -210,7 +205,7 @@ int fdtv_dvb_register(struct firedtv *fdtv)
210 205
211 dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); 206 dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
212 207
213 fdtv_frontend_init(fdtv); 208 fdtv_frontend_init(fdtv, name);
214 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); 209 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
215 if (err) 210 if (err)
216 goto fail_net_release; 211 goto fail_net_release;
@@ -248,127 +243,3 @@ void fdtv_dvb_unregister(struct firedtv *fdtv)
248 dvb_dmx_release(&fdtv->demux); 243 dvb_dmx_release(&fdtv->demux);
249 dvb_unregister_adapter(&fdtv->adapter); 244 dvb_unregister_adapter(&fdtv->adapter);
250} 245}
251
252const char *fdtv_model_names[] = {
253 [FIREDTV_UNKNOWN] = "unknown type",
254 [FIREDTV_DVB_S] = "FireDTV S/CI",
255 [FIREDTV_DVB_C] = "FireDTV C/CI",
256 [FIREDTV_DVB_T] = "FireDTV T/CI",
257 [FIREDTV_DVB_S2] = "FireDTV S2 ",
258};
259
260struct firedtv *fdtv_alloc(struct device *dev,
261 const struct firedtv_backend *backend,
262 const char *name, size_t name_len)
263{
264 struct firedtv *fdtv;
265 int i;
266
267 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
268 if (!fdtv)
269 return NULL;
270
271 dev_set_drvdata(dev, fdtv);
272 fdtv->device = dev;
273 fdtv->isochannel = -1;
274 fdtv->voltage = 0xff;
275 fdtv->tone = 0xff;
276 fdtv->backend = backend;
277
278 mutex_init(&fdtv->avc_mutex);
279 init_waitqueue_head(&fdtv->avc_wait);
280 mutex_init(&fdtv->demux_mutex);
281 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
282
283 for (i = ARRAY_SIZE(fdtv_model_names); --i; )
284 if (strlen(fdtv_model_names[i]) <= name_len &&
285 strncmp(name, fdtv_model_names[i], name_len) == 0)
286 break;
287 fdtv->type = i;
288
289 return fdtv;
290}
291
292#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
293 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
294
295#define DIGITAL_EVERYWHERE_OUI 0x001287
296#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
297#define AVC_SW_VERSION_ENTRY 0x010001
298
299const struct ieee1394_device_id fdtv_id_table[] = {
300 {
301 /* FloppyDTV S/CI and FloppyDTV S2 */
302 .match_flags = MATCH_FLAGS,
303 .vendor_id = DIGITAL_EVERYWHERE_OUI,
304 .model_id = 0x000024,
305 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
306 .version = AVC_SW_VERSION_ENTRY,
307 }, {
308 /* FloppyDTV T/CI */
309 .match_flags = MATCH_FLAGS,
310 .vendor_id = DIGITAL_EVERYWHERE_OUI,
311 .model_id = 0x000025,
312 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
313 .version = AVC_SW_VERSION_ENTRY,
314 }, {
315 /* FloppyDTV C/CI */
316 .match_flags = MATCH_FLAGS,
317 .vendor_id = DIGITAL_EVERYWHERE_OUI,
318 .model_id = 0x000026,
319 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
320 .version = AVC_SW_VERSION_ENTRY,
321 }, {
322 /* FireDTV S/CI and FloppyDTV S2 */
323 .match_flags = MATCH_FLAGS,
324 .vendor_id = DIGITAL_EVERYWHERE_OUI,
325 .model_id = 0x000034,
326 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
327 .version = AVC_SW_VERSION_ENTRY,
328 }, {
329 /* FireDTV T/CI */
330 .match_flags = MATCH_FLAGS,
331 .vendor_id = DIGITAL_EVERYWHERE_OUI,
332 .model_id = 0x000035,
333 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
334 .version = AVC_SW_VERSION_ENTRY,
335 }, {
336 /* FireDTV C/CI */
337 .match_flags = MATCH_FLAGS,
338 .vendor_id = DIGITAL_EVERYWHERE_OUI,
339 .model_id = 0x000036,
340 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
341 .version = AVC_SW_VERSION_ENTRY,
342 }, {}
343};
344MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
345
346static int __init fdtv_init(void)
347{
348 int ret;
349
350 ret = fdtv_fw_init();
351 if (ret < 0)
352 return ret;
353
354 ret = fdtv_1394_init();
355 if (ret < 0)
356 fdtv_fw_exit();
357
358 return ret;
359}
360
361static void __exit fdtv_exit(void)
362{
363 fdtv_1394_exit();
364 fdtv_fw_exit();
365}
366
367module_init(fdtv_init);
368module_exit(fdtv_exit);
369
370MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
371MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
372MODULE_DESCRIPTION("FireDTV DVB Driver");
373MODULE_LICENSE("GPL");
374MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c
index d10920e2f3a2..8748a61be73d 100644
--- a/drivers/media/dvb/firewire/firedtv-fe.c
+++ b/drivers/media/dvb/firewire/firedtv-fe.c
@@ -36,14 +36,14 @@ static int fdtv_dvb_init(struct dvb_frontend *fe)
36 return err; 36 return err;
37 } 37 }
38 38
39 return fdtv->backend->start_iso(fdtv); 39 return fdtv_start_iso(fdtv);
40} 40}
41 41
42static int fdtv_sleep(struct dvb_frontend *fe) 42static int fdtv_sleep(struct dvb_frontend *fe)
43{ 43{
44 struct firedtv *fdtv = fe->sec_priv; 44 struct firedtv *fdtv = fe->sec_priv;
45 45
46 fdtv->backend->stop_iso(fdtv); 46 fdtv_stop_iso(fdtv);
47 cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); 47 cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
48 fdtv->isochannel = -1; 48 fdtv->isochannel = -1;
49 return 0; 49 return 0;
@@ -165,7 +165,7 @@ static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp)
165 return 0; 165 return 0;
166} 166}
167 167
168void fdtv_frontend_init(struct firedtv *fdtv) 168void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
169{ 169{
170 struct dvb_frontend_ops *ops = &fdtv->fe.ops; 170 struct dvb_frontend_ops *ops = &fdtv->fe.ops;
171 struct dvb_frontend_info *fi = &ops->info; 171 struct dvb_frontend_info *fi = &ops->info;
@@ -266,7 +266,7 @@ void fdtv_frontend_init(struct firedtv *fdtv)
266 dev_err(fdtv->device, "no frontend for model type %d\n", 266 dev_err(fdtv->device, "no frontend for model type %d\n",
267 fdtv->type); 267 fdtv->type);
268 } 268 }
269 strcpy(fi->name, fdtv_model_names[fdtv->type]); 269 strcpy(fi->name, name);
270 270
271 fdtv->fe.dvb = &fdtv->adapter; 271 fdtv->fe.dvb = &fdtv->adapter;
272 fdtv->fe.sec_priv = fdtv; 272 fdtv->fe.sec_priv = fdtv;
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
index 7424b0493f9d..8022b743af91 100644
--- a/drivers/media/dvb/firewire/firedtv-fw.c
+++ b/drivers/media/dvb/firewire/firedtv-fw.c
@@ -9,11 +9,18 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/list.h> 10#include <linux/list.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/mod_devicetable.h>
13#include <linux/module.h>
14#include <linux/mutex.h>
12#include <linux/slab.h> 15#include <linux/slab.h>
13#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/string.h>
14#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/wait.h>
20#include <linux/workqueue.h>
15 21
16#include <asm/page.h> 22#include <asm/page.h>
23#include <asm/system.h>
17 24
18#include <dvb_demux.h> 25#include <dvb_demux.h>
19 26
@@ -41,17 +48,17 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
41 return rcode != RCODE_COMPLETE ? -EIO : 0; 48 return rcode != RCODE_COMPLETE ? -EIO : 0;
42} 49}
43 50
44static int node_lock(struct firedtv *fdtv, u64 addr, void *data) 51int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data)
45{ 52{
46 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); 53 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
47} 54}
48 55
49static int node_read(struct firedtv *fdtv, u64 addr, void *data) 56int fdtv_read(struct firedtv *fdtv, u64 addr, void *data)
50{ 57{
51 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST); 58 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
52} 59}
53 60
54static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) 61int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
55{ 62{
56 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST); 63 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
57} 64}
@@ -67,7 +74,7 @@ static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
67#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE) 74#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
68#define IRQ_INTERVAL 16 75#define IRQ_INTERVAL 16
69 76
70struct firedtv_receive_context { 77struct fdtv_ir_context {
71 struct fw_iso_context *context; 78 struct fw_iso_context *context;
72 struct fw_iso_buffer buffer; 79 struct fw_iso_buffer buffer;
73 int interrupt_packet; 80 int interrupt_packet;
@@ -75,7 +82,7 @@ struct firedtv_receive_context {
75 char *pages[N_PAGES]; 82 char *pages[N_PAGES];
76}; 83};
77 84
78static int queue_iso(struct firedtv_receive_context *ctx, int index) 85static int queue_iso(struct fdtv_ir_context *ctx, int index)
79{ 86{
80 struct fw_iso_packet p; 87 struct fw_iso_packet p;
81 88
@@ -92,7 +99,7 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
92 size_t header_length, void *header, void *data) 99 size_t header_length, void *header, void *data)
93{ 100{
94 struct firedtv *fdtv = data; 101 struct firedtv *fdtv = data;
95 struct firedtv_receive_context *ctx = fdtv->backend_data; 102 struct fdtv_ir_context *ctx = fdtv->ir_context;
96 __be32 *h, *h_end; 103 __be32 *h, *h_end;
97 int length, err, i = ctx->current_packet; 104 int length, err, i = ctx->current_packet;
98 char *p, *p_end; 105 char *p, *p_end;
@@ -121,9 +128,9 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
121 ctx->current_packet = i; 128 ctx->current_packet = i;
122} 129}
123 130
124static int start_iso(struct firedtv *fdtv) 131int fdtv_start_iso(struct firedtv *fdtv)
125{ 132{
126 struct firedtv_receive_context *ctx; 133 struct fdtv_ir_context *ctx;
127 struct fw_device *device = device_of(fdtv); 134 struct fw_device *device = device_of(fdtv);
128 int i, err; 135 int i, err;
129 136
@@ -161,7 +168,7 @@ static int start_iso(struct firedtv *fdtv)
161 if (err) 168 if (err)
162 goto fail; 169 goto fail;
163 170
164 fdtv->backend_data = ctx; 171 fdtv->ir_context = ctx;
165 172
166 return 0; 173 return 0;
167fail: 174fail:
@@ -174,9 +181,9 @@ fail_free:
174 return err; 181 return err;
175} 182}
176 183
177static void stop_iso(struct firedtv *fdtv) 184void fdtv_stop_iso(struct firedtv *fdtv)
178{ 185{
179 struct firedtv_receive_context *ctx = fdtv->backend_data; 186 struct fdtv_ir_context *ctx = fdtv->ir_context;
180 187
181 fw_iso_context_stop(ctx->context); 188 fw_iso_context_stop(ctx->context);
182 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card); 189 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
@@ -184,14 +191,6 @@ static void stop_iso(struct firedtv *fdtv)
184 kfree(ctx); 191 kfree(ctx);
185} 192}
186 193
187static const struct firedtv_backend backend = {
188 .lock = node_lock,
189 .read = node_read,
190 .write = node_write,
191 .start_iso = start_iso,
192 .stop_iso = stop_iso,
193};
194
195static void handle_fcp(struct fw_card *card, struct fw_request *request, 194static void handle_fcp(struct fw_card *card, struct fw_request *request,
196 int tcode, int destination, int source, int generation, 195 int tcode, int destination, int source, int generation,
197 unsigned long long offset, void *payload, size_t length, 196 unsigned long long offset, void *payload, size_t length,
@@ -238,6 +237,14 @@ static const struct fw_address_region fcp_region = {
238 .end = CSR_REGISTER_BASE + CSR_FCP_END, 237 .end = CSR_REGISTER_BASE + CSR_FCP_END,
239}; 238};
240 239
240static const char * const model_names[] = {
241 [FIREDTV_UNKNOWN] = "unknown type",
242 [FIREDTV_DVB_S] = "FireDTV S/CI",
243 [FIREDTV_DVB_C] = "FireDTV C/CI",
244 [FIREDTV_DVB_T] = "FireDTV T/CI",
245 [FIREDTV_DVB_S2] = "FireDTV S2 ",
246};
247
241/* Adjust the template string if models with longer names appear. */ 248/* Adjust the template string if models with longer names appear. */
242#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????") 249#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
243 250
@@ -245,15 +252,31 @@ static int node_probe(struct device *dev)
245{ 252{
246 struct firedtv *fdtv; 253 struct firedtv *fdtv;
247 char name[MAX_MODEL_NAME_LEN]; 254 char name[MAX_MODEL_NAME_LEN];
248 int name_len, err; 255 int name_len, i, err;
249
250 name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
251 name, sizeof(name));
252 256
253 fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0); 257 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
254 if (!fdtv) 258 if (!fdtv)
255 return -ENOMEM; 259 return -ENOMEM;
256 260
261 dev_set_drvdata(dev, fdtv);
262 fdtv->device = dev;
263 fdtv->isochannel = -1;
264 fdtv->voltage = 0xff;
265 fdtv->tone = 0xff;
266
267 mutex_init(&fdtv->avc_mutex);
268 init_waitqueue_head(&fdtv->avc_wait);
269 mutex_init(&fdtv->demux_mutex);
270 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
271
272 name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
273 name, sizeof(name));
274 for (i = ARRAY_SIZE(model_names); --i; )
275 if (strlen(model_names[i]) <= name_len &&
276 strncmp(name, model_names[i], name_len) == 0)
277 break;
278 fdtv->type = i;
279
257 err = fdtv_register_rc(fdtv, dev); 280 err = fdtv_register_rc(fdtv, dev);
258 if (err) 281 if (err)
259 goto fail_free; 282 goto fail_free;
@@ -266,7 +289,7 @@ static int node_probe(struct device *dev)
266 if (err) 289 if (err)
267 goto fail; 290 goto fail;
268 291
269 err = fdtv_dvb_register(fdtv); 292 err = fdtv_dvb_register(fdtv, model_names[fdtv->type]);
270 if (err) 293 if (err)
271 goto fail; 294 goto fail;
272 295
@@ -309,6 +332,60 @@ static void node_update(struct fw_unit *unit)
309 fdtv->isochannel); 332 fdtv->isochannel);
310} 333}
311 334
335#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
336 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
337
338#define DIGITAL_EVERYWHERE_OUI 0x001287
339#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
340#define AVC_SW_VERSION_ENTRY 0x010001
341
342static const struct ieee1394_device_id fdtv_id_table[] = {
343 {
344 /* FloppyDTV S/CI and FloppyDTV S2 */
345 .match_flags = MATCH_FLAGS,
346 .vendor_id = DIGITAL_EVERYWHERE_OUI,
347 .model_id = 0x000024,
348 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
349 .version = AVC_SW_VERSION_ENTRY,
350 }, {
351 /* FloppyDTV T/CI */
352 .match_flags = MATCH_FLAGS,
353 .vendor_id = DIGITAL_EVERYWHERE_OUI,
354 .model_id = 0x000025,
355 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
356 .version = AVC_SW_VERSION_ENTRY,
357 }, {
358 /* FloppyDTV C/CI */
359 .match_flags = MATCH_FLAGS,
360 .vendor_id = DIGITAL_EVERYWHERE_OUI,
361 .model_id = 0x000026,
362 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
363 .version = AVC_SW_VERSION_ENTRY,
364 }, {
365 /* FireDTV S/CI and FloppyDTV S2 */
366 .match_flags = MATCH_FLAGS,
367 .vendor_id = DIGITAL_EVERYWHERE_OUI,
368 .model_id = 0x000034,
369 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
370 .version = AVC_SW_VERSION_ENTRY,
371 }, {
372 /* FireDTV T/CI */
373 .match_flags = MATCH_FLAGS,
374 .vendor_id = DIGITAL_EVERYWHERE_OUI,
375 .model_id = 0x000035,
376 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
377 .version = AVC_SW_VERSION_ENTRY,
378 }, {
379 /* FireDTV C/CI */
380 .match_flags = MATCH_FLAGS,
381 .vendor_id = DIGITAL_EVERYWHERE_OUI,
382 .model_id = 0x000036,
383 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
384 .version = AVC_SW_VERSION_ENTRY,
385 }, {}
386};
387MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
388
312static struct fw_driver fdtv_driver = { 389static struct fw_driver fdtv_driver = {
313 .driver = { 390 .driver = {
314 .owner = THIS_MODULE, 391 .owner = THIS_MODULE,
@@ -321,7 +398,7 @@ static struct fw_driver fdtv_driver = {
321 .id_table = fdtv_id_table, 398 .id_table = fdtv_id_table,
322}; 399};
323 400
324int __init fdtv_fw_init(void) 401static int __init fdtv_init(void)
325{ 402{
326 int ret; 403 int ret;
327 404
@@ -329,11 +406,24 @@ int __init fdtv_fw_init(void)
329 if (ret < 0) 406 if (ret < 0)
330 return ret; 407 return ret;
331 408
332 return driver_register(&fdtv_driver.driver); 409 ret = driver_register(&fdtv_driver.driver);
410 if (ret < 0)
411 fw_core_remove_address_handler(&fcp_handler);
412
413 return ret;
333} 414}
334 415
335void fdtv_fw_exit(void) 416static void __exit fdtv_exit(void)
336{ 417{
337 driver_unregister(&fdtv_driver.driver); 418 driver_unregister(&fdtv_driver.driver);
338 fw_core_remove_address_handler(&fcp_handler); 419 fw_core_remove_address_handler(&fcp_handler);
339} 420}
421
422module_init(fdtv_init);
423module_exit(fdtv_exit);
424
425MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
426MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
427MODULE_DESCRIPTION("FireDTV DVB Driver");
428MODULE_LICENSE("GPL");
429MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
index 78cc28f36914..bd00b04e079d 100644
--- a/drivers/media/dvb/firewire/firedtv.h
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -70,15 +70,7 @@ enum model_type {
70 70
71struct device; 71struct device;
72struct input_dev; 72struct input_dev;
73struct firedtv; 73struct fdtv_ir_context;
74
75struct firedtv_backend {
76 int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
77 int (*read)(struct firedtv *fdtv, u64 addr, void *data);
78 int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
79 int (*start_iso)(struct firedtv *fdtv);
80 void (*stop_iso)(struct firedtv *fdtv);
81};
82 74
83struct firedtv { 75struct firedtv {
84 struct device *device; 76 struct device *device;
@@ -104,12 +96,11 @@ struct firedtv {
104 enum model_type type; 96 enum model_type type;
105 char subunit; 97 char subunit;
106 char isochannel; 98 char isochannel;
99 struct fdtv_ir_context *ir_context;
100
107 fe_sec_voltage_t voltage; 101 fe_sec_voltage_t voltage;
108 fe_sec_tone_mode_t tone; 102 fe_sec_tone_mode_t tone;
109 103
110 const struct firedtv_backend *backend;
111 void *backend_data;
112
113 struct mutex demux_mutex; 104 struct mutex demux_mutex;
114 unsigned long channel_active; 105 unsigned long channel_active;
115 u16 channel_pid[16]; 106 u16 channel_pid[16];
@@ -118,15 +109,6 @@ struct firedtv {
118 u8 avc_data[512]; 109 u8 avc_data[512];
119}; 110};
120 111
121/* firedtv-1394.c */
122#ifdef CONFIG_DVB_FIREDTV_IEEE1394
123int fdtv_1394_init(void);
124void fdtv_1394_exit(void);
125#else
126static inline int fdtv_1394_init(void) { return 0; }
127static inline void fdtv_1394_exit(void) {}
128#endif
129
130/* firedtv-avc.c */ 112/* firedtv-avc.c */
131int avc_recv(struct firedtv *fdtv, void *data, size_t length); 113int avc_recv(struct firedtv *fdtv, void *data, size_t length);
132int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); 114int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat);
@@ -158,25 +140,18 @@ void fdtv_ca_release(struct firedtv *fdtv);
158/* firedtv-dvb.c */ 140/* firedtv-dvb.c */
159int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); 141int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
160int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); 142int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
161int fdtv_dvb_register(struct firedtv *fdtv); 143int fdtv_dvb_register(struct firedtv *fdtv, const char *name);
162void fdtv_dvb_unregister(struct firedtv *fdtv); 144void fdtv_dvb_unregister(struct firedtv *fdtv);
163struct firedtv *fdtv_alloc(struct device *dev,
164 const struct firedtv_backend *backend,
165 const char *name, size_t name_len);
166extern const char *fdtv_model_names[];
167extern const struct ieee1394_device_id fdtv_id_table[];
168 145
169/* firedtv-fe.c */ 146/* firedtv-fe.c */
170void fdtv_frontend_init(struct firedtv *fdtv); 147void fdtv_frontend_init(struct firedtv *fdtv, const char *name);
171 148
172/* firedtv-fw.c */ 149/* firedtv-fw.c */
173#ifdef CONFIG_DVB_FIREDTV_FIREWIRE 150int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data);
174int fdtv_fw_init(void); 151int fdtv_read(struct firedtv *fdtv, u64 addr, void *data);
175void fdtv_fw_exit(void); 152int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len);
176#else 153int fdtv_start_iso(struct firedtv *fdtv);
177static inline int fdtv_fw_init(void) { return 0; } 154void fdtv_stop_iso(struct firedtv *fdtv);
178static inline void fdtv_fw_exit(void) {}
179#endif
180 155
181/* firedtv-rc.c */ 156/* firedtv-rc.c */
182#ifdef CONFIG_DVB_FIREDTV_INPUT 157#ifdef CONFIG_DVB_FIREDTV_INPUT
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b8519ba511e5..83093d1f4f74 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -349,6 +349,14 @@ config DVB_DIB7000P
349 A DVB-T tuner module. Designed for mobile usage. Say Y when you want 349 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
350 to support this frontend. 350 to support this frontend.
351 351
352config DVB_DIB9000
353 tristate "DiBcom 9000"
354 depends on DVB_CORE && I2C
355 default m if DVB_FE_CUSTOMISE
356 help
357 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
358 to support this frontend.
359
352config DVB_TDA10048 360config DVB_TDA10048
353 tristate "Philips TDA10048HN based" 361 tristate "Philips TDA10048HN based"
354 depends on DVB_CORE && I2C 362 depends on DVB_CORE && I2C
@@ -370,6 +378,13 @@ config DVB_EC100
370 help 378 help
371 Say Y when you want to support this frontend. 379 Say Y when you want to support this frontend.
372 380
381config DVB_STV0367
382 tristate "ST STV0367 based"
383 depends on DVB_CORE && I2C
384 default m if DVB_FE_CUSTOMISE
385 help
386 A DVB-T/C tuner module. Say Y when you want to support this frontend.
387
373comment "DVB-C (cable) frontends" 388comment "DVB-C (cable) frontends"
374 depends on DVB_CORE 389 depends on DVB_CORE
375 390
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index b1d9525aa7e3..3b0c4bdc4b2b 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
24obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o 24obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
25obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o 25obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
26obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o 26obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
27obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
27obj-$(CONFIG_DVB_MT312) += mt312.o 28obj-$(CONFIG_DVB_MT312) += mt312.o
28obj-$(CONFIG_DVB_VES1820) += ves1820.o 29obj-$(CONFIG_DVB_VES1820) += ves1820.o
29obj-$(CONFIG_DVB_VES1X93) += ves1x93.o 30obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -83,3 +84,4 @@ obj-$(CONFIG_DVB_DS3000) += ds3000.o
83obj-$(CONFIG_DVB_MB86A16) += mb86a16.o 84obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
84obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o 85obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
85obj-$(CONFIG_DVB_IX2505V) += ix2505v.o 86obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
87obj-$(CONFIG_DVB_STV0367) += stv0367.o
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index ba25fa0b0fc2..345311c33383 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -1323,13 +1323,11 @@ static struct dvb_frontend_ops af9013_ops;
1323 1323
1324static int af9013_download_firmware(struct af9013_state *state) 1324static int af9013_download_firmware(struct af9013_state *state)
1325{ 1325{
1326 int i, len, packets, remainder, ret; 1326 int i, len, remaining, ret;
1327 const struct firmware *fw; 1327 const struct firmware *fw;
1328 u16 addr = 0x5100; /* firmware start address */
1329 u16 checksum = 0; 1328 u16 checksum = 0;
1330 u8 val; 1329 u8 val;
1331 u8 fw_params[4]; 1330 u8 fw_params[4];
1332 u8 *data;
1333 u8 *fw_file = AF9013_DEFAULT_FIRMWARE; 1331 u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
1334 1332
1335 msleep(100); 1333 msleep(100);
@@ -1373,21 +1371,18 @@ static int af9013_download_firmware(struct af9013_state *state)
1373 if (ret) 1371 if (ret)
1374 goto error_release; 1372 goto error_release;
1375 1373
1376 #define FW_PACKET_MAX_DATA 16 1374 #define FW_ADDR 0x5100 /* firmware start address */
1377 1375 #define LEN_MAX 16 /* max packet size */
1378 packets = fw->size / FW_PACKET_MAX_DATA; 1376 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
1379 remainder = fw->size % FW_PACKET_MAX_DATA; 1377 len = remaining;
1380 len = FW_PACKET_MAX_DATA; 1378 if (len > LEN_MAX)
1381 for (i = 0; i <= packets; i++) { 1379 len = LEN_MAX;
1382 if (i == packets) /* set size of the last packet */
1383 len = remainder;
1384
1385 data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
1386 ret = af9013_write_ofsm_regs(state, addr, data, len);
1387 addr += FW_PACKET_MAX_DATA;
1388 1380
1381 ret = af9013_write_ofsm_regs(state,
1382 FW_ADDR + fw->size - remaining,
1383 (u8 *) &fw->data[fw->size - remaining], len);
1389 if (ret) { 1384 if (ret) {
1390 err("firmware download failed at %d with %d", i, ret); 1385 err("firmware download failed:%d", ret);
1391 goto error_release; 1386 goto error_release;
1392 } 1387 }
1393 } 1388 }
@@ -1466,20 +1461,6 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
1466 state->i2c = i2c; 1461 state->i2c = i2c;
1467 memcpy(&state->config, config, sizeof(struct af9013_config)); 1462 memcpy(&state->config, config, sizeof(struct af9013_config));
1468 1463
1469 /* chip version */
1470 ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
1471 if (ret)
1472 goto error;
1473
1474 /* ROM version */
1475 for (i = 0; i < 2; i++) {
1476 ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
1477 if (ret)
1478 goto error;
1479 }
1480 deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
1481 buf[2], buf[0], buf[1]);
1482
1483 /* download firmware */ 1464 /* download firmware */
1484 if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { 1465 if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) {
1485 ret = af9013_download_firmware(state); 1466 ret = af9013_download_firmware(state);
@@ -1495,6 +1476,20 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
1495 } 1476 }
1496 info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]); 1477 info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);
1497 1478
1479 /* chip version */
1480 ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
1481 if (ret)
1482 goto error;
1483
1484 /* ROM version */
1485 for (i = 0; i < 2; i++) {
1486 ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
1487 if (ret)
1488 goto error;
1489 }
1490 deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
1491 buf[2], buf[0], buf[1]);
1492
1498 /* settings for mp2if */ 1493 /* settings for mp2if */
1499 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { 1494 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) {
1500 /* AF9015 split PSB to 1.5k + 0.5k */ 1495 /* AF9015 split PSB to 1.5k + 0.5k */
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index 65240b7801e8..52ff1a252a90 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -45,6 +45,7 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
45 } \ 45 } \
46} while (0) 46} while (0)
47 47
48#define CONFIG_SYS_DVBT
48#define CONFIG_SYS_ISDBT 49#define CONFIG_SYS_ISDBT
49#define CONFIG_BAND_CBAND 50#define CONFIG_BAND_CBAND
50#define CONFIG_BAND_VHF 51#define CONFIG_BAND_VHF
@@ -76,6 +77,34 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
76#define EN_SBD 0x44E9 77#define EN_SBD 0x44E9
77#define EN_CAB 0x88E9 78#define EN_CAB 0x88E9
78 79
80/* Calibration defines */
81#define DC_CAL 0x1
82#define WBD_CAL 0x2
83#define TEMP_CAL 0x4
84#define CAPTRIM_CAL 0x8
85
86#define KROSUS_PLL_LOCKED 0x800
87#define KROSUS 0x2
88
89/* Use those defines to identify SOC version */
90#define SOC 0x02
91#define SOC_7090_P1G_11R1 0x82
92#define SOC_7090_P1G_21R1 0x8a
93#define SOC_8090_P1G_11R1 0x86
94#define SOC_8090_P1G_21R1 0x8e
95
96/* else use thos ones to check */
97#define P1A_B 0x0
98#define P1C 0x1
99#define P1D_E_F 0x3
100#define P1G 0x7
101#define P1G_21R2 0xf
102
103#define MP001 0x1 /* Single 9090/8096 */
104#define MP005 0x4 /* Single Sband */
105#define MP008 0x6 /* Dual diversity VHF-UHF-LBAND */
106#define MP009 0x7 /* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
107
79#define pgm_read_word(w) (*w) 108#define pgm_read_word(w) (*w)
80 109
81struct dc_calibration; 110struct dc_calibration;
@@ -84,7 +113,7 @@ struct dib0090_tuning {
84 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 113 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
85 u8 switch_trim; 114 u8 switch_trim;
86 u8 lna_tune; 115 u8 lna_tune;
87 u8 lna_bias; 116 u16 lna_bias;
88 u16 v2i; 117 u16 v2i;
89 u16 mix; 118 u16 mix;
90 u16 load; 119 u16 load;
@@ -99,13 +128,19 @@ struct dib0090_pll {
99 u8 topresc; 128 u8 topresc;
100}; 129};
101 130
131struct dib0090_identity {
132 u8 version;
133 u8 product;
134 u8 p1g;
135 u8 in_soc;
136};
137
102struct dib0090_state { 138struct dib0090_state {
103 struct i2c_adapter *i2c; 139 struct i2c_adapter *i2c;
104 struct dvb_frontend *fe; 140 struct dvb_frontend *fe;
105 const struct dib0090_config *config; 141 const struct dib0090_config *config;
106 142
107 u8 current_band; 143 u8 current_band;
108 u16 revision;
109 enum frontend_tune_state tune_state; 144 enum frontend_tune_state tune_state;
110 u32 current_rf; 145 u32 current_rf;
111 146
@@ -143,7 +178,26 @@ struct dib0090_state {
143 u8 tuner_is_tuned; 178 u8 tuner_is_tuned;
144 u8 agc_freeze; 179 u8 agc_freeze;
145 180
146 u8 reset; 181 struct dib0090_identity identity;
182
183 u32 rf_request;
184 u8 current_standard;
185
186 u8 calibrate;
187 u32 rest;
188 u16 bias;
189 s16 temperature;
190
191 u8 wbd_calibration_gain;
192 const struct dib0090_wbd_slope *current_wbd_table;
193 u16 wbdmux;
194};
195
196struct dib0090_fw_state {
197 struct i2c_adapter *i2c;
198 struct dvb_frontend *fe;
199 struct dib0090_identity identity;
200 const struct dib0090_config *config;
147}; 201};
148 202
149static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) 203static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
@@ -171,6 +225,28 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
171 return 0; 225 return 0;
172} 226}
173 227
228static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
229{
230 u8 b[2];
231 struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 };
232 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
233 printk(KERN_WARNING "DiB0090 I2C read failed\n");
234 return 0;
235 }
236 return (b[0] << 8) | b[1];
237}
238
239static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
240{
241 u8 b[2] = { val >> 8, val & 0xff };
242 struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 };
243 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
244 printk(KERN_WARNING "DiB0090 I2C write failed\n");
245 return -EREMOTEIO;
246 }
247 return 0;
248}
249
174#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0) 250#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0)
175#define ADC_TARGET -220 251#define ADC_TARGET -220
176#define GAIN_ALPHA 5 252#define GAIN_ALPHA 5
@@ -183,89 +259,327 @@ static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b,
183 } while (--c); 259 } while (--c);
184} 260}
185 261
186static u16 dib0090_identify(struct dvb_frontend *fe) 262static int dib0090_identify(struct dvb_frontend *fe)
187{ 263{
188 struct dib0090_state *state = fe->tuner_priv; 264 struct dib0090_state *state = fe->tuner_priv;
189 u16 v; 265 u16 v;
266 struct dib0090_identity *identity = &state->identity;
190 267
191 v = dib0090_read_reg(state, 0x1a); 268 v = dib0090_read_reg(state, 0x1a);
192 269
193#ifdef FIRMWARE_FIREFLY 270 identity->p1g = 0;
194 /* pll is not locked locked */ 271 identity->in_soc = 0;
195 if (!(v & 0x800)) 272
196 dprintk("FE%d : Identification : pll is not yet locked", fe->id); 273 dprintk("Tuner identification (Version = 0x%04x)", v);
197#endif
198 274
199 /* without PLL lock info */ 275 /* without PLL lock info */
200 v &= 0x3ff; 276 v &= ~KROSUS_PLL_LOCKED;
201 dprintk("P/V: %04x:", v);
202 277
203 if ((v >> 8) & 0xf) 278 identity->version = v & 0xff;
204 dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf); 279 identity->product = (v >> 8) & 0xf;
205 else 280
206 return 0xff; 281 if (identity->product != KROSUS)
207 282 goto identification_error;
208 v &= 0xff; 283
209 if (((v >> 5) & 0x7) == 0x1) 284 if ((identity->version & 0x3) == SOC) {
210 dprintk("FE%d : MP001 : 9090/8096", fe->id); 285 identity->in_soc = 1;
211 else if (((v >> 5) & 0x7) == 0x4) 286 switch (identity->version) {
212 dprintk("FE%d : MP005 : Single Sband", fe->id); 287 case SOC_8090_P1G_11R1:
213 else if (((v >> 5) & 0x7) == 0x6) 288 dprintk("SOC 8090 P1-G11R1 Has been detected");
214 dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id); 289 identity->p1g = 1;
215 else if (((v >> 5) & 0x7) == 0x7) 290 break;
216 dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id); 291 case SOC_8090_P1G_21R1:
217 else 292 dprintk("SOC 8090 P1-G21R1 Has been detected");
218 return 0xff; 293 identity->p1g = 1;
219 294 break;
220 /* revision only */ 295 case SOC_7090_P1G_11R1:
221 if ((v & 0x1f) == 0x3) 296 dprintk("SOC 7090 P1-G11R1 Has been detected");
222 dprintk("FE%d : P1-D/E/F detected", fe->id); 297 identity->p1g = 1;
223 else if ((v & 0x1f) == 0x1) 298 break;
224 dprintk("FE%d : P1C detected", fe->id); 299 case SOC_7090_P1G_21R1:
225 else if ((v & 0x1f) == 0x0) { 300 dprintk("SOC 7090 P1-G21R1 Has been detected");
226#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT 301 identity->p1g = 1;
227 dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id); 302 break;
228 dib0090_p1b_register(fe); 303 default:
229#else 304 goto identification_error;
230 dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id); 305 }
231 return 0xff; 306 } else {
232#endif 307 switch ((identity->version >> 5) & 0x7) {
308 case MP001:
309 dprintk("MP001 : 9090/8096");
310 break;
311 case MP005:
312 dprintk("MP005 : Single Sband");
313 break;
314 case MP008:
315 dprintk("MP008 : diversity VHF-UHF-LBAND");
316 break;
317 case MP009:
318 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
319 break;
320 default:
321 goto identification_error;
322 }
323
324 switch (identity->version & 0x1f) {
325 case P1G_21R2:
326 dprintk("P1G_21R2 detected");
327 identity->p1g = 1;
328 break;
329 case P1G:
330 dprintk("P1G detected");
331 identity->p1g = 1;
332 break;
333 case P1D_E_F:
334 dprintk("P1D/E/F detected");
335 break;
336 case P1C:
337 dprintk("P1C detected");
338 break;
339 case P1A_B:
340 dprintk("P1-A/B detected: driver is deactivated - not available");
341 goto identification_error;
342 break;
343 default:
344 goto identification_error;
345 }
233 } 346 }
234 347
235 return v; 348 return 0;
349
350identification_error:
351 return -EIO;
352}
353
354static int dib0090_fw_identify(struct dvb_frontend *fe)
355{
356 struct dib0090_fw_state *state = fe->tuner_priv;
357 struct dib0090_identity *identity = &state->identity;
358
359 u16 v = dib0090_fw_read_reg(state, 0x1a);
360 identity->p1g = 0;
361 identity->in_soc = 0;
362
363 dprintk("FE: Tuner identification (Version = 0x%04x)", v);
364
365 /* without PLL lock info */
366 v &= ~KROSUS_PLL_LOCKED;
367
368 identity->version = v & 0xff;
369 identity->product = (v >> 8) & 0xf;
370
371 if (identity->product != KROSUS)
372 goto identification_error;
373
374 if ((identity->version & 0x3) == SOC) {
375 identity->in_soc = 1;
376 switch (identity->version) {
377 case SOC_8090_P1G_11R1:
378 dprintk("SOC 8090 P1-G11R1 Has been detected");
379 identity->p1g = 1;
380 break;
381 case SOC_8090_P1G_21R1:
382 dprintk("SOC 8090 P1-G21R1 Has been detected");
383 identity->p1g = 1;
384 break;
385 case SOC_7090_P1G_11R1:
386 dprintk("SOC 7090 P1-G11R1 Has been detected");
387 identity->p1g = 1;
388 break;
389 case SOC_7090_P1G_21R1:
390 dprintk("SOC 7090 P1-G21R1 Has been detected");
391 identity->p1g = 1;
392 break;
393 default:
394 goto identification_error;
395 }
396 } else {
397 switch ((identity->version >> 5) & 0x7) {
398 case MP001:
399 dprintk("MP001 : 9090/8096");
400 break;
401 case MP005:
402 dprintk("MP005 : Single Sband");
403 break;
404 case MP008:
405 dprintk("MP008 : diversity VHF-UHF-LBAND");
406 break;
407 case MP009:
408 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
409 break;
410 default:
411 goto identification_error;
412 }
413
414 switch (identity->version & 0x1f) {
415 case P1G_21R2:
416 dprintk("P1G_21R2 detected");
417 identity->p1g = 1;
418 break;
419 case P1G:
420 dprintk("P1G detected");
421 identity->p1g = 1;
422 break;
423 case P1D_E_F:
424 dprintk("P1D/E/F detected");
425 break;
426 case P1C:
427 dprintk("P1C detected");
428 break;
429 case P1A_B:
430 dprintk("P1-A/B detected: driver is deactivated - not available");
431 goto identification_error;
432 break;
433 default:
434 goto identification_error;
435 }
436 }
437
438 return 0;
439
440identification_error:
441 return -EIO;;
236} 442}
237 443
238static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) 444static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
239{ 445{
240 struct dib0090_state *state = fe->tuner_priv; 446 struct dib0090_state *state = fe->tuner_priv;
447 u16 PllCfg, i, v;
241 448
242 HARD_RESET(state); 449 HARD_RESET(state);
243 450
244 dib0090_write_reg(state, 0x24, EN_PLL); 451 dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
245 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */ 452 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
246 453
247 /* adcClkOutRatio=8->7, release reset */ 454 if (!cfg->in_soc) {
248 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0); 455 /* adcClkOutRatio=8->7, release reset */
456 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
457 if (cfg->clkoutdrive != 0)
458 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
459 | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
460 else
461 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
462 | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
463 }
464
465 /* Read Pll current config * */
466 PllCfg = dib0090_read_reg(state, 0x21);
467
468 /** Reconfigure PLL if current setting is different from default setting **/
469 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
470 && !cfg->io.pll_bypass) {
471
472 /* Set Bypass mode */
473 PllCfg |= (1 << 15);
474 dib0090_write_reg(state, 0x21, PllCfg);
475
476 /* Set Reset Pll */
477 PllCfg &= ~(1 << 13);
478 dib0090_write_reg(state, 0x21, PllCfg);
479
480 /*** Set new Pll configuration in bypass and reset state ***/
481 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
482 dib0090_write_reg(state, 0x21, PllCfg);
483
484 /* Remove Reset Pll */
485 PllCfg |= (1 << 13);
486 dib0090_write_reg(state, 0x21, PllCfg);
487
488 /*** Wait for PLL lock ***/
489 i = 100;
490 do {
491 v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
492 if (v)
493 break;
494 } while (--i);
495
496 if (i == 0) {
497 dprintk("Pll: Unable to lock Pll");
498 return;
499 }
500
501 /* Finally Remove Bypass mode */
502 PllCfg &= ~(1 << 15);
503 dib0090_write_reg(state, 0x21, PllCfg);
504 }
505
506 if (cfg->io.pll_bypass) {
507 PllCfg |= (cfg->io.pll_bypass << 15);
508 dib0090_write_reg(state, 0x21, PllCfg);
509 }
510}
511
512static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
513{
514 struct dib0090_fw_state *state = fe->tuner_priv;
515 u16 PllCfg;
516 u16 v;
517 int i;
518
519 dprintk("fw reset digital");
520 HARD_RESET(state);
521
522 dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
523 dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
524
525 dib0090_fw_write_reg(state, 0x20,
526 ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
527
528 v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
249 if (cfg->clkoutdrive != 0) 529 if (cfg->clkoutdrive != 0)
250 dib0090_write_reg(state, 0x23, 530 v |= cfg->clkoutdrive << 5;
251 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg->
252 clkouttobamse
253 << 4) | (0
254 <<
255 2)
256 | (0));
257 else 531 else
258 dib0090_write_reg(state, 0x23, 532 v |= 7 << 5;
259 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg-> 533
260 clkouttobamse << 4) | (0 534 v |= 2 << 10;
261 << 535 dib0090_fw_write_reg(state, 0x23, v);
262 2) 536
263 | (0)); 537 /* Read Pll current config * */
538 PllCfg = dib0090_fw_read_reg(state, 0x21);
539
540 /** Reconfigure PLL if current setting is different from default setting **/
541 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
264 542
265 /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */ 543 /* Set Bypass mode */
266 dib0090_write_reg(state, 0x21, 544 PllCfg |= (1 << 15);
267 (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)); 545 dib0090_fw_write_reg(state, 0x21, PllCfg);
268 546
547 /* Set Reset Pll */
548 PllCfg &= ~(1 << 13);
549 dib0090_fw_write_reg(state, 0x21, PllCfg);
550
551 /*** Set new Pll configuration in bypass and reset state ***/
552 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
553 dib0090_fw_write_reg(state, 0x21, PllCfg);
554
555 /* Remove Reset Pll */
556 PllCfg |= (1 << 13);
557 dib0090_fw_write_reg(state, 0x21, PllCfg);
558
559 /*** Wait for PLL lock ***/
560 i = 100;
561 do {
562 v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
563 if (v)
564 break;
565 } while (--i);
566
567 if (i == 0) {
568 dprintk("Pll: Unable to lock Pll");
569 return -EIO;
570 }
571
572 /* Finally Remove Bypass mode */
573 PllCfg &= ~(1 << 15);
574 dib0090_fw_write_reg(state, 0x21, PllCfg);
575 }
576
577 if (cfg->io.pll_bypass) {
578 PllCfg |= (cfg->io.pll_bypass << 15);
579 dib0090_fw_write_reg(state, 0x21, PllCfg);
580 }
581
582 return dib0090_fw_identify(fe);
269} 583}
270 584
271static int dib0090_wakeup(struct dvb_frontend *fe) 585static int dib0090_wakeup(struct dvb_frontend *fe)
@@ -273,6 +587,9 @@ static int dib0090_wakeup(struct dvb_frontend *fe)
273 struct dib0090_state *state = fe->tuner_priv; 587 struct dib0090_state *state = fe->tuner_priv;
274 if (state->config->sleep) 588 if (state->config->sleep)
275 state->config->sleep(fe, 0); 589 state->config->sleep(fe, 0);
590
591 /* enable dataTX in case we have been restarted in the wrong moment */
592 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
276 return 0; 593 return 0;
277} 594}
278 595
@@ -292,8 +609,75 @@ void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
292 else 609 else
293 dib0090_write_reg(state, 0x04, 1); 610 dib0090_write_reg(state, 0x04, 1);
294} 611}
612
295EXPORT_SYMBOL(dib0090_dcc_freq); 613EXPORT_SYMBOL(dib0090_dcc_freq);
296 614
615static const u16 bb_ramp_pwm_normal_socs[] = {
616 550, /* max BB gain in 10th of dB */
617 (1 << 9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
618 440,
619 (4 << 9) | 0, /* BB_RAMP3 = 26dB */
620 (0 << 9) | 208, /* BB_RAMP4 */
621 (4 << 9) | 208, /* BB_RAMP5 = 29dB */
622 (0 << 9) | 440, /* BB_RAMP6 */
623};
624
625static const u16 rf_ramp_pwm_cband_7090[] = {
626 280, /* max RF gain in 10th of dB */
627 18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
628 504, /* ramp_max = maximum X used on the ramp */
629 (29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
630 (0 << 10) | 504, /* RF_RAMP6, LNA 1 */
631 (60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
632 (0 << 10) | 364, /* RF_RAMP8, LNA 2 */
633 (34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
634 (0 << 10) | 228, /* GAIN_4_2, LNA 3 */
635 (37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
636 (0 << 10) | 109, /* RF_RAMP4, LNA 4 */
637};
638
639static const u16 rf_ramp_pwm_cband_8090[] = {
640 345, /* max RF gain in 10th of dB */
641 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
642 1000, /* ramp_max = maximum X used on the ramp */
643 (35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
644 (0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
645 (58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
646 (0 << 10) | 772, /* RF_RAMP6, LNA 2 */
647 (27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
648 (0 << 10) | 496, /* RF_RAMP8, LNA 3 */
649 (40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
650 (0 << 10) | 200, /* GAIN_4_2, LNA 4 */
651};
652
653static const u16 rf_ramp_pwm_uhf_7090[] = {
654 407, /* max RF gain in 10th of dB */
655 13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
656 529, /* ramp_max = maximum X used on the ramp */
657 (23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
658 (0 << 10) | 176, /* RF_RAMP4, LNA 1 */
659 (63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
660 (0 << 10) | 529, /* RF_RAMP6, LNA 2 */
661 (48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
662 (0 << 10) | 400, /* RF_RAMP8, LNA 3 */
663 (29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
664 (0 << 10) | 316, /* GAIN_4_2, LNA 4 */
665};
666
667static const u16 rf_ramp_pwm_uhf_8090[] = {
668 388, /* max RF gain in 10th of dB */
669 26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
670 1008, /* ramp_max = maximum X used on the ramp */
671 (11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
672 (0 << 10) | 369, /* RF_RAMP4, LNA 1 */
673 (41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
674 (0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
675 (27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
676 (0 << 10) | 809, /* RF_RAMP8, LNA 3 */
677 (14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
678 (0 << 10) | 659, /* GAIN_4_2, LNA 4 */
679};
680
297static const u16 rf_ramp_pwm_cband[] = { 681static const u16 rf_ramp_pwm_cband[] = {
298 0, /* max RF gain in 10th of dB */ 682 0, /* max RF gain in 10th of dB */
299 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ 683 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
@@ -326,6 +710,16 @@ static const u16 rf_ramp_uhf[] = {
326 0, 0, 127, /* CBAND : 0.0 dB */ 710 0, 0, 127, /* CBAND : 0.0 dB */
327}; 711};
328 712
713static const u16 rf_ramp_cband_broadmatching[] = /* for p1G only */
714{
715 314, /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
716 84, 314, 127, /* LNA1 */
717 80, 230, 255, /* LNA2 */
718 80, 150, 127, /* LNA3 It was measured 12dB, do not lock if 120 */
719 70, 70, 127, /* LNA4 */
720 0, 0, 127, /* CBAND */
721};
722
329static const u16 rf_ramp_cband[] = { 723static const u16 rf_ramp_cband[] = {
330 332, /* max RF gain in 10th of dB */ 724 332, /* max RF gain in 10th of dB */
331 132, 252, 127, /* LNA1, dB */ 725 132, 252, 127, /* LNA1, dB */
@@ -380,8 +774,8 @@ static const u16 bb_ramp_pwm_normal[] = {
380}; 774};
381 775
382struct slope { 776struct slope {
383 int16_t range; 777 s16 range;
384 int16_t slope; 778 s16 slope;
385}; 779};
386static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val) 780static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
387{ 781{
@@ -597,19 +991,39 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
597#endif 991#endif
598#ifdef CONFIG_BAND_CBAND 992#ifdef CONFIG_BAND_CBAND
599 if (state->current_band == BAND_CBAND) { 993 if (state->current_band == BAND_CBAND) {
600 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); 994 if (state->identity.in_soc) {
601 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 995 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
996 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
997 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
998 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
999 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
1000 } else {
1001 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
1002 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1003 }
602 } else 1004 } else
603#endif 1005#endif
604#ifdef CONFIG_BAND_VHF 1006#ifdef CONFIG_BAND_VHF
605 if (state->current_band == BAND_VHF) { 1007 if (state->current_band == BAND_VHF) {
606 dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf); 1008 if (state->identity.in_soc) {
607 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 1009 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1010 } else {
1011 dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
1012 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1013 }
608 } else 1014 } else
609#endif 1015#endif
610 { 1016 {
611 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf); 1017 if (state->identity.in_soc) {
612 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 1018 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1019 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
1020 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1021 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
1022 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1023 } else {
1024 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
1025 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1026 }
613 } 1027 }
614 1028
615 if (state->rf_ramp[0] != 0) 1029 if (state->rf_ramp[0] != 0)
@@ -617,11 +1031,21 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
617 else 1031 else
618 dib0090_write_reg(state, 0x32, (0 << 11)); 1032 dib0090_write_reg(state, 0x32, (0 << 11));
619 1033
1034 dib0090_write_reg(state, 0x04, 0x01);
620 dib0090_write_reg(state, 0x39, (1 << 10)); 1035 dib0090_write_reg(state, 0x39, (1 << 10));
621 } 1036 }
622} 1037}
1038
623EXPORT_SYMBOL(dib0090_pwm_gain_reset); 1039EXPORT_SYMBOL(dib0090_pwm_gain_reset);
624 1040
1041static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1042{
1043 u16 adc_val = dib0090_read_reg(state, 0x1d);
1044 if (state->identity.in_soc)
1045 adc_val >>= 2;
1046 return adc_val;
1047}
1048
625int dib0090_gain_control(struct dvb_frontend *fe) 1049int dib0090_gain_control(struct dvb_frontend *fe)
626{ 1050{
627 struct dib0090_state *state = fe->tuner_priv; 1051 struct dib0090_state *state = fe->tuner_priv;
@@ -643,18 +1067,21 @@ int dib0090_gain_control(struct dvb_frontend *fe)
643 } else 1067 } else
644#endif 1068#endif
645#ifdef CONFIG_BAND_VHF 1069#ifdef CONFIG_BAND_VHF
646 if (state->current_band == BAND_VHF) { 1070 if (state->current_band == BAND_VHF && !state->identity.p1g) {
647 dib0090_set_rframp(state, rf_ramp_vhf); 1071 dib0090_set_rframp(state, rf_ramp_vhf);
648 dib0090_set_bbramp(state, bb_ramp_boost); 1072 dib0090_set_bbramp(state, bb_ramp_boost);
649 } else 1073 } else
650#endif 1074#endif
651#ifdef CONFIG_BAND_CBAND 1075#ifdef CONFIG_BAND_CBAND
652 if (state->current_band == BAND_CBAND) { 1076 if (state->current_band == BAND_CBAND && !state->identity.p1g) {
653 dib0090_set_rframp(state, rf_ramp_cband); 1077 dib0090_set_rframp(state, rf_ramp_cband);
654 dib0090_set_bbramp(state, bb_ramp_boost); 1078 dib0090_set_bbramp(state, bb_ramp_boost);
655 } else 1079 } else
656#endif 1080#endif
657 { 1081 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1082 dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
1083 dib0090_set_bbramp(state, bb_ramp_boost);
1084 } else {
658 dib0090_set_rframp(state, rf_ramp_uhf); 1085 dib0090_set_rframp(state, rf_ramp_uhf);
659 dib0090_set_bbramp(state, bb_ramp_boost); 1086 dib0090_set_bbramp(state, bb_ramp_boost);
660 } 1087 }
@@ -669,17 +1096,25 @@ int dib0090_gain_control(struct dvb_frontend *fe)
669 1096
670 *tune_state = CT_AGC_STEP_0; 1097 *tune_state = CT_AGC_STEP_0;
671 } else if (!state->agc_freeze) { 1098 } else if (!state->agc_freeze) {
672 s16 wbd; 1099 s16 wbd = 0, i, cnt;
673 1100
674 int adc; 1101 int adc;
675 wbd_val = dib0090_read_reg(state, 0x1d); 1102 wbd_val = dib0090_get_slow_adc_val(state);
676 1103
677 /* read and calc the wbd power */ 1104 if (*tune_state == CT_AGC_STEP_0)
678 wbd = dib0090_wbd_to_db(state, wbd_val); 1105 cnt = 5;
1106 else
1107 cnt = 1;
1108
1109 for (i = 0; i < cnt; i++) {
1110 wbd_val = dib0090_get_slow_adc_val(state);
1111 wbd += dib0090_wbd_to_db(state, wbd_val);
1112 }
1113 wbd /= cnt;
679 wbd_error = state->wbd_target - wbd; 1114 wbd_error = state->wbd_target - wbd;
680 1115
681 if (*tune_state == CT_AGC_STEP_0) { 1116 if (*tune_state == CT_AGC_STEP_0) {
682 if (wbd_error < 0 && state->rf_gain_limit > 0) { 1117 if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
683#ifdef CONFIG_BAND_CBAND 1118#ifdef CONFIG_BAND_CBAND
684 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */ 1119 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
685 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7; 1120 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
@@ -700,39 +1135,39 @@ int dib0090_gain_control(struct dvb_frontend *fe)
700 adc_error = (s16) (((s32) ADC_TARGET) - adc); 1135 adc_error = (s16) (((s32) ADC_TARGET) - adc);
701#ifdef CONFIG_STANDARD_DAB 1136#ifdef CONFIG_STANDARD_DAB
702 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) 1137 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
703 adc_error += 130; 1138 adc_error -= 10;
704#endif 1139#endif
705#ifdef CONFIG_STANDARD_DVBT 1140#ifdef CONFIG_STANDARD_DVBT
706 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT && 1141 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
707 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16)) 1142 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
708 adc_error += 60; 1143 adc_error += 60;
709#endif 1144#endif
710#ifdef CONFIG_SYS_ISDBT 1145#ifdef CONFIG_SYS_ISDBT
711 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count > 1146 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
712 0) 1147 0)
713 && 1148 &&
714 ((state->fe->dtv_property_cache.layer[0].modulation == 1149 ((state->fe->dtv_property_cache.layer[0].modulation ==
715 QAM_64) 1150 QAM_64)
716 || (state->fe->dtv_property_cache.layer[0]. 1151 || (state->fe->dtv_property_cache.
717 modulation == QAM_16))) 1152 layer[0].modulation == QAM_16)))
718 || 1153 ||
719 ((state->fe->dtv_property_cache.layer[1].segment_count > 1154 ((state->fe->dtv_property_cache.layer[1].segment_count >
720 0) 1155 0)
721 && 1156 &&
722 ((state->fe->dtv_property_cache.layer[1].modulation == 1157 ((state->fe->dtv_property_cache.layer[1].modulation ==
723 QAM_64) 1158 QAM_64)
724 || (state->fe->dtv_property_cache.layer[1]. 1159 || (state->fe->dtv_property_cache.
725 modulation == QAM_16))) 1160 layer[1].modulation == QAM_16)))
726 || 1161 ||
727 ((state->fe->dtv_property_cache.layer[2].segment_count > 1162 ((state->fe->dtv_property_cache.layer[2].segment_count >
728 0) 1163 0)
729 && 1164 &&
730 ((state->fe->dtv_property_cache.layer[2].modulation == 1165 ((state->fe->dtv_property_cache.layer[2].modulation ==
731 QAM_64) 1166 QAM_64)
732 || (state->fe->dtv_property_cache.layer[2]. 1167 || (state->fe->dtv_property_cache.
733 modulation == QAM_16))) 1168 layer[2].modulation == QAM_16)))
734 ) 1169 )
735 ) 1170 )
736 adc_error += 60; 1171 adc_error += 60;
737#endif 1172#endif
738 1173
@@ -760,9 +1195,9 @@ int dib0090_gain_control(struct dvb_frontend *fe)
760 } 1195 }
761#ifdef DEBUG_AGC 1196#ifdef DEBUG_AGC
762 dprintk 1197 dprintk
763 ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", 1198 ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
764 (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, 1199 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
765 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); 1200 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
766#endif 1201#endif
767 } 1202 }
768 1203
@@ -771,6 +1206,7 @@ int dib0090_gain_control(struct dvb_frontend *fe)
771 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly); 1206 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
772 return ret; 1207 return ret;
773} 1208}
1209
774EXPORT_SYMBOL(dib0090_gain_control); 1210EXPORT_SYMBOL(dib0090_gain_control);
775 1211
776void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) 1212void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
@@ -785,13 +1221,47 @@ void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 *
785 if (rflt) 1221 if (rflt)
786 *rflt = (state->rf_lt_def >> 10) & 0x7; 1222 *rflt = (state->rf_lt_def >> 10) & 0x7;
787} 1223}
1224
788EXPORT_SYMBOL(dib0090_get_current_gain); 1225EXPORT_SYMBOL(dib0090_get_current_gain);
789 1226
790u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) 1227u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
791{ 1228{
792 struct dib0090_state *st = tuner->tuner_priv; 1229 struct dib0090_state *state = fe->tuner_priv;
793 return st->wbd_offset; 1230 u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1231 s32 current_temp = state->temperature;
1232 s32 wbd_thot, wbd_tcold;
1233 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1234
1235 while (f_MHz > wbd->max_freq)
1236 wbd++;
1237
1238 dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
1239
1240 if (current_temp < 0)
1241 current_temp = 0;
1242 if (current_temp > 128)
1243 current_temp = 128;
1244
1245 state->wbdmux &= ~(7 << 13);
1246 if (wbd->wbd_gain != 0)
1247 state->wbdmux |= (wbd->wbd_gain << 13);
1248 else
1249 state->wbdmux |= (4 << 13);
1250
1251 dib0090_write_reg(state, 0x10, state->wbdmux);
1252
1253 wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1254 wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1255
1256 wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1257
1258 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1259 dprintk("wbd-target: %d dB", (u32) state->wbd_target);
1260 dprintk("wbd offset applied is %d", wbd_tcold);
1261
1262 return state->wbd_offset + wbd_tcold;
794} 1263}
1264
795EXPORT_SYMBOL(dib0090_get_wbd_offset); 1265EXPORT_SYMBOL(dib0090_get_wbd_offset);
796 1266
797static const u16 dib0090_defaults[] = { 1267static const u16 dib0090_defaults[] = {
@@ -801,7 +1271,7 @@ static const u16 dib0090_defaults[] = {
801 0x99a0, 1271 0x99a0,
802 0x6008, 1272 0x6008,
803 0x0000, 1273 0x0000,
804 0x8acb, 1274 0x8bcb,
805 0x0000, 1275 0x0000,
806 0x0405, 1276 0x0405,
807 0x0000, 1277 0x0000,
@@ -829,8 +1299,6 @@ static const u16 dib0090_defaults[] = {
829 1, 0x39, 1299 1, 0x39,
830 0x0000, 1300 0x0000,
831 1301
832 1, 0x1b,
833 EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL,
834 2, 0x1e, 1302 2, 0x1e,
835 0x07FF, 1303 0x07FF,
836 0x0007, 1304 0x0007,
@@ -844,50 +1312,125 @@ static const u16 dib0090_defaults[] = {
844 0 1312 0
845}; 1313};
846 1314
847static int dib0090_reset(struct dvb_frontend *fe) 1315static const u16 dib0090_p1g_additionnal_defaults[] = {
848{ 1316 1, 0x05,
849 struct dib0090_state *state = fe->tuner_priv; 1317 0xabcd,
850 u16 l, r, *n;
851 1318
852 dib0090_reset_digital(fe, state->config); 1319 1, 0x11,
853 state->revision = dib0090_identify(fe); 1320 0x00b4,
854 1321
855 /* Revision definition */ 1322 1, 0x1c,
856 if (state->revision == 0xff) 1323 0xfffd,
857 return -EINVAL;
858#ifdef EFUSE
859 else if ((state->revision & 0x1f) >= 3) /* Update the efuse : Only available for KROSUS > P1C */
860 dib0090_set_EFUSE(state);
861#endif
862 1324
863#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT 1325 1, 0x40,
864 if (!(state->revision & 0x1)) /* it is P1B - reset is already done */ 1326 0x108,
865 return 0; 1327 0
866#endif 1328};
1329
1330static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1331{
1332 u16 l, r;
867 1333
868 /* Upload the default values */
869 n = (u16 *) dib0090_defaults;
870 l = pgm_read_word(n++); 1334 l = pgm_read_word(n++);
871 while (l) { 1335 while (l) {
872 r = pgm_read_word(n++); 1336 r = pgm_read_word(n++);
873 do { 1337 do {
874 /* DEBUG_TUNER */
875 /* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */
876 dib0090_write_reg(state, r, pgm_read_word(n++)); 1338 dib0090_write_reg(state, r, pgm_read_word(n++));
877 r++; 1339 r++;
878 } while (--l); 1340 } while (--l);
879 l = pgm_read_word(n++); 1341 l = pgm_read_word(n++);
880 } 1342 }
1343}
1344
1345#define CAP_VALUE_MIN (u8) 9
1346#define CAP_VALUE_MAX (u8) 40
1347#define HR_MIN (u8) 25
1348#define HR_MAX (u8) 40
1349#define POLY_MIN (u8) 0
1350#define POLY_MAX (u8) 8
1351
1352void dib0090_set_EFUSE(struct dib0090_state *state)
1353{
1354 u8 c, h, n;
1355 u16 e2, e4;
1356 u16 cal;
1357
1358 e2 = dib0090_read_reg(state, 0x26);
1359 e4 = dib0090_read_reg(state, 0x28);
1360
1361 if ((state->identity.version == P1D_E_F) ||
1362 (state->identity.version == P1G) || (e2 == 0xffff)) {
1363
1364 dib0090_write_reg(state, 0x22, 0x10);
1365 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1366
1367 if ((cal < 670) || (cal == 1023))
1368 cal = 850;
1369 n = 165 - ((cal * 10)>>6) ;
1370 e2 = e4 = (3<<12) | (34<<6) | (n);
1371 }
1372
1373 if (e2 != e4)
1374 e2 &= e4; /* Remove the redundancy */
1375
1376 if (e2 != 0xffff) {
1377 c = e2 & 0x3f;
1378 n = (e2 >> 12) & 0xf;
1379 h = (e2 >> 6) & 0x3f;
1380
1381 if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1382 c = 32;
1383 if ((h >= HR_MAX) || (h <= HR_MIN))
1384 h = 34;
1385 if ((n >= POLY_MAX) || (n <= POLY_MIN))
1386 n = 3;
1387
1388 dib0090_write_reg(state, 0x13, (h << 10)) ;
1389 e2 = (n<<11) | ((h>>2)<<6) | (c);
1390 dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
1391 }
1392}
1393
1394static int dib0090_reset(struct dvb_frontend *fe)
1395{
1396 struct dib0090_state *state = fe->tuner_priv;
1397
1398 dib0090_reset_digital(fe, state->config);
1399 if (dib0090_identify(fe) < 0)
1400 return -EIO;
1401
1402#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1403 if (!(state->identity.version & 0x1)) /* it is P1B - reset is already done */
1404 return 0;
1405#endif
1406
1407 if (!state->identity.in_soc) {
1408 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1409 dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1410 else
1411 dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1412 }
1413
1414 dib0090_set_default_config(state, dib0090_defaults);
1415
1416 if (state->identity.in_soc)
1417 dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */
1418
1419 if (state->identity.p1g)
1420 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1421
1422 /* Update the efuse : Only available for KROSUS > P1C and SOC as well*/
1423 if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1424 dib0090_set_EFUSE(state);
881 1425
882 /* Congigure in function of the crystal */ 1426 /* Congigure in function of the crystal */
883 if (state->config->io.clock_khz >= 24000) 1427 if (state->config->io.clock_khz >= 24000)
884 l = 1; 1428 dib0090_write_reg(state, 0x14, 1);
885 else 1429 else
886 l = 2; 1430 dib0090_write_reg(state, 0x14, 2);
887 dib0090_write_reg(state, 0x14, l);
888 dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); 1431 dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
889 1432
890 state->reset = 3; /* enable iq-offset-calibration and wbd-calibration when tuning next time */ 1433 state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
891 1434
892 return 0; 1435 return 0;
893} 1436}
@@ -927,11 +1470,11 @@ static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_st
927} 1470}
928 1471
929struct dc_calibration { 1472struct dc_calibration {
930 uint8_t addr; 1473 u8 addr;
931 uint8_t offset; 1474 u8 offset;
932 uint8_t pga:1; 1475 u8 pga:1;
933 uint16_t bb1; 1476 u16 bb1;
934 uint8_t i:1; 1477 u8 i:1;
935}; 1478};
936 1479
937static const struct dc_calibration dc_table[] = { 1480static const struct dc_calibration dc_table[] = {
@@ -944,6 +1487,17 @@ static const struct dc_calibration dc_table[] = {
944 {0}, 1487 {0},
945}; 1488};
946 1489
1490static const struct dc_calibration dc_p1g_table[] = {
1491 /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1492 /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
1493 {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1494 {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1495 /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1496 {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1497 {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1498 {0},
1499};
1500
947static void dib0090_set_trim(struct dib0090_state *state) 1501static void dib0090_set_trim(struct dib0090_state *state)
948{ 1502{
949 u16 *val; 1503 u16 *val;
@@ -962,41 +1516,45 @@ static void dib0090_set_trim(struct dib0090_state *state)
962static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1516static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
963{ 1517{
964 int ret = 0; 1518 int ret = 0;
1519 u16 reg;
965 1520
966 switch (*tune_state) { 1521 switch (*tune_state) {
967
968 case CT_TUNER_START: 1522 case CT_TUNER_START:
969 /* init */ 1523 dprintk("Start DC offset calibration");
970 dprintk("Internal DC calibration");
971
972 /* the LNA is off */
973 dib0090_write_reg(state, 0x24, 0x02ed);
974 1524
975 /* force vcm2 = 0.8V */ 1525 /* force vcm2 = 0.8V */
976 state->bb6 = 0; 1526 state->bb6 = 0;
977 state->bb7 = 0x040d; 1527 state->bb7 = 0x040d;
978 1528
1529 /* the LNA AND LO are off */
1530 reg = dib0090_read_reg(state, 0x24) & 0x0ffb; /* shutdown lna and lo */
1531 dib0090_write_reg(state, 0x24, reg);
1532
1533 state->wbdmux = dib0090_read_reg(state, 0x10);
1534 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1535 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1536
979 state->dc = dc_table; 1537 state->dc = dc_table;
980 1538
1539 if (state->identity.p1g)
1540 state->dc = dc_p1g_table;
981 *tune_state = CT_TUNER_STEP_0; 1541 *tune_state = CT_TUNER_STEP_0;
982 1542
983 /* fall through */ 1543 /* fall through */
984 1544
985 case CT_TUNER_STEP_0: 1545 case CT_TUNER_STEP_0:
1546 dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
986 dib0090_write_reg(state, 0x01, state->dc->bb1); 1547 dib0090_write_reg(state, 0x01, state->dc->bb1);
987 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); 1548 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
988 1549
989 state->step = 0; 1550 state->step = 0;
990
991 state->min_adc_diff = 1023; 1551 state->min_adc_diff = 1023;
992
993 *tune_state = CT_TUNER_STEP_1; 1552 *tune_state = CT_TUNER_STEP_1;
994 ret = 50; 1553 ret = 50;
995 break; 1554 break;
996 1555
997 case CT_TUNER_STEP_1: 1556 case CT_TUNER_STEP_1:
998 dib0090_set_trim(state); 1557 dib0090_set_trim(state);
999
1000 *tune_state = CT_TUNER_STEP_2; 1558 *tune_state = CT_TUNER_STEP_2;
1001 break; 1559 break;
1002 1560
@@ -1007,7 +1565,13 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1007 break; 1565 break;
1008 1566
1009 case CT_TUNER_STEP_5: /* found an offset */ 1567 case CT_TUNER_STEP_5: /* found an offset */
1010 dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step); 1568 dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
1569 if (state->step == 0 && state->adc_diff < 0) {
1570 state->min_adc_diff = -1023;
1571 dprintk("Change of sign of the minimum adc diff");
1572 }
1573
1574 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
1011 1575
1012 /* first turn for this frequency */ 1576 /* first turn for this frequency */
1013 if (state->step == 0) { 1577 if (state->step == 0) {
@@ -1017,20 +1581,21 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1017 state->step = 0x10; 1581 state->step = 0x10;
1018 } 1582 }
1019 1583
1020 state->adc_diff = ABS(state->adc_diff); 1584 /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
1021 1585 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1022 if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) { /* stop search when the delta to 0 is increasing */ 1586 /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
1023 state->step++; 1587 state->step++;
1024 state->min_adc_diff = state->adc_diff; 1588 state->min_adc_diff = state->adc_diff;
1025 *tune_state = CT_TUNER_STEP_1; 1589 *tune_state = CT_TUNER_STEP_1;
1026 } else { 1590 } else {
1027
1028 /* the minimum was what we have seen in the step before */ 1591 /* the minimum was what we have seen in the step before */
1029 state->step--; 1592 if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
1030 dib0090_set_trim(state); 1593 dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
1594 state->step--;
1595 }
1031 1596
1032 dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff, 1597 dib0090_set_trim(state);
1033 state->step); 1598 dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
1034 1599
1035 state->dc++; 1600 state->dc++;
1036 if (state->dc->addr == 0) /* done */ 1601 if (state->dc->addr == 0) /* done */
@@ -1045,7 +1610,7 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1045 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); 1610 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1046 dib0090_write_reg(state, 0x1f, 0x7); 1611 dib0090_write_reg(state, 0x1f, 0x7);
1047 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1612 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
1048 state->reset &= ~0x1; 1613 state->calibrate &= ~DC_CAL;
1049 default: 1614 default:
1050 break; 1615 break;
1051 } 1616 }
@@ -1054,21 +1619,43 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1054 1619
1055static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1620static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1056{ 1621{
1622 u8 wbd_gain;
1623 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1624
1057 switch (*tune_state) { 1625 switch (*tune_state) {
1058 case CT_TUNER_START: 1626 case CT_TUNER_START:
1059 /* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */ 1627 while (state->current_rf / 1000 > wbd->max_freq)
1060 dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10)); 1628 wbd++;
1061 dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff); 1629 if (wbd->wbd_gain != 0)
1630 wbd_gain = wbd->wbd_gain;
1631 else {
1632 wbd_gain = 4;
1633#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1634 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1635 wbd_gain = 2;
1636#endif
1637 }
1638
1639 if (wbd_gain == state->wbd_calibration_gain) { /* the WBD calibration has already been done */
1640 *tune_state = CT_TUNER_START;
1641 state->calibrate &= ~WBD_CAL;
1642 return 0;
1643 }
1644
1645 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1062 1646
1647 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1063 *tune_state = CT_TUNER_STEP_0; 1648 *tune_state = CT_TUNER_STEP_0;
1649 state->wbd_calibration_gain = wbd_gain;
1064 return 90; /* wait for the WBDMUX to switch and for the ADC to sample */ 1650 return 90; /* wait for the WBDMUX to switch and for the ADC to sample */
1651
1065 case CT_TUNER_STEP_0: 1652 case CT_TUNER_STEP_0:
1066 state->wbd_offset = dib0090_read_reg(state, 0x1d); 1653 state->wbd_offset = dib0090_get_slow_adc_val(state);
1067 dprintk("WBD calibration offset = %d", state->wbd_offset); 1654 dprintk("WBD calibration offset = %d", state->wbd_offset);
1068
1069 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1655 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
1070 state->reset &= ~0x2; 1656 state->calibrate &= ~WBD_CAL;
1071 break; 1657 break;
1658
1072 default: 1659 default:
1073 break; 1660 break;
1074 } 1661 }
@@ -1092,6 +1679,15 @@ static void dib0090_set_bandwidth(struct dib0090_state *state)
1092 state->bb_1_def |= tmp; 1679 state->bb_1_def |= tmp;
1093 1680
1094 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */ 1681 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */
1682
1683 dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1684 dib0090_write_reg(state, 0x04, 0x1); /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1685 if (state->identity.in_soc) {
1686 dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
1687 } else {
1688 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f)); /* 22 = cap_value */
1689 dib0090_write_reg(state, 0x05, 0xabcd); /* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
1690 }
1095} 1691}
1096 1692
1097static const struct dib0090_pll dib0090_pll_table[] = { 1693static const struct dib0090_pll dib0090_pll_table[] = {
@@ -1180,6 +1776,255 @@ static const struct dib0090_tuning dib0090_tuning_table[] = {
1180#endif 1776#endif
1181}; 1777};
1182 1778
1779static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1780#ifdef CONFIG_BAND_CBAND
1781 {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1782#endif
1783#ifdef CONFIG_BAND_VHF
1784 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1785 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1786 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1787#endif
1788#ifdef CONFIG_BAND_UHF
1789 {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1790 {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1791 {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1792 {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1793 {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1794 {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1795 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1796#endif
1797#ifdef CONFIG_BAND_LBAND
1798 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1799 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1800 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1801#endif
1802#ifdef CONFIG_BAND_SBAND
1803 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1804 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1805#endif
1806};
1807
1808static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1809#ifdef CONFIG_BAND_CBAND
1810 {57000, 0, 11, 48, 6},
1811 {70000, 1, 11, 48, 6},
1812 {86000, 0, 10, 32, 4},
1813 {105000, 1, 10, 32, 4},
1814 {115000, 0, 9, 24, 6},
1815 {140000, 1, 9, 24, 6},
1816 {170000, 0, 8, 16, 4},
1817#endif
1818#ifdef CONFIG_BAND_VHF
1819 {200000, 1, 8, 16, 4},
1820 {230000, 0, 7, 12, 6},
1821 {280000, 1, 7, 12, 6},
1822 {340000, 0, 6, 8, 4},
1823 {380000, 1, 6, 8, 4},
1824 {455000, 0, 5, 6, 6},
1825#endif
1826#ifdef CONFIG_BAND_UHF
1827 {580000, 1, 5, 6, 6},
1828 {680000, 0, 4, 4, 4},
1829 {860000, 1, 4, 4, 4},
1830#endif
1831#ifdef CONFIG_BAND_LBAND
1832 {1800000, 1, 2, 2, 4},
1833#endif
1834#ifdef CONFIG_BAND_SBAND
1835 {2900000, 0, 1, 1, 6},
1836#endif
1837};
1838
1839static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
1840#ifdef CONFIG_BAND_CBAND
1841 {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1842 {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1843 {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1844#endif
1845#ifdef CONFIG_BAND_UHF
1846 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1847 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1848 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1849 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1850 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1851 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1852#endif
1853#ifdef CONFIG_BAND_LBAND
1854 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1855 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1856 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1857#endif
1858#ifdef CONFIG_BAND_SBAND
1859 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1860 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1861#endif
1862};
1863
1864static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
1865#ifdef CONFIG_BAND_CBAND
1866 {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1867 {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1868 {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1869 {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1870#endif
1871};
1872
1873static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1874{
1875 int ret = 0;
1876 u16 lo4 = 0xe900;
1877
1878 s16 adc_target;
1879 u16 adc;
1880 s8 step_sign;
1881 u8 force_soft_search = 0;
1882
1883 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1884 force_soft_search = 1;
1885
1886 if (*tune_state == CT_TUNER_START) {
1887 dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
1888 dib0090_write_reg(state, 0x10, 0x2B1);
1889 dib0090_write_reg(state, 0x1e, 0x0032);
1890
1891 if (!state->tuner_is_tuned) {
1892 /* prepare a complete captrim */
1893 if (!state->identity.p1g || force_soft_search)
1894 state->step = state->captrim = state->fcaptrim = 64;
1895
1896 state->current_rf = state->rf_request;
1897 } else { /* we are already tuned to this frequency - the configuration is correct */
1898 if (!state->identity.p1g || force_soft_search) {
1899 /* do a minimal captrim even if the frequency has not changed */
1900 state->step = 4;
1901 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
1902 }
1903 }
1904 state->adc_diff = 3000;
1905 *tune_state = CT_TUNER_STEP_0;
1906
1907 } else if (*tune_state == CT_TUNER_STEP_0) {
1908 if (state->identity.p1g && !force_soft_search) {
1909 u8 ratio = 31;
1910
1911 dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
1912 dib0090_read_reg(state, 0x40);
1913 ret = 50;
1914 } else {
1915 state->step /= 2;
1916 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
1917
1918 if (state->identity.in_soc)
1919 ret = 25;
1920 }
1921 *tune_state = CT_TUNER_STEP_1;
1922
1923 } else if (*tune_state == CT_TUNER_STEP_1) {
1924 if (state->identity.p1g && !force_soft_search) {
1925 dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
1926 dib0090_read_reg(state, 0x40);
1927
1928 state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
1929 dprintk("***Final Captrim= 0x%x", state->fcaptrim);
1930 *tune_state = CT_TUNER_STEP_3;
1931
1932 } else {
1933 /* MERGE for all krosus before P1G */
1934 adc = dib0090_get_slow_adc_val(state);
1935 dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
1936
1937 if (state->rest == 0 || state->identity.in_soc) { /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
1938 adc_target = 200;
1939 } else
1940 adc_target = 400;
1941
1942 if (adc >= adc_target) {
1943 adc -= adc_target;
1944 step_sign = -1;
1945 } else {
1946 adc = adc_target - adc;
1947 step_sign = 1;
1948 }
1949
1950 if (adc < state->adc_diff) {
1951 dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
1952 state->adc_diff = adc;
1953 state->fcaptrim = state->captrim;
1954 }
1955
1956 state->captrim += step_sign * state->step;
1957 if (state->step >= 1)
1958 *tune_state = CT_TUNER_STEP_0;
1959 else
1960 *tune_state = CT_TUNER_STEP_2;
1961
1962 ret = 25;
1963 }
1964 } else if (*tune_state == CT_TUNER_STEP_2) { /* this step is only used by krosus < P1G */
1965 /*write the final cptrim config */
1966 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
1967
1968 *tune_state = CT_TUNER_STEP_3;
1969
1970 } else if (*tune_state == CT_TUNER_STEP_3) {
1971 state->calibrate &= ~CAPTRIM_CAL;
1972 *tune_state = CT_TUNER_STEP_0;
1973 }
1974
1975 return ret;
1976}
1977
1978static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1979{
1980 int ret = 15;
1981 s16 val;
1982
1983 switch (*tune_state) {
1984 case CT_TUNER_START:
1985 state->wbdmux = dib0090_read_reg(state, 0x10);
1986 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
1987
1988 state->bias = dib0090_read_reg(state, 0x13);
1989 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
1990
1991 *tune_state = CT_TUNER_STEP_0;
1992 /* wait for the WBDMUX to switch and for the ADC to sample */
1993 break;
1994
1995 case CT_TUNER_STEP_0:
1996 state->adc_diff = dib0090_get_slow_adc_val(state);
1997 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
1998 *tune_state = CT_TUNER_STEP_1;
1999 break;
2000
2001 case CT_TUNER_STEP_1:
2002 val = dib0090_get_slow_adc_val(state);
2003 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2004
2005 dprintk("temperature: %d C", state->temperature - 30);
2006
2007 *tune_state = CT_TUNER_STEP_2;
2008 break;
2009
2010 case CT_TUNER_STEP_2:
2011 dib0090_write_reg(state, 0x13, state->bias);
2012 dib0090_write_reg(state, 0x10, state->wbdmux); /* write back original WBDMUX */
2013
2014 *tune_state = CT_TUNER_START;
2015 state->calibrate &= ~TEMP_CAL;
2016 if (state->config->analog_output == 0)
2017 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2018
2019 break;
2020
2021 default:
2022 ret = 0;
2023 break;
2024 }
2025 return ret;
2026}
2027
1183#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ 2028#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
1184static int dib0090_tune(struct dvb_frontend *fe) 2029static int dib0090_tune(struct dvb_frontend *fe)
1185{ 2030{
@@ -1188,87 +2033,131 @@ static int dib0090_tune(struct dvb_frontend *fe)
1188 const struct dib0090_pll *pll = state->current_pll_table_index; 2033 const struct dib0090_pll *pll = state->current_pll_table_index;
1189 enum frontend_tune_state *tune_state = &state->tune_state; 2034 enum frontend_tune_state *tune_state = &state->tune_state;
1190 2035
1191 u32 rf; 2036 u16 lo5, lo6, Den, tmp;
1192 u16 lo4 = 0xe900, lo5, lo6, Den;
1193 u32 FBDiv, Rest, FREF, VCOF_kHz = 0; 2037 u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
1194 u16 tmp, adc;
1195 int8_t step_sign;
1196 int ret = 10; /* 1ms is the default delay most of the time */ 2038 int ret = 10; /* 1ms is the default delay most of the time */
1197 u8 c, i; 2039 u8 c, i;
1198 2040
1199 state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); 2041 /************************* VCO ***************************/
1200 rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
1201 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf);
1202 /* in any case we first need to do a reset if needed */
1203 if (state->reset & 0x1)
1204 return dib0090_dc_offset_calibration(state, tune_state);
1205 else if (state->reset & 0x2)
1206 return dib0090_wbd_calibration(state, tune_state);
1207
1208 /************************* VCO ***************************/
1209 /* Default values for FG */ 2042 /* Default values for FG */
1210 /* from these are needed : */ 2043 /* from these are needed : */
1211 /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */ 2044 /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */
1212 2045
1213#ifdef CONFIG_SYS_ISDBT 2046 /* in any case we first need to do a calibration if needed */
1214 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) 2047 if (*tune_state == CT_TUNER_START) {
1215 rf += 850; 2048 /* deactivate DataTX before some calibrations */
1216#endif 2049 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2050 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2051 else
2052 /* Activate DataTX in case a calibration has been done before */
2053 if (state->config->analog_output == 0)
2054 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2055 }
1217 2056
1218 if (state->current_rf != rf) { 2057 if (state->calibrate & DC_CAL)
1219 state->tuner_is_tuned = 0; 2058 return dib0090_dc_offset_calibration(state, tune_state);
2059 else if (state->calibrate & WBD_CAL) {
2060 if (state->current_rf == 0)
2061 state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2062 return dib0090_wbd_calibration(state, tune_state);
2063 } else if (state->calibrate & TEMP_CAL)
2064 return dib0090_get_temperature(state, tune_state);
2065 else if (state->calibrate & CAPTRIM_CAL)
2066 return dib0090_captrim_search(state, tune_state);
1220 2067
1221 tune = dib0090_tuning_table; 2068 if (*tune_state == CT_TUNER_START) {
2069 /* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
2070 if (state->config->use_pwm_agc && state->identity.in_soc) {
2071 tmp = dib0090_read_reg(state, 0x39);
2072 if ((tmp >> 10) & 0x1)
2073 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2074 }
1222 2075
1223 tmp = (state->revision >> 5) & 0x7; 2076 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
1224 if (tmp == 0x4 || tmp == 0x7) { 2077 state->rf_request =
1225 /* CBAND tuner version for VHF */ 2078 state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
1226 if (state->current_band == BAND_FM || state->current_band == BAND_VHF) { 2079 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
1227 /* Force CBAND */ 2080 freq_offset_khz_vhf);
1228 state->current_band = BAND_CBAND; 2081
1229 tune = dib0090_tuning_table_fm_vhf_on_cband; 2082 /* in ISDB-T 1seg we shift tuning frequency */
2083 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2084 && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2085 const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2086 u8 found_offset = 0;
2087 u32 margin_khz = 100;
2088
2089 if (LUT_offset != NULL) {
2090 while (LUT_offset->RF_freq != 0xffff) {
2091 if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2092 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2093 && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2094 state->rf_request += LUT_offset->offset_khz;
2095 found_offset = 1;
2096 break;
2097 }
2098 LUT_offset++;
2099 }
1230 } 2100 }
2101
2102 if (found_offset == 0)
2103 state->rf_request += 400;
1231 } 2104 }
2105 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2106 state->tuner_is_tuned = 0;
2107 state->current_rf = 0;
2108 state->current_standard = 0;
1232 2109
1233 pll = dib0090_pll_table; 2110 tune = dib0090_tuning_table;
1234 /* Look for the interval */ 2111 if (state->identity.p1g)
1235 while (rf > tune->max_freq) 2112 tune = dib0090_p1g_tuning_table;
1236 tune++;
1237 while (rf > pll->max_freq)
1238 pll++;
1239 state->current_tune_table_index = tune;
1240 state->current_pll_table_index = pll;
1241 }
1242 2113
1243 if (*tune_state == CT_TUNER_START) { 2114 tmp = (state->identity.version >> 5) & 0x7;
1244 2115
1245 if (state->tuner_is_tuned == 0) 2116 if (state->identity.in_soc) {
1246 state->current_rf = 0; 2117 if (state->config->force_cband_input) { /* Use the CBAND input for all band */
2118 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2119 || state->current_band & BAND_UHF) {
2120 state->current_band = BAND_CBAND;
2121 tune = dib0090_tuning_table_cband_7090;
2122 }
2123 } else { /* Use the CBAND input for all band under UHF */
2124 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2125 state->current_band = BAND_CBAND;
2126 tune = dib0090_tuning_table_cband_7090;
2127 }
2128 }
2129 } else
2130 if (tmp == 0x4 || tmp == 0x7) {
2131 /* CBAND tuner version for VHF */
2132 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2133 state->current_band = BAND_CBAND; /* Force CBAND */
2134
2135 tune = dib0090_tuning_table_fm_vhf_on_cband;
2136 if (state->identity.p1g)
2137 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2138 }
2139 }
1247 2140
1248 if (state->current_rf != rf) { 2141 pll = dib0090_pll_table;
2142 if (state->identity.p1g)
2143 pll = dib0090_p1g_pll_table;
1249 2144
1250 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim)); 2145 /* Look for the interval */
2146 while (state->rf_request > tune->max_freq)
2147 tune++;
2148 while (state->rf_request > pll->max_freq)
2149 pll++;
1251 2150
1252 /* external loop filter, otherwise: 2151 state->current_tune_table_index = tune;
1253 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4; 2152 state->current_pll_table_index = pll;
1254 * lo6 = 0x0e34 */
1255 if (pll->vco_band)
1256 lo5 = 0x049e;
1257 else if (state->config->analog_output)
1258 lo5 = 0x041d;
1259 else
1260 lo5 = 0x041c;
1261
1262 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */
1263 2153
1264 if (!state->config->io.pll_int_loop_filt) 2154 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
1265 lo6 = 0xff28;
1266 else
1267 lo6 = (state->config->io.pll_int_loop_filt << 3);
1268 2155
1269 VCOF_kHz = (pll->hfdiv * rf) * 2; 2156 VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
1270 2157
1271 FREF = state->config->io.clock_khz; 2158 FREF = state->config->io.clock_khz;
2159 if (state->config->fref_clock_ratio != 0)
2160 FREF /= state->config->fref_clock_ratio;
1272 2161
1273 FBDiv = (VCOF_kHz / pll->topresc / FREF); 2162 FBDiv = (VCOF_kHz / pll->topresc / FREF);
1274 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; 2163 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
@@ -1283,144 +2172,132 @@ static int dib0090_tune(struct dvb_frontend *fe)
1283 } else if (Rest > (FREF - 2 * LPF)) 2172 } else if (Rest > (FREF - 2 * LPF))
1284 Rest = FREF - 2 * LPF; 2173 Rest = FREF - 2 * LPF;
1285 Rest = (Rest * 6528) / (FREF / 10); 2174 Rest = (Rest * 6528) / (FREF / 10);
2175 state->rest = Rest;
1286 2176
1287 Den = 1; 2177 /* external loop filter, otherwise:
2178 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2179 * lo6 = 0x0e34 */
2180
2181 if (Rest == 0) {
2182 if (pll->vco_band)
2183 lo5 = 0x049f;
2184 else
2185 lo5 = 0x041f;
2186 } else {
2187 if (pll->vco_band)
2188 lo5 = 0x049e;
2189 else if (state->config->analog_output)
2190 lo5 = 0x041d;
2191 else
2192 lo5 = 0x041c;
2193 }
2194
2195 if (state->identity.p1g) { /* Bias is done automatically in P1G */
2196 if (state->identity.in_soc) {
2197 if (state->identity.version == SOC_8090_P1G_11R1)
2198 lo5 = 0x46f;
2199 else
2200 lo5 = 0x42f;
2201 } else
2202 lo5 = 0x42c;
2203 }
2204
2205 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */
1288 2206
1289 dprintk(" ***** ******* Rest value = %d", Rest); 2207 if (!state->config->io.pll_int_loop_filt) {
2208 if (state->identity.in_soc)
2209 lo6 = 0xff98;
2210 else if (state->identity.p1g || (Rest == 0))
2211 lo6 = 0xfff8;
2212 else
2213 lo6 = 0xff28;
2214 } else
2215 lo6 = (state->config->io.pll_int_loop_filt << 3);
2216
2217 Den = 1;
1290 2218
1291 if (Rest > 0) { 2219 if (Rest > 0) {
1292 if (state->config->analog_output) 2220 if (state->config->analog_output)
1293 lo6 |= (1 << 2) | 2; 2221 lo6 |= (1 << 2) | 2;
1294 else 2222 else {
1295 lo6 |= (1 << 2) | 1; 2223 if (state->identity.in_soc)
2224 lo6 |= (1 << 2) | 2;
2225 else
2226 lo6 |= (1 << 2) | 2;
2227 }
1296 Den = 255; 2228 Den = 255;
1297 } 2229 }
1298#ifdef CONFIG_BAND_SBAND
1299 if (state->current_band == BAND_SBAND)
1300 lo6 &= 0xfffb;
1301#endif
1302
1303 dib0090_write_reg(state, 0x15, (u16) FBDiv); 2230 dib0090_write_reg(state, 0x15, (u16) FBDiv);
1304 2231 if (state->config->fref_clock_ratio != 0)
1305 dib0090_write_reg(state, 0x16, (Den << 8) | 1); 2232 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
1306 2233 else
2234 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
1307 dib0090_write_reg(state, 0x17, (u16) Rest); 2235 dib0090_write_reg(state, 0x17, (u16) Rest);
1308
1309 dib0090_write_reg(state, 0x19, lo5); 2236 dib0090_write_reg(state, 0x19, lo5);
1310
1311 dib0090_write_reg(state, 0x1c, lo6); 2237 dib0090_write_reg(state, 0x1c, lo6);
1312 2238
1313 lo6 = tune->tuner_enable; 2239 lo6 = tune->tuner_enable;
1314 if (state->config->analog_output) 2240 if (state->config->analog_output)
1315 lo6 = (lo6 & 0xff9f) | 0x2; 2241 lo6 = (lo6 & 0xff9f) | 0x2;
1316 2242
1317 dib0090_write_reg(state, 0x24, lo6 | EN_LO 2243 dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
1318#ifdef CONFIG_DIB0090_USE_PWM_AGC
1319 | state->config->use_pwm_agc * EN_CRYSTAL
1320#endif
1321 );
1322
1323 state->current_rf = rf;
1324
1325 /* prepare a complete captrim */
1326 state->step = state->captrim = state->fcaptrim = 64;
1327
1328 } else { /* we are already tuned to this frequency - the configuration is correct */
1329 2244
1330 /* do a minimal captrim even if the frequency has not changed */
1331 state->step = 4;
1332 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
1333 } 2245 }
1334 state->adc_diff = 3000;
1335
1336 dib0090_write_reg(state, 0x10, 0x2B1);
1337 2246
1338 dib0090_write_reg(state, 0x1e, 0x0032); 2247 state->current_rf = state->rf_request;
2248 state->current_standard = state->fe->dtv_property_cache.delivery_system;
1339 2249
1340 ret = 20; 2250 ret = 20;
1341 *tune_state = CT_TUNER_STEP_1; 2251 state->calibrate = CAPTRIM_CAL; /* captrim serach now */
1342 } else if (*tune_state == CT_TUNER_STEP_0) { 2252 }
1343 /* nothing */
1344 } else if (*tune_state == CT_TUNER_STEP_1) {
1345 state->step /= 2;
1346 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
1347 *tune_state = CT_TUNER_STEP_2;
1348 } else if (*tune_state == CT_TUNER_STEP_2) {
1349 2253
1350 adc = dib0090_read_reg(state, 0x1d); 2254 else if (*tune_state == CT_TUNER_STEP_0) { /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
1351 dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc, 2255 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1352 (u32) (adc) * (u32) 1800 / (u32) 1024);
1353 2256
1354 if (adc >= 400) { 2257 while (state->current_rf / 1000 > wbd->max_freq)
1355 adc -= 400; 2258 wbd++;
1356 step_sign = -1;
1357 } else {
1358 adc = 400 - adc;
1359 step_sign = 1;
1360 }
1361 2259
1362 if (adc < state->adc_diff) { 2260 dib0090_write_reg(state, 0x1e, 0x07ff);
1363 dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff); 2261 dprintk("Final Captrim: %d", (u32) state->fcaptrim);
1364 state->adc_diff = adc; 2262 dprintk("HFDIV code: %d", (u32) pll->hfdiv_code);
1365 state->fcaptrim = state->captrim; 2263 dprintk("VCO = %d", (u32) pll->vco_band);
1366 2264 dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
1367 } 2265 dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz);
2266 dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2267 dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2268 (u32) dib0090_read_reg(state, 0x1c) & 0x3);
1368 2269
1369 state->captrim += step_sign * state->step; 2270#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
1370 if (state->step >= 1) 2271 c = 4;
1371 *tune_state = CT_TUNER_STEP_1; 2272 i = 3;
1372 else
1373 *tune_state = CT_TUNER_STEP_3;
1374 2273
1375 ret = 15; 2274 if (wbd->wbd_gain != 0)
1376 } else if (*tune_state == CT_TUNER_STEP_3) { 2275 c = wbd->wbd_gain;
1377 /*write the final cptrim config */
1378 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
1379 2276
1380#ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY 2277 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
1381 state->memory[state->memory_index].cap = state->fcaptrim; 2278 dib0090_write_reg(state, 0x10, state->wbdmux);
1382#endif
1383 2279
1384 *tune_state = CT_TUNER_STEP_4; 2280 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
1385 } else if (*tune_state == CT_TUNER_STEP_4) { 2281 dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune);
1386 dib0090_write_reg(state, 0x1e, 0x07ff); 2282 dib0090_write_reg(state, 0x09, tune->lna_bias);
1387 2283 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
1388 dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim); 2284 } else
1389 dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code); 2285 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
1390 dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band);
1391 dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf);
1392 dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz);
1393 dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
1394 dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17),
1395 (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3);
1396 2286
1397 c = 4;
1398 i = 3;
1399#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1400 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) {
1401 c = 2;
1402 i = 2;
1403 }
1404#endif
1405 dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD
1406#ifdef CONFIG_DIB0090_USE_PWM_AGC
1407 | (state->config->use_pwm_agc << 1)
1408#endif
1409 ));
1410 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0));
1411 dib0090_write_reg(state, 0x0c, tune->v2i); 2287 dib0090_write_reg(state, 0x0c, tune->v2i);
1412 dib0090_write_reg(state, 0x0d, tune->mix); 2288 dib0090_write_reg(state, 0x0d, tune->mix);
1413 dib0090_write_reg(state, 0x0e, tune->load); 2289 dib0090_write_reg(state, 0x0e, tune->load);
2290 *tune_state = CT_TUNER_STEP_1;
1414 2291
1415 *tune_state = CT_TUNER_STEP_5; 2292 } else if (*tune_state == CT_TUNER_STEP_1) {
1416 } else if (*tune_state == CT_TUNER_STEP_5) {
1417
1418 /* initialize the lt gain register */ 2293 /* initialize the lt gain register */
1419 state->rf_lt_def = 0x7c00; 2294 state->rf_lt_def = 0x7c00;
1420 dib0090_write_reg(state, 0x0f, state->rf_lt_def);
1421 2295
1422 dib0090_set_bandwidth(state); 2296 dib0090_set_bandwidth(state);
1423 state->tuner_is_tuned = 1; 2297 state->tuner_is_tuned = 1;
2298
2299 state->calibrate |= WBD_CAL;
2300 state->calibrate |= TEMP_CAL;
1424 *tune_state = CT_TUNER_STOP; 2301 *tune_state = CT_TUNER_STOP;
1425 } else 2302 } else
1426 ret = FE_CALLBACK_TIME_NEVER; 2303 ret = FE_CALLBACK_TIME_NEVER;
@@ -1440,6 +2317,7 @@ enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
1440 2317
1441 return state->tune_state; 2318 return state->tune_state;
1442} 2319}
2320
1443EXPORT_SYMBOL(dib0090_get_tune_state); 2321EXPORT_SYMBOL(dib0090_get_tune_state);
1444 2322
1445int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) 2323int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
@@ -1449,6 +2327,7 @@ int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun
1449 state->tune_state = tune_state; 2327 state->tune_state = tune_state;
1450 return 0; 2328 return 0;
1451} 2329}
2330
1452EXPORT_SYMBOL(dib0090_set_tune_state); 2331EXPORT_SYMBOL(dib0090_set_tune_state);
1453 2332
1454static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) 2333static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
@@ -1462,7 +2341,7 @@ static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
1462static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) 2341static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1463{ 2342{
1464 struct dib0090_state *state = fe->tuner_priv; 2343 struct dib0090_state *state = fe->tuner_priv;
1465 uint32_t ret; 2344 u32 ret;
1466 2345
1467 state->tune_state = CT_TUNER_START; 2346 state->tune_state = CT_TUNER_START;
1468 2347
@@ -1492,6 +2371,29 @@ static const struct dvb_tuner_ops dib0090_ops = {
1492 .get_frequency = dib0090_get_frequency, 2371 .get_frequency = dib0090_get_frequency,
1493}; 2372};
1494 2373
2374static const struct dvb_tuner_ops dib0090_fw_ops = {
2375 .info = {
2376 .name = "DiBcom DiB0090",
2377 .frequency_min = 45000000,
2378 .frequency_max = 860000000,
2379 .frequency_step = 1000,
2380 },
2381 .release = dib0090_release,
2382
2383 .init = NULL,
2384 .sleep = NULL,
2385 .set_params = NULL,
2386 .get_frequency = NULL,
2387};
2388
2389static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2390 {470, 0, 250, 0, 100, 4},
2391 {860, 51, 866, 21, 375, 4},
2392 {1700, 0, 800, 0, 850, 4},
2393 {2900, 0, 250, 0, 100, 6},
2394 {0xFFFF, 0, 0, 0, 0, 0},
2395};
2396
1495struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) 2397struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
1496{ 2398{
1497 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL); 2399 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
@@ -1503,6 +2405,11 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte
1503 st->fe = fe; 2405 st->fe = fe;
1504 fe->tuner_priv = st; 2406 fe->tuner_priv = st;
1505 2407
2408 if (config->wbd == NULL)
2409 st->current_wbd_table = dib0090_wbd_table_default;
2410 else
2411 st->current_wbd_table = config->wbd;
2412
1506 if (dib0090_reset(fe) != 0) 2413 if (dib0090_reset(fe) != 0)
1507 goto free_mem; 2414 goto free_mem;
1508 2415
@@ -1515,8 +2422,34 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte
1515 fe->tuner_priv = NULL; 2422 fe->tuner_priv = NULL;
1516 return NULL; 2423 return NULL;
1517} 2424}
2425
1518EXPORT_SYMBOL(dib0090_register); 2426EXPORT_SYMBOL(dib0090_register);
1519 2427
2428struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2429{
2430 struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2431 if (st == NULL)
2432 return NULL;
2433
2434 st->config = config;
2435 st->i2c = i2c;
2436 st->fe = fe;
2437 fe->tuner_priv = st;
2438
2439 if (dib0090_fw_reset_digital(fe, st->config) != 0)
2440 goto free_mem;
2441
2442 dprintk("DiB0090 FW: successfully identified");
2443 memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2444
2445 return fe;
2446free_mem:
2447 kfree(st);
2448 fe->tuner_priv = NULL;
2449 return NULL;
2450}
2451EXPORT_SYMBOL(dib0090_fw_register);
2452
1520MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 2453MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1521MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>"); 2454MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
1522MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner"); 2455MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h
index aa7711e88776..13d85244ec16 100644
--- a/drivers/media/dvb/frontends/dib0090.h
+++ b/drivers/media/dvb/frontends/dib0090.h
@@ -27,6 +27,21 @@ struct dib0090_io_config {
27 u16 pll_int_loop_filt; 27 u16 pll_int_loop_filt;
28}; 28};
29 29
30struct dib0090_wbd_slope {
31 u16 max_freq; /* for every frequency less than or equal to that field: this information is correct */
32 u16 slope_cold;
33 u16 offset_cold;
34 u16 slope_hot;
35 u16 offset_hot;
36 u8 wbd_gain;
37};
38
39struct dib0090_low_if_offset_table {
40 int std;
41 u32 RF_freq;
42 s32 offset_khz;
43};
44
30struct dib0090_config { 45struct dib0090_config {
31 struct dib0090_io_config io; 46 struct dib0090_io_config io;
32 int (*reset) (struct dvb_frontend *, int); 47 int (*reset) (struct dvb_frontend *, int);
@@ -47,10 +62,20 @@ struct dib0090_config {
47 u16 wbd_cband_offset; 62 u16 wbd_cband_offset;
48 u8 use_pwm_agc; 63 u8 use_pwm_agc;
49 u8 clkoutdrive; 64 u8 clkoutdrive;
65
66 u8 ls_cfg_pad_drv;
67 u8 data_tx_drv;
68
69 u8 in_soc;
70 const struct dib0090_low_if_offset_table *low_if;
71 u8 fref_clock_ratio;
72 u16 force_cband_input;
73 struct dib0090_wbd_slope *wbd;
50}; 74};
51 75
52#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) 76#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
53extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); 77extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
78extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
54extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); 79extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
55extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); 80extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
56extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); 81extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
@@ -65,6 +90,12 @@ static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, str
65 return NULL; 90 return NULL;
66} 91}
67 92
93static inline struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
94{
95 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
96 return NULL;
97}
98
68static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) 99static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
69{ 100{
70 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 101 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 6aa02cb80733..900af60b9d36 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -26,24 +26,29 @@ MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (defau
26 26
27#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0) 27#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
28 28
29struct i2c_device {
30 struct i2c_adapter *i2c_adap;
31 u8 i2c_addr;
32};
33
29struct dib7000p_state { 34struct dib7000p_state {
30 struct dvb_frontend demod; 35 struct dvb_frontend demod;
31 struct dib7000p_config cfg; 36 struct dib7000p_config cfg;
32 37
33 u8 i2c_addr; 38 u8 i2c_addr;
34 struct i2c_adapter *i2c_adap; 39 struct i2c_adapter *i2c_adap;
35 40
36 struct dibx000_i2c_master i2c_master; 41 struct dibx000_i2c_master i2c_master;
37 42
38 u16 wbd_ref; 43 u16 wbd_ref;
39 44
40 u8 current_band; 45 u8 current_band;
41 u32 current_bandwidth; 46 u32 current_bandwidth;
42 struct dibx000_agc_config *current_agc; 47 struct dibx000_agc_config *current_agc;
43 u32 timf; 48 u32 timf;
44 49
45 u8 div_force_off : 1; 50 u8 div_force_off:1;
46 u8 div_state : 1; 51 u8 div_state:1;
47 u16 div_sync_wait; 52 u16 div_sync_wait;
48 53
49 u8 agc_state; 54 u8 agc_state;
@@ -51,7 +56,13 @@ struct dib7000p_state {
51 u16 gpio_dir; 56 u16 gpio_dir;
52 u16 gpio_val; 57 u16 gpio_val;
53 58
54 u8 sfn_workaround_active :1; 59 u8 sfn_workaround_active:1;
60
61#define SOC7090 0x7090
62 u16 version;
63
64 u16 tuner_enable;
65 struct i2c_adapter dib7090_tuner_adap;
55}; 66};
56 67
57enum dib7000p_power_mode { 68enum dib7000p_power_mode {
@@ -60,17 +71,20 @@ enum dib7000p_power_mode {
60 DIB7000P_POWER_INTERFACE_ONLY, 71 DIB7000P_POWER_INTERFACE_ONLY,
61}; 72};
62 73
74static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
75static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
76
63static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) 77static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
64{ 78{
65 u8 wb[2] = { reg >> 8, reg & 0xff }; 79 u8 wb[2] = { reg >> 8, reg & 0xff };
66 u8 rb[2]; 80 u8 rb[2];
67 struct i2c_msg msg[2] = { 81 struct i2c_msg msg[2] = {
68 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, 82 {.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
69 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, 83 {.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
70 }; 84 };
71 85
72 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 86 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
73 dprintk("i2c read error on %d",reg); 87 dprintk("i2c read error on %d", reg);
74 88
75 return (rb[0] << 8) | rb[1]; 89 return (rb[0] << 8) | rb[1];
76} 90}
@@ -86,7 +100,8 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
86 }; 100 };
87 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 101 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
88} 102}
89static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf) 103
104static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
90{ 105{
91 u16 l = 0, r, *n; 106 u16 l = 0, r, *n;
92 n = buf; 107 n = buf;
@@ -104,54 +119,54 @@ static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
104 119
105static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) 120static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
106{ 121{
107 int ret = 0; 122 int ret = 0;
108 u16 outreg, fifo_threshold, smo_mode; 123 u16 outreg, fifo_threshold, smo_mode;
109 124
110 outreg = 0; 125 outreg = 0;
111 fifo_threshold = 1792; 126 fifo_threshold = 1792;
112 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1); 127 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
113 128
114 dprintk( "setting output mode for demod %p to %d", 129 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
115 &state->demod, mode);
116 130
117 switch (mode) { 131 switch (mode) {
118 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 132 case OUTMODE_MPEG2_PAR_GATED_CLK:
119 outreg = (1 << 10); /* 0x0400 */ 133 outreg = (1 << 10); /* 0x0400 */
120 break; 134 break;
121 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock 135 case OUTMODE_MPEG2_PAR_CONT_CLK:
122 outreg = (1 << 10) | (1 << 6); /* 0x0440 */ 136 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
123 break; 137 break;
124 case OUTMODE_MPEG2_SERIAL: // STBs with serial input 138 case OUTMODE_MPEG2_SERIAL:
125 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */ 139 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
126 break; 140 break;
127 case OUTMODE_DIVERSITY: 141 case OUTMODE_DIVERSITY:
128 if (state->cfg.hostbus_diversity) 142 if (state->cfg.hostbus_diversity)
129 outreg = (1 << 10) | (4 << 6); /* 0x0500 */ 143 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
130 else 144 else
131 outreg = (1 << 11); 145 outreg = (1 << 11);
132 break; 146 break;
133 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding 147 case OUTMODE_MPEG2_FIFO:
134 smo_mode |= (3 << 1); 148 smo_mode |= (3 << 1);
135 fifo_threshold = 512; 149 fifo_threshold = 512;
136 outreg = (1 << 10) | (5 << 6); 150 outreg = (1 << 10) | (5 << 6);
137 break; 151 break;
138 case OUTMODE_ANALOG_ADC: 152 case OUTMODE_ANALOG_ADC:
139 outreg = (1 << 10) | (3 << 6); 153 outreg = (1 << 10) | (3 << 6);
140 break; 154 break;
141 case OUTMODE_HIGH_Z: // disable 155 case OUTMODE_HIGH_Z:
142 outreg = 0; 156 outreg = 0;
143 break; 157 break;
144 default: 158 default:
145 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod); 159 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
146 break; 160 break;
147 } 161 }
148 162
149 if (state->cfg.output_mpeg2_in_188_bytes) 163 if (state->cfg.output_mpeg2_in_188_bytes)
150 smo_mode |= (1 << 5) ; 164 smo_mode |= (1 << 5);
151 165
152 ret |= dib7000p_write_word(state, 235, smo_mode); 166 ret |= dib7000p_write_word(state, 235, smo_mode);
153 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ 167 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
154 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */ 168 if (state->version != SOC7090)
169 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
155 170
156 return ret; 171 return ret;
157} 172}
@@ -161,13 +176,13 @@ static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
161 struct dib7000p_state *state = demod->demodulator_priv; 176 struct dib7000p_state *state = demod->demodulator_priv;
162 177
163 if (state->div_force_off) { 178 if (state->div_force_off) {
164 dprintk( "diversity combination deactivated - forced by COFDM parameters"); 179 dprintk("diversity combination deactivated - forced by COFDM parameters");
165 onoff = 0; 180 onoff = 0;
166 dib7000p_write_word(state, 207, 0); 181 dib7000p_write_word(state, 207, 0);
167 } else 182 } else
168 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); 183 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
169 184
170 state->div_state = (u8)onoff; 185 state->div_state = (u8) onoff;
171 186
172 if (onoff) { 187 if (onoff) {
173 dib7000p_write_word(state, 204, 6); 188 dib7000p_write_word(state, 204, 6);
@@ -184,37 +199,48 @@ static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
184static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode) 199static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
185{ 200{
186 /* by default everything is powered off */ 201 /* by default everything is powered off */
187 u16 reg_774 = 0xffff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, 202 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
188 reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
189 203
190 /* now, depending on the requested mode, we power on */ 204 /* now, depending on the requested mode, we power on */
191 switch (mode) { 205 switch (mode) {
192 /* power up everything in the demod */ 206 /* power up everything in the demod */
193 case DIB7000P_POWER_ALL: 207 case DIB7000P_POWER_ALL:
194 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff; 208 reg_774 = 0x0000;
195 break; 209 reg_775 = 0x0000;
196 210 reg_776 = 0x0;
197 case DIB7000P_POWER_ANALOG_ADC: 211 reg_899 = 0x0;
198 /* dem, cfg, iqc, sad, agc */ 212 if (state->version == SOC7090)
199 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9)); 213 reg_1280 &= 0x001f;
200 /* nud */ 214 else
201 reg_776 &= ~((1 << 0)); 215 reg_1280 &= 0x01ff;
202 /* Dout */ 216 break;
217
218 case DIB7000P_POWER_ANALOG_ADC:
219 /* dem, cfg, iqc, sad, agc */
220 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
221 /* nud */
222 reg_776 &= ~((1 << 0));
223 /* Dout */
224 if (state->version != SOC7090)
203 reg_1280 &= ~((1 << 11)); 225 reg_1280 &= ~((1 << 11));
204 /* fall through wanted to enable the interfaces */ 226 reg_1280 &= ~(1 << 6);
227 /* fall through wanted to enable the interfaces */
205 228
206 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */ 229 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
207 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */ 230 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
231 if (state->version == SOC7090)
232 reg_1280 &= ~((1 << 7) | (1 << 5));
233 else
208 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); 234 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
209 break; 235 break;
210 236
211/* TODO following stuff is just converted from the dib7000-driver - check when is used what */ 237/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
212 } 238 }
213 239
214 dib7000p_write_word(state, 774, reg_774); 240 dib7000p_write_word(state, 774, reg_774);
215 dib7000p_write_word(state, 775, reg_775); 241 dib7000p_write_word(state, 775, reg_775);
216 dib7000p_write_word(state, 776, reg_776); 242 dib7000p_write_word(state, 776, reg_776);
217 dib7000p_write_word(state, 899, reg_899); 243 dib7000p_write_word(state, 899, reg_899);
218 dib7000p_write_word(state, 1280, reg_1280); 244 dib7000p_write_word(state, 1280, reg_1280);
219 245
220 return 0; 246 return 0;
@@ -222,40 +248,57 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p
222 248
223static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) 249static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
224{ 250{
225 u16 reg_908 = dib7000p_read_word(state, 908), 251 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
226 reg_909 = dib7000p_read_word(state, 909); 252 u16 reg;
227 253
228 switch (no) { 254 switch (no) {
229 case DIBX000_SLOW_ADC_ON: 255 case DIBX000_SLOW_ADC_ON:
256 if (state->version == SOC7090) {
257 reg = dib7000p_read_word(state, 1925);
258
259 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
260
261 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
262 msleep(200);
263 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
264
265 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
266 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
267 } else {
230 reg_909 |= (1 << 1) | (1 << 0); 268 reg_909 |= (1 << 1) | (1 << 0);
231 dib7000p_write_word(state, 909, reg_909); 269 dib7000p_write_word(state, 909, reg_909);
232 reg_909 &= ~(1 << 1); 270 reg_909 &= ~(1 << 1);
233 break; 271 }
272 break;
234 273
235 case DIBX000_SLOW_ADC_OFF: 274 case DIBX000_SLOW_ADC_OFF:
236 reg_909 |= (1 << 1) | (1 << 0); 275 if (state->version == SOC7090) {
237 break; 276 reg = dib7000p_read_word(state, 1925);
277 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
278 } else
279 reg_909 |= (1 << 1) | (1 << 0);
280 break;
238 281
239 case DIBX000_ADC_ON: 282 case DIBX000_ADC_ON:
240 reg_908 &= 0x0fff; 283 reg_908 &= 0x0fff;
241 reg_909 &= 0x0003; 284 reg_909 &= 0x0003;
242 break; 285 break;
243 286
244 case DIBX000_ADC_OFF: // leave the VBG voltage on 287 case DIBX000_ADC_OFF:
245 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12); 288 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
246 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); 289 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
247 break; 290 break;
248 291
249 case DIBX000_VBG_ENABLE: 292 case DIBX000_VBG_ENABLE:
250 reg_908 &= ~(1 << 15); 293 reg_908 &= ~(1 << 15);
251 break; 294 break;
252 295
253 case DIBX000_VBG_DISABLE: 296 case DIBX000_VBG_DISABLE:
254 reg_908 |= (1 << 15); 297 reg_908 |= (1 << 15);
255 break; 298 break;
256 299
257 default: 300 default:
258 break; 301 break;
259 } 302 }
260 303
261// dprintk( "908: %x, 909: %x\n", reg_908, reg_909); 304// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
@@ -275,17 +318,17 @@ static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
275 state->current_bandwidth = bw; 318 state->current_bandwidth = bw;
276 319
277 if (state->timf == 0) { 320 if (state->timf == 0) {
278 dprintk( "using default timf"); 321 dprintk("using default timf");
279 timf = state->cfg.bw->timf; 322 timf = state->cfg.bw->timf;
280 } else { 323 } else {
281 dprintk( "using updated timf"); 324 dprintk("using updated timf");
282 timf = state->timf; 325 timf = state->timf;
283 } 326 }
284 327
285 timf = timf * (bw / 50) / 160; 328 timf = timf * (bw / 50) / 160;
286 329
287 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff)); 330 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
288 dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff)); 331 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
289 332
290 return 0; 333 return 0;
291} 334}
@@ -293,9 +336,12 @@ static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
293static int dib7000p_sad_calib(struct dib7000p_state *state) 336static int dib7000p_sad_calib(struct dib7000p_state *state)
294{ 337{
295/* internal */ 338/* internal */
296// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
297 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0)); 339 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
298 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096 340
341 if (state->version == SOC7090)
342 dib7000p_write_word(state, 74, 2048);
343 else
344 dib7000p_write_word(state, 74, 776);
299 345
300 /* do the calibration */ 346 /* do the calibration */
301 dib7000p_write_word(state, 73, (1 << 0)); 347 dib7000p_write_word(state, 73, (1 << 0));
@@ -314,37 +360,91 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
314 state->wbd_ref = value; 360 state->wbd_ref = value;
315 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value); 361 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
316} 362}
317
318EXPORT_SYMBOL(dib7000p_set_wbd_ref); 363EXPORT_SYMBOL(dib7000p_set_wbd_ref);
364
319static void dib7000p_reset_pll(struct dib7000p_state *state) 365static void dib7000p_reset_pll(struct dib7000p_state *state)
320{ 366{
321 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; 367 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
322 u16 clk_cfg0; 368 u16 clk_cfg0;
323 369
324 /* force PLL bypass */ 370 if (state->version == SOC7090) {
325 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) | 371 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
326 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | 372
327 (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0); 373 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
374 ;
328 375
329 dib7000p_write_word(state, 900, clk_cfg0); 376 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
377 } else {
378 /* force PLL bypass */
379 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
380 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
381
382 dib7000p_write_word(state, 900, clk_cfg0);
330 383
331 /* P_pll_cfg */ 384 /* P_pll_cfg */
332 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset); 385 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
333 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff); 386 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
334 dib7000p_write_word(state, 900, clk_cfg0); 387 dib7000p_write_word(state, 900, clk_cfg0);
388 }
335 389
336 dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff)); 390 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
337 dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff)); 391 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
338 dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff)); 392 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
339 dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff)); 393 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
340 394
341 dib7000p_write_word(state, 72, bw->sad_cfg); 395 dib7000p_write_word(state, 72, bw->sad_cfg);
342} 396}
343 397
398static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
399{
400 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
401 internal |= (u32) dib7000p_read_word(state, 19);
402 internal /= 1000;
403
404 return internal;
405}
406
407int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
408{
409 struct dib7000p_state *state = fe->demodulator_priv;
410 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
411 u8 loopdiv, prediv;
412 u32 internal, xtal;
413
414 /* get back old values */
415 prediv = reg_1856 & 0x3f;
416 loopdiv = (reg_1856 >> 6) & 0x3f;
417
418 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
419 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
420 reg_1856 &= 0xf000;
421 reg_1857 = dib7000p_read_word(state, 1857);
422 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
423
424 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
425
426 /* write new system clk into P_sec_len */
427 internal = dib7000p_get_internal_freq(state);
428 xtal = (internal / loopdiv) * prediv;
429 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
430 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
431 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
432
433 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
434
435 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
436 dprintk("Waiting for PLL to lock");
437
438 return 0;
439 }
440 return -EIO;
441}
442EXPORT_SYMBOL(dib7000p_update_pll);
443
344static int dib7000p_reset_gpio(struct dib7000p_state *st) 444static int dib7000p_reset_gpio(struct dib7000p_state *st)
345{ 445{
346 /* reset the GPIOs */ 446 /* reset the GPIOs */
347 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos); 447 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
348 448
349 dib7000p_write_word(st, 1029, st->gpio_dir); 449 dib7000p_write_word(st, 1029, st->gpio_dir);
350 dib7000p_write_word(st, 1030, st->gpio_val); 450 dib7000p_write_word(st, 1030, st->gpio_val);
@@ -360,13 +460,13 @@ static int dib7000p_reset_gpio(struct dib7000p_state *st)
360static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val) 460static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
361{ 461{
362 st->gpio_dir = dib7000p_read_word(st, 1029); 462 st->gpio_dir = dib7000p_read_word(st, 1029);
363 st->gpio_dir &= ~(1 << num); /* reset the direction bit */ 463 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
364 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */ 464 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
365 dib7000p_write_word(st, 1029, st->gpio_dir); 465 dib7000p_write_word(st, 1029, st->gpio_dir);
366 466
367 st->gpio_val = dib7000p_read_word(st, 1030); 467 st->gpio_val = dib7000p_read_word(st, 1030);
368 st->gpio_val &= ~(1 << num); /* reset the direction bit */ 468 st->gpio_val &= ~(1 << num); /* reset the direction bit */
369 st->gpio_val |= (val & 0x01) << num; /* set the new value */ 469 st->gpio_val |= (val & 0x01) << num; /* set the new value */
370 dib7000p_write_word(st, 1030, st->gpio_val); 470 dib7000p_write_word(st, 1030, st->gpio_val);
371 471
372 return 0; 472 return 0;
@@ -377,96 +477,94 @@ int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
377 struct dib7000p_state *state = demod->demodulator_priv; 477 struct dib7000p_state *state = demod->demodulator_priv;
378 return dib7000p_cfg_gpio(state, num, dir, val); 478 return dib7000p_cfg_gpio(state, num, dir, val);
379} 479}
380
381EXPORT_SYMBOL(dib7000p_set_gpio); 480EXPORT_SYMBOL(dib7000p_set_gpio);
382static u16 dib7000p_defaults[] =
383 481
384{ 482static u16 dib7000p_defaults[] = {
385 // auto search configuration 483 // auto search configuration
386 3, 2, 484 3, 2,
387 0x0004, 485 0x0004,
388 0x1000, 486 0x1000,
389 0x0814, /* Equal Lock */ 487 0x0814, /* Equal Lock */
390 488
391 12, 6, 489 12, 6,
392 0x001b, 490 0x001b,
393 0x7740, 491 0x7740,
394 0x005b, 492 0x005b,
395 0x8d80, 493 0x8d80,
396 0x01c9, 494 0x01c9,
397 0xc380, 495 0xc380,
398 0x0000, 496 0x0000,
399 0x0080, 497 0x0080,
400 0x0000, 498 0x0000,
401 0x0090, 499 0x0090,
402 0x0001, 500 0x0001,
403 0xd4c0, 501 0xd4c0,
404 502
405 1, 26, 503 1, 26,
406 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26 504 0x6680,
407 505
408 /* set ADC level to -16 */ 506 /* set ADC level to -16 */
409 11, 79, 507 11, 79,
410 (1 << 13) - 825 - 117, 508 (1 << 13) - 825 - 117,
411 (1 << 13) - 837 - 117, 509 (1 << 13) - 837 - 117,
412 (1 << 13) - 811 - 117, 510 (1 << 13) - 811 - 117,
413 (1 << 13) - 766 - 117, 511 (1 << 13) - 766 - 117,
414 (1 << 13) - 737 - 117, 512 (1 << 13) - 737 - 117,
415 (1 << 13) - 693 - 117, 513 (1 << 13) - 693 - 117,
416 (1 << 13) - 648 - 117, 514 (1 << 13) - 648 - 117,
417 (1 << 13) - 619 - 117, 515 (1 << 13) - 619 - 117,
418 (1 << 13) - 575 - 117, 516 (1 << 13) - 575 - 117,
419 (1 << 13) - 531 - 117, 517 (1 << 13) - 531 - 117,
420 (1 << 13) - 501 - 117, 518 (1 << 13) - 501 - 117,
421 519
422 1, 142, 520 1, 142,
423 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16 521 0x0410,
424 522
425 /* disable power smoothing */ 523 /* disable power smoothing */
426 8, 145, 524 8, 145,
427 0, 525 0,
428 0, 526 0,
429 0, 527 0,
430 0, 528 0,
431 0, 529 0,
432 0, 530 0,
433 0, 531 0,
434 0, 532 0,
435 533
436 1, 154, 534 1, 154,
437 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0 535 1 << 13,
438 536
439 1, 168, 537 1, 168,
440 0x0ccd, // P_pha3_thres, default 0x3000 538 0x0ccd,
441
442// 1, 169,
443// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
444 539
445 1, 183, 540 1, 183,
446 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005 541 0x200f,
542
543 1, 212,
544 0x169,
447 545
448 5, 187, 546 5, 187,
449 0x023d, // P_adp_regul_cnt=573, default: 410 547 0x023d,
450 0x00a4, // P_adp_noise_cnt= 548 0x00a4,
451 0x00a4, // P_adp_regul_ext 549 0x00a4,
452 0x7ff0, // P_adp_noise_ext 550 0x7ff0,
453 0x3ccc, // P_adp_fil 551 0x3ccc,
454 552
455 1, 198, 553 1, 198,
456 0x800, // P_equal_thres_wgn 554 0x800,
457 555
458 1, 222, 556 1, 222,
459 0x0010, // P_fec_ber_rs_len=2 557 0x0010,
460 558
461 1, 235, 559 1, 235,
462 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard 560 0x0062,
463 561
464 2, 901, 562 2, 901,
465 0x0006, // P_clk_cfg1 563 0x0006,
466 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1 564 (3 << 10) | (1 << 6),
467 565
468 1, 905, 566 1, 905,
469 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive 567 0x2c8e,
470 568
471 0, 569 0,
472}; 570};
@@ -475,51 +573,64 @@ static int dib7000p_demod_reset(struct dib7000p_state *state)
475{ 573{
476 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 574 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
477 575
576 if (state->version == SOC7090)
577 dibx000_reset_i2c_master(&state->i2c_master);
578
478 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE); 579 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
479 580
480 /* restart all parts */ 581 /* restart all parts */
481 dib7000p_write_word(state, 770, 0xffff); 582 dib7000p_write_word(state, 770, 0xffff);
482 dib7000p_write_word(state, 771, 0xffff); 583 dib7000p_write_word(state, 771, 0xffff);
483 dib7000p_write_word(state, 772, 0x001f); 584 dib7000p_write_word(state, 772, 0x001f);
484 dib7000p_write_word(state, 898, 0x0003); 585 dib7000p_write_word(state, 898, 0x0003);
485 /* except i2c, sdio, gpio - control interfaces */ 586 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
486 dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) ); 587
487 588 dib7000p_write_word(state, 770, 0);
488 dib7000p_write_word(state, 770, 0); 589 dib7000p_write_word(state, 771, 0);
489 dib7000p_write_word(state, 771, 0); 590 dib7000p_write_word(state, 772, 0);
490 dib7000p_write_word(state, 772, 0); 591 dib7000p_write_word(state, 898, 0);
491 dib7000p_write_word(state, 898, 0);
492 dib7000p_write_word(state, 1280, 0); 592 dib7000p_write_word(state, 1280, 0);
493 593
494 /* default */ 594 /* default */
495 dib7000p_reset_pll(state); 595 dib7000p_reset_pll(state);
496 596
497 if (dib7000p_reset_gpio(state) != 0) 597 if (dib7000p_reset_gpio(state) != 0)
498 dprintk( "GPIO reset was not successful."); 598 dprintk("GPIO reset was not successful.");
499
500 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
501 dprintk( "OUTPUT_MODE could not be reset.");
502 599
503 /* unforce divstr regardless whether i2c enumeration was done or not */ 600 if (state->version == SOC7090) {
504 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) ); 601 dib7000p_write_word(state, 899, 0);
505 602
506 dib7000p_set_bandwidth(state, 8000); 603 /* impulse noise */
604 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
605 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
606 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
607 dib7000p_write_word(state, 273, (1<<6) | 30);
608 }
609 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
610 dprintk("OUTPUT_MODE could not be reset.");
507 611
508 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 612 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
509 dib7000p_sad_calib(state); 613 dib7000p_sad_calib(state);
510 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 614 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
511 615
512 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ... 616 /* unforce divstr regardless whether i2c enumeration was done or not */
513 if(state->cfg.tuner_is_baseband) 617 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
514 dib7000p_write_word(state, 36,0x0755); 618
515 else 619 dib7000p_set_bandwidth(state, 8000);
516 dib7000p_write_word(state, 36,0x1f55); 620
621 if (state->version == SOC7090) {
622 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
623 } else {
624 if (state->cfg.tuner_is_baseband)
625 dib7000p_write_word(state, 36, 0x0755);
626 else
627 dib7000p_write_word(state, 36, 0x1f55);
628 }
517 629
518 dib7000p_write_tab(state, dib7000p_defaults); 630 dib7000p_write_tab(state, dib7000p_defaults);
519 631
520 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 632 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
521 633
522
523 return 0; 634 return 0;
524} 635}
525 636
@@ -527,9 +638,9 @@ static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
527{ 638{
528 u16 tmp = 0; 639 u16 tmp = 0;
529 tmp = dib7000p_read_word(state, 903); 640 tmp = dib7000p_read_word(state, 903);
530 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll 641 dib7000p_write_word(state, 903, (tmp | 0x1));
531 tmp = dib7000p_read_word(state, 900); 642 tmp = dib7000p_read_word(state, 900);
532 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock 643 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
533} 644}
534 645
535static void dib7000p_restart_agc(struct dib7000p_state *state) 646static void dib7000p_restart_agc(struct dib7000p_state *state)
@@ -543,11 +654,9 @@ static int dib7000p_update_lna(struct dib7000p_state *state)
543{ 654{
544 u16 dyn_gain; 655 u16 dyn_gain;
545 656
546 // when there is no LNA to program return immediatly
547 if (state->cfg.update_lna) { 657 if (state->cfg.update_lna) {
548 // read dyn_gain here (because it is demod-dependent and not fe)
549 dyn_gain = dib7000p_read_word(state, 394); 658 dyn_gain = dib7000p_read_word(state, 394);
550 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed 659 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
551 dib7000p_restart_agc(state); 660 dib7000p_restart_agc(state);
552 return 1; 661 return 1;
553 } 662 }
@@ -571,24 +680,24 @@ static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
571 } 680 }
572 681
573 if (agc == NULL) { 682 if (agc == NULL) {
574 dprintk( "no valid AGC configuration found for band 0x%02x",band); 683 dprintk("no valid AGC configuration found for band 0x%02x", band);
575 return -EINVAL; 684 return -EINVAL;
576 } 685 }
577 686
578 state->current_agc = agc; 687 state->current_agc = agc;
579 688
580 /* AGC */ 689 /* AGC */
581 dib7000p_write_word(state, 75 , agc->setup ); 690 dib7000p_write_word(state, 75, agc->setup);
582 dib7000p_write_word(state, 76 , agc->inv_gain ); 691 dib7000p_write_word(state, 76, agc->inv_gain);
583 dib7000p_write_word(state, 77 , agc->time_stabiliz ); 692 dib7000p_write_word(state, 77, agc->time_stabiliz);
584 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock); 693 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
585 694
586 // Demod AGC loop configuration 695 // Demod AGC loop configuration
587 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp); 696 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
588 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp); 697 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
589 698
590 /* AGC continued */ 699 /* AGC continued */
591 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d", 700 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
592 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); 701 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
593 702
594 if (state->wbd_ref != 0) 703 if (state->wbd_ref != 0)
@@ -598,101 +707,135 @@ static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
598 707
599 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); 708 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
600 709
601 dib7000p_write_word(state, 107, agc->agc1_max); 710 dib7000p_write_word(state, 107, agc->agc1_max);
602 dib7000p_write_word(state, 108, agc->agc1_min); 711 dib7000p_write_word(state, 108, agc->agc1_min);
603 dib7000p_write_word(state, 109, agc->agc2_max); 712 dib7000p_write_word(state, 109, agc->agc2_max);
604 dib7000p_write_word(state, 110, agc->agc2_min); 713 dib7000p_write_word(state, 110, agc->agc2_min);
605 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2); 714 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
606 dib7000p_write_word(state, 112, agc->agc1_pt3); 715 dib7000p_write_word(state, 112, agc->agc1_pt3);
607 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2); 716 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
608 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2); 717 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
609 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); 718 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
610 return 0; 719 return 0;
611} 720}
612 721
722static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
723{
724 u32 internal = dib7000p_get_internal_freq(state);
725 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
726 u32 abs_offset_khz = ABS(offset_khz);
727 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
728 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
729
730 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
731
732 if (offset_khz < 0)
733 unit_khz_dds_val *= -1;
734
735 /* IF tuner */
736 if (invert)
737 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
738 else
739 dds += (abs_offset_khz * unit_khz_dds_val);
740
741 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
742 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
743 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
744 }
745}
746
613static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) 747static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
614{ 748{
615 struct dib7000p_state *state = demod->demodulator_priv; 749 struct dib7000p_state *state = demod->demodulator_priv;
616 int ret = -1; 750 int ret = -1;
617 u8 *agc_state = &state->agc_state; 751 u8 *agc_state = &state->agc_state;
618 u8 agc_split; 752 u8 agc_split;
753 u16 reg;
754 u32 upd_demod_gain_period = 0x1000;
619 755
620 switch (state->agc_state) { 756 switch (state->agc_state) {
621 case 0: 757 case 0:
622 // set power-up level: interf+analog+AGC 758 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
623 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 759 if (state->version == SOC7090) {
760 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
761 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
762 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
763
764 /* enable adc i & q */
765 reg = dib7000p_read_word(state, 0x780);
766 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
767 } else {
624 dib7000p_set_adc_state(state, DIBX000_ADC_ON); 768 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
625 dib7000p_pll_clk_cfg(state); 769 dib7000p_pll_clk_cfg(state);
770 }
626 771
627 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0) 772 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
628 return -1; 773 return -1;
629
630 ret = 7;
631 (*agc_state)++;
632 break;
633 774
634 case 1: 775 dib7000p_set_dds(state, 0);
635 // AGC initialization 776 ret = 7;
636 if (state->cfg.agc_control) 777 (*agc_state)++;
637 state->cfg.agc_control(&state->demod, 1); 778 break;
638
639 dib7000p_write_word(state, 78, 32768);
640 if (!state->current_agc->perform_agc_softsplit) {
641 /* we are using the wbd - so slow AGC startup */
642 /* force 0 split on WBD and restart AGC */
643 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
644 (*agc_state)++;
645 ret = 5;
646 } else {
647 /* default AGC startup */
648 (*agc_state) = 4;
649 /* wait AGC rough lock time */
650 ret = 7;
651 }
652 779
653 dib7000p_restart_agc(state); 780 case 1:
654 break; 781 if (state->cfg.agc_control)
782 state->cfg.agc_control(&state->demod, 1);
655 783
656 case 2: /* fast split search path after 5sec */ 784 dib7000p_write_word(state, 78, 32768);
657 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */ 785 if (!state->current_agc->perform_agc_softsplit) {
658 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */ 786 /* we are using the wbd - so slow AGC startup */
787 /* force 0 split on WBD and restart AGC */
788 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
659 (*agc_state)++; 789 (*agc_state)++;
660 ret = 14; 790 ret = 5;
661 break; 791 } else {
792 /* default AGC startup */
793 (*agc_state) = 4;
794 /* wait AGC rough lock time */
795 ret = 7;
796 }
662 797
663 case 3: /* split search ended */ 798 dib7000p_restart_agc(state);
664 agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */ 799 break;
665 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
666 800
667 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */ 801 case 2: /* fast split search path after 5sec */
668 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */ 802 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
803 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
804 (*agc_state)++;
805 ret = 14;
806 break;
669 807
670 dib7000p_restart_agc(state); 808 case 3: /* split search ended */
809 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
810 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
671 811
672 dprintk( "SPLIT %p: %hd", demod, agc_split); 812 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
813 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
673 814
674 (*agc_state)++; 815 dib7000p_restart_agc(state);
675 ret = 5;
676 break;
677 816
678 case 4: /* LNA startup */ 817 dprintk("SPLIT %p: %hd", demod, agc_split);
679 // wait AGC accurate lock time
680 ret = 7;
681 818
682 if (dib7000p_update_lna(state)) 819 (*agc_state)++;
683 // wait only AGC rough lock time 820 ret = 5;
684 ret = 5; 821 break;
685 else // nothing was done, go to the next state
686 (*agc_state)++;
687 break;
688 822
689 case 5: 823 case 4: /* LNA startup */
690 if (state->cfg.agc_control) 824 ret = 7;
691 state->cfg.agc_control(&state->demod, 0); 825
826 if (dib7000p_update_lna(state))
827 ret = 5;
828 else
692 (*agc_state)++; 829 (*agc_state)++;
693 break; 830 break;
694 default: 831
695 break; 832 case 5:
833 if (state->cfg.agc_control)
834 state->cfg.agc_control(&state->demod, 0);
835 (*agc_state)++;
836 break;
837 default:
838 break;
696 } 839 }
697 return ret; 840 return ret;
698} 841}
@@ -703,45 +846,89 @@ static void dib7000p_update_timf(struct dib7000p_state *state)
703 state->timf = timf * 160 / (state->current_bandwidth / 50); 846 state->timf = timf * 160 / (state->current_bandwidth / 50);
704 dib7000p_write_word(state, 23, (u16) (timf >> 16)); 847 dib7000p_write_word(state, 23, (u16) (timf >> 16));
705 dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); 848 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
706 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf); 849 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
850
851}
707 852
853u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
854{
855 struct dib7000p_state *state = fe->demodulator_priv;
856 switch (op) {
857 case DEMOD_TIMF_SET:
858 state->timf = timf;
859 break;
860 case DEMOD_TIMF_UPDATE:
861 dib7000p_update_timf(state);
862 break;
863 case DEMOD_TIMF_GET:
864 break;
865 }
866 dib7000p_set_bandwidth(state, state->current_bandwidth);
867 return state->timf;
708} 868}
869EXPORT_SYMBOL(dib7000p_ctrl_timf);
709 870
710static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq) 871static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
711{ 872{
712 u16 value, est[4]; 873 u16 value, est[4];
713 874
714 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 875 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
715 876
716 /* nfft, guard, qam, alpha */ 877 /* nfft, guard, qam, alpha */
717 value = 0; 878 value = 0;
718 switch (ch->u.ofdm.transmission_mode) { 879 switch (ch->u.ofdm.transmission_mode) {
719 case TRANSMISSION_MODE_2K: value |= (0 << 7); break; 880 case TRANSMISSION_MODE_2K:
720 case TRANSMISSION_MODE_4K: value |= (2 << 7); break; 881 value |= (0 << 7);
721 default: 882 break;
722 case TRANSMISSION_MODE_8K: value |= (1 << 7); break; 883 case TRANSMISSION_MODE_4K:
884 value |= (2 << 7);
885 break;
886 default:
887 case TRANSMISSION_MODE_8K:
888 value |= (1 << 7);
889 break;
723 } 890 }
724 switch (ch->u.ofdm.guard_interval) { 891 switch (ch->u.ofdm.guard_interval) {
725 case GUARD_INTERVAL_1_32: value |= (0 << 5); break; 892 case GUARD_INTERVAL_1_32:
726 case GUARD_INTERVAL_1_16: value |= (1 << 5); break; 893 value |= (0 << 5);
727 case GUARD_INTERVAL_1_4: value |= (3 << 5); break; 894 break;
728 default: 895 case GUARD_INTERVAL_1_16:
729 case GUARD_INTERVAL_1_8: value |= (2 << 5); break; 896 value |= (1 << 5);
897 break;
898 case GUARD_INTERVAL_1_4:
899 value |= (3 << 5);
900 break;
901 default:
902 case GUARD_INTERVAL_1_8:
903 value |= (2 << 5);
904 break;
730 } 905 }
731 switch (ch->u.ofdm.constellation) { 906 switch (ch->u.ofdm.constellation) {
732 case QPSK: value |= (0 << 3); break; 907 case QPSK:
733 case QAM_16: value |= (1 << 3); break; 908 value |= (0 << 3);
734 default: 909 break;
735 case QAM_64: value |= (2 << 3); break; 910 case QAM_16:
911 value |= (1 << 3);
912 break;
913 default:
914 case QAM_64:
915 value |= (2 << 3);
916 break;
736 } 917 }
737 switch (HIERARCHY_1) { 918 switch (HIERARCHY_1) {
738 case HIERARCHY_2: value |= 2; break; 919 case HIERARCHY_2:
739 case HIERARCHY_4: value |= 4; break; 920 value |= 2;
740 default: 921 break;
741 case HIERARCHY_1: value |= 1; break; 922 case HIERARCHY_4:
923 value |= 4;
924 break;
925 default:
926 case HIERARCHY_1:
927 value |= 1;
928 break;
742 } 929 }
743 dib7000p_write_word(state, 0, value); 930 dib7000p_write_word(state, 0, value);
744 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */ 931 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
745 932
746 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */ 933 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
747 value = 0; 934 value = 0;
@@ -752,39 +939,63 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
752 if (1 == 1) 939 if (1 == 1)
753 value |= 1; 940 value |= 1;
754 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { 941 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
755 case FEC_2_3: value |= (2 << 1); break; 942 case FEC_2_3:
756 case FEC_3_4: value |= (3 << 1); break; 943 value |= (2 << 1);
757 case FEC_5_6: value |= (5 << 1); break; 944 break;
758 case FEC_7_8: value |= (7 << 1); break; 945 case FEC_3_4:
759 default: 946 value |= (3 << 1);
760 case FEC_1_2: value |= (1 << 1); break; 947 break;
948 case FEC_5_6:
949 value |= (5 << 1);
950 break;
951 case FEC_7_8:
952 value |= (7 << 1);
953 break;
954 default:
955 case FEC_1_2:
956 value |= (1 << 1);
957 break;
761 } 958 }
762 dib7000p_write_word(state, 208, value); 959 dib7000p_write_word(state, 208, value);
763 960
764 /* offset loop parameters */ 961 /* offset loop parameters */
765 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) 962 dib7000p_write_word(state, 26, 0x6680);
766 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) 963 dib7000p_write_word(state, 32, 0x0003);
767 dib7000p_write_word(state, 29, 0x1273); // isi 964 dib7000p_write_word(state, 29, 0x1273);
768 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5) 965 dib7000p_write_word(state, 33, 0x0005);
769 966
770 /* P_dvsy_sync_wait */ 967 /* P_dvsy_sync_wait */
771 switch (ch->u.ofdm.transmission_mode) { 968 switch (ch->u.ofdm.transmission_mode) {
772 case TRANSMISSION_MODE_8K: value = 256; break; 969 case TRANSMISSION_MODE_8K:
773 case TRANSMISSION_MODE_4K: value = 128; break; 970 value = 256;
774 case TRANSMISSION_MODE_2K: 971 break;
775 default: value = 64; break; 972 case TRANSMISSION_MODE_4K:
973 value = 128;
974 break;
975 case TRANSMISSION_MODE_2K:
976 default:
977 value = 64;
978 break;
776 } 979 }
777 switch (ch->u.ofdm.guard_interval) { 980 switch (ch->u.ofdm.guard_interval) {
778 case GUARD_INTERVAL_1_16: value *= 2; break; 981 case GUARD_INTERVAL_1_16:
779 case GUARD_INTERVAL_1_8: value *= 4; break; 982 value *= 2;
780 case GUARD_INTERVAL_1_4: value *= 8; break; 983 break;
781 default: 984 case GUARD_INTERVAL_1_8:
782 case GUARD_INTERVAL_1_32: value *= 1; break; 985 value *= 4;
986 break;
987 case GUARD_INTERVAL_1_4:
988 value *= 8;
989 break;
990 default:
991 case GUARD_INTERVAL_1_32:
992 value *= 1;
993 break;
783 } 994 }
784 if (state->cfg.diversity_delay == 0) 995 if (state->cfg.diversity_delay == 0)
785 state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo 996 state->div_sync_wait = (value * 3) / 2 + 48;
786 else 997 else
787 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo 998 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
788 999
789 /* deactive the possibility of diversity reception if extended interleaver */ 1000 /* deactive the possibility of diversity reception if extended interleaver */
790 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; 1001 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
@@ -792,24 +1003,24 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
792 1003
793 /* channel estimation fine configuration */ 1004 /* channel estimation fine configuration */
794 switch (ch->u.ofdm.constellation) { 1005 switch (ch->u.ofdm.constellation) {
795 case QAM_64: 1006 case QAM_64:
796 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ 1007 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
797 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ 1008 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
798 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 1009 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
799 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ 1010 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
800 break; 1011 break;
801 case QAM_16: 1012 case QAM_16:
802 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ 1013 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
803 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ 1014 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
804 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 1015 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
805 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */ 1016 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
806 break; 1017 break;
807 default: 1018 default:
808 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */ 1019 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
809 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */ 1020 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
810 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */ 1021 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
811 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ 1022 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
812 break; 1023 break;
813 } 1024 }
814 for (value = 0; value < 4; value++) 1025 for (value = 0; value < 4; value++)
815 dib7000p_write_word(state, 187 + value, est[value]); 1026 dib7000p_write_word(state, 187 + value, est[value]);
@@ -820,14 +1031,15 @@ static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_fron
820 struct dib7000p_state *state = demod->demodulator_priv; 1031 struct dib7000p_state *state = demod->demodulator_priv;
821 struct dvb_frontend_parameters schan; 1032 struct dvb_frontend_parameters schan;
822 u32 value, factor; 1033 u32 value, factor;
1034 u32 internal = dib7000p_get_internal_freq(state);
823 1035
824 schan = *ch; 1036 schan = *ch;
825 schan.u.ofdm.constellation = QAM_64; 1037 schan.u.ofdm.constellation = QAM_64;
826 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; 1038 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
827 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; 1039 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
828 schan.u.ofdm.code_rate_HP = FEC_2_3; 1040 schan.u.ofdm.code_rate_HP = FEC_2_3;
829 schan.u.ofdm.code_rate_LP = FEC_3_4; 1041 schan.u.ofdm.code_rate_LP = FEC_3_4;
830 schan.u.ofdm.hierarchy_information = 0; 1042 schan.u.ofdm.hierarchy_information = 0;
831 1043
832 dib7000p_set_channel(state, &schan, 7); 1044 dib7000p_set_channel(state, &schan, 7);
833 1045
@@ -837,16 +1049,15 @@ static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_fron
837 else 1049 else
838 factor = 6; 1050 factor = 6;
839 1051
840 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer 1052 value = 30 * internal * factor;
841 value = 30 * state->cfg.bw->internal * factor; 1053 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
842 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time 1054 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
843 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time 1055 value = 100 * internal * factor;
844 value = 100 * state->cfg.bw->internal * factor; 1056 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
845 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time 1057 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
846 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time 1058 value = 500 * internal * factor;
847 value = 500 * state->cfg.bw->internal * factor; 1059 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
848 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time 1060 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
849 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
850 1061
851 value = dib7000p_read_word(state, 0); 1062 value = dib7000p_read_word(state, 0);
852 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value)); 1063 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
@@ -861,101 +1072,101 @@ static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
861 struct dib7000p_state *state = demod->demodulator_priv; 1072 struct dib7000p_state *state = demod->demodulator_priv;
862 u16 irq_pending = dib7000p_read_word(state, 1284); 1073 u16 irq_pending = dib7000p_read_word(state, 1284);
863 1074
864 if (irq_pending & 0x1) // failed 1075 if (irq_pending & 0x1)
865 return 1; 1076 return 1;
866 1077
867 if (irq_pending & 0x2) // succeeded 1078 if (irq_pending & 0x2)
868 return 2; 1079 return 2;
869 1080
870 return 0; // still pending 1081 return 0;
871} 1082}
872 1083
873static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw) 1084static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
874{ 1085{
875 static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392}; 1086 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
876 static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, 1087 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
877 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 1088 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
878 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, 1089 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
879 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105, 1090 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
880 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126, 1091 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
881 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, 1092 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
882 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165, 1093 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
883 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 1094 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
884 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 1095 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
885 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212, 1096 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
886 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224, 1097 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
887 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, 1098 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
888 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243, 1099 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
889 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249, 1100 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
890 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 1101 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
891 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1102 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
892 255, 255, 255, 255, 255, 255}; 1103 255, 255, 255, 255, 255, 255
1104 };
893 1105
894 u32 xtal = state->cfg.bw->xtal_hz / 1000; 1106 u32 xtal = state->cfg.bw->xtal_hz / 1000;
895 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz; 1107 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
896 int k; 1108 int k;
897 int coef_re[8],coef_im[8]; 1109 int coef_re[8], coef_im[8];
898 int bw_khz = bw; 1110 int bw_khz = bw;
899 u32 pha; 1111 u32 pha;
900 1112
901 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal); 1113 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
902
903 1114
904 if (f_rel < -bw_khz/2 || f_rel > bw_khz/2) 1115 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
905 return; 1116 return;
906 1117
907 bw_khz /= 100; 1118 bw_khz /= 100;
908 1119
909 dib7000p_write_word(state, 142 ,0x0610); 1120 dib7000p_write_word(state, 142, 0x0610);
910 1121
911 for (k = 0; k < 8; k++) { 1122 for (k = 0; k < 8; k++) {
912 pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff; 1123 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
913 1124
914 if (pha==0) { 1125 if (pha == 0) {
915 coef_re[k] = 256; 1126 coef_re[k] = 256;
916 coef_im[k] = 0; 1127 coef_im[k] = 0;
917 } else if(pha < 256) { 1128 } else if (pha < 256) {
918 coef_re[k] = sine[256-(pha&0xff)]; 1129 coef_re[k] = sine[256 - (pha & 0xff)];
919 coef_im[k] = sine[pha&0xff]; 1130 coef_im[k] = sine[pha & 0xff];
920 } else if (pha == 256) { 1131 } else if (pha == 256) {
921 coef_re[k] = 0; 1132 coef_re[k] = 0;
922 coef_im[k] = 256; 1133 coef_im[k] = 256;
923 } else if (pha < 512) { 1134 } else if (pha < 512) {
924 coef_re[k] = -sine[pha&0xff]; 1135 coef_re[k] = -sine[pha & 0xff];
925 coef_im[k] = sine[256 - (pha&0xff)]; 1136 coef_im[k] = sine[256 - (pha & 0xff)];
926 } else if (pha == 512) { 1137 } else if (pha == 512) {
927 coef_re[k] = -256; 1138 coef_re[k] = -256;
928 coef_im[k] = 0; 1139 coef_im[k] = 0;
929 } else if (pha < 768) { 1140 } else if (pha < 768) {
930 coef_re[k] = -sine[256-(pha&0xff)]; 1141 coef_re[k] = -sine[256 - (pha & 0xff)];
931 coef_im[k] = -sine[pha&0xff]; 1142 coef_im[k] = -sine[pha & 0xff];
932 } else if (pha == 768) { 1143 } else if (pha == 768) {
933 coef_re[k] = 0; 1144 coef_re[k] = 0;
934 coef_im[k] = -256; 1145 coef_im[k] = -256;
935 } else { 1146 } else {
936 coef_re[k] = sine[pha&0xff]; 1147 coef_re[k] = sine[pha & 0xff];
937 coef_im[k] = -sine[256 - (pha&0xff)]; 1148 coef_im[k] = -sine[256 - (pha & 0xff)];
938 } 1149 }
939 1150
940 coef_re[k] *= notch[k]; 1151 coef_re[k] *= notch[k];
941 coef_re[k] += (1<<14); 1152 coef_re[k] += (1 << 14);
942 if (coef_re[k] >= (1<<24)) 1153 if (coef_re[k] >= (1 << 24))
943 coef_re[k] = (1<<24) - 1; 1154 coef_re[k] = (1 << 24) - 1;
944 coef_re[k] /= (1<<15); 1155 coef_re[k] /= (1 << 15);
945 1156
946 coef_im[k] *= notch[k]; 1157 coef_im[k] *= notch[k];
947 coef_im[k] += (1<<14); 1158 coef_im[k] += (1 << 14);
948 if (coef_im[k] >= (1<<24)) 1159 if (coef_im[k] >= (1 << 24))
949 coef_im[k] = (1<<24)-1; 1160 coef_im[k] = (1 << 24) - 1;
950 coef_im[k] /= (1<<15); 1161 coef_im[k] /= (1 << 15);
951 1162
952 dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]); 1163 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
953 1164
954 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); 1165 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
955 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff); 1166 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
956 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); 1167 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
957 } 1168 }
958 dib7000p_write_word(state,143 ,0); 1169 dib7000p_write_word(state, 143, 0);
959} 1170}
960 1171
961static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) 1172static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
@@ -976,11 +1187,11 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
976 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ 1187 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
977 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3); 1188 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
978 if (state->sfn_workaround_active) { 1189 if (state->sfn_workaround_active) {
979 dprintk( "SFN workaround is active"); 1190 dprintk("SFN workaround is active");
980 tmp |= (1 << 9); 1191 tmp |= (1 << 9);
981 dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift 1192 dib7000p_write_word(state, 166, 0x4000);
982 } else { 1193 } else {
983 dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift 1194 dib7000p_write_word(state, 166, 0x0000);
984 } 1195 }
985 dib7000p_write_word(state, 29, tmp); 1196 dib7000p_write_word(state, 29, tmp);
986 1197
@@ -993,51 +1204,72 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
993 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ 1204 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
994 tmp = (6 << 8) | 0x80; 1205 tmp = (6 << 8) | 0x80;
995 switch (ch->u.ofdm.transmission_mode) { 1206 switch (ch->u.ofdm.transmission_mode) {
996 case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break; 1207 case TRANSMISSION_MODE_2K:
997 case TRANSMISSION_MODE_4K: tmp |= (8 << 12); break; 1208 tmp |= (2 << 12);
998 default: 1209 break;
999 case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break; 1210 case TRANSMISSION_MODE_4K:
1211 tmp |= (3 << 12);
1212 break;
1213 default:
1214 case TRANSMISSION_MODE_8K:
1215 tmp |= (4 << 12);
1216 break;
1000 } 1217 }
1001 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */ 1218 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1002 1219
1003 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ 1220 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1004 tmp = (0 << 4); 1221 tmp = (0 << 4);
1005 switch (ch->u.ofdm.transmission_mode) { 1222 switch (ch->u.ofdm.transmission_mode) {
1006 case TRANSMISSION_MODE_2K: tmp |= 0x6; break; 1223 case TRANSMISSION_MODE_2K:
1007 case TRANSMISSION_MODE_4K: tmp |= 0x7; break; 1224 tmp |= 0x6;
1008 default: 1225 break;
1009 case TRANSMISSION_MODE_8K: tmp |= 0x8; break; 1226 case TRANSMISSION_MODE_4K:
1227 tmp |= 0x7;
1228 break;
1229 default:
1230 case TRANSMISSION_MODE_8K:
1231 tmp |= 0x8;
1232 break;
1010 } 1233 }
1011 dib7000p_write_word(state, 32, tmp); 1234 dib7000p_write_word(state, 32, tmp);
1012 1235
1013 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ 1236 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1014 tmp = (0 << 4); 1237 tmp = (0 << 4);
1015 switch (ch->u.ofdm.transmission_mode) { 1238 switch (ch->u.ofdm.transmission_mode) {
1016 case TRANSMISSION_MODE_2K: tmp |= 0x6; break; 1239 case TRANSMISSION_MODE_2K:
1017 case TRANSMISSION_MODE_4K: tmp |= 0x7; break; 1240 tmp |= 0x6;
1018 default: 1241 break;
1019 case TRANSMISSION_MODE_8K: tmp |= 0x8; break; 1242 case TRANSMISSION_MODE_4K:
1243 tmp |= 0x7;
1244 break;
1245 default:
1246 case TRANSMISSION_MODE_8K:
1247 tmp |= 0x8;
1248 break;
1020 } 1249 }
1021 dib7000p_write_word(state, 33, tmp); 1250 dib7000p_write_word(state, 33, tmp);
1022 1251
1023 tmp = dib7000p_read_word(state,509); 1252 tmp = dib7000p_read_word(state, 509);
1024 if (!((tmp >> 6) & 0x1)) { 1253 if (!((tmp >> 6) & 0x1)) {
1025 /* restart the fec */ 1254 /* restart the fec */
1026 tmp = dib7000p_read_word(state,771); 1255 tmp = dib7000p_read_word(state, 771);
1027 dib7000p_write_word(state, 771, tmp | (1 << 1)); 1256 dib7000p_write_word(state, 771, tmp | (1 << 1));
1028 dib7000p_write_word(state, 771, tmp); 1257 dib7000p_write_word(state, 771, tmp);
1029 msleep(10); 1258 msleep(40);
1030 tmp = dib7000p_read_word(state,509); 1259 tmp = dib7000p_read_word(state, 509);
1031 } 1260 }
1032
1033 // we achieved a lock - it's time to update the osc freq 1261 // we achieved a lock - it's time to update the osc freq
1034 if ((tmp >> 6) & 0x1) 1262 if ((tmp >> 6) & 0x1) {
1035 dib7000p_update_timf(state); 1263 dib7000p_update_timf(state);
1264 /* P_timf_alpha += 2 */
1265 tmp = dib7000p_read_word(state, 26);
1266 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1267 }
1036 1268
1037 if (state->cfg.spur_protect) 1269 if (state->cfg.spur_protect)
1038 dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 1270 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1039 1271
1040 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 1272 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1041 return 0; 1273 return 0;
1042} 1274}
1043 1275
@@ -1046,63 +1278,82 @@ static int dib7000p_wakeup(struct dvb_frontend *demod)
1046 struct dib7000p_state *state = demod->demodulator_priv; 1278 struct dib7000p_state *state = demod->demodulator_priv;
1047 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 1279 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1048 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 1280 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1281 if (state->version == SOC7090)
1282 dib7000p_sad_calib(state);
1049 return 0; 1283 return 0;
1050} 1284}
1051 1285
1052static int dib7000p_sleep(struct dvb_frontend *demod) 1286static int dib7000p_sleep(struct dvb_frontend *demod)
1053{ 1287{
1054 struct dib7000p_state *state = demod->demodulator_priv; 1288 struct dib7000p_state *state = demod->demodulator_priv;
1289 if (state->version == SOC7090)
1290 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1055 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 1291 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1056} 1292}
1057 1293
1058static int dib7000p_identify(struct dib7000p_state *st) 1294static int dib7000p_identify(struct dib7000p_state *st)
1059{ 1295{
1060 u16 value; 1296 u16 value;
1061 dprintk( "checking demod on I2C address: %d (%x)", 1297 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1062 st->i2c_addr, st->i2c_addr);
1063 1298
1064 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { 1299 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1065 dprintk( "wrong Vendor ID (read=0x%x)",value); 1300 dprintk("wrong Vendor ID (read=0x%x)", value);
1066 return -EREMOTEIO; 1301 return -EREMOTEIO;
1067 } 1302 }
1068 1303
1069 if ((value = dib7000p_read_word(st, 769)) != 0x4000) { 1304 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1070 dprintk( "wrong Device ID (%x)",value); 1305 dprintk("wrong Device ID (%x)", value);
1071 return -EREMOTEIO; 1306 return -EREMOTEIO;
1072 } 1307 }
1073 1308
1074 return 0; 1309 return 0;
1075} 1310}
1076 1311
1077 1312static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1078static int dib7000p_get_frontend(struct dvb_frontend* fe,
1079 struct dvb_frontend_parameters *fep)
1080{ 1313{
1081 struct dib7000p_state *state = fe->demodulator_priv; 1314 struct dib7000p_state *state = fe->demodulator_priv;
1082 u16 tps = dib7000p_read_word(state,463); 1315 u16 tps = dib7000p_read_word(state, 463);
1083 1316
1084 fep->inversion = INVERSION_AUTO; 1317 fep->inversion = INVERSION_AUTO;
1085 1318
1086 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); 1319 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1087 1320
1088 switch ((tps >> 8) & 0x3) { 1321 switch ((tps >> 8) & 0x3) {
1089 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; 1322 case 0:
1090 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; 1323 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1091 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ 1324 break;
1325 case 1:
1326 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1327 break;
1328 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1092 } 1329 }
1093 1330
1094 switch (tps & 0x3) { 1331 switch (tps & 0x3) {
1095 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; 1332 case 0:
1096 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; 1333 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1097 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; 1334 break;
1098 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; 1335 case 1:
1336 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1337 break;
1338 case 2:
1339 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1340 break;
1341 case 3:
1342 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1343 break;
1099 } 1344 }
1100 1345
1101 switch ((tps >> 14) & 0x3) { 1346 switch ((tps >> 14) & 0x3) {
1102 case 0: fep->u.ofdm.constellation = QPSK; break; 1347 case 0:
1103 case 1: fep->u.ofdm.constellation = QAM_16; break; 1348 fep->u.ofdm.constellation = QPSK;
1104 case 2: 1349 break;
1105 default: fep->u.ofdm.constellation = QAM_64; break; 1350 case 1:
1351 fep->u.ofdm.constellation = QAM_16;
1352 break;
1353 case 2:
1354 default:
1355 fep->u.ofdm.constellation = QAM_64;
1356 break;
1106 } 1357 }
1107 1358
1108 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ 1359 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
@@ -1110,22 +1361,42 @@ static int dib7000p_get_frontend(struct dvb_frontend* fe,
1110 1361
1111 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; 1362 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1112 switch ((tps >> 5) & 0x7) { 1363 switch ((tps >> 5) & 0x7) {
1113 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; 1364 case 1:
1114 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; 1365 fep->u.ofdm.code_rate_HP = FEC_1_2;
1115 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; 1366 break;
1116 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; 1367 case 2:
1117 case 7: 1368 fep->u.ofdm.code_rate_HP = FEC_2_3;
1118 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; 1369 break;
1370 case 3:
1371 fep->u.ofdm.code_rate_HP = FEC_3_4;
1372 break;
1373 case 5:
1374 fep->u.ofdm.code_rate_HP = FEC_5_6;
1375 break;
1376 case 7:
1377 default:
1378 fep->u.ofdm.code_rate_HP = FEC_7_8;
1379 break;
1119 1380
1120 } 1381 }
1121 1382
1122 switch ((tps >> 2) & 0x7) { 1383 switch ((tps >> 2) & 0x7) {
1123 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; 1384 case 1:
1124 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; 1385 fep->u.ofdm.code_rate_LP = FEC_1_2;
1125 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; 1386 break;
1126 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; 1387 case 2:
1127 case 7: 1388 fep->u.ofdm.code_rate_LP = FEC_2_3;
1128 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; 1389 break;
1390 case 3:
1391 fep->u.ofdm.code_rate_LP = FEC_3_4;
1392 break;
1393 case 5:
1394 fep->u.ofdm.code_rate_LP = FEC_5_6;
1395 break;
1396 case 7:
1397 default:
1398 fep->u.ofdm.code_rate_LP = FEC_7_8;
1399 break;
1129 } 1400 }
1130 1401
1131 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */ 1402 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
@@ -1133,15 +1404,18 @@ static int dib7000p_get_frontend(struct dvb_frontend* fe,
1133 return 0; 1404 return 0;
1134} 1405}
1135 1406
1136static int dib7000p_set_frontend(struct dvb_frontend* fe, 1407static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1137 struct dvb_frontend_parameters *fep)
1138{ 1408{
1139 struct dib7000p_state *state = fe->demodulator_priv; 1409 struct dib7000p_state *state = fe->demodulator_priv;
1140 int time, ret; 1410 int time, ret;
1141 1411
1142 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); 1412 if (state->version == SOC7090) {
1413 dib7090_set_diversity_in(fe, 0);
1414 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1415 } else
1416 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1143 1417
1144 /* maybe the parameter has been changed */ 1418 /* maybe the parameter has been changed */
1145 state->sfn_workaround_active = buggy_sfn_workaround; 1419 state->sfn_workaround_active = buggy_sfn_workaround;
1146 1420
1147 if (fe->ops.tuner_ops.set_params) 1421 if (fe->ops.tuner_ops.set_params)
@@ -1156,9 +1430,7 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
1156 } while (time != -1); 1430 } while (time != -1);
1157 1431
1158 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || 1432 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1159 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || 1433 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1160 fep->u.ofdm.constellation == QAM_AUTO ||
1161 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1162 int i = 800, found; 1434 int i = 800, found;
1163 1435
1164 dib7000p_autosearch_start(fe, fep); 1436 dib7000p_autosearch_start(fe, fep);
@@ -1167,9 +1439,9 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
1167 found = dib7000p_autosearch_is_irq(fe); 1439 found = dib7000p_autosearch_is_irq(fe);
1168 } while (found == 0 && i--); 1440 } while (found == 0 && i--);
1169 1441
1170 dprintk("autosearch returns: %d",found); 1442 dprintk("autosearch returns: %d", found);
1171 if (found == 0 || found == 1) 1443 if (found == 0 || found == 1)
1172 return 0; // no channel found 1444 return 0;
1173 1445
1174 dib7000p_get_frontend(fe, fep); 1446 dib7000p_get_frontend(fe, fep);
1175 } 1447 }
@@ -1177,11 +1449,15 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
1177 ret = dib7000p_tune(fe, fep); 1449 ret = dib7000p_tune(fe, fep);
1178 1450
1179 /* make this a config parameter */ 1451 /* make this a config parameter */
1180 dib7000p_set_output_mode(state, state->cfg.output_mode); 1452 if (state->version == SOC7090)
1181 return ret; 1453 dib7090_set_output_mode(fe, state->cfg.output_mode);
1454 else
1455 dib7000p_set_output_mode(state, state->cfg.output_mode);
1456
1457 return ret;
1182} 1458}
1183 1459
1184static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) 1460static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1185{ 1461{
1186 struct dib7000p_state *state = fe->demodulator_priv; 1462 struct dib7000p_state *state = fe->demodulator_priv;
1187 u16 lock = dib7000p_read_word(state, 509); 1463 u16 lock = dib7000p_read_word(state, 509);
@@ -1196,27 +1472,27 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1196 *stat |= FE_HAS_VITERBI; 1472 *stat |= FE_HAS_VITERBI;
1197 if (lock & 0x0010) 1473 if (lock & 0x0010)
1198 *stat |= FE_HAS_SYNC; 1474 *stat |= FE_HAS_SYNC;
1199 if ((lock & 0x0038) == 0x38) 1475 if ((lock & 0x0038) == 0x38)
1200 *stat |= FE_HAS_LOCK; 1476 *stat |= FE_HAS_LOCK;
1201 1477
1202 return 0; 1478 return 0;
1203} 1479}
1204 1480
1205static int dib7000p_read_ber(struct dvb_frontend *fe, u32 *ber) 1481static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1206{ 1482{
1207 struct dib7000p_state *state = fe->demodulator_priv; 1483 struct dib7000p_state *state = fe->demodulator_priv;
1208 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501); 1484 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1209 return 0; 1485 return 0;
1210} 1486}
1211 1487
1212static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) 1488static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1213{ 1489{
1214 struct dib7000p_state *state = fe->demodulator_priv; 1490 struct dib7000p_state *state = fe->demodulator_priv;
1215 *unc = dib7000p_read_word(state, 506); 1491 *unc = dib7000p_read_word(state, 506);
1216 return 0; 1492 return 0;
1217} 1493}
1218 1494
1219static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 1495static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1220{ 1496{
1221 struct dib7000p_state *state = fe->demodulator_priv; 1497 struct dib7000p_state *state = fe->demodulator_priv;
1222 u16 val = dib7000p_read_word(state, 394); 1498 u16 val = dib7000p_read_word(state, 394);
@@ -1224,7 +1500,7 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1224 return 0; 1500 return 0;
1225} 1501}
1226 1502
1227static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr) 1503static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1228{ 1504{
1229 struct dib7000p_state *state = fe->demodulator_priv; 1505 struct dib7000p_state *state = fe->demodulator_priv;
1230 u16 val; 1506 u16 val;
@@ -1240,19 +1516,17 @@ static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1240 noise_exp -= 0x40; 1516 noise_exp -= 0x40;
1241 1517
1242 signal_mant = (val >> 6) & 0xFF; 1518 signal_mant = (val >> 6) & 0xFF;
1243 signal_exp = (val & 0x3F); 1519 signal_exp = (val & 0x3F);
1244 if ((signal_exp & 0x20) != 0) 1520 if ((signal_exp & 0x20) != 0)
1245 signal_exp -= 0x40; 1521 signal_exp -= 0x40;
1246 1522
1247 if (signal_mant != 0) 1523 if (signal_mant != 0)
1248 result = intlog10(2) * 10 * signal_exp + 10 * 1524 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1249 intlog10(signal_mant);
1250 else 1525 else
1251 result = intlog10(2) * 10 * signal_exp - 100; 1526 result = intlog10(2) * 10 * signal_exp - 100;
1252 1527
1253 if (noise_mant != 0) 1528 if (noise_mant != 0)
1254 result -= intlog10(2) * 10 * noise_exp + 10 * 1529 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1255 intlog10(noise_mant);
1256 else 1530 else
1257 result -= intlog10(2) * 10 * noise_exp - 100; 1531 result -= intlog10(2) * 10 * noise_exp - 100;
1258 1532
@@ -1260,7 +1534,7 @@ static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1260 return 0; 1534 return 0;
1261} 1535}
1262 1536
1263static int dib7000p_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 1537static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1264{ 1538{
1265 tune->min_delay_ms = 1000; 1539 tune->min_delay_ms = 1000;
1266 return 0; 1540 return 0;
@@ -1270,6 +1544,7 @@ static void dib7000p_release(struct dvb_frontend *demod)
1270{ 1544{
1271 struct dib7000p_state *st = demod->demodulator_priv; 1545 struct dib7000p_state *st = demod->demodulator_priv;
1272 dibx000_exit_i2c_master(&st->i2c_master); 1546 dibx000_exit_i2c_master(&st->i2c_master);
1547 i2c_del_adapter(&st->dib7090_tuner_adap);
1273 kfree(st); 1548 kfree(st);
1274} 1549}
1275 1550
@@ -1277,8 +1552,8 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1277{ 1552{
1278 u8 tx[2], rx[2]; 1553 u8 tx[2], rx[2];
1279 struct i2c_msg msg[2] = { 1554 struct i2c_msg msg[2] = {
1280 { .addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2 }, 1555 {.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2},
1281 { .addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2 }, 1556 {.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2},
1282 }; 1557 };
1283 1558
1284 tx[0] = 0x03; 1559 tx[0] = 0x03;
@@ -1303,7 +1578,7 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1303} 1578}
1304EXPORT_SYMBOL(dib7000pc_detection); 1579EXPORT_SYMBOL(dib7000pc_detection);
1305 1580
1306struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) 1581struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1307{ 1582{
1308 struct dib7000p_state *st = demod->demodulator_priv; 1583 struct dib7000p_state *st = demod->demodulator_priv;
1309 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); 1584 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
@@ -1312,19 +1587,19 @@ EXPORT_SYMBOL(dib7000p_get_i2c_master);
1312 1587
1313int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) 1588int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1314{ 1589{
1315 struct dib7000p_state *state = fe->demodulator_priv; 1590 struct dib7000p_state *state = fe->demodulator_priv;
1316 u16 val = dib7000p_read_word(state, 235) & 0xffef; 1591 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1317 val |= (onoff & 0x1) << 4; 1592 val |= (onoff & 0x1) << 4;
1318 dprintk("PID filter enabled %d", onoff); 1593 dprintk("PID filter enabled %d", onoff);
1319 return dib7000p_write_word(state, 235, val); 1594 return dib7000p_write_word(state, 235, val);
1320} 1595}
1321EXPORT_SYMBOL(dib7000p_pid_filter_ctrl); 1596EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1322 1597
1323int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) 1598int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1324{ 1599{
1325 struct dib7000p_state *state = fe->demodulator_priv; 1600 struct dib7000p_state *state = fe->demodulator_priv;
1326 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); 1601 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1327 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0); 1602 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1328} 1603}
1329EXPORT_SYMBOL(dib7000p_pid_filter); 1604EXPORT_SYMBOL(dib7000p_pid_filter);
1330 1605
@@ -1340,16 +1615,19 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1340 1615
1341 dpst->i2c_adap = i2c; 1616 dpst->i2c_adap = i2c;
1342 1617
1343 for (k = no_of_demods-1; k >= 0; k--) { 1618 for (k = no_of_demods - 1; k >= 0; k--) {
1344 dpst->cfg = cfg[k]; 1619 dpst->cfg = cfg[k];
1345 1620
1346 /* designated i2c address */ 1621 /* designated i2c address */
1347 new_addr = (0x40 + k) << 1; 1622 if (cfg[k].default_i2c_addr != 0)
1623 new_addr = cfg[k].default_i2c_addr + (k << 1);
1624 else
1625 new_addr = (0x40 + k) << 1;
1348 dpst->i2c_addr = new_addr; 1626 dpst->i2c_addr = new_addr;
1349 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */ 1627 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1350 if (dib7000p_identify(dpst) != 0) { 1628 if (dib7000p_identify(dpst) != 0) {
1351 dpst->i2c_addr = default_addr; 1629 dpst->i2c_addr = default_addr;
1352 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */ 1630 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1353 if (dib7000p_identify(dpst) != 0) { 1631 if (dib7000p_identify(dpst) != 0) {
1354 dprintk("DiB7000P #%d: not identified\n", k); 1632 dprintk("DiB7000P #%d: not identified\n", k);
1355 kfree(dpst); 1633 kfree(dpst);
@@ -1368,7 +1646,10 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1368 1646
1369 for (k = 0; k < no_of_demods; k++) { 1647 for (k = 0; k < no_of_demods; k++) {
1370 dpst->cfg = cfg[k]; 1648 dpst->cfg = cfg[k];
1371 dpst->i2c_addr = (0x40 + k) << 1; 1649 if (cfg[k].default_i2c_addr != 0)
1650 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1651 else
1652 dpst->i2c_addr = (0x40 + k) << 1;
1372 1653
1373 // unforce divstr 1654 // unforce divstr
1374 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2); 1655 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
@@ -1382,8 +1663,613 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1382} 1663}
1383EXPORT_SYMBOL(dib7000p_i2c_enumeration); 1664EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1384 1665
1666static const s32 lut_1000ln_mant[] = {
1667 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1668};
1669
1670static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1671{
1672 struct dib7000p_state *state = fe->demodulator_priv;
1673 u32 tmp_val = 0, exp = 0, mant = 0;
1674 s32 pow_i;
1675 u16 buf[2];
1676 u8 ix = 0;
1677
1678 buf[0] = dib7000p_read_word(state, 0x184);
1679 buf[1] = dib7000p_read_word(state, 0x185);
1680 pow_i = (buf[0] << 16) | buf[1];
1681 dprintk("raw pow_i = %d", pow_i);
1682
1683 tmp_val = pow_i;
1684 while (tmp_val >>= 1)
1685 exp++;
1686
1687 mant = (pow_i * 1000 / (1 << exp));
1688 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1689
1690 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1691 dprintk(" ix = %d", ix);
1692
1693 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1694 pow_i = (pow_i << 8) / 1000;
1695 dprintk(" pow_i = %d", pow_i);
1696
1697 return pow_i;
1698}
1699
1700static int map_addr_to_serpar_number(struct i2c_msg *msg)
1701{
1702 if ((msg->buf[0] <= 15))
1703 msg->buf[0] -= 1;
1704 else if (msg->buf[0] == 17)
1705 msg->buf[0] = 15;
1706 else if (msg->buf[0] == 16)
1707 msg->buf[0] = 17;
1708 else if (msg->buf[0] == 19)
1709 msg->buf[0] = 16;
1710 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1711 msg->buf[0] -= 3;
1712 else if (msg->buf[0] == 28)
1713 msg->buf[0] = 23;
1714 else
1715 return -EINVAL;
1716 return 0;
1717}
1718
1719static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1720{
1721 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1722 u8 n_overflow = 1;
1723 u16 i = 1000;
1724 u16 serpar_num = msg[0].buf[0];
1725
1726 while (n_overflow == 1 && i) {
1727 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1728 i--;
1729 if (i == 0)
1730 dprintk("Tuner ITF: write busy (overflow)");
1731 }
1732 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1733 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1734
1735 return num;
1736}
1737
1738static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1739{
1740 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1741 u8 n_overflow = 1, n_empty = 1;
1742 u16 i = 1000;
1743 u16 serpar_num = msg[0].buf[0];
1744 u16 read_word;
1745
1746 while (n_overflow == 1 && i) {
1747 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1748 i--;
1749 if (i == 0)
1750 dprintk("TunerITF: read busy (overflow)");
1751 }
1752 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1753
1754 i = 1000;
1755 while (n_empty == 1 && i) {
1756 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1757 i--;
1758 if (i == 0)
1759 dprintk("TunerITF: read busy (empty)");
1760 }
1761 read_word = dib7000p_read_word(state, 1987);
1762 msg[1].buf[0] = (read_word >> 8) & 0xff;
1763 msg[1].buf[1] = (read_word) & 0xff;
1764
1765 return num;
1766}
1767
1768static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1769{
1770 if (map_addr_to_serpar_number(&msg[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
1771 if (num == 1) { /* write */
1772 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1773 } else { /* read */
1774 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1775 }
1776 }
1777 return num;
1778}
1779
1780int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1781{
1782 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1783 u16 word;
1784
1785 if (num == 1) { /* write */
1786 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1787 } else {
1788 word = dib7000p_read_word(state, apb_address);
1789 msg[1].buf[0] = (word >> 8) & 0xff;
1790 msg[1].buf[1] = (word) & 0xff;
1791 }
1792
1793 return num;
1794}
1795
1796static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1797{
1798 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1799
1800 u16 apb_address = 0, word;
1801 int i = 0;
1802 switch (msg[0].buf[0]) {
1803 case 0x12:
1804 apb_address = 1920;
1805 break;
1806 case 0x14:
1807 apb_address = 1921;
1808 break;
1809 case 0x24:
1810 apb_address = 1922;
1811 break;
1812 case 0x1a:
1813 apb_address = 1923;
1814 break;
1815 case 0x22:
1816 apb_address = 1924;
1817 break;
1818 case 0x33:
1819 apb_address = 1926;
1820 break;
1821 case 0x34:
1822 apb_address = 1927;
1823 break;
1824 case 0x35:
1825 apb_address = 1928;
1826 break;
1827 case 0x36:
1828 apb_address = 1929;
1829 break;
1830 case 0x37:
1831 apb_address = 1930;
1832 break;
1833 case 0x38:
1834 apb_address = 1931;
1835 break;
1836 case 0x39:
1837 apb_address = 1932;
1838 break;
1839 case 0x2a:
1840 apb_address = 1935;
1841 break;
1842 case 0x2b:
1843 apb_address = 1936;
1844 break;
1845 case 0x2c:
1846 apb_address = 1937;
1847 break;
1848 case 0x2d:
1849 apb_address = 1938;
1850 break;
1851 case 0x2e:
1852 apb_address = 1939;
1853 break;
1854 case 0x2f:
1855 apb_address = 1940;
1856 break;
1857 case 0x30:
1858 apb_address = 1941;
1859 break;
1860 case 0x31:
1861 apb_address = 1942;
1862 break;
1863 case 0x32:
1864 apb_address = 1943;
1865 break;
1866 case 0x3e:
1867 apb_address = 1944;
1868 break;
1869 case 0x3f:
1870 apb_address = 1945;
1871 break;
1872 case 0x40:
1873 apb_address = 1948;
1874 break;
1875 case 0x25:
1876 apb_address = 914;
1877 break;
1878 case 0x26:
1879 apb_address = 915;
1880 break;
1881 case 0x27:
1882 apb_address = 916;
1883 break;
1884 case 0x28:
1885 apb_address = 917;
1886 break;
1887 case 0x1d:
1888 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1889 word = dib7000p_read_word(state, 384 + i);
1890 msg[1].buf[0] = (word >> 8) & 0xff;
1891 msg[1].buf[1] = (word) & 0xff;
1892 return num;
1893 case 0x1f:
1894 if (num == 1) { /* write */
1895 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1896 word &= 0x3;
1897 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1898 dib7000p_write_word(state, 72, word); /* Set the proper input */
1899 return num;
1900 }
1901 }
1902
1903 if (apb_address != 0) /* R/W acces via APB */
1904 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1905 else /* R/W access via SERPAR */
1906 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1907
1908 return 0;
1909}
1910
1911static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1912{
1913 return I2C_FUNC_I2C;
1914}
1915
1916static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1917 .master_xfer = dib7090_tuner_xfer,
1918 .functionality = dib7000p_i2c_func,
1919};
1920
1921struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1922{
1923 struct dib7000p_state *st = fe->demodulator_priv;
1924 return &st->dib7090_tuner_adap;
1925}
1926EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1927
1928static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1929{
1930 u16 reg;
1931
1932 /* drive host bus 2, 3, 4 */
1933 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1934 reg |= (drive << 12) | (drive << 6) | drive;
1935 dib7000p_write_word(state, 1798, reg);
1936
1937 /* drive host bus 5,6 */
1938 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1939 reg |= (drive << 8) | (drive << 2);
1940 dib7000p_write_word(state, 1799, reg);
1941
1942 /* drive host bus 7, 8, 9 */
1943 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1944 reg |= (drive << 12) | (drive << 6) | drive;
1945 dib7000p_write_word(state, 1800, reg);
1946
1947 /* drive host bus 10, 11 */
1948 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1949 reg |= (drive << 8) | (drive << 2);
1950 dib7000p_write_word(state, 1801, reg);
1951
1952 /* drive host bus 12, 13, 14 */
1953 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1954 reg |= (drive << 12) | (drive << 6) | drive;
1955 dib7000p_write_word(state, 1802, reg);
1956
1957 return 0;
1958}
1959
1960static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
1961{
1962 u32 quantif = 3;
1963 u32 nom = (insertExtSynchro * P_Kin + syncSize);
1964 u32 denom = P_Kout;
1965 u32 syncFreq = ((nom << quantif) / denom);
1966
1967 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1968 syncFreq = (syncFreq >> quantif) + 1;
1969 else
1970 syncFreq = (syncFreq >> quantif);
1971
1972 if (syncFreq != 0)
1973 syncFreq = syncFreq - 1;
1974
1975 return syncFreq;
1976}
1977
1978static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
1979{
1980 u8 index_buf;
1981 u16 rx_copy_buf[22];
1982
1983 dprintk("Configure DibStream Tx");
1984 for (index_buf = 0; index_buf < 22; index_buf++)
1985 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
1986
1987 dib7000p_write_word(state, 1615, 1);
1988 dib7000p_write_word(state, 1603, P_Kin);
1989 dib7000p_write_word(state, 1605, P_Kout);
1990 dib7000p_write_word(state, 1606, insertExtSynchro);
1991 dib7000p_write_word(state, 1608, synchroMode);
1992 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1993 dib7000p_write_word(state, 1610, syncWord & 0xffff);
1994 dib7000p_write_word(state, 1612, syncSize);
1995 dib7000p_write_word(state, 1615, 0);
1996
1997 for (index_buf = 0; index_buf < 22; index_buf++)
1998 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
1999
2000 return 0;
2001}
2002
2003static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2004 u32 dataOutRate)
2005{
2006 u32 syncFreq;
2007
2008 dprintk("Configure DibStream Rx");
2009 if ((P_Kin != 0) && (P_Kout != 0)) {
2010 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2011 dib7000p_write_word(state, 1542, syncFreq);
2012 }
2013 dib7000p_write_word(state, 1554, 1);
2014 dib7000p_write_word(state, 1536, P_Kin);
2015 dib7000p_write_word(state, 1537, P_Kout);
2016 dib7000p_write_word(state, 1539, synchroMode);
2017 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2018 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2019 dib7000p_write_word(state, 1543, syncSize);
2020 dib7000p_write_word(state, 1544, dataOutRate);
2021 dib7000p_write_word(state, 1554, 0);
2022
2023 return 0;
2024}
2025
2026static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2027{
2028 u16 reg;
2029
2030 dprintk("Enable Diversity on host bus");
2031 reg = (1 << 8) | (1 << 5);
2032 dib7000p_write_word(state, 1288, reg);
2033
2034 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2035}
2036
2037static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2038{
2039 u16 reg;
2040
2041 dprintk("Enable ADC on host bus");
2042 reg = (1 << 7) | (1 << 5);
2043 dib7000p_write_word(state, 1288, reg);
2044
2045 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2046}
2047
2048static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2049{
2050 u16 reg;
2051
2052 dprintk("Enable Mpeg on host bus");
2053 reg = (1 << 9) | (1 << 5);
2054 dib7000p_write_word(state, 1288, reg);
2055
2056 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2057}
2058
2059static int dib7090_enMpegInput(struct dib7000p_state *state)
2060{
2061 dprintk("Enable Mpeg input");
2062 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2063}
2064
2065static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2066{
2067 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2068
2069 dprintk("Enable Mpeg mux");
2070 dib7000p_write_word(state, 1287, reg);
2071
2072 reg &= ~(1 << 7);
2073 dib7000p_write_word(state, 1287, reg);
2074
2075 reg = (1 << 4);
2076 dib7000p_write_word(state, 1288, reg);
2077
2078 return 0;
2079}
2080
2081static int dib7090_disableMpegMux(struct dib7000p_state *state)
2082{
2083 u16 reg;
2084
2085 dprintk("Disable Mpeg mux");
2086 dib7000p_write_word(state, 1288, 0);
2087
2088 reg = dib7000p_read_word(state, 1287);
2089 reg &= ~(1 << 7);
2090 dib7000p_write_word(state, 1287, reg);
2091
2092 return 0;
2093}
2094
2095static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2096{
2097 struct dib7000p_state *state = fe->demodulator_priv;
2098
2099 switch (mode) {
2100 case INPUT_MODE_DIVERSITY:
2101 dprintk("Enable diversity INPUT");
2102 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2103 break;
2104 case INPUT_MODE_MPEG:
2105 dprintk("Enable Mpeg INPUT");
2106 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2107 break;
2108 case INPUT_MODE_OFF:
2109 default:
2110 dprintk("Disable INPUT");
2111 dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2112 break;
2113 }
2114 return 0;
2115}
2116
2117static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2118{
2119 switch (onoff) {
2120 case 0: /* only use the internal way - not the diversity input */
2121 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2122 break;
2123 case 1: /* both ways */
2124 case 2: /* only the diversity input */
2125 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2126 break;
2127 }
2128
2129 return 0;
2130}
2131
2132static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2133{
2134 struct dib7000p_state *state = fe->demodulator_priv;
2135
2136 u16 outreg, smo_mode, fifo_threshold;
2137 u8 prefer_mpeg_mux_use = 1;
2138 int ret = 0;
2139
2140 dib7090_host_bus_drive(state, 1);
2141
2142 fifo_threshold = 1792;
2143 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2144 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2145
2146 switch (mode) {
2147 case OUTMODE_HIGH_Z:
2148 outreg = 0;
2149 break;
2150
2151 case OUTMODE_MPEG2_SERIAL:
2152 if (prefer_mpeg_mux_use) {
2153 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2154 dib7090_enMpegOnHostBus(state);
2155 dib7090_enMpegInput(state);
2156 if (state->cfg.enMpegOutput == 1)
2157 dib7090_enMpegMux(state, 3, 1, 1);
2158
2159 } else { /* Use Smooth block */
2160 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2161 dib7090_disableMpegMux(state);
2162 dib7000p_write_word(state, 1288, (1 << 6));
2163 outreg |= (2 << 6) | (0 << 1);
2164 }
2165 break;
2166
2167 case OUTMODE_MPEG2_PAR_GATED_CLK:
2168 if (prefer_mpeg_mux_use) {
2169 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2170 dib7090_enMpegOnHostBus(state);
2171 dib7090_enMpegInput(state);
2172 if (state->cfg.enMpegOutput == 1)
2173 dib7090_enMpegMux(state, 2, 0, 0);
2174 } else { /* Use Smooth block */
2175 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2176 dib7090_disableMpegMux(state);
2177 dib7000p_write_word(state, 1288, (1 << 6));
2178 outreg |= (0 << 6);
2179 }
2180 break;
2181
2182 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2183 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2184 dib7090_disableMpegMux(state);
2185 dib7000p_write_word(state, 1288, (1 << 6));
2186 outreg |= (1 << 6);
2187 break;
2188
2189 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2190 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2191 dib7090_disableMpegMux(state);
2192 dib7000p_write_word(state, 1288, (1 << 6));
2193 outreg |= (5 << 6);
2194 smo_mode |= (3 << 1);
2195 fifo_threshold = 512;
2196 break;
2197
2198 case OUTMODE_DIVERSITY:
2199 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2200 dib7090_disableMpegMux(state);
2201 dib7090_enDivOnHostBus(state);
2202 break;
2203
2204 case OUTMODE_ANALOG_ADC:
2205 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2206 dib7090_enAdcOnHostBus(state);
2207 break;
2208 }
2209
2210 if (state->cfg.output_mpeg2_in_188_bytes)
2211 smo_mode |= (1 << 5);
2212
2213 ret |= dib7000p_write_word(state, 235, smo_mode);
2214 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2215 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2216
2217 return ret;
2218}
2219
2220int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2221{
2222 struct dib7000p_state *state = fe->demodulator_priv;
2223 u16 en_cur_state;
2224
2225 dprintk("sleep dib7090: %d", onoff);
2226
2227 en_cur_state = dib7000p_read_word(state, 1922);
2228
2229 if (en_cur_state > 0xff)
2230 state->tuner_enable = en_cur_state;
2231
2232 if (onoff)
2233 en_cur_state &= 0x00ff;
2234 else {
2235 if (state->tuner_enable != 0)
2236 en_cur_state = state->tuner_enable;
2237 }
2238
2239 dib7000p_write_word(state, 1922, en_cur_state);
2240
2241 return 0;
2242}
2243EXPORT_SYMBOL(dib7090_tuner_sleep);
2244
2245int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2246{
2247 dprintk("AGC restart callback: %d", restart);
2248 return 0;
2249}
2250EXPORT_SYMBOL(dib7090_agc_restart);
2251
2252int dib7090_get_adc_power(struct dvb_frontend *fe)
2253{
2254 return dib7000p_get_adc_power(fe);
2255}
2256EXPORT_SYMBOL(dib7090_get_adc_power);
2257
2258int dib7090_slave_reset(struct dvb_frontend *fe)
2259{
2260 struct dib7000p_state *state = fe->demodulator_priv;
2261 u16 reg;
2262
2263 reg = dib7000p_read_word(state, 1794);
2264 dib7000p_write_word(state, 1794, reg | (4 << 12));
2265
2266 dib7000p_write_word(state, 1032, 0xffff);
2267 return 0;
2268}
2269EXPORT_SYMBOL(dib7090_slave_reset);
2270
1385static struct dvb_frontend_ops dib7000p_ops; 2271static struct dvb_frontend_ops dib7000p_ops;
1386struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) 2272struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
1387{ 2273{
1388 struct dvb_frontend *demod; 2274 struct dvb_frontend *demod;
1389 struct dib7000p_state *st; 2275 struct dib7000p_state *st;
@@ -1400,28 +2286,41 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
1400 /* Ensure the output mode remains at the previous default if it's 2286 /* Ensure the output mode remains at the previous default if it's
1401 * not specifically set by the caller. 2287 * not specifically set by the caller.
1402 */ 2288 */
1403 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && 2289 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
1404 (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
1405 st->cfg.output_mode = OUTMODE_MPEG2_FIFO; 2290 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
1406 2291
1407 demod = &st->demod; 2292 demod = &st->demod;
1408 demod->demodulator_priv = st; 2293 demod->demodulator_priv = st;
1409 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); 2294 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
1410 2295
1411 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */ 2296 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
1412 2297
1413 if (dib7000p_identify(st) != 0) 2298 if (dib7000p_identify(st) != 0)
1414 goto error; 2299 goto error;
1415 2300
2301 st->version = dib7000p_read_word(st, 897);
2302
1416 /* FIXME: make sure the dev.parent field is initialized, or else 2303 /* FIXME: make sure the dev.parent field is initialized, or else
1417 request_firmware() will hit an OOPS (this should be moved somewhere 2304 request_firmware() will hit an OOPS (this should be moved somewhere
1418 more common) */ 2305 more common) */
1419 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
1420 2306
1421 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); 2307 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
1422 2308
2309 /* init 7090 tuner adapter */
2310 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2311 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2312 st->dib7090_tuner_adap.algo_data = NULL;
2313 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2314 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2315 i2c_add_adapter(&st->dib7090_tuner_adap);
2316
1423 dib7000p_demod_reset(st); 2317 dib7000p_demod_reset(st);
1424 2318
2319 if (st->version == SOC7090) {
2320 dib7090_set_output_mode(demod, st->cfg.output_mode);
2321 dib7090_set_diversity_in(demod, 0);
2322 }
2323
1425 return demod; 2324 return demod;
1426 2325
1427error: 2326error:
@@ -1432,37 +2331,35 @@ EXPORT_SYMBOL(dib7000p_attach);
1432 2331
1433static struct dvb_frontend_ops dib7000p_ops = { 2332static struct dvb_frontend_ops dib7000p_ops = {
1434 .info = { 2333 .info = {
1435 .name = "DiBcom 7000PC", 2334 .name = "DiBcom 7000PC",
1436 .type = FE_OFDM, 2335 .type = FE_OFDM,
1437 .frequency_min = 44250000, 2336 .frequency_min = 44250000,
1438 .frequency_max = 867250000, 2337 .frequency_max = 867250000,
1439 .frequency_stepsize = 62500, 2338 .frequency_stepsize = 62500,
1440 .caps = FE_CAN_INVERSION_AUTO | 2339 .caps = FE_CAN_INVERSION_AUTO |
1441 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 2340 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1442 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 2341 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1443 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 2342 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1444 FE_CAN_TRANSMISSION_MODE_AUTO | 2343 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
1445 FE_CAN_GUARD_INTERVAL_AUTO | 2344 },
1446 FE_CAN_RECOVER | 2345
1447 FE_CAN_HIERARCHY_AUTO, 2346 .release = dib7000p_release,
1448 }, 2347
1449 2348 .init = dib7000p_wakeup,
1450 .release = dib7000p_release, 2349 .sleep = dib7000p_sleep,
1451 2350
1452 .init = dib7000p_wakeup, 2351 .set_frontend = dib7000p_set_frontend,
1453 .sleep = dib7000p_sleep, 2352 .get_tune_settings = dib7000p_fe_get_tune_settings,
1454 2353 .get_frontend = dib7000p_get_frontend,
1455 .set_frontend = dib7000p_set_frontend, 2354
1456 .get_tune_settings = dib7000p_fe_get_tune_settings, 2355 .read_status = dib7000p_read_status,
1457 .get_frontend = dib7000p_get_frontend, 2356 .read_ber = dib7000p_read_ber,
1458
1459 .read_status = dib7000p_read_status,
1460 .read_ber = dib7000p_read_ber,
1461 .read_signal_strength = dib7000p_read_signal_strength, 2357 .read_signal_strength = dib7000p_read_signal_strength,
1462 .read_snr = dib7000p_read_snr, 2358 .read_snr = dib7000p_read_snr,
1463 .read_ucblocks = dib7000p_read_unc_blocks, 2359 .read_ucblocks = dib7000p_read_unc_blocks,
1464}; 2360};
1465 2361
2362MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
1466MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 2363MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1467MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator"); 2364MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1468MODULE_LICENSE("GPL"); 2365MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index da17345bf5bd..0179f9474bac 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -33,59 +33,54 @@ struct dib7000p_config {
33 int (*agc_control) (struct dvb_frontend *, u8 before); 33 int (*agc_control) (struct dvb_frontend *, u8 before);
34 34
35 u8 output_mode; 35 u8 output_mode;
36 u8 disable_sample_and_hold : 1; 36 u8 disable_sample_and_hold:1;
37 37
38 u8 enable_current_mirror : 1; 38 u8 enable_current_mirror:1;
39 u8 diversity_delay; 39 u16 diversity_delay;
40 40
41 u8 default_i2c_addr;
42 u8 enMpegOutput:1;
41}; 43};
42 44
43#define DEFAULT_DIB7000P_I2C_ADDRESS 18 45#define DEFAULT_DIB7000P_I2C_ADDRESS 18
44 46
45#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \ 47#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
46 defined(MODULE)) 48 defined(MODULE))
47extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, 49extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
48 u8 i2c_addr, 50extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
49 struct dib7000p_config *cfg); 51extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
50extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *,
51 enum dibx000_i2c_interface,
52 int);
53extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
54 int no_of_demods, u8 default_addr,
55 struct dib7000p_config cfg[]);
56extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); 52extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
57extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); 53extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
58extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); 54extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
59extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); 55extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
60extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); 56extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
57extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
58extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
59extern int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart);
60extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
61extern int dib7090_get_adc_power(struct dvb_frontend *fe);
62extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
63extern int dib7090_slave_reset(struct dvb_frontend *fe);
61#else 64#else
62static inline 65static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
63struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
64 struct dib7000p_config *cfg)
65{ 66{
66 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
67 return NULL; 68 return NULL;
68} 69}
69 70
70static inline 71static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
71struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
72 enum dibx000_i2c_interface i,
73 int x)
74{ 72{
75 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
76 return NULL; 74 return NULL;
77} 75}
78 76
79static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, 77static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
80 int no_of_demods, u8 default_addr,
81 struct dib7000p_config cfg[])
82{ 78{
83 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 79 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
84 return -ENODEV; 80 return -ENODEV;
85} 81}
86 82
87static inline int dib7000p_set_gpio(struct dvb_frontend *fe, 83static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
88 u8 num, u8 dir, u8 val)
89{ 84{
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 85 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
91 return -ENODEV; 86 return -ENODEV;
@@ -102,16 +97,59 @@ static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 97 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return -ENODEV; 98 return -ENODEV;
104} 99}
100
105static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) 101static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
106{ 102{
107 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 103 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
108 return -ENODEV; 104 return -ENODEV;
109} 105}
110 106
111static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff) 107static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
112{ 108{
113 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 109 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
114 return -ENODEV; 110 return -ENODEV;
111}
112
113static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
114{
115 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
116 return -ENODEV;
117}
118
119static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
120{
121 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
122 return 0;
123}
124
125static inline int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
126{
127 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
128 return -ENODEV;
129}
130
131static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
132{
133 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
134 return -ENODEV;
135}
136
137static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
138{
139 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
140 return -ENODEV;
141}
142
143static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
144{
145 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
146 return NULL;
147}
148
149static inline int dib7090_slave_reset(struct dvb_frontend *fe)
150{
151 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
152 return -ENODEV;
115} 153}
116#endif 154#endif
117 155
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index df17b91b3250..c1c3e26906e2 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -22,6 +22,7 @@
22#define LAYER_C 3 22#define LAYER_C 3
23 23
24#define FE_CALLBACK_TIME_NEVER 0xffffffff 24#define FE_CALLBACK_TIME_NEVER 0xffffffff
25#define MAX_NUMBER_OF_FRONTENDS 6
25 26
26static int debug; 27static int debug;
27module_param(debug, int, 0644); 28module_param(debug, int, 0644);
@@ -37,7 +38,6 @@ struct i2c_device {
37}; 38};
38 39
39struct dib8000_state { 40struct dib8000_state {
40 struct dvb_frontend fe;
41 struct dib8000_config cfg; 41 struct dib8000_config cfg;
42 42
43 struct i2c_device i2c; 43 struct i2c_device i2c;
@@ -68,6 +68,8 @@ struct dib8000_state {
68 u8 isdbt_cfg_loaded; 68 u8 isdbt_cfg_loaded;
69 enum frontend_tune_state tune_state; 69 enum frontend_tune_state tune_state;
70 u32 status; 70 u32 status;
71
72 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
71}; 73};
72 74
73enum dib8000_power_mode { 75enum dib8000_power_mode {
@@ -122,111 +124,111 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
122 return dib8000_i2c_write16(&state->i2c, reg, val); 124 return dib8000_i2c_write16(&state->i2c, reg, val);
123} 125}
124 126
125static const int16_t coeff_2k_sb_1seg_dqpsk[8] = { 127static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
126 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c, 128 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
127 (920 << 5) | 0x09 129 (920 << 5) | 0x09
128}; 130};
129 131
130static const int16_t coeff_2k_sb_1seg[8] = { 132static const s16 coeff_2k_sb_1seg[8] = {
131 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f 133 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
132}; 134};
133 135
134static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = { 136static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
135 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11, 137 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
136 (-931 << 5) | 0x0f 138 (-931 << 5) | 0x0f
137}; 139};
138 140
139static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = { 141static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
140 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e, 142 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
141 (982 << 5) | 0x0c 143 (982 << 5) | 0x0c
142}; 144};
143 145
144static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = { 146static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
145 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12, 147 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
146 (-720 << 5) | 0x0d 148 (-720 << 5) | 0x0d
147}; 149};
148 150
149static const int16_t coeff_2k_sb_3seg[8] = { 151static const s16 coeff_2k_sb_3seg[8] = {
150 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e, 152 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
151 (-610 << 5) | 0x0a 153 (-610 << 5) | 0x0a
152}; 154};
153 155
154static const int16_t coeff_4k_sb_1seg_dqpsk[8] = { 156static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
155 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f, 157 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
156 (-922 << 5) | 0x0d 158 (-922 << 5) | 0x0d
157}; 159};
158 160
159static const int16_t coeff_4k_sb_1seg[8] = { 161static const s16 coeff_4k_sb_1seg[8] = {
160 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d, 162 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
161 (-655 << 5) | 0x0a 163 (-655 << 5) | 0x0a
162}; 164};
163 165
164static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = { 166static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
165 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14, 167 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
166 (-958 << 5) | 0x13 168 (-958 << 5) | 0x13
167}; 169};
168 170
169static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = { 171static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
170 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12, 172 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
171 (-568 << 5) | 0x0f 173 (-568 << 5) | 0x0f
172}; 174};
173 175
174static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = { 176static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
175 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14, 177 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
176 (-848 << 5) | 0x13 178 (-848 << 5) | 0x13
177}; 179};
178 180
179static const int16_t coeff_4k_sb_3seg[8] = { 181static const s16 coeff_4k_sb_3seg[8] = {
180 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12, 182 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
181 (-869 << 5) | 0x13 183 (-869 << 5) | 0x13
182}; 184};
183 185
184static const int16_t coeff_8k_sb_1seg_dqpsk[8] = { 186static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
185 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13, 187 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
186 (-598 << 5) | 0x10 188 (-598 << 5) | 0x10
187}; 189};
188 190
189static const int16_t coeff_8k_sb_1seg[8] = { 191static const s16 coeff_8k_sb_1seg[8] = {
190 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f, 192 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
191 (585 << 5) | 0x0f 193 (585 << 5) | 0x0f
192}; 194};
193 195
194static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = { 196static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
195 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18, 197 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
196 (0 << 5) | 0x14 198 (0 << 5) | 0x14
197}; 199};
198 200
199static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = { 201static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
200 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15, 202 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
201 (-877 << 5) | 0x15 203 (-877 << 5) | 0x15
202}; 204};
203 205
204static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = { 206static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
205 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18, 207 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
206 (-921 << 5) | 0x14 208 (-921 << 5) | 0x14
207}; 209};
208 210
209static const int16_t coeff_8k_sb_3seg[8] = { 211static const s16 coeff_8k_sb_3seg[8] = {
210 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15, 212 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
211 (690 << 5) | 0x14 213 (690 << 5) | 0x14
212}; 214};
213 215
214static const int16_t ana_fe_coeff_3seg[24] = { 216static const s16 ana_fe_coeff_3seg[24] = {
215 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017 217 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
216}; 218};
217 219
218static const int16_t ana_fe_coeff_1seg[24] = { 220static const s16 ana_fe_coeff_1seg[24] = {
219 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003 221 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
220}; 222};
221 223
222static const int16_t ana_fe_coeff_13seg[24] = { 224static const s16 ana_fe_coeff_13seg[24] = {
223 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1 225 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
224}; 226};
225 227
226static u16 fft_to_mode(struct dib8000_state *state) 228static u16 fft_to_mode(struct dib8000_state *state)
227{ 229{
228 u16 mode; 230 u16 mode;
229 switch (state->fe.dtv_property_cache.transmission_mode) { 231 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
230 case TRANSMISSION_MODE_2K: 232 case TRANSMISSION_MODE_2K:
231 mode = 1; 233 mode = 1;
232 break; 234 break;
@@ -249,16 +251,18 @@ static void dib8000_set_acquisition_mode(struct dib8000_state *state)
249 dprintk("acquisition mode activated"); 251 dprintk("acquisition mode activated");
250 dib8000_write_word(state, 298, nud); 252 dib8000_write_word(state, 298, nud);
251} 253}
252 254static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
253static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
254{ 255{
256 struct dib8000_state *state = fe->demodulator_priv;
257
255 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */ 258 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
256 259
257 outreg = 0; 260 outreg = 0;
258 fifo_threshold = 1792; 261 fifo_threshold = 1792;
259 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); 262 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
260 263
261 dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode); 264 dprintk("-I- Setting output mode for demod %p to %d",
265 &state->fe[0], mode);
262 266
263 switch (mode) { 267 switch (mode) {
264 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 268 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
@@ -292,7 +296,8 @@ static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
292 break; 296 break;
293 297
294 default: 298 default:
295 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe); 299 dprintk("Unhandled output_mode passed to be set for demod %p",
300 &state->fe[0]);
296 return -EINVAL; 301 return -EINVAL;
297 } 302 }
298 303
@@ -342,7 +347,8 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow
342{ 347{
343 /* by default everything is going to be powered off */ 348 /* by default everything is going to be powered off */
344 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, 349 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
345 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; 350 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
351 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
346 352
347 /* now, depending on the requested mode, we power on */ 353 /* now, depending on the requested mode, we power on */
348 switch (mode) { 354 switch (mode) {
@@ -411,8 +417,9 @@ static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_s
411 return ret; 417 return ret;
412} 418}
413 419
414static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw) 420static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
415{ 421{
422 struct dib8000_state *state = fe->demodulator_priv;
416 u32 timf; 423 u32 timf;
417 424
418 if (bw == 0) 425 if (bw == 0)
@@ -478,7 +485,8 @@ static void dib8000_reset_pll(struct dib8000_state *state)
478 485
479 // clk_cfg1 486 // clk_cfg1
480 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | 487 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
481 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0); 488 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
489 (pll->pll_range << 1) | (pll->pll_reset << 0);
482 490
483 dib8000_write_word(state, 902, clk_cfg1); 491 dib8000_write_word(state, 902, clk_cfg1);
484 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); 492 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
@@ -488,11 +496,12 @@ static void dib8000_reset_pll(struct dib8000_state *state)
488 496
489 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ 497 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
490 if (state->cfg.pll->ADClkSrc == 0) 498 if (state->cfg.pll->ADClkSrc == 0)
491 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 499 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
500 (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
492 else if (state->cfg.refclksel != 0) 501 else if (state->cfg.refclksel != 0)
493 dib8000_write_word(state, 904, 502 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
494 (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll-> 503 ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
495 ADClkSrc << 7) | (0 << 1)); 504 (pll->ADClkSrc << 7) | (0 << 1));
496 else 505 else
497 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 506 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
498 507
@@ -560,7 +569,7 @@ static const u16 dib8000_defaults[] = {
560 0xd4c0, 569 0xd4c0,
561 570
562 /*1, 32, 571 /*1, 32,
563 0x6680 // P_corm_thres Lock algorithms configuration */ 572 0x6680 // P_corm_thres Lock algorithms configuration */
564 573
565 11, 80, /* set ADC level to -16 */ 574 11, 80, /* set ADC level to -16 */
566 (1 << 13) - 825 - 117, 575 (1 << 13) - 825 - 117,
@@ -623,14 +632,14 @@ static const u16 dib8000_defaults[] = {
623 1, 285, 632 1, 285,
624 0x0020, //p_fec_ 633 0x0020, //p_fec_
625 1, 299, 634 1, 299,
626 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard 635 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
627 636
628 1, 338, 637 1, 338,
629 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 638 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
630 (1 << 10) | // P_ctrl_pre_freq_mode_sat=1 639 (1 << 10) |
631 (0 << 9) | // P_ctrl_pre_freq_inh=0 640 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
632 (3 << 5) | // P_ctrl_pre_freq_step=3 641 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
633 (1 << 0), // P_pre_freq_win_len=1 642 (1 << 0), /* P_pre_freq_win_len=1 */
634 643
635 1, 903, 644 1, 903,
636 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) 645 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
@@ -717,7 +726,7 @@ static int dib8000_reset(struct dvb_frontend *fe)
717 if (dib8000_reset_gpio(state) != 0) 726 if (dib8000_reset_gpio(state) != 0)
718 dprintk("GPIO reset was not successful."); 727 dprintk("GPIO reset was not successful.");
719 728
720 if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0) 729 if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
721 dprintk("OUTPUT_MODE could not be resetted."); 730 dprintk("OUTPUT_MODE could not be resetted.");
722 731
723 state->current_agc = NULL; 732 state->current_agc = NULL;
@@ -752,7 +761,7 @@ static int dib8000_reset(struct dvb_frontend *fe)
752 /* unforce divstr regardless whether i2c enumeration was done or not */ 761 /* unforce divstr regardless whether i2c enumeration was done or not */
753 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1)); 762 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
754 763
755 dib8000_set_bandwidth(state, 6000); 764 dib8000_set_bandwidth(fe, 6000);
756 765
757 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); 766 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
758 dib8000_sad_calib(state); 767 dib8000_sad_calib(state);
@@ -778,7 +787,7 @@ static int dib8000_update_lna(struct dib8000_state *state)
778 // read dyn_gain here (because it is demod-dependent and not tuner) 787 // read dyn_gain here (because it is demod-dependent and not tuner)
779 dyn_gain = dib8000_read_word(state, 390); 788 dyn_gain = dib8000_read_word(state, 390);
780 789
781 if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed 790 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
782 dib8000_restart_agc(state); 791 dib8000_restart_agc(state);
783 return 1; 792 return 1;
784 } 793 }
@@ -865,7 +874,8 @@ static int dib8000_agc_soft_split(struct dib8000_state *state)
865 split_offset = state->current_agc->split.max; 874 split_offset = state->current_agc->split.max;
866 else 875 else
867 split_offset = state->current_agc->split.max * 876 split_offset = state->current_agc->split.max *
868 (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres); 877 (agc - state->current_agc->split.min_thres) /
878 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
869 879
870 dprintk("AGC split_offset: %d", split_offset); 880 dprintk("AGC split_offset: %d", split_offset);
871 881
@@ -900,7 +910,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
900 case CT_AGC_STEP_0: 910 case CT_AGC_STEP_0:
901 //AGC initialization 911 //AGC initialization
902 if (state->cfg.agc_control) 912 if (state->cfg.agc_control)
903 state->cfg.agc_control(&state->fe, 1); 913 state->cfg.agc_control(fe, 1);
904 914
905 dib8000_restart_agc(state); 915 dib8000_restart_agc(state);
906 916
@@ -924,7 +934,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
924 dib8000_agc_soft_split(state); 934 dib8000_agc_soft_split(state);
925 935
926 if (state->cfg.agc_control) 936 if (state->cfg.agc_control)
927 state->cfg.agc_control(&state->fe, 0); 937 state->cfg.agc_control(fe, 0);
928 938
929 *tune_state = CT_AGC_STOP; 939 *tune_state = CT_AGC_STOP;
930 break; 940 break;
@@ -936,29 +946,28 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
936 946
937} 947}
938 948
939static const int32_t lut_1000ln_mant[] = 949static const s32 lut_1000ln_mant[] =
940{ 950{
941 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 951 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
942}; 952};
943 953
944int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode) 954s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
945{ 955{
946 struct dib8000_state *state = fe->demodulator_priv; 956 struct dib8000_state *state = fe->demodulator_priv;
947 uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0; 957 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
948 int32_t val; 958 s32 val;
949 959
950 val = dib8000_read32(state, 384); 960 val = dib8000_read32(state, 384);
951 /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ 961 if (mode) {
952 if (mode) { 962 tmp_val = val;
953 tmp_val = val; 963 while (tmp_val >>= 1)
954 while (tmp_val >>= 1) 964 exp++;
955 exp++; 965 mant = (val * 1000 / (1<<exp));
956 mant = (val * 1000 / (1<<exp)); 966 ix = (u8)((mant-1000)/100); /* index of the LUT */
957 ix = (uint8_t)((mant-1000)/100); /* index of the LUT */ 967 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
958 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */ 968 val = (val*256)/1000;
959 val = (val*256)/1000; 969 }
960 } 970 return val;
961 return val;
962} 971}
963EXPORT_SYMBOL(dib8000_get_adc_power); 972EXPORT_SYMBOL(dib8000_get_adc_power);
964 973
@@ -1002,22 +1011,23 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1002 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); 1011 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1003 1012
1004 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec 1013 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1005 dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i); 1014 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1006 1015
1007 if (state->fe.dtv_property_cache.isdbt_sb_mode) { 1016 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1008 //compute new dds_freq for the seg and adjust prbs 1017 //compute new dds_freq for the seg and adjust prbs
1009 int seg_offset = 1018 int seg_offset =
1010 state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) - 1019 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1011 (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2); 1020 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1021 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1012 int clk = state->cfg.pll->internal; 1022 int clk = state->cfg.pll->internal;
1013 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) 1023 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1014 int dds_offset = seg_offset * segtodds; 1024 int dds_offset = seg_offset * segtodds;
1015 int new_dds, sub_channel; 1025 int new_dds, sub_channel;
1016 if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even 1026 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1017 dds_offset -= (int)(segtodds / 2); 1027 dds_offset -= (int)(segtodds / 2);
1018 1028
1019 if (state->cfg.pll->ifreq == 0) { 1029 if (state->cfg.pll->ifreq == 0) {
1020 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) { 1030 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1021 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1); 1031 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1022 new_dds = dds_offset; 1032 new_dds = dds_offset;
1023 } else 1033 } else
@@ -1027,35 +1037,35 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1027 // - the segment of center frequency with an odd total number of segments 1037 // - the segment of center frequency with an odd total number of segments
1028 // - the segment to the left of center frequency with an even total number of segments 1038 // - the segment to the left of center frequency with an even total number of segments
1029 // - the segment to the right of center frequency with an even total number of segments 1039 // - the segment to the right of center frequency with an even total number of segments
1030 if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1) 1040 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1031 && 1041 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1032 (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) 1042 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1033 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == 1043 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1034 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) 1044 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1035 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 1045 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1036 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2))) 1046 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1037 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 1047 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1038 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == 1048 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1039 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) 1049 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1040 )) { 1050 )) {
1041 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26) 1051 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1042 } 1052 }
1043 } else { 1053 } else {
1044 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) 1054 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1045 new_dds = state->cfg.pll->ifreq - dds_offset; 1055 new_dds = state->cfg.pll->ifreq - dds_offset;
1046 else 1056 else
1047 new_dds = state->cfg.pll->ifreq + dds_offset; 1057 new_dds = state->cfg.pll->ifreq + dds_offset;
1048 } 1058 }
1049 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); 1059 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1050 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); 1060 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1051 if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd 1061 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1052 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; 1062 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1053 else // if even 1063 else
1054 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; 1064 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1055 sub_channel -= 6; 1065 sub_channel -= 6;
1056 1066
1057 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K 1067 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1058 || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) { 1068 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1059 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1 1069 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1060 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1 1070 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1061 } else { 1071 } else {
@@ -1063,7 +1073,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1063 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0 1073 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1064 } 1074 }
1065 1075
1066 switch (state->fe.dtv_property_cache.transmission_mode) { 1076 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1067 case TRANSMISSION_MODE_2K: 1077 case TRANSMISSION_MODE_2K:
1068 switch (sub_channel) { 1078 switch (sub_channel) {
1069 case -6: 1079 case -6:
@@ -1209,7 +1219,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1209 } 1219 }
1210 break; 1220 break;
1211 } 1221 }
1212 } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode 1222 } else {
1213 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); 1223 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1214 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); 1224 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1215 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); 1225 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
@@ -1218,7 +1228,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1218 dib8000_write_word(state, 10, (seq << 4)); 1228 dib8000_write_word(state, 10, (seq << 4));
1219 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000); 1229 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1220 1230
1221 switch (state->fe.dtv_property_cache.guard_interval) { 1231 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1222 case GUARD_INTERVAL_1_32: 1232 case GUARD_INTERVAL_1_32:
1223 guard = 0; 1233 guard = 0;
1224 break; 1234 break;
@@ -1238,7 +1248,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1238 1248
1239 max_constellation = DQPSK; 1249 max_constellation = DQPSK;
1240 for (i = 0; i < 3; i++) { 1250 for (i = 0; i < 3; i++) {
1241 switch (state->fe.dtv_property_cache.layer[i].modulation) { 1251 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
1242 case DQPSK: 1252 case DQPSK:
1243 constellation = 0; 1253 constellation = 0;
1244 break; 1254 break;
@@ -1254,7 +1264,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1254 break; 1264 break;
1255 } 1265 }
1256 1266
1257 switch (state->fe.dtv_property_cache.layer[i].fec) { 1267 switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
1258 case FEC_1_2: 1268 case FEC_1_2:
1259 crate = 1; 1269 crate = 1;
1260 break; 1270 break;
@@ -1273,26 +1283,26 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1273 break; 1283 break;
1274 } 1284 }
1275 1285
1276 if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) && 1286 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
1277 ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) || 1287 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
1278 (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1)) 1288 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
1279 ) 1289 )
1280 timeI = state->fe.dtv_property_cache.layer[i].interleaving; 1290 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
1281 else 1291 else
1282 timeI = 0; 1292 timeI = 0;
1283 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) | 1293 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1284 (crate << 3) | timeI); 1294 (crate << 3) | timeI);
1285 if (state->fe.dtv_property_cache.layer[i].segment_count > 0) { 1295 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
1286 switch (max_constellation) { 1296 switch (max_constellation) {
1287 case DQPSK: 1297 case DQPSK:
1288 case QPSK: 1298 case QPSK:
1289 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 || 1299 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
1290 state->fe.dtv_property_cache.layer[i].modulation == QAM_64) 1300 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1291 max_constellation = state->fe.dtv_property_cache.layer[i].modulation; 1301 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1292 break; 1302 break;
1293 case QAM_16: 1303 case QAM_16:
1294 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64) 1304 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1295 max_constellation = state->fe.dtv_property_cache.layer[i].modulation; 1305 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1296 break; 1306 break;
1297 } 1307 }
1298 } 1308 }
@@ -1303,34 +1313,34 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1303 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/ 1313 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1304 1314
1305 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | 1315 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1306 ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache. 1316 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
1307 isdbt_sb_mode & 1) << 4)); 1317 isdbt_sb_mode & 1) << 4));
1308 1318
1309 dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval); 1319 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
1310 1320
1311 /* signal optimization parameter */ 1321 /* signal optimization parameter */
1312 1322
1313 if (state->fe.dtv_property_cache.isdbt_partial_reception) { 1323 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
1314 seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0]; 1324 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1315 for (i = 1; i < 3; i++) 1325 for (i = 1; i < 3; i++)
1316 nbseg_diff += 1326 nbseg_diff +=
1317 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; 1327 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1318 for (i = 0; i < nbseg_diff; i++) 1328 for (i = 0; i < nbseg_diff; i++)
1319 seg_diff_mask |= 1 << permu_seg[i + 1]; 1329 seg_diff_mask |= 1 << permu_seg[i + 1];
1320 } else { 1330 } else {
1321 for (i = 0; i < 3; i++) 1331 for (i = 0; i < 3; i++)
1322 nbseg_diff += 1332 nbseg_diff +=
1323 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; 1333 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1324 for (i = 0; i < nbseg_diff; i++) 1334 for (i = 0; i < nbseg_diff; i++)
1325 seg_diff_mask |= 1 << permu_seg[i]; 1335 seg_diff_mask |= 1 << permu_seg[i];
1326 } 1336 }
1327 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); 1337 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1328 1338
1329 state->differential_constellation = (seg_diff_mask != 0); 1339 state->differential_constellation = (seg_diff_mask != 0);
1330 dib8000_set_diversity_in(&state->fe, state->diversity_onoff); 1340 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
1331 1341
1332 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb 1342 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1333 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments 1343 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1334 seg_mask13 = 0x00E0; 1344 seg_mask13 = 0x00E0;
1335 else // 1-segment 1345 else // 1-segment
1336 seg_mask13 = 0x0040; 1346 seg_mask13 = 0x0040;
@@ -1340,7 +1350,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1340 // WRITE: Mode & Diff mask 1350 // WRITE: Mode & Diff mask
1341 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); 1351 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1342 1352
1343 if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode)) 1353 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
1344 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200); 1354 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1345 else 1355 else
1346 dib8000_write_word(state, 268, (2 << 9) | 39); //init value 1356 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
@@ -1351,26 +1361,25 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1351 1361
1352 dib8000_write_word(state, 353, seg_mask13); // ADDR 353 1362 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1353 1363
1354/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ 1364/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1355 // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1356 1365
1357 // ---- SMALL ---- 1366 // ---- SMALL ----
1358 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1367 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1359 switch (state->fe.dtv_property_cache.transmission_mode) { 1368 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1360 case TRANSMISSION_MODE_2K: 1369 case TRANSMISSION_MODE_2K:
1361 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg 1370 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1362 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK 1371 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1363 ncoeff = coeff_2k_sb_1seg_dqpsk; 1372 ncoeff = coeff_2k_sb_1seg_dqpsk;
1364 else // QPSK or QAM 1373 else // QPSK or QAM
1365 ncoeff = coeff_2k_sb_1seg; 1374 ncoeff = coeff_2k_sb_1seg;
1366 } else { // 3-segments 1375 } else { // 3-segments
1367 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment 1376 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1368 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments 1377 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1369 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; 1378 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1370 else // QPSK or QAM on external segments 1379 else // QPSK or QAM on external segments
1371 ncoeff = coeff_2k_sb_3seg_0dqpsk; 1380 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1372 } else { // QPSK or QAM on central segment 1381 } else { // QPSK or QAM on central segment
1373 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments 1382 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1374 ncoeff = coeff_2k_sb_3seg_1dqpsk; 1383 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1375 else // QPSK or QAM on external segments 1384 else // QPSK or QAM on external segments
1376 ncoeff = coeff_2k_sb_3seg; 1385 ncoeff = coeff_2k_sb_3seg;
@@ -1379,20 +1388,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1379 break; 1388 break;
1380 1389
1381 case TRANSMISSION_MODE_4K: 1390 case TRANSMISSION_MODE_4K:
1382 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg 1391 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1383 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK 1392 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1384 ncoeff = coeff_4k_sb_1seg_dqpsk; 1393 ncoeff = coeff_4k_sb_1seg_dqpsk;
1385 else // QPSK or QAM 1394 else // QPSK or QAM
1386 ncoeff = coeff_4k_sb_1seg; 1395 ncoeff = coeff_4k_sb_1seg;
1387 } else { // 3-segments 1396 } else { // 3-segments
1388 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment 1397 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1389 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1398 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1390 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; 1399 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1391 } else { // QPSK or QAM on external segments 1400 } else { // QPSK or QAM on external segments
1392 ncoeff = coeff_4k_sb_3seg_0dqpsk; 1401 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1393 } 1402 }
1394 } else { // QPSK or QAM on central segment 1403 } else { // QPSK or QAM on central segment
1395 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1404 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1396 ncoeff = coeff_4k_sb_3seg_1dqpsk; 1405 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1397 } else // QPSK or QAM on external segments 1406 } else // QPSK or QAM on external segments
1398 ncoeff = coeff_4k_sb_3seg; 1407 ncoeff = coeff_4k_sb_3seg;
@@ -1403,20 +1412,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1403 case TRANSMISSION_MODE_AUTO: 1412 case TRANSMISSION_MODE_AUTO:
1404 case TRANSMISSION_MODE_8K: 1413 case TRANSMISSION_MODE_8K:
1405 default: 1414 default:
1406 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg 1415 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1407 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK 1416 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1408 ncoeff = coeff_8k_sb_1seg_dqpsk; 1417 ncoeff = coeff_8k_sb_1seg_dqpsk;
1409 else // QPSK or QAM 1418 else // QPSK or QAM
1410 ncoeff = coeff_8k_sb_1seg; 1419 ncoeff = coeff_8k_sb_1seg;
1411 } else { // 3-segments 1420 } else { // 3-segments
1412 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment 1421 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1413 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1422 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1414 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; 1423 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1415 } else { // QPSK or QAM on external segments 1424 } else { // QPSK or QAM on external segments
1416 ncoeff = coeff_8k_sb_3seg_0dqpsk; 1425 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1417 } 1426 }
1418 } else { // QPSK or QAM on central segment 1427 } else { // QPSK or QAM on central segment
1419 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1428 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1420 ncoeff = coeff_8k_sb_3seg_1dqpsk; 1429 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1421 } else // QPSK or QAM on external segments 1430 } else // QPSK or QAM on external segments
1422 ncoeff = coeff_8k_sb_3seg; 1431 ncoeff = coeff_8k_sb_3seg;
@@ -1430,22 +1439,22 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1430 1439
1431 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 1440 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1432 dib8000_write_word(state, 351, 1441 dib8000_write_word(state, 351,
1433 (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5); 1442 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1434 1443
1435 // ---- COFF ---- 1444 // ---- COFF ----
1436 // Carloff, the most robust 1445 // Carloff, the most robust
1437 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots 1446 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1438 1447
1439 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 1448 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1440 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1 1449 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
1441 dib8000_write_word(state, 187, 1450 dib8000_write_word(state, 187,
1442 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2) 1451 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
1443 | 0x3); 1452 | 0x3);
1444 1453
1445/* // P_small_coef_ext_enable = 1 */ 1454/* // P_small_coef_ext_enable = 1 */
1446/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ 1455/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1447 1456
1448 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg 1457 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1449 1458
1450 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1) 1459 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
1451 if (mode == 3) 1460 if (mode == 3)
@@ -1469,10 +1478,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1469 dib8000_write_word(state, 186, 80); 1478 dib8000_write_word(state, 186, 80);
1470 } else { // Sound Broadcasting mode 3 seg 1479 } else { // Sound Broadcasting mode 3 seg
1471 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15 1480 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1472 /* if (mode == 3) */ 1481 /* if (mode == 3) */
1473 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */ 1482 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1474 /* else */ 1483 /* else */
1475 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */ 1484 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1476 dib8000_write_word(state, 180, 0x1fcf | (1 << 14)); 1485 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1477 1486
1478 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, 1487 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
@@ -1509,7 +1518,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1509 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); 1518 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1510 } 1519 }
1511 // ---- FFT ---- 1520 // ---- FFT ----
1512 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg 1521 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1513 dib8000_write_word(state, 178, 64); // P_fft_powrange=64 1522 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1514 else 1523 else
1515 dib8000_write_word(state, 178, 32); // P_fft_powrange=32 1524 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
@@ -1518,12 +1527,12 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1518 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed) 1527 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1519 */ 1528 */
1520 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) 1529 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1521 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ 1530 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1522 1531
1523 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */ 1532 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1524 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */ 1533 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1525 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */ 1534 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1526 if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0)) 1535 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1527 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */ 1536 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1528 else 1537 else
1529 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */ 1538 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
@@ -1538,8 +1547,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1538 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */ 1547 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1539 1548
1540 /* offset loop parameters */ 1549 /* offset loop parameters */
1541 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1550 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1542 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg 1551 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1543 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ 1552 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1544 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40); 1553 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1545 1554
@@ -1551,8 +1560,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1551 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */ 1560 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1552 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80); 1561 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1553 1562
1554 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1563 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1555 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg 1564 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1556 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */ 1565 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1557 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode)); 1566 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1558 1567
@@ -1564,7 +1573,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1564 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode)); 1573 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1565 1574
1566 /* P_dvsy_sync_wait - reuse mode */ 1575 /* P_dvsy_sync_wait - reuse mode */
1567 switch (state->fe.dtv_property_cache.transmission_mode) { 1576 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1568 case TRANSMISSION_MODE_8K: 1577 case TRANSMISSION_MODE_8K:
1569 mode = 256; 1578 mode = 256;
1570 break; 1579 break;
@@ -1624,15 +1633,15 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1624 } 1633 }
1625 1634
1626 // ---- ANA_FE ---- 1635 // ---- ANA_FE ----
1627 if (state->fe.dtv_property_cache.isdbt_sb_mode) { 1636 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1628 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments 1637 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1629 ana_fe = ana_fe_coeff_3seg; 1638 ana_fe = ana_fe_coeff_3seg;
1630 else // 1-segment 1639 else // 1-segment
1631 ana_fe = ana_fe_coeff_1seg; 1640 ana_fe = ana_fe_coeff_1seg;
1632 } else 1641 } else
1633 ana_fe = ana_fe_coeff_13seg; 1642 ana_fe = ana_fe_coeff_13seg;
1634 1643
1635 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0) 1644 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1636 for (mode = 0; mode < 24; mode++) 1645 for (mode = 0; mode < 24; mode++)
1637 dib8000_write_word(state, 117 + mode, ana_fe[mode]); 1646 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1638 1647
@@ -1648,11 +1657,11 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1648 // "P_cspu_left_edge" not used => do not care 1657 // "P_cspu_left_edge" not used => do not care
1649 // "P_cspu_right_edge" not used => do not care 1658 // "P_cspu_right_edge" not used => do not care
1650 1659
1651 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb 1660 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1652 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1 1661 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1653 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0 1662 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1654 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment 1663 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
1655 && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) { 1664 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1656 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0 1665 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1657 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15 1666 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1658 } 1667 }
@@ -1664,7 +1673,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1664 // ---- TMCC ---- 1673 // ---- TMCC ----
1665 for (i = 0; i < 3; i++) 1674 for (i = 0; i < 3; i++)
1666 tmcc_pow += 1675 tmcc_pow +=
1667 (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count); 1676 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
1668 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); 1677 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1669 // Threshold is set at 1/4 of max power. 1678 // Threshold is set at 1/4 of max power.
1670 tmcc_pow *= (1 << (9 - 2)); 1679 tmcc_pow *= (1 << (9 - 2));
@@ -1678,7 +1687,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1678 if (state->isdbt_cfg_loaded == 0) 1687 if (state->isdbt_cfg_loaded == 0)
1679 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */ 1688 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1680 1689
1681 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) 1690 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1682 state->isdbt_cfg_loaded = 0; 1691 state->isdbt_cfg_loaded = 0;
1683 else 1692 else
1684 state->isdbt_cfg_loaded = 1; 1693 state->isdbt_cfg_loaded = 1;
@@ -1693,38 +1702,38 @@ static int dib8000_autosearch_start(struct dvb_frontend *fe)
1693 1702
1694 int slist = 0; 1703 int slist = 0;
1695 1704
1696 state->fe.dtv_property_cache.inversion = 0; 1705 state->fe[0]->dtv_property_cache.inversion = 0;
1697 if (!state->fe.dtv_property_cache.isdbt_sb_mode) 1706 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
1698 state->fe.dtv_property_cache.layer[0].segment_count = 13; 1707 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
1699 state->fe.dtv_property_cache.layer[0].modulation = QAM_64; 1708 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
1700 state->fe.dtv_property_cache.layer[0].fec = FEC_2_3; 1709 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
1701 state->fe.dtv_property_cache.layer[0].interleaving = 0; 1710 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
1702 1711
1703 //choose the right list, in sb, always do everything 1712 //choose the right list, in sb, always do everything
1704 if (state->fe.dtv_property_cache.isdbt_sb_mode) { 1713 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1705 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; 1714 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1706 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; 1715 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1707 slist = 7; 1716 slist = 7;
1708 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); 1717 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1709 } else { 1718 } else {
1710 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) { 1719 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1711 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { 1720 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1712 slist = 7; 1721 slist = 7;
1713 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2 1722 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1714 } else 1723 } else
1715 slist = 3; 1724 slist = 3;
1716 } else { 1725 } else {
1717 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { 1726 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1718 slist = 2; 1727 slist = 2;
1719 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 1728 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1720 } else 1729 } else
1721 slist = 0; 1730 slist = 0;
1722 } 1731 }
1723 1732
1724 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) 1733 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1725 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; 1734 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1726 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) 1735 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1727 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; 1736 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1728 1737
1729 dprintk("using list for autosearch : %d", slist); 1738 dprintk("using list for autosearch : %d", slist);
1730 dib8000_set_channel(state, (unsigned char)slist, 1); 1739 dib8000_set_channel(state, (unsigned char)slist, 1);
@@ -1786,7 +1795,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
1786 if (state == NULL) 1795 if (state == NULL)
1787 return -EINVAL; 1796 return -EINVAL;
1788 1797
1789 dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000); 1798 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
1790 dib8000_set_channel(state, 0, 0); 1799 dib8000_set_channel(state, 0, 0);
1791 1800
1792 // restart demod 1801 // restart demod
@@ -1799,17 +1808,16 @@ static int dib8000_tune(struct dvb_frontend *fe)
1799 1808
1800 // never achieved a lock before - wait for timfreq to update 1809 // never achieved a lock before - wait for timfreq to update
1801 if (state->timf == 0) { 1810 if (state->timf == 0) {
1802 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1811 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1803 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg 1812 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1804 msleep(300); 1813 msleep(300);
1805 else // Sound Broadcasting mode 3 seg 1814 else // Sound Broadcasting mode 3 seg
1806 msleep(500); 1815 msleep(500);
1807 } else // 13 seg 1816 } else // 13 seg
1808 msleep(200); 1817 msleep(200);
1809 } 1818 }
1810 //dump_reg(state); 1819 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1811 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1820 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1812 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1813 1821
1814 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */ 1822 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1815 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40); 1823 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
@@ -1854,26 +1862,38 @@ static int dib8000_tune(struct dvb_frontend *fe)
1854static int dib8000_wakeup(struct dvb_frontend *fe) 1862static int dib8000_wakeup(struct dvb_frontend *fe)
1855{ 1863{
1856 struct dib8000_state *state = fe->demodulator_priv; 1864 struct dib8000_state *state = fe->demodulator_priv;
1865 u8 index_frontend;
1866 int ret;
1857 1867
1858 dib8000_set_power_mode(state, DIB8000M_POWER_ALL); 1868 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1859 dib8000_set_adc_state(state, DIBX000_ADC_ON); 1869 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1860 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) 1870 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1861 dprintk("could not start Slow ADC"); 1871 dprintk("could not start Slow ADC");
1862 1872
1873 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1874 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
1875 if (ret < 0)
1876 return ret;
1877 }
1878
1863 return 0; 1879 return 0;
1864} 1880}
1865 1881
1866static int dib8000_sleep(struct dvb_frontend *fe) 1882static int dib8000_sleep(struct dvb_frontend *fe)
1867{ 1883{
1868 struct dib8000_state *st = fe->demodulator_priv; 1884 struct dib8000_state *state = fe->demodulator_priv;
1869 if (1) { 1885 u8 index_frontend;
1870 dib8000_set_output_mode(st, OUTMODE_HIGH_Z); 1886 int ret;
1871 dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1872 return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1873 } else {
1874 1887
1875 return 0; 1888 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1889 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1890 if (ret < 0)
1891 return ret;
1876 } 1892 }
1893
1894 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
1895 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
1896 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
1877} 1897}
1878 1898
1879enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) 1899enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
@@ -1891,16 +1911,40 @@ int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun
1891} 1911}
1892EXPORT_SYMBOL(dib8000_set_tune_state); 1912EXPORT_SYMBOL(dib8000_set_tune_state);
1893 1913
1894
1895
1896
1897static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 1914static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1898{ 1915{
1899 struct dib8000_state *state = fe->demodulator_priv; 1916 struct dib8000_state *state = fe->demodulator_priv;
1900 u16 i, val = 0; 1917 u16 i, val = 0;
1918 fe_status_t stat;
1919 u8 index_frontend, sub_index_frontend;
1901 1920
1902 fe->dtv_property_cache.bandwidth_hz = 6000000; 1921 fe->dtv_property_cache.bandwidth_hz = 6000000;
1903 1922
1923 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1924 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1925 if (stat&FE_HAS_SYNC) {
1926 dprintk("TMCC lock on the slave%i", index_frontend);
1927 /* synchronize the cache with the other frontends */
1928 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
1929 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
1930 if (sub_index_frontend != index_frontend) {
1931 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
1932 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
1933 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1934 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
1935 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
1936 for (i = 0; i < 3; i++) {
1937 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
1938 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
1939 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
1940 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
1941 }
1942 }
1943 }
1944 return 0;
1945 }
1946 }
1947
1904 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; 1948 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1905 1949
1906 val = dib8000_read_word(state, 570); 1950 val = dib8000_read_word(state, 570);
@@ -1992,112 +2036,200 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
1992 break; 2036 break;
1993 } 2037 }
1994 } 2038 }
2039
2040 /* synchronize the cache with the other frontends */
2041 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2042 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2043 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2044 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2045 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2046 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2047 for (i = 0; i < 3; i++) {
2048 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2049 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2050 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2051 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2052 }
2053 }
1995 return 0; 2054 return 0;
1996} 2055}
1997 2056
1998static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 2057static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1999{ 2058{
2000 struct dib8000_state *state = fe->demodulator_priv; 2059 struct dib8000_state *state = fe->demodulator_priv;
2060 u8 nbr_pending, exit_condition, index_frontend;
2061 s8 index_frontend_success = -1;
2001 int time, ret; 2062 int time, ret;
2063 int time_slave = FE_CALLBACK_TIME_NEVER;
2002 2064
2003 fe->dtv_property_cache.delivery_system = SYS_ISDBT; 2065 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2066 dprintk("dib8000: must at least specify frequency ");
2067 return 0;
2068 }
2004 2069
2005 dib8000_set_output_mode(state, OUTMODE_HIGH_Z); 2070 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2071 dprintk("dib8000: no bandwidth specified, set to default ");
2072 state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2073 }
2074
2075 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2076 /* synchronization of the cache */
2077 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2078 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2079
2080 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2081 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2082 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep);
2006 2083
2007 if (fe->ops.tuner_ops.set_params) 2084 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2008 fe->ops.tuner_ops.set_params(fe, fep); 2085 }
2009 2086
2010 /* start up the AGC */ 2087 /* start up the AGC */
2011 state->tune_state = CT_AGC_START;
2012 do { 2088 do {
2013 time = dib8000_agc_startup(fe); 2089 time = dib8000_agc_startup(state->fe[0]);
2090 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2091 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
2092 if (time == FE_CALLBACK_TIME_NEVER)
2093 time = time_slave;
2094 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
2095 time = time_slave;
2096 }
2014 if (time != FE_CALLBACK_TIME_NEVER) 2097 if (time != FE_CALLBACK_TIME_NEVER)
2015 msleep(time / 10); 2098 msleep(time / 10);
2016 else 2099 else
2017 break; 2100 break;
2018 } while (state->tune_state != CT_AGC_STOP); 2101 exit_condition = 1;
2019 2102 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2020 if (state->fe.dtv_property_cache.frequency == 0) { 2103 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
2021 dprintk("dib8000: must at least specify frequency "); 2104 exit_condition = 0;
2022 return 0; 2105 break;
2023 } 2106 }
2024 2107 }
2025 if (state->fe.dtv_property_cache.bandwidth_hz == 0) { 2108 } while (exit_condition == 0);
2026 dprintk("dib8000: no bandwidth specified, set to default "); 2109
2027 state->fe.dtv_property_cache.bandwidth_hz = 6000000; 2110 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2028 } 2111 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2112
2113 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
2114 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
2115 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2116 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2117 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2118 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
2119 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
2120 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2121 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2122 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2123 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
2124 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
2125 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2126 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2127 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2128 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
2129 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
2130 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2131 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2132 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
2133 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2134 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
2135 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2136 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2137 int i = 80000;
2138 u8 found = 0;
2139 u8 tune_failed = 0;
2140
2141 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2142 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
2143 dib8000_autosearch_start(state->fe[index_frontend]);
2144 }
2029 2145
2030 state->tune_state = CT_DEMOD_START;
2031
2032 if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
2033 (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
2034 (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2035 (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2036 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2037 (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
2038 (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
2039 ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2040 (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2041 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2042 (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2043 (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2044 ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2045 (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2046 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2047 (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2048 (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2049 ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2050 (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2051 (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2052 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2053 ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2054 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2055 ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2056 int i = 800, found;
2057
2058 dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2059 dib8000_autosearch_start(fe);
2060 do { 2146 do {
2061 msleep(10); 2147 msleep(20);
2062 found = dib8000_autosearch_irq(fe); 2148 nbr_pending = 0;
2063 } while (found == 0 && i--); 2149 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
2150 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2151 if (((tune_failed >> index_frontend) & 0x1) == 0) {
2152 found = dib8000_autosearch_irq(state->fe[index_frontend]);
2153 switch (found) {
2154 case 0: /* tune pending */
2155 nbr_pending++;
2156 break;
2157 case 2:
2158 dprintk("autosearch succeed on the frontend%i", index_frontend);
2159 exit_condition = 2;
2160 index_frontend_success = index_frontend;
2161 break;
2162 default:
2163 dprintk("unhandled autosearch result");
2164 case 1:
2165 dprintk("autosearch failed for the frontend%i", index_frontend);
2166 break;
2167 }
2168 }
2169 }
2064 2170
2065 dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found); 2171 /* if all tune are done and no success, exit: tune failed */
2172 if ((nbr_pending == 0) && (exit_condition == 0))
2173 exit_condition = 1;
2174 } while ((exit_condition == 0) && i--);
2066 2175
2067 if (found == 0 || found == 1) 2176 if (exit_condition == 1) { /* tune failed */
2068 return 0; // no channel found 2177 dprintk("tune failed");
2178 return 0;
2179 }
2180
2181 dprintk("tune success on frontend%i", index_frontend_success);
2069 2182
2070 dib8000_get_frontend(fe, fep); 2183 dib8000_get_frontend(fe, fep);
2071 } 2184 }
2072 2185
2073 ret = dib8000_tune(fe); 2186 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2187 ret = dib8000_tune(state->fe[index_frontend]);
2188
2189 /* set output mode and diversity input */
2190 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
2191 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2192 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2193 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
2194 }
2074 2195
2075 /* make this a config parameter */ 2196 /* turn off the diversity of the last chip */
2076 dib8000_set_output_mode(state, state->cfg.output_mode); 2197 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
2077 2198
2078 return ret; 2199 return ret;
2079} 2200}
2080 2201
2202static u16 dib8000_read_lock(struct dvb_frontend *fe)
2203{
2204 struct dib8000_state *state = fe->demodulator_priv;
2205
2206 return dib8000_read_word(state, 568);
2207}
2208
2081static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) 2209static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2082{ 2210{
2083 struct dib8000_state *state = fe->demodulator_priv; 2211 struct dib8000_state *state = fe->demodulator_priv;
2084 u16 lock = dib8000_read_word(state, 568); 2212 u16 lock_slave = 0, lock = dib8000_read_word(state, 568);
2213 u8 index_frontend;
2214
2215 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2216 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
2085 2217
2086 *stat = 0; 2218 *stat = 0;
2087 2219
2088 if ((lock >> 13) & 1) 2220 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
2089 *stat |= FE_HAS_SIGNAL; 2221 *stat |= FE_HAS_SIGNAL;
2090 2222
2091 if ((lock >> 8) & 1) /* Equal */ 2223 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
2092 *stat |= FE_HAS_CARRIER; 2224 *stat |= FE_HAS_CARRIER;
2093 2225
2094 if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */ 2226 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
2095 *stat |= FE_HAS_SYNC; 2227 *stat |= FE_HAS_SYNC;
2096 2228
2097 if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */ 2229 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
2098 *stat |= FE_HAS_LOCK; 2230 *stat |= FE_HAS_LOCK;
2099 2231
2100 if ((lock >> 12) & 1) { 2232 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
2101 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ 2233 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2102 if (lock & 0x01) 2234 if (lock & 0x01)
2103 *stat |= FE_HAS_VITERBI; 2235 *stat |= FE_HAS_VITERBI;
@@ -2131,44 +2263,120 @@ static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2131static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) 2263static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2132{ 2264{
2133 struct dib8000_state *state = fe->demodulator_priv; 2265 struct dib8000_state *state = fe->demodulator_priv;
2134 u16 val = dib8000_read_word(state, 390); 2266 u8 index_frontend;
2135 *strength = 65535 - val; 2267 u16 val;
2268
2269 *strength = 0;
2270 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2271 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2272 if (val > 65535 - *strength)
2273 *strength = 65535;
2274 else
2275 *strength += val;
2276 }
2277
2278 val = 65535 - dib8000_read_word(state, 390);
2279 if (val > 65535 - *strength)
2280 *strength = 65535;
2281 else
2282 *strength += val;
2136 return 0; 2283 return 0;
2137} 2284}
2138 2285
2139static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) 2286static u32 dib8000_get_snr(struct dvb_frontend *fe)
2140{ 2287{
2141 struct dib8000_state *state = fe->demodulator_priv; 2288 struct dib8000_state *state = fe->demodulator_priv;
2289 u32 n, s, exp;
2142 u16 val; 2290 u16 val;
2143 s32 signal_mant, signal_exp, noise_mant, noise_exp;
2144 u32 result = 0;
2145 2291
2146 val = dib8000_read_word(state, 542); 2292 val = dib8000_read_word(state, 542);
2147 noise_mant = (val >> 6) & 0xff; 2293 n = (val >> 6) & 0xff;
2148 noise_exp = (val & 0x3f); 2294 exp = (val & 0x3f);
2295 if ((exp & 0x20) != 0)
2296 exp -= 0x40;
2297 n <<= exp+16;
2149 2298
2150 val = dib8000_read_word(state, 543); 2299 val = dib8000_read_word(state, 543);
2151 signal_mant = (val >> 6) & 0xff; 2300 s = (val >> 6) & 0xff;
2152 signal_exp = (val & 0x3f); 2301 exp = (val & 0x3f);
2302 if ((exp & 0x20) != 0)
2303 exp -= 0x40;
2304 s <<= exp+16;
2305
2306 if (n > 0) {
2307 u32 t = (s/n) << 16;
2308 return t + ((s << 16) - n*t) / n;
2309 }
2310 return 0xffffffff;
2311}
2153 2312
2154 if ((noise_exp & 0x20) != 0) 2313static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2155 noise_exp -= 0x40; 2314{
2156 if ((signal_exp & 0x20) != 0) 2315 struct dib8000_state *state = fe->demodulator_priv;
2157 signal_exp -= 0x40; 2316 u8 index_frontend;
2317 u32 snr_master;
2158 2318
2159 if (signal_mant != 0) 2319 snr_master = dib8000_get_snr(fe);
2160 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant); 2320 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2161 else 2321 snr_master += dib8000_get_snr(state->fe[index_frontend]);
2162 result = intlog10(2) * 10 * signal_exp - 100; 2322
2163 if (noise_mant != 0) 2323 if (snr_master != 0) {
2164 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant); 2324 snr_master = 10*intlog10(snr_master>>16);
2325 *snr = snr_master / ((1 << 24) / 10);
2326 }
2165 else 2327 else
2166 result -= intlog10(2) * 10 * noise_exp - 100; 2328 *snr = 0;
2167 2329
2168 *snr = result / ((1 << 24) / 10);
2169 return 0; 2330 return 0;
2170} 2331}
2171 2332
2333int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2334{
2335 struct dib8000_state *state = fe->demodulator_priv;
2336 u8 index_frontend = 1;
2337
2338 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2339 index_frontend++;
2340 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2341 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2342 state->fe[index_frontend] = fe_slave;
2343 return 0;
2344 }
2345
2346 dprintk("too many slave frontend");
2347 return -ENOMEM;
2348}
2349EXPORT_SYMBOL(dib8000_set_slave_frontend);
2350
2351int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
2352{
2353 struct dib8000_state *state = fe->demodulator_priv;
2354 u8 index_frontend = 1;
2355
2356 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2357 index_frontend++;
2358 if (index_frontend != 1) {
2359 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
2360 state->fe[index_frontend] = NULL;
2361 return 0;
2362 }
2363
2364 dprintk("no frontend to be removed");
2365 return -ENODEV;
2366}
2367EXPORT_SYMBOL(dib8000_remove_slave_frontend);
2368
2369struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2370{
2371 struct dib8000_state *state = fe->demodulator_priv;
2372
2373 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2374 return NULL;
2375 return state->fe[slave_index];
2376}
2377EXPORT_SYMBOL(dib8000_get_slave_frontend);
2378
2379
2172int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) 2380int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2173{ 2381{
2174 int k = 0; 2382 int k = 0;
@@ -2227,7 +2435,13 @@ static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_fron
2227static void dib8000_release(struct dvb_frontend *fe) 2435static void dib8000_release(struct dvb_frontend *fe)
2228{ 2436{
2229 struct dib8000_state *st = fe->demodulator_priv; 2437 struct dib8000_state *st = fe->demodulator_priv;
2438 u8 index_frontend;
2439
2440 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
2441 dvb_frontend_detach(st->fe[index_frontend]);
2442
2230 dibx000_exit_i2c_master(&st->i2c_master); 2443 dibx000_exit_i2c_master(&st->i2c_master);
2444 kfree(st->fe[0]);
2231 kfree(st); 2445 kfree(st);
2232} 2446}
2233 2447
@@ -2242,19 +2456,19 @@ EXPORT_SYMBOL(dib8000_get_i2c_master);
2242int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) 2456int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2243{ 2457{
2244 struct dib8000_state *st = fe->demodulator_priv; 2458 struct dib8000_state *st = fe->demodulator_priv;
2245 u16 val = dib8000_read_word(st, 299) & 0xffef; 2459 u16 val = dib8000_read_word(st, 299) & 0xffef;
2246 val |= (onoff & 0x1) << 4; 2460 val |= (onoff & 0x1) << 4;
2247 2461
2248 dprintk("pid filter enabled %d", onoff); 2462 dprintk("pid filter enabled %d", onoff);
2249 return dib8000_write_word(st, 299, val); 2463 return dib8000_write_word(st, 299, val);
2250} 2464}
2251EXPORT_SYMBOL(dib8000_pid_filter_ctrl); 2465EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2252 2466
2253int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) 2467int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2254{ 2468{
2255 struct dib8000_state *st = fe->demodulator_priv; 2469 struct dib8000_state *st = fe->demodulator_priv;
2256 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); 2470 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2257 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); 2471 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2258} 2472}
2259EXPORT_SYMBOL(dib8000_pid_filter); 2473EXPORT_SYMBOL(dib8000_pid_filter);
2260 2474
@@ -2298,6 +2512,9 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
2298 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); 2512 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2299 if (state == NULL) 2513 if (state == NULL)
2300 return NULL; 2514 return NULL;
2515 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2516 if (fe == NULL)
2517 goto error;
2301 2518
2302 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); 2519 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2303 state->i2c.adap = i2c_adap; 2520 state->i2c.adap = i2c_adap;
@@ -2311,9 +2528,9 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
2311 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) 2528 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2312 state->cfg.output_mode = OUTMODE_MPEG2_FIFO; 2529 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2313 2530
2314 fe = &state->fe; 2531 state->fe[0] = fe;
2315 fe->demodulator_priv = state; 2532 fe->demodulator_priv = state;
2316 memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops)); 2533 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2317 2534
2318 state->timf_default = cfg->pll->timf; 2535 state->timf_default = cfg->pll->timf;
2319 2536
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
index e0a9ded11df4..617f9eba3a09 100644
--- a/drivers/media/dvb/frontends/dib8000.h
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -50,6 +50,9 @@ extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_st
50extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); 50extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
51extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); 51extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
52extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); 52extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
53extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
54extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
55extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
53#else 56#else
54static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) 57static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
55{ 58{
@@ -111,6 +114,23 @@ static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
111 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 114 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
112 return 0; 115 return 0;
113} 116}
117static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
118{
119 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
120 return -ENODEV;
121}
122
123int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
124{
125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
126 return -ENODEV;
127}
128
129static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
130{
131 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
132 return NULL;
133}
114#endif 134#endif
115 135
116#endif 136#endif
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
new file mode 100644
index 000000000000..91518761a2da
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -0,0 +1,2351 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.
3 *
4 * Copyright (C) 2005-10 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/i2c.h>
12#include <linux/mutex.h>
13
14#include "dvb_math.h"
15#include "dvb_frontend.h"
16
17#include "dib9000.h"
18#include "dibx000_common.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23
24#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB9000: "); printk(args); printk("\n"); } } while (0)
25#define MAX_NUMBER_OF_FRONTENDS 6
26
27struct i2c_device {
28 struct i2c_adapter *i2c_adap;
29 u8 i2c_addr;
30};
31
32/* lock */
33#define DIB_LOCK struct mutex
34#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) dprintk("could not get the lock"); } while (0)
35#define DibReleaseLock(lock) mutex_unlock(lock)
36#define DibInitLock(lock) mutex_init(lock)
37#define DibFreeLock(lock)
38
39struct dib9000_state {
40 struct i2c_device i2c;
41
42 struct dibx000_i2c_master i2c_master;
43 struct i2c_adapter tuner_adap;
44 struct i2c_adapter component_bus;
45
46 u16 revision;
47 u8 reg_offs;
48
49 enum frontend_tune_state tune_state;
50 u32 status;
51 struct dvb_frontend_parametersContext channel_status;
52
53 u8 fe_id;
54
55#define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff
56 u16 gpio_dir;
57#define DIB9000_GPIO_DEFAULT_VALUES 0x0000
58 u16 gpio_val;
59#define DIB9000_GPIO_DEFAULT_PWM_POS 0xffff
60 u16 gpio_pwm_pos;
61
62 union { /* common for all chips */
63 struct {
64 u8 mobile_mode:1;
65 } host;
66
67 struct {
68 struct dib9000_fe_memory_map {
69 u16 addr;
70 u16 size;
71 } fe_mm[18];
72 u8 memcmd;
73
74 DIB_LOCK mbx_if_lock; /* to protect read/write operations */
75 DIB_LOCK mbx_lock; /* to protect the whole mailbox handling */
76
77 DIB_LOCK mem_lock; /* to protect the memory accesses */
78 DIB_LOCK mem_mbx_lock; /* to protect the memory-based mailbox */
79
80#define MBX_MAX_WORDS (256 - 200 - 2)
81#define DIB9000_MSG_CACHE_SIZE 2
82 u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];
83 u8 fw_is_running;
84 } risc;
85 } platform;
86
87 union { /* common for all platforms */
88 struct {
89 struct dib9000_config cfg;
90 } d9;
91 } chip;
92
93 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
94 u16 component_bus_speed;
95};
96
97u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99 0, 0, 0
100};
101
102enum dib9000_power_mode {
103 DIB9000_POWER_ALL = 0,
104
105 DIB9000_POWER_NO,
106 DIB9000_POWER_INTERF_ANALOG_AGC,
107 DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
108 DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,
109 DIB9000_POWER_INTERFACE_ONLY,
110};
111
112enum dib9000_out_messages {
113 OUT_MSG_HBM_ACK,
114 OUT_MSG_HOST_BUF_FAIL,
115 OUT_MSG_REQ_VERSION,
116 OUT_MSG_BRIDGE_I2C_W,
117 OUT_MSG_BRIDGE_I2C_R,
118 OUT_MSG_BRIDGE_APB_W,
119 OUT_MSG_BRIDGE_APB_R,
120 OUT_MSG_SCAN_CHANNEL,
121 OUT_MSG_MONIT_DEMOD,
122 OUT_MSG_CONF_GPIO,
123 OUT_MSG_DEBUG_HELP,
124 OUT_MSG_SUBBAND_SEL,
125 OUT_MSG_ENABLE_TIME_SLICE,
126 OUT_MSG_FE_FW_DL,
127 OUT_MSG_FE_CHANNEL_SEARCH,
128 OUT_MSG_FE_CHANNEL_TUNE,
129 OUT_MSG_FE_SLEEP,
130 OUT_MSG_FE_SYNC,
131 OUT_MSG_CTL_MONIT,
132
133 OUT_MSG_CONF_SVC,
134 OUT_MSG_SET_HBM,
135 OUT_MSG_INIT_DEMOD,
136 OUT_MSG_ENABLE_DIVERSITY,
137 OUT_MSG_SET_OUTPUT_MODE,
138 OUT_MSG_SET_PRIORITARY_CHANNEL,
139 OUT_MSG_ACK_FRG,
140 OUT_MSG_INIT_PMU,
141};
142
143enum dib9000_in_messages {
144 IN_MSG_DATA,
145 IN_MSG_FRAME_INFO,
146 IN_MSG_CTL_MONIT,
147 IN_MSG_ACK_FREE_ITEM,
148 IN_MSG_DEBUG_BUF,
149 IN_MSG_MPE_MONITOR,
150 IN_MSG_RAWTS_MONITOR,
151 IN_MSG_END_BRIDGE_I2C_RW,
152 IN_MSG_END_BRIDGE_APB_RW,
153 IN_MSG_VERSION,
154 IN_MSG_END_OF_SCAN,
155 IN_MSG_MONIT_DEMOD,
156 IN_MSG_ERROR,
157 IN_MSG_FE_FW_DL_DONE,
158 IN_MSG_EVENT,
159 IN_MSG_ACK_CHANGE_SVC,
160 IN_MSG_HBM_PROF,
161};
162
163/* memory_access requests */
164#define FE_MM_W_CHANNEL 0
165#define FE_MM_W_FE_INFO 1
166#define FE_MM_RW_SYNC 2
167
168#define FE_SYNC_CHANNEL 1
169#define FE_SYNC_W_GENERIC_MONIT 2
170#define FE_SYNC_COMPONENT_ACCESS 3
171
172#define FE_MM_R_CHANNEL_SEARCH_STATE 3
173#define FE_MM_R_CHANNEL_UNION_CONTEXT 4
174#define FE_MM_R_FE_INFO 5
175#define FE_MM_R_FE_MONITOR 6
176
177#define FE_MM_W_CHANNEL_HEAD 7
178#define FE_MM_W_CHANNEL_UNION 8
179#define FE_MM_W_CHANNEL_CONTEXT 9
180#define FE_MM_R_CHANNEL_UNION 10
181#define FE_MM_R_CHANNEL_CONTEXT 11
182#define FE_MM_R_CHANNEL_TUNE_STATE 12
183
184#define FE_MM_R_GENERIC_MONITORING_SIZE 13
185#define FE_MM_W_GENERIC_MONITORING 14
186#define FE_MM_R_GENERIC_MONITORING 15
187
188#define FE_MM_W_COMPONENT_ACCESS 16
189#define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17
190static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);
191static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);
192
193static u16 to_fw_output_mode(u16 mode)
194{
195 switch (mode) {
196 case OUTMODE_HIGH_Z:
197 return 0;
198 case OUTMODE_MPEG2_PAR_GATED_CLK:
199 return 4;
200 case OUTMODE_MPEG2_PAR_CONT_CLK:
201 return 8;
202 case OUTMODE_MPEG2_SERIAL:
203 return 16;
204 case OUTMODE_DIVERSITY:
205 return 128;
206 case OUTMODE_MPEG2_FIFO:
207 return 2;
208 case OUTMODE_ANALOG_ADC:
209 return 1;
210 default:
211 return 0;
212 }
213}
214
215static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 len, u16 attribute)
216{
217 u32 chunk_size = 126;
218 u32 l;
219 int ret;
220 u8 wb[2] = { reg >> 8, reg & 0xff };
221 struct i2c_msg msg[2] = {
222 {.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
223 {.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len},
224 };
225
226 if (state->platform.risc.fw_is_running && (reg < 1024))
227 return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
228
229 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
230 wb[0] |= (1 << 5);
231 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
232 wb[0] |= (1 << 4);
233
234 do {
235 l = len < chunk_size ? len : chunk_size;
236 msg[1].len = l;
237 msg[1].buf = b;
238 ret = i2c_transfer(state->i2c.i2c_adap, msg, 2) != 2 ? -EREMOTEIO : 0;
239 if (ret != 0) {
240 dprintk("i2c read error on %d", reg);
241 return -EREMOTEIO;
242 }
243
244 b += l;
245 len -= l;
246
247 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
248 reg += l / 2;
249 } while ((ret == 0) && len);
250
251 return 0;
252}
253
254static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
255{
256 u8 b[2];
257 u8 wb[2] = { reg >> 8, reg & 0xff };
258 struct i2c_msg msg[2] = {
259 {.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
260 {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2},
261 };
262
263 if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
264 dprintk("read register %x error", reg);
265 return 0;
266 }
267
268 return (b[0] << 8) | b[1];
269}
270
271static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
272{
273 u8 b[2];
274 if (dib9000_read16_attr(state, reg, b, 2, 0) != 0)
275 return 0;
276 return (b[0] << 8 | b[1]);
277}
278
279static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
280{
281 u8 b[2];
282 if (dib9000_read16_attr(state, reg, b, 2, attribute) != 0)
283 return 0;
284 return (b[0] << 8 | b[1]);
285}
286
287#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
288
289static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
290{
291 u8 b[255];
292 u32 chunk_size = 126;
293 u32 l;
294 int ret;
295
296 struct i2c_msg msg = {
297 .addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2
298 };
299
300 if (state->platform.risc.fw_is_running && (reg < 1024)) {
301 if (dib9000_risc_apb_access_write
302 (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
303 return -EINVAL;
304 return 0;
305 }
306
307 b[0] = (reg >> 8) & 0xff;
308 b[1] = (reg) & 0xff;
309
310 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
311 b[0] |= (1 << 5);
312 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
313 b[0] |= (1 << 4);
314
315 do {
316 l = len < chunk_size ? len : chunk_size;
317 msg.len = l + 2;
318 memcpy(&b[2], buf, l);
319
320 ret = i2c_transfer(state->i2c.i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
321
322 buf += l;
323 len -= l;
324
325 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
326 reg += l / 2;
327 } while ((ret == 0) && len);
328
329 return ret;
330}
331
332static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
333{
334 u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff };
335 struct i2c_msg msg = {
336 .addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
337 };
338
339 return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
340}
341
342static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)
343{
344 u8 b[2] = { val >> 8, val & 0xff };
345 return dib9000_write16_attr(state, reg, b, 2, 0);
346}
347
348static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)
349{
350 u8 b[2] = { val >> 8, val & 0xff };
351 return dib9000_write16_attr(state, reg, b, 2, attribute);
352}
353
354#define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)
355#define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
356#define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))
357
358#define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)
359#define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)
360
361#define MAC_IRQ (1 << 1)
362#define IRQ_POL_MSK (1 << 4)
363
364#define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
365#define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
366
367static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)
368{
369 u8 b[14] = { 0 };
370
371/* dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */
372/* b[0] = 0 << 7; */
373 b[1] = 1;
374
375/* b[2] = 0; */
376/* b[3] = 0; */
377 b[4] = (u8) (addr >> 8);
378 b[5] = (u8) (addr & 0xff);
379
380/* b[10] = 0; */
381/* b[11] = 0; */
382 b[12] = (u8) (addr >> 8);
383 b[13] = (u8) (addr & 0xff);
384
385 addr += len;
386/* b[6] = 0; */
387/* b[7] = 0; */
388 b[8] = (u8) (addr >> 8);
389 b[9] = (u8) (addr & 0xff);
390
391 dib9000_write(state, 1056, b, 14);
392 if (reading)
393 dib9000_write_word(state, 1056, (1 << 15) | 1);
394 state->platform.risc.memcmd = -1; /* if it was called directly reset it - to force a future setup-call to set it */
395}
396
397static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)
398{
399 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];
400 /* decide whether we need to "refresh" the memory controller */
401 if (state->platform.risc.memcmd == cmd && /* same command */
402 !(cmd & 0x80 && m->size < 67)) /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */
403 return;
404 dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);
405 state->platform.risc.memcmd = cmd;
406}
407
408static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)
409{
410 if (!state->platform.risc.fw_is_running)
411 return -EIO;
412
413 DibAcquireLock(&state->platform.risc.mem_lock);
414 dib9000_risc_mem_setup(state, cmd | 0x80);
415 dib9000_risc_mem_read_chunks(state, b, len);
416 DibReleaseLock(&state->platform.risc.mem_lock);
417 return 0;
418}
419
420static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)
421{
422 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];
423 if (!state->platform.risc.fw_is_running)
424 return -EIO;
425
426 DibAcquireLock(&state->platform.risc.mem_lock);
427 dib9000_risc_mem_setup(state, cmd);
428 dib9000_risc_mem_write_chunks(state, b, m->size);
429 DibReleaseLock(&state->platform.risc.mem_lock);
430 return 0;
431}
432
433static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)
434{
435 u16 offs;
436
437 if (risc_id == 1)
438 offs = 16;
439 else
440 offs = 0;
441
442 /* config crtl reg */
443 dib9000_write_word(state, 1024 + offs, 0x000f);
444 dib9000_write_word(state, 1025 + offs, 0);
445 dib9000_write_word(state, 1031 + offs, key);
446
447 dprintk("going to download %dB of microcode", len);
448 if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {
449 dprintk("error while downloading microcode for RISC %c", 'A' + risc_id);
450 return -EIO;
451 }
452
453 dprintk("Microcode for RISC %c loaded", 'A' + risc_id);
454
455 return 0;
456}
457
458static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)
459{
460 u16 mbox_offs;
461 u16 reset_reg;
462 u16 tries = 1000;
463
464 if (risc_id == 1)
465 mbox_offs = 16;
466 else
467 mbox_offs = 0;
468
469 /* Reset mailbox */
470 dib9000_write_word(state, 1027 + mbox_offs, 0x8000);
471
472 /* Read reset status */
473 do {
474 reset_reg = dib9000_read_word(state, 1027 + mbox_offs);
475 msleep(100);
476 } while ((reset_reg & 0x8000) && --tries);
477
478 if (reset_reg & 0x8000) {
479 dprintk("MBX: init ERROR, no response from RISC %c", 'A' + risc_id);
480 return -EIO;
481 }
482 dprintk("MBX: initialized");
483 return 0;
484}
485
486#define MAX_MAILBOX_TRY 100
487static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)
488{
489 u8 *d, b[2];
490 u16 tmp;
491 u16 size;
492 u32 i;
493 int ret = 0;
494
495 if (!state->platform.risc.fw_is_running)
496 return -EINVAL;
497
498 DibAcquireLock(&state->platform.risc.mbx_if_lock);
499 tmp = MAX_MAILBOX_TRY;
500 do {
501 size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
502 if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {
503 dprintk("MBX: RISC mbx full, retrying");
504 msleep(100);
505 } else
506 break;
507 } while (1);
508
509 /*dprintk( "MBX: size: %d", size); */
510
511 if (tmp == 0) {
512 ret = -EINVAL;
513 goto out;
514 }
515#ifdef DUMP_MSG
516 dprintk("--> %02x %d ", id, len + 1);
517 for (i = 0; i < len; i++)
518 dprintk("%04x ", data[i]);
519 dprintk("\n");
520#endif
521
522 /* byte-order conversion - works on big (where it is not necessary) or little endian */
523 d = (u8 *) data;
524 for (i = 0; i < len; i++) {
525 tmp = data[i];
526 *d++ = tmp >> 8;
527 *d++ = tmp & 0xff;
528 }
529
530 /* write msg */
531 b[0] = id;
532 b[1] = len + 1;
533 if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {
534 ret = -EIO;
535 goto out;
536 }
537
538 /* update register nb_mes_in_RX */
539 ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
540
541out:
542 DibReleaseLock(&state->platform.risc.mbx_if_lock);
543
544 return ret;
545}
546
547static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)
548{
549#ifdef DUMP_MSG
550 u16 *d = data;
551#endif
552
553 u16 tmp, i;
554 u8 size;
555 u8 mc_base;
556
557 if (!state->platform.risc.fw_is_running)
558 return 0;
559
560 DibAcquireLock(&state->platform.risc.mbx_if_lock);
561 if (risc_id == 1)
562 mc_base = 16;
563 else
564 mc_base = 0;
565
566 /* Length and type in the first word */
567 *data = dib9000_read_word_attr(state, 1029 + mc_base, attr);
568
569 size = *data & 0xff;
570 if (size <= MBX_MAX_WORDS) {
571 data++;
572 size--; /* Initial word already read */
573
574 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);
575
576 /* to word conversion */
577 for (i = 0; i < size; i++) {
578 tmp = *data;
579 *data = (tmp >> 8) | (tmp << 8);
580 data++;
581 }
582
583#ifdef DUMP_MSG
584 dprintk("<-- ");
585 for (i = 0; i < size + 1; i++)
586 dprintk("%04x ", d[i]);
587 dprintk("\n");
588#endif
589 } else {
590 dprintk("MBX: message is too big for message cache (%d), flushing message", size);
591 size--; /* Initial word already read */
592 while (size--)
593 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);
594 }
595 /* Update register nb_mes_in_TX */
596 dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
597
598 DibReleaseLock(&state->platform.risc.mbx_if_lock);
599
600 return size + 1;
601}
602
603static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)
604{
605 u32 ts = data[1] << 16 | data[0];
606 char *b = (char *)&data[2];
607
608 b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */
609 if (*b == '~') {
610 b++;
611 dprintk(b);
612 } else
613 dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<emtpy>");
614 return 1;
615}
616
617static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)
618{
619 int i;
620 u8 size;
621 u16 *block;
622 /* find a free slot */
623 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
624 block = state->platform.risc.message_cache[i];
625 if (*block == 0) {
626 size = dib9000_mbx_read(state, block, 1, attr);
627
628/* dprintk( "MBX: fetched %04x message to cache", *block); */
629
630 switch (*block >> 8) {
631 case IN_MSG_DEBUG_BUF:
632 dib9000_risc_debug_buf(state, block + 1, size); /* debug-messages are going to be printed right away */
633 *block = 0; /* free the block */
634 break;
635#if 0
636 case IN_MSG_DATA: /* FE-TRACE */
637 dib9000_risc_data_process(state, block + 1, size);
638 *block = 0;
639 break;
640#endif
641 default:
642 break;
643 }
644
645 return 1;
646 }
647 }
648 dprintk("MBX: no free cache-slot found for new message...");
649 return -1;
650}
651
652static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
653{
654 if (risc_id == 0)
655 return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f; /* 5 bit field */
656 else
657 return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f; /* 7 bit field */
658}
659
660static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
661{
662 int ret = 0;
663 u16 tmp;
664
665 if (!state->platform.risc.fw_is_running)
666 return -1;
667
668 DibAcquireLock(&state->platform.risc.mbx_lock);
669
670 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
671 ret = dib9000_mbx_fetch_to_cache(state, attr);
672
673 tmp = dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */
674/* if (tmp) */
675/* dprintk( "cleared IRQ: %x", tmp); */
676 DibReleaseLock(&state->platform.risc.mbx_lock);
677
678 return ret;
679}
680
681static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)
682{
683 u8 i;
684 u16 *block;
685 u16 timeout = 30;
686
687 *msg = 0;
688 do {
689 /* dib9000_mbx_get_from_cache(); */
690 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
691 block = state->platform.risc.message_cache[i];
692 if ((*block >> 8) == id) {
693 *size = (*block & 0xff) - 1;
694 memcpy(msg, block + 1, (*size) * 2);
695 *block = 0; /* free the block */
696 i = 0; /* signal that we found a message */
697 break;
698 }
699 }
700
701 if (i == 0)
702 break;
703
704 if (dib9000_mbx_process(state, attr) == -1) /* try to fetch one message - if any */
705 return -1;
706
707 } while (--timeout);
708
709 if (timeout == 0) {
710 dprintk("waiting for message %d timed out", id);
711 return -1;
712 }
713
714 return i == 0;
715}
716
717static int dib9000_risc_check_version(struct dib9000_state *state)
718{
719 u8 r[4];
720 u8 size;
721 u16 fw_version = 0;
722
723 if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)
724 return -EIO;
725
726 if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)
727 return -EIO;
728
729 fw_version = (r[0] << 8) | r[1];
730 dprintk("RISC: ver: %d.%02d (IC: %d)", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);
731
732 if ((fw_version >> 10) != 7)
733 return -EINVAL;
734
735 switch (fw_version & 0x3ff) {
736 case 11:
737 case 12:
738 case 14:
739 case 15:
740 case 16:
741 case 17:
742 break;
743 default:
744 dprintk("RISC: invalid firmware version");
745 return -EINVAL;
746 }
747
748 dprintk("RISC: valid firmware version");
749 return 0;
750}
751
752static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)
753{
754 /* Reconfig pool mac ram */
755 dib9000_write_word(state, 1225, 0x02); /* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */
756 dib9000_write_word(state, 1226, 0x05);
757
758 /* Toggles IP crypto to Host APB interface. */
759 dib9000_write_word(state, 1542, 1);
760
761 /* Set jump and no jump in the dma box */
762 dib9000_write_word(state, 1074, 0);
763 dib9000_write_word(state, 1075, 0);
764
765 /* Set MAC as APB Master. */
766 dib9000_write_word(state, 1237, 0);
767
768 /* Reset the RISCs */
769 if (codeA != NULL)
770 dib9000_write_word(state, 1024, 2);
771 else
772 dib9000_write_word(state, 1024, 15);
773 if (codeB != NULL)
774 dib9000_write_word(state, 1040, 2);
775
776 if (codeA != NULL)
777 dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);
778 if (codeB != NULL)
779 dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);
780
781 /* Run the RISCs */
782 if (codeA != NULL)
783 dib9000_write_word(state, 1024, 0);
784 if (codeB != NULL)
785 dib9000_write_word(state, 1040, 0);
786
787 if (codeA != NULL)
788 if (dib9000_mbx_host_init(state, 0) != 0)
789 return -EIO;
790 if (codeB != NULL)
791 if (dib9000_mbx_host_init(state, 1) != 0)
792 return -EIO;
793
794 msleep(100);
795 state->platform.risc.fw_is_running = 1;
796
797 if (dib9000_risc_check_version(state) != 0)
798 return -EINVAL;
799
800 state->platform.risc.memcmd = 0xff;
801 return 0;
802}
803
804static u16 dib9000_identify(struct i2c_device *client)
805{
806 u16 value;
807
808 value = dib9000_i2c_read16(client, 896);
809 if (value != 0x01b3) {
810 dprintk("wrong Vendor ID (0x%x)", value);
811 return 0;
812 }
813
814 value = dib9000_i2c_read16(client, 897);
815 if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {
816 dprintk("wrong Device ID (0x%x)", value);
817 return 0;
818 }
819
820 /* protect this driver to be used with 7000PC */
821 if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {
822 dprintk("this driver does not work with DiB7000PC");
823 return 0;
824 }
825
826 switch (value) {
827 case 0x4000:
828 dprintk("found DiB7000MA/PA/MB/PB");
829 break;
830 case 0x4001:
831 dprintk("found DiB7000HC");
832 break;
833 case 0x4002:
834 dprintk("found DiB7000MC");
835 break;
836 case 0x4003:
837 dprintk("found DiB9000A");
838 break;
839 case 0x4004:
840 dprintk("found DiB9000H");
841 break;
842 case 0x4005:
843 dprintk("found DiB9000M");
844 break;
845 }
846
847 return value;
848}
849
850static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)
851{
852 /* by default everything is going to be powered off */
853 u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;
854 u8 offset;
855
856 if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)
857 offset = 1;
858 else
859 offset = 0;
860
861 reg_906 = dib9000_read_word(state, 906 + offset) | 0x3; /* keep settings for RISC */
862
863 /* now, depending on the requested mode, we power on */
864 switch (mode) {
865 /* power up everything in the demod */
866 case DIB9000_POWER_ALL:
867 reg_903 = 0x0000;
868 reg_904 = 0x0000;
869 reg_905 = 0x0000;
870 reg_906 = 0x0000;
871 break;
872
873 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
874 case DIB9000_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
875 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
876 break;
877
878 case DIB9000_POWER_INTERF_ANALOG_AGC:
879 reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
880 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
881 reg_906 &= ~((1 << 0));
882 break;
883
884 case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
885 reg_903 = 0x0000;
886 reg_904 = 0x801f;
887 reg_905 = 0x0000;
888 reg_906 &= ~((1 << 0));
889 break;
890
891 case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:
892 reg_903 = 0x0000;
893 reg_904 = 0x8000;
894 reg_905 = 0x010b;
895 reg_906 &= ~((1 << 0));
896 break;
897 default:
898 case DIB9000_POWER_NO:
899 break;
900 }
901
902 /* always power down unused parts */
903 if (!state->platform.host.mobile_mode)
904 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
905
906 /* P_sdio_select_clk = 0 on MC and after */
907 if (state->revision != 0x4000)
908 reg_906 <<= 1;
909
910 dib9000_write_word(state, 903 + offset, reg_903);
911 dib9000_write_word(state, 904 + offset, reg_904);
912 dib9000_write_word(state, 905 + offset, reg_905);
913 dib9000_write_word(state, 906 + offset, reg_906);
914}
915
916static int dib9000_fw_reset(struct dvb_frontend *fe)
917{
918 struct dib9000_state *state = fe->demodulator_priv;
919
920 dib9000_write_word(state, 1817, 0x0003);
921
922 dib9000_write_word(state, 1227, 1);
923 dib9000_write_word(state, 1227, 0);
924
925 switch ((state->revision = dib9000_identify(&state->i2c))) {
926 case 0x4003:
927 case 0x4004:
928 case 0x4005:
929 state->reg_offs = 1;
930 break;
931 default:
932 return -EINVAL;
933 }
934
935 /* reset the i2c-master to use the host interface */
936 dibx000_reset_i2c_master(&state->i2c_master);
937
938 dib9000_set_power_mode(state, DIB9000_POWER_ALL);
939
940 /* unforce divstr regardless whether i2c enumeration was done or not */
941 dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));
942 dib9000_write_word(state, 1796, 0);
943 dib9000_write_word(state, 1805, 0x805);
944
945 /* restart all parts */
946 dib9000_write_word(state, 898, 0xffff);
947 dib9000_write_word(state, 899, 0xffff);
948 dib9000_write_word(state, 900, 0x0001);
949 dib9000_write_word(state, 901, 0xff19);
950 dib9000_write_word(state, 902, 0x003c);
951
952 dib9000_write_word(state, 898, 0);
953 dib9000_write_word(state, 899, 0);
954 dib9000_write_word(state, 900, 0);
955 dib9000_write_word(state, 901, 0);
956 dib9000_write_word(state, 902, 0);
957
958 dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);
959
960 dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);
961
962 return 0;
963}
964
965static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)
966{
967 u16 mb[10];
968 u8 i, s;
969
970 if (address >= 1024 || !state->platform.risc.fw_is_running)
971 return -EINVAL;
972
973 /* dprintk( "APB access thru rd fw %d %x", address, attribute); */
974
975 mb[0] = (u16) address;
976 mb[1] = len / 2;
977 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);
978 switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {
979 case 1:
980 s--;
981 for (i = 0; i < s; i++) {
982 b[i * 2] = (mb[i + 1] >> 8) & 0xff;
983 b[i * 2 + 1] = (mb[i + 1]) & 0xff;
984 }
985 return 0;
986 default:
987 return -EIO;
988 }
989 return -EIO;
990}
991
992static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)
993{
994 u16 mb[10];
995 u8 s, i;
996
997 if (address >= 1024 || !state->platform.risc.fw_is_running)
998 return -EINVAL;
999
1000 /* dprintk( "APB access thru wr fw %d %x", address, attribute); */
1001
1002 mb[0] = (unsigned short)address;
1003 for (i = 0; i < len && i < 20; i += 2)
1004 mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]);
1005
1006 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute);
1007 return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
1008}
1009
1010static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
1011{
1012 u8 index_loop = 10;
1013
1014 if (!state->platform.risc.fw_is_running)
1015 return 0;
1016 dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
1017 do {
1018 dib9000_risc_mem_read(state, FE_MM_RW_SYNC, &i, 1);
1019 } while (i && index_loop--);
1020
1021 if (index_loop > 0)
1022 return 0;
1023 return -EIO;
1024}
1025
1026static int dib9000_fw_init(struct dib9000_state *state)
1027{
1028 struct dibGPIOFunction *f;
1029 u16 b[40] = { 0 };
1030 u8 i;
1031 u8 size;
1032
1033 if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)
1034 return -EIO;
1035
1036 /* initialize the firmware */
1037 for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {
1038 f = &state->chip.d9.cfg.gpio_function[i];
1039 if (f->mask) {
1040 switch (f->function) {
1041 case BOARD_GPIO_FUNCTION_COMPONENT_ON:
1042 b[0] = (u16) f->mask;
1043 b[1] = (u16) f->direction;
1044 b[2] = (u16) f->value;
1045 break;
1046 case BOARD_GPIO_FUNCTION_COMPONENT_OFF:
1047 b[3] = (u16) f->mask;
1048 b[4] = (u16) f->direction;
1049 b[5] = (u16) f->value;
1050 break;
1051 }
1052 }
1053 }
1054 if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)
1055 return -EIO;
1056
1057 /* subband */
1058 b[0] = state->chip.d9.cfg.subband.size; /* type == 0 -> GPIO - PWM not yet supported */
1059 for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {
1060 b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;
1061 b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;
1062 b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;
1063 b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;
1064 }
1065 b[1 + i * 4] = 0; /* fe_id */
1066 if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)
1067 return -EIO;
1068
1069 /* 0 - id, 1 - no_of_frontends */
1070 b[0] = (0 << 8) | 1;
1071 /* 0 = i2c-address demod, 0 = tuner */
1072 b[1] = (0 << 8) | (0);
1073 b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);
1074 b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);
1075 b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);
1076 b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);
1077 b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);
1078 b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);
1079 b[29] = state->chip.d9.cfg.if_drives;
1080 if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)
1081 return -EIO;
1082
1083 if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)
1084 return -EIO;
1085
1086 if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)
1087 return -EIO;
1088
1089 if (size > ARRAY_SIZE(b)) {
1090 dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,
1091 (int)ARRAY_SIZE(b));
1092 return -EINVAL;
1093 }
1094
1095 for (i = 0; i < size; i += 2) {
1096 state->platform.risc.fe_mm[i / 2].addr = b[i + 0];
1097 state->platform.risc.fe_mm[i / 2].size = b[i + 1];
1098 }
1099
1100 return 0;
1101}
1102
1103static void dib9000_fw_set_channel_head(struct dib9000_state *state, struct dvb_frontend_parameters *ch)
1104{
1105 u8 b[9];
1106 u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;
1107 if (state->fe_id % 2)
1108 freq += 101;
1109
1110 b[0] = (u8) ((freq >> 0) & 0xff);
1111 b[1] = (u8) ((freq >> 8) & 0xff);
1112 b[2] = (u8) ((freq >> 16) & 0xff);
1113 b[3] = (u8) ((freq >> 24) & 0xff);
1114 b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);
1115 b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);
1116 b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);
1117 b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);
1118 b[8] = 0x80; /* do not wait for CELL ID when doing autosearch */
1119 if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)
1120 b[8] |= 1;
1121 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);
1122}
1123
1124static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel)
1125{
1126 struct dib9000_state *state = fe->demodulator_priv;
1127 struct dibDVBTChannel {
1128 s8 spectrum_inversion;
1129
1130 s8 nfft;
1131 s8 guard;
1132 s8 constellation;
1133
1134 s8 hrch;
1135 s8 alpha;
1136 s8 code_rate_hp;
1137 s8 code_rate_lp;
1138 s8 select_hp;
1139
1140 s8 intlv_native;
1141 };
1142 struct dibDVBTChannel ch;
1143 int ret = 0;
1144
1145 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
1146 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1147 goto error;
1148 ret = -EIO;
1149 }
1150
1151 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel));
1152
1153 switch (ch.spectrum_inversion & 0x7) {
1154 case 1:
1155 state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
1156 break;
1157 case 0:
1158 state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;
1159 break;
1160 default:
1161 case -1:
1162 state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
1163 break;
1164 }
1165 switch (ch.nfft) {
1166 case 0:
1167 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1168 break;
1169 case 2:
1170 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
1171 break;
1172 case 1:
1173 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1174 break;
1175 default:
1176 case -1:
1177 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
1178 break;
1179 }
1180 switch (ch.guard) {
1181 case 0:
1182 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1183 break;
1184 case 1:
1185 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1186 break;
1187 case 2:
1188 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1189 break;
1190 case 3:
1191 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1192 break;
1193 default:
1194 case -1:
1195 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
1196 break;
1197 }
1198 switch (ch.constellation) {
1199 case 2:
1200 state->fe[0]->dtv_property_cache.modulation = QAM_64;
1201 break;
1202 case 1:
1203 state->fe[0]->dtv_property_cache.modulation = QAM_16;
1204 break;
1205 case 0:
1206 state->fe[0]->dtv_property_cache.modulation = QPSK;
1207 break;
1208 default:
1209 case -1:
1210 state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
1211 break;
1212 }
1213 switch (ch.hrch) {
1214 case 0:
1215 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
1216 break;
1217 case 1:
1218 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;
1219 break;
1220 default:
1221 case -1:
1222 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
1223 break;
1224 }
1225 switch (ch.code_rate_hp) {
1226 case 1:
1227 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
1228 break;
1229 case 2:
1230 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;
1231 break;
1232 case 3:
1233 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;
1234 break;
1235 case 5:
1236 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;
1237 break;
1238 case 7:
1239 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;
1240 break;
1241 default:
1242 case -1:
1243 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
1244 break;
1245 }
1246 switch (ch.code_rate_lp) {
1247 case 1:
1248 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
1249 break;
1250 case 2:
1251 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;
1252 break;
1253 case 3:
1254 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;
1255 break;
1256 case 5:
1257 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;
1258 break;
1259 case 7:
1260 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;
1261 break;
1262 default:
1263 case -1:
1264 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;
1265 break;
1266 }
1267
1268error:
1269 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1270 return ret;
1271}
1272
1273static int dib9000_fw_set_channel_union(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel)
1274{
1275 struct dib9000_state *state = fe->demodulator_priv;
1276 struct dibDVBTChannel {
1277 s8 spectrum_inversion;
1278
1279 s8 nfft;
1280 s8 guard;
1281 s8 constellation;
1282
1283 s8 hrch;
1284 s8 alpha;
1285 s8 code_rate_hp;
1286 s8 code_rate_lp;
1287 s8 select_hp;
1288
1289 s8 intlv_native;
1290 };
1291 struct dibDVBTChannel ch;
1292
1293 switch (state->fe[0]->dtv_property_cache.inversion) {
1294 case INVERSION_ON:
1295 ch.spectrum_inversion = 1;
1296 break;
1297 case INVERSION_OFF:
1298 ch.spectrum_inversion = 0;
1299 break;
1300 default:
1301 case INVERSION_AUTO:
1302 ch.spectrum_inversion = -1;
1303 break;
1304 }
1305 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1306 case TRANSMISSION_MODE_2K:
1307 ch.nfft = 0;
1308 break;
1309 case TRANSMISSION_MODE_4K:
1310 ch.nfft = 2;
1311 break;
1312 case TRANSMISSION_MODE_8K:
1313 ch.nfft = 1;
1314 break;
1315 default:
1316 case TRANSMISSION_MODE_AUTO:
1317 ch.nfft = 1;
1318 break;
1319 }
1320 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1321 case GUARD_INTERVAL_1_32:
1322 ch.guard = 0;
1323 break;
1324 case GUARD_INTERVAL_1_16:
1325 ch.guard = 1;
1326 break;
1327 case GUARD_INTERVAL_1_8:
1328 ch.guard = 2;
1329 break;
1330 case GUARD_INTERVAL_1_4:
1331 ch.guard = 3;
1332 break;
1333 default:
1334 case GUARD_INTERVAL_AUTO:
1335 ch.guard = -1;
1336 break;
1337 }
1338 switch (state->fe[0]->dtv_property_cache.modulation) {
1339 case QAM_64:
1340 ch.constellation = 2;
1341 break;
1342 case QAM_16:
1343 ch.constellation = 1;
1344 break;
1345 case QPSK:
1346 ch.constellation = 0;
1347 break;
1348 default:
1349 case QAM_AUTO:
1350 ch.constellation = -1;
1351 break;
1352 }
1353 switch (state->fe[0]->dtv_property_cache.hierarchy) {
1354 case HIERARCHY_NONE:
1355 ch.hrch = 0;
1356 break;
1357 case HIERARCHY_1:
1358 case HIERARCHY_2:
1359 case HIERARCHY_4:
1360 ch.hrch = 1;
1361 break;
1362 default:
1363 case HIERARCHY_AUTO:
1364 ch.hrch = -1;
1365 break;
1366 }
1367 ch.alpha = 1;
1368 switch (state->fe[0]->dtv_property_cache.code_rate_HP) {
1369 case FEC_1_2:
1370 ch.code_rate_hp = 1;
1371 break;
1372 case FEC_2_3:
1373 ch.code_rate_hp = 2;
1374 break;
1375 case FEC_3_4:
1376 ch.code_rate_hp = 3;
1377 break;
1378 case FEC_5_6:
1379 ch.code_rate_hp = 5;
1380 break;
1381 case FEC_7_8:
1382 ch.code_rate_hp = 7;
1383 break;
1384 default:
1385 case FEC_AUTO:
1386 ch.code_rate_hp = -1;
1387 break;
1388 }
1389 switch (state->fe[0]->dtv_property_cache.code_rate_LP) {
1390 case FEC_1_2:
1391 ch.code_rate_lp = 1;
1392 break;
1393 case FEC_2_3:
1394 ch.code_rate_lp = 2;
1395 break;
1396 case FEC_3_4:
1397 ch.code_rate_lp = 3;
1398 break;
1399 case FEC_5_6:
1400 ch.code_rate_lp = 5;
1401 break;
1402 case FEC_7_8:
1403 ch.code_rate_lp = 7;
1404 break;
1405 default:
1406 case FEC_AUTO:
1407 ch.code_rate_lp = -1;
1408 break;
1409 }
1410 ch.select_hp = 1;
1411 ch.intlv_native = 1;
1412
1413 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);
1414
1415 return 0;
1416}
1417
1418static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
1419{
1420 struct dib9000_state *state = fe->demodulator_priv;
1421 int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;
1422 s8 i;
1423
1424 switch (state->tune_state) {
1425 case CT_DEMOD_START:
1426 dib9000_fw_set_channel_head(state, ch);
1427
1428 /* write the channel context - a channel is initialized to 0, so it is OK */
1429 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);
1430 dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);
1431
1432 if (search)
1433 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);
1434 else {
1435 dib9000_fw_set_channel_union(fe, ch);
1436 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);
1437 }
1438 state->tune_state = CT_DEMOD_STEP_1;
1439 break;
1440 case CT_DEMOD_STEP_1:
1441 if (search)
1442 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1);
1443 else
1444 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1);
1445 switch (i) { /* something happened */
1446 case 0:
1447 break;
1448 case -2: /* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */
1449 if (search)
1450 state->status = FE_STATUS_DEMOD_SUCCESS;
1451 else {
1452 state->tune_state = CT_DEMOD_STOP;
1453 state->status = FE_STATUS_LOCKED;
1454 }
1455 break;
1456 default:
1457 state->status = FE_STATUS_TUNE_FAILED;
1458 state->tune_state = CT_DEMOD_STOP;
1459 break;
1460 }
1461 break;
1462 default:
1463 ret = FE_CALLBACK_TIME_NEVER;
1464 break;
1465 }
1466
1467 return ret;
1468}
1469
1470static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)
1471{
1472 struct dib9000_state *state = fe->demodulator_priv;
1473 u16 mode = (u16) onoff;
1474 return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);
1475}
1476
1477static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)
1478{
1479 struct dib9000_state *state = fe->demodulator_priv;
1480 u16 outreg, smo_mode;
1481
1482 dprintk("setting output mode for demod %p to %d", fe, mode);
1483
1484 switch (mode) {
1485 case OUTMODE_MPEG2_PAR_GATED_CLK:
1486 outreg = (1 << 10); /* 0x0400 */
1487 break;
1488 case OUTMODE_MPEG2_PAR_CONT_CLK:
1489 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
1490 break;
1491 case OUTMODE_MPEG2_SERIAL:
1492 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
1493 break;
1494 case OUTMODE_DIVERSITY:
1495 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
1496 break;
1497 case OUTMODE_MPEG2_FIFO:
1498 outreg = (1 << 10) | (5 << 6);
1499 break;
1500 case OUTMODE_HIGH_Z:
1501 outreg = 0;
1502 break;
1503 default:
1504 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]);
1505 return -EINVAL;
1506 }
1507
1508 dib9000_write_word(state, 1795, outreg);
1509
1510 switch (mode) {
1511 case OUTMODE_MPEG2_PAR_GATED_CLK:
1512 case OUTMODE_MPEG2_PAR_CONT_CLK:
1513 case OUTMODE_MPEG2_SERIAL:
1514 case OUTMODE_MPEG2_FIFO:
1515 smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);
1516 if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)
1517 smo_mode |= (1 << 5);
1518 dib9000_write_word(state, 295, smo_mode);
1519 break;
1520 }
1521
1522 outreg = to_fw_output_mode(mode);
1523 return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);
1524}
1525
1526static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1527{
1528 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
1529 u16 i, len, t, index_msg;
1530
1531 for (index_msg = 0; index_msg < num; index_msg++) {
1532 if (msg[index_msg].flags & I2C_M_RD) { /* read */
1533 len = msg[index_msg].len;
1534 if (len > 16)
1535 len = 16;
1536
1537 if (dib9000_read_word(state, 790) != 0)
1538 dprintk("TunerITF: read busy");
1539
1540 dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));
1541 dib9000_write_word(state, 787, (len / 2) - 1);
1542 dib9000_write_word(state, 786, 1); /* start read */
1543
1544 i = 1000;
1545 while (dib9000_read_word(state, 790) != (len / 2) && i)
1546 i--;
1547
1548 if (i == 0)
1549 dprintk("TunerITF: read failed");
1550
1551 for (i = 0; i < len; i += 2) {
1552 t = dib9000_read_word(state, 785);
1553 msg[index_msg].buf[i] = (t >> 8) & 0xff;
1554 msg[index_msg].buf[i + 1] = (t) & 0xff;
1555 }
1556 if (dib9000_read_word(state, 790) != 0)
1557 dprintk("TunerITF: read more data than expected");
1558 } else {
1559 i = 1000;
1560 while (dib9000_read_word(state, 789) && i)
1561 i--;
1562 if (i == 0)
1563 dprintk("TunerITF: write busy");
1564
1565 len = msg[index_msg].len;
1566 if (len > 16)
1567 len = 16;
1568
1569 for (i = 0; i < len; i += 2)
1570 dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);
1571 dib9000_write_word(state, 784, (u16) msg[index_msg].addr);
1572 dib9000_write_word(state, 787, (len / 2) - 1);
1573 dib9000_write_word(state, 786, 0); /* start write */
1574
1575 i = 1000;
1576 while (dib9000_read_word(state, 791) > 0 && i)
1577 i--;
1578 if (i == 0)
1579 dprintk("TunerITF: write failed");
1580 }
1581 }
1582 return num;
1583}
1584
1585int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
1586{
1587 struct dib9000_state *state = fe->demodulator_priv;
1588
1589 state->component_bus_speed = speed;
1590 return 0;
1591}
1592EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);
1593
1594static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1595{
1596 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
1597 u8 type = 0; /* I2C */
1598 u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;
1599 u16 scl = state->component_bus_speed; /* SCL frequency */
1600 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];
1601 u8 p[13] = { 0 };
1602
1603 p[0] = type;
1604 p[1] = port;
1605 p[2] = msg[0].addr << 1;
1606
1607 p[3] = (u8) scl & 0xff; /* scl */
1608 p[4] = (u8) (scl >> 8);
1609
1610 p[7] = 0;
1611 p[8] = 0;
1612
1613 p[9] = (u8) (msg[0].len);
1614 p[10] = (u8) (msg[0].len >> 8);
1615 if ((num > 1) && (msg[1].flags & I2C_M_RD)) {
1616 p[11] = (u8) (msg[1].len);
1617 p[12] = (u8) (msg[1].len >> 8);
1618 } else {
1619 p[11] = 0;
1620 p[12] = 0;
1621 }
1622
1623 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
1624
1625 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
1626
1627 { /* write-part */
1628 dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);
1629 dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);
1630 }
1631
1632 /* do the transaction */
1633 if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
1634 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1635 return 0;
1636 }
1637
1638 /* read back any possible result */
1639 if ((num > 1) && (msg[1].flags & I2C_M_RD))
1640 dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
1641
1642 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1643
1644 return num;
1645}
1646
1647static u32 dib9000_i2c_func(struct i2c_adapter *adapter)
1648{
1649 return I2C_FUNC_I2C;
1650}
1651
1652static struct i2c_algorithm dib9000_tuner_algo = {
1653 .master_xfer = dib9000_tuner_xfer,
1654 .functionality = dib9000_i2c_func,
1655};
1656
1657static struct i2c_algorithm dib9000_component_bus_algo = {
1658 .master_xfer = dib9000_fw_component_bus_xfer,
1659 .functionality = dib9000_i2c_func,
1660};
1661
1662struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
1663{
1664 struct dib9000_state *st = fe->demodulator_priv;
1665 return &st->tuner_adap;
1666}
1667EXPORT_SYMBOL(dib9000_get_tuner_interface);
1668
1669struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
1670{
1671 struct dib9000_state *st = fe->demodulator_priv;
1672 return &st->component_bus;
1673}
1674EXPORT_SYMBOL(dib9000_get_component_bus_interface);
1675
1676struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
1677{
1678 struct dib9000_state *st = fe->demodulator_priv;
1679 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1680}
1681EXPORT_SYMBOL(dib9000_get_i2c_master);
1682
1683int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
1684{
1685 struct dib9000_state *st = fe->demodulator_priv;
1686
1687 st->i2c.i2c_adap = i2c;
1688 return 0;
1689}
1690EXPORT_SYMBOL(dib9000_set_i2c_adapter);
1691
1692static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)
1693{
1694 st->gpio_dir = dib9000_read_word(st, 773);
1695 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
1696 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
1697 dib9000_write_word(st, 773, st->gpio_dir);
1698
1699 st->gpio_val = dib9000_read_word(st, 774);
1700 st->gpio_val &= ~(1 << num); /* reset the direction bit */
1701 st->gpio_val |= (val & 0x01) << num; /* set the new value */
1702 dib9000_write_word(st, 774, st->gpio_val);
1703
1704 dprintk("gpio dir: %04x: gpio val: %04x", st->gpio_dir, st->gpio_val);
1705
1706 return 0;
1707}
1708
1709int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
1710{
1711 struct dib9000_state *state = fe->demodulator_priv;
1712 return dib9000_cfg_gpio(state, num, dir, val);
1713}
1714EXPORT_SYMBOL(dib9000_set_gpio);
1715
1716int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1717{
1718 struct dib9000_state *state = fe->demodulator_priv;
1719 u16 val = dib9000_read_word(state, 294 + 1) & 0xffef;
1720 val |= (onoff & 0x1) << 4;
1721
1722 dprintk("PID filter enabled %d", onoff);
1723 return dib9000_write_word(state, 294 + 1, val);
1724}
1725EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
1726
1727int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1728{
1729 struct dib9000_state *state = fe->demodulator_priv;
1730 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
1731 return dib9000_write_word(state, 300 + 1 + id, onoff ? (1 << 13) | pid : 0);
1732}
1733EXPORT_SYMBOL(dib9000_fw_pid_filter);
1734
1735int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
1736{
1737 struct dib9000_state *state = fe->demodulator_priv;
1738 return dib9000_fw_init(state);
1739}
1740EXPORT_SYMBOL(dib9000_firmware_post_pll_init);
1741
1742static void dib9000_release(struct dvb_frontend *demod)
1743{
1744 struct dib9000_state *st = demod->demodulator_priv;
1745 u8 index_frontend;
1746
1747 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
1748 dvb_frontend_detach(st->fe[index_frontend]);
1749
1750 DibFreeLock(&state->platform.risc.mbx_if_lock);
1751 DibFreeLock(&state->platform.risc.mbx_lock);
1752 DibFreeLock(&state->platform.risc.mem_lock);
1753 DibFreeLock(&state->platform.risc.mem_mbx_lock);
1754 dibx000_exit_i2c_master(&st->i2c_master);
1755
1756 i2c_del_adapter(&st->tuner_adap);
1757 i2c_del_adapter(&st->component_bus);
1758 kfree(st->fe[0]);
1759 kfree(st);
1760}
1761
1762static int dib9000_wakeup(struct dvb_frontend *fe)
1763{
1764 return 0;
1765}
1766
1767static int dib9000_sleep(struct dvb_frontend *fe)
1768{
1769 struct dib9000_state *state = fe->demodulator_priv;
1770 u8 index_frontend;
1771 int ret;
1772
1773 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1774 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1775 if (ret < 0)
1776 return ret;
1777 }
1778 return dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
1779}
1780
1781static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1782{
1783 tune->min_delay_ms = 1000;
1784 return 0;
1785}
1786
1787static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1788{
1789 struct dib9000_state *state = fe->demodulator_priv;
1790 u8 index_frontend, sub_index_frontend;
1791 fe_status_t stat;
1792 int ret;
1793
1794 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1795 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1796 if (stat & FE_HAS_SYNC) {
1797 dprintk("TPS lock on the slave%i", index_frontend);
1798
1799 /* synchronize the cache with the other frontends */
1800 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
1801 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);
1802 sub_index_frontend++) {
1803 if (sub_index_frontend != index_frontend) {
1804 state->fe[sub_index_frontend]->dtv_property_cache.modulation =
1805 state->fe[index_frontend]->dtv_property_cache.modulation;
1806 state->fe[sub_index_frontend]->dtv_property_cache.inversion =
1807 state->fe[index_frontend]->dtv_property_cache.inversion;
1808 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =
1809 state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1810 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =
1811 state->fe[index_frontend]->dtv_property_cache.guard_interval;
1812 state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =
1813 state->fe[index_frontend]->dtv_property_cache.hierarchy;
1814 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =
1815 state->fe[index_frontend]->dtv_property_cache.code_rate_HP;
1816 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =
1817 state->fe[index_frontend]->dtv_property_cache.code_rate_LP;
1818 state->fe[sub_index_frontend]->dtv_property_cache.rolloff =
1819 state->fe[index_frontend]->dtv_property_cache.rolloff;
1820 }
1821 }
1822 return 0;
1823 }
1824 }
1825
1826 /* get the channel from master chip */
1827 ret = dib9000_fw_get_channel(fe, fep);
1828 if (ret != 0)
1829 return ret;
1830
1831 /* synchronize the cache with the other frontends */
1832 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1833 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
1834 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
1835 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
1836 state->fe[index_frontend]->dtv_property_cache.modulation = fe->dtv_property_cache.modulation;
1837 state->fe[index_frontend]->dtv_property_cache.hierarchy = fe->dtv_property_cache.hierarchy;
1838 state->fe[index_frontend]->dtv_property_cache.code_rate_HP = fe->dtv_property_cache.code_rate_HP;
1839 state->fe[index_frontend]->dtv_property_cache.code_rate_LP = fe->dtv_property_cache.code_rate_LP;
1840 state->fe[index_frontend]->dtv_property_cache.rolloff = fe->dtv_property_cache.rolloff;
1841 }
1842
1843 return 0;
1844}
1845
1846static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1847{
1848 struct dib9000_state *state = fe->demodulator_priv;
1849 state->tune_state = tune_state;
1850 if (tune_state == CT_DEMOD_START)
1851 state->status = FE_STATUS_TUNE_PENDING;
1852
1853 return 0;
1854}
1855
1856static u32 dib9000_get_status(struct dvb_frontend *fe)
1857{
1858 struct dib9000_state *state = fe->demodulator_priv;
1859 return state->status;
1860}
1861
1862static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)
1863{
1864 struct dib9000_state *state = fe->demodulator_priv;
1865
1866 memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));
1867 return 0;
1868}
1869
1870static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1871{
1872 struct dib9000_state *state = fe->demodulator_priv;
1873 int sleep_time, sleep_time_slave;
1874 u32 frontend_status;
1875 u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;
1876 struct dvb_frontend_parametersContext channel_status;
1877
1878 /* check that the correct parameters are set */
1879 if (state->fe[0]->dtv_property_cache.frequency == 0) {
1880 dprintk("dib9000: must specify frequency ");
1881 return 0;
1882 }
1883
1884 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
1885 dprintk("dib9000: must specify bandwidth ");
1886 return 0;
1887 }
1888 fe->dtv_property_cache.delivery_system = SYS_DVBT;
1889
1890 /* set the master status */
1891 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1892 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1893 /* no channel specified, autosearch the channel */
1894 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;
1895 } else
1896 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
1897
1898 /* set mode and status for the different frontends */
1899 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1900 dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);
1901
1902 /* synchronization of the cache */
1903 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
1904
1905 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;
1906 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
1907
1908 dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);
1909 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
1910 }
1911
1912 /* actual tune */
1913 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
1914 index_frontend_success = 0;
1915 do {
1916 sleep_time = dib9000_fw_tune(state->fe[0], NULL);
1917 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1918 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL);
1919 if (sleep_time == FE_CALLBACK_TIME_NEVER)
1920 sleep_time = sleep_time_slave;
1921 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
1922 sleep_time = sleep_time_slave;
1923 }
1924 if (sleep_time != FE_CALLBACK_TIME_NEVER)
1925 msleep(sleep_time / 10);
1926 else
1927 break;
1928
1929 nbr_pending = 0;
1930 exit_condition = 0;
1931 index_frontend_success = 0;
1932 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1933 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
1934 if (frontend_status > -FE_STATUS_TUNE_PENDING) {
1935 exit_condition = 2; /* tune success */
1936 index_frontend_success = index_frontend;
1937 break;
1938 }
1939 if (frontend_status == -FE_STATUS_TUNE_PENDING)
1940 nbr_pending++; /* some frontends are still tuning */
1941 }
1942 if ((exit_condition != 2) && (nbr_pending == 0))
1943 exit_condition = 1; /* if all tune are done and no success, exit: tune failed */
1944
1945 } while (exit_condition == 0);
1946
1947 /* check the tune result */
1948 if (exit_condition == 1) { /* tune failed */
1949 dprintk("tune failed");
1950 return 0;
1951 }
1952
1953 dprintk("tune success on frontend%i", index_frontend_success);
1954
1955 /* synchronize all the channel cache */
1956 dib9000_get_frontend(state->fe[0], fep);
1957
1958 /* retune the other frontends with the found channel */
1959 channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
1960 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1961 /* only retune the frontends which was not tuned success */
1962 if (index_frontend != index_frontend_success) {
1963 dib9000_set_channel_status(state->fe[index_frontend], &channel_status);
1964 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
1965 }
1966 }
1967 do {
1968 sleep_time = FE_CALLBACK_TIME_NEVER;
1969 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1970 if (index_frontend != index_frontend_success) {
1971 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL);
1972 if (sleep_time == FE_CALLBACK_TIME_NEVER)
1973 sleep_time = sleep_time_slave;
1974 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
1975 sleep_time = sleep_time_slave;
1976 }
1977 }
1978 if (sleep_time != FE_CALLBACK_TIME_NEVER)
1979 msleep(sleep_time / 10);
1980 else
1981 break;
1982
1983 nbr_pending = 0;
1984 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1985 if (index_frontend != index_frontend_success) {
1986 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
1987 if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))
1988 nbr_pending++; /* some frontends are still tuning */
1989 }
1990 }
1991 } while (nbr_pending != 0);
1992
1993 /* set the output mode */
1994 dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);
1995 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
1996 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
1997
1998 /* turn off the diversity for the last frontend */
1999 dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
2000
2001 return 0;
2002}
2003
2004static u16 dib9000_read_lock(struct dvb_frontend *fe)
2005{
2006 struct dib9000_state *state = fe->demodulator_priv;
2007
2008 return dib9000_read_word(state, 535);
2009}
2010
2011static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2012{
2013 struct dib9000_state *state = fe->demodulator_priv;
2014 u8 index_frontend;
2015 u16 lock = 0, lock_slave = 0;
2016
2017 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2018 lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
2019
2020 lock = dib9000_read_word(state, 535);
2021
2022 *stat = 0;
2023
2024 if ((lock & 0x8000) || (lock_slave & 0x8000))
2025 *stat |= FE_HAS_SIGNAL;
2026 if ((lock & 0x3000) || (lock_slave & 0x3000))
2027 *stat |= FE_HAS_CARRIER;
2028 if ((lock & 0x0100) || (lock_slave & 0x0100))
2029 *stat |= FE_HAS_VITERBI;
2030 if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))
2031 *stat |= FE_HAS_SYNC;
2032 if ((lock & 0x0008) || (lock_slave & 0x0008))
2033 *stat |= FE_HAS_LOCK;
2034
2035 return 0;
2036}
2037
2038static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2039{
2040 struct dib9000_state *state = fe->demodulator_priv;
2041 u16 c[16];
2042
2043 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2044 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2045 return -EIO;
2046 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2047 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2048
2049 *ber = c[10] << 16 | c[11];
2050 return 0;
2051}
2052
2053static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2054{
2055 struct dib9000_state *state = fe->demodulator_priv;
2056 u8 index_frontend;
2057 u16 c[16];
2058 u16 val;
2059
2060 *strength = 0;
2061 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2062 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2063 if (val > 65535 - *strength)
2064 *strength = 65535;
2065 else
2066 *strength += val;
2067 }
2068
2069 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2070 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2071 return -EIO;
2072 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2073 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2074
2075 val = 65535 - c[4];
2076 if (val > 65535 - *strength)
2077 *strength = 65535;
2078 else
2079 *strength += val;
2080 return 0;
2081}
2082
2083static u32 dib9000_get_snr(struct dvb_frontend *fe)
2084{
2085 struct dib9000_state *state = fe->demodulator_priv;
2086 u16 c[16];
2087 u32 n, s, exp;
2088 u16 val;
2089
2090 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2091 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2092 return -EIO;
2093 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2094 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2095
2096 val = c[7];
2097 n = (val >> 4) & 0xff;
2098 exp = ((val & 0xf) << 2);
2099 val = c[8];
2100 exp += ((val >> 14) & 0x3);
2101 if ((exp & 0x20) != 0)
2102 exp -= 0x40;
2103 n <<= exp + 16;
2104
2105 s = (val >> 6) & 0xFF;
2106 exp = (val & 0x3F);
2107 if ((exp & 0x20) != 0)
2108 exp -= 0x40;
2109 s <<= exp + 16;
2110
2111 if (n > 0) {
2112 u32 t = (s / n) << 16;
2113 return t + ((s << 16) - n * t) / n;
2114 }
2115 return 0xffffffff;
2116}
2117
2118static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2119{
2120 struct dib9000_state *state = fe->demodulator_priv;
2121 u8 index_frontend;
2122 u32 snr_master;
2123
2124 snr_master = dib9000_get_snr(fe);
2125 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2126 snr_master += dib9000_get_snr(state->fe[index_frontend]);
2127
2128 if ((snr_master >> 16) != 0) {
2129 snr_master = 10 * intlog10(snr_master >> 16);
2130 *snr = snr_master / ((1 << 24) / 10);
2131 } else
2132 *snr = 0;
2133
2134 return 0;
2135}
2136
2137static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2138{
2139 struct dib9000_state *state = fe->demodulator_priv;
2140 u16 c[16];
2141
2142 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2143 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2144 return -EIO;
2145 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2146 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2147
2148 *unc = c[12];
2149 return 0;
2150}
2151
2152int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
2153{
2154 int k = 0;
2155 u8 new_addr = 0;
2156 struct i2c_device client = {.i2c_adap = i2c };
2157
2158 client.i2c_addr = default_addr + 16;
2159 dib9000_i2c_write16(&client, 1796, 0x0);
2160
2161 for (k = no_of_demods - 1; k >= 0; k--) {
2162 /* designated i2c address */
2163 new_addr = first_addr + (k << 1);
2164 client.i2c_addr = default_addr;
2165
2166 dib9000_i2c_write16(&client, 1817, 3);
2167 dib9000_i2c_write16(&client, 1796, 0);
2168 dib9000_i2c_write16(&client, 1227, 1);
2169 dib9000_i2c_write16(&client, 1227, 0);
2170
2171 client.i2c_addr = new_addr;
2172 dib9000_i2c_write16(&client, 1817, 3);
2173 dib9000_i2c_write16(&client, 1796, 0);
2174 dib9000_i2c_write16(&client, 1227, 1);
2175 dib9000_i2c_write16(&client, 1227, 0);
2176
2177 if (dib9000_identify(&client) == 0) {
2178 client.i2c_addr = default_addr;
2179 if (dib9000_identify(&client) == 0) {
2180 dprintk("DiB9000 #%d: not identified", k);
2181 return -EIO;
2182 }
2183 }
2184
2185 dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));
2186 dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);
2187
2188 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2189 }
2190
2191 for (k = 0; k < no_of_demods; k++) {
2192 new_addr = first_addr | (k << 1);
2193 client.i2c_addr = new_addr;
2194
2195 dib9000_i2c_write16(&client, 1794, (new_addr << 2));
2196 dib9000_i2c_write16(&client, 1795, 0);
2197 }
2198
2199 return 0;
2200}
2201EXPORT_SYMBOL(dib9000_i2c_enumeration);
2202
2203int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2204{
2205 struct dib9000_state *state = fe->demodulator_priv;
2206 u8 index_frontend = 1;
2207
2208 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2209 index_frontend++;
2210 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2211 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2212 state->fe[index_frontend] = fe_slave;
2213 return 0;
2214 }
2215
2216 dprintk("too many slave frontend");
2217 return -ENOMEM;
2218}
2219EXPORT_SYMBOL(dib9000_set_slave_frontend);
2220
2221int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
2222{
2223 struct dib9000_state *state = fe->demodulator_priv;
2224 u8 index_frontend = 1;
2225
2226 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2227 index_frontend++;
2228 if (index_frontend != 1) {
2229 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend - 1], index_frontend - 1);
2230 state->fe[index_frontend] = NULL;
2231 return 0;
2232 }
2233
2234 dprintk("no frontend to be removed");
2235 return -ENODEV;
2236}
2237EXPORT_SYMBOL(dib9000_remove_slave_frontend);
2238
2239struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2240{
2241 struct dib9000_state *state = fe->demodulator_priv;
2242
2243 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2244 return NULL;
2245 return state->fe[slave_index];
2246}
2247EXPORT_SYMBOL(dib9000_get_slave_frontend);
2248
2249static struct dvb_frontend_ops dib9000_ops;
2250struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
2251{
2252 struct dvb_frontend *fe;
2253 struct dib9000_state *st;
2254 st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);
2255 if (st == NULL)
2256 return NULL;
2257 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2258 if (fe == NULL)
2259 return NULL;
2260
2261 memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
2262 st->i2c.i2c_adap = i2c_adap;
2263 st->i2c.i2c_addr = i2c_addr;
2264
2265 st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
2266 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
2267 st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
2268
2269 DibInitLock(&st->platform.risc.mbx_if_lock);
2270 DibInitLock(&st->platform.risc.mbx_lock);
2271 DibInitLock(&st->platform.risc.mem_lock);
2272 DibInitLock(&st->platform.risc.mem_mbx_lock);
2273
2274 st->fe[0] = fe;
2275 fe->demodulator_priv = st;
2276 memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));
2277
2278 /* Ensure the output mode remains at the previous default if it's
2279 * not specifically set by the caller.
2280 */
2281 if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2282 st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;
2283
2284 if (dib9000_identify(&st->i2c) == 0)
2285 goto error;
2286
2287 dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);
2288
2289 st->tuner_adap.dev.parent = i2c_adap->dev.parent;
2290 strncpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS", sizeof(st->tuner_adap.name));
2291 st->tuner_adap.algo = &dib9000_tuner_algo;
2292 st->tuner_adap.algo_data = NULL;
2293 i2c_set_adapdata(&st->tuner_adap, st);
2294 if (i2c_add_adapter(&st->tuner_adap) < 0)
2295 goto error;
2296
2297 st->component_bus.dev.parent = i2c_adap->dev.parent;
2298 strncpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS", sizeof(st->component_bus.name));
2299 st->component_bus.algo = &dib9000_component_bus_algo;
2300 st->component_bus.algo_data = NULL;
2301 st->component_bus_speed = 340;
2302 i2c_set_adapdata(&st->component_bus, st);
2303 if (i2c_add_adapter(&st->component_bus) < 0)
2304 goto component_bus_add_error;
2305
2306 dib9000_fw_reset(fe);
2307
2308 return fe;
2309
2310component_bus_add_error:
2311 i2c_del_adapter(&st->tuner_adap);
2312error:
2313 kfree(st);
2314 return NULL;
2315}
2316EXPORT_SYMBOL(dib9000_attach);
2317
2318static struct dvb_frontend_ops dib9000_ops = {
2319 .info = {
2320 .name = "DiBcom 9000",
2321 .type = FE_OFDM,
2322 .frequency_min = 44250000,
2323 .frequency_max = 867250000,
2324 .frequency_stepsize = 62500,
2325 .caps = FE_CAN_INVERSION_AUTO |
2326 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2327 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2328 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2329 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2330 },
2331
2332 .release = dib9000_release,
2333
2334 .init = dib9000_wakeup,
2335 .sleep = dib9000_sleep,
2336
2337 .set_frontend = dib9000_set_frontend,
2338 .get_tune_settings = dib9000_fe_get_tune_settings,
2339 .get_frontend = dib9000_get_frontend,
2340
2341 .read_status = dib9000_read_status,
2342 .read_ber = dib9000_read_ber,
2343 .read_signal_strength = dib9000_read_signal_strength,
2344 .read_snr = dib9000_read_snr,
2345 .read_ucblocks = dib9000_read_unc_blocks,
2346};
2347
2348MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2349MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2350MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
2351MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib9000.h b/drivers/media/dvb/frontends/dib9000.h
new file mode 100644
index 000000000000..b5781a48034c
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib9000.h
@@ -0,0 +1,131 @@
1#ifndef DIB9000_H
2#define DIB9000_H
3
4#include "dibx000_common.h"
5
6struct dib9000_config {
7 u8 dvbt_mode;
8 u8 output_mpeg2_in_188_bytes;
9 u8 hostbus_diversity;
10 struct dibx000_bandwidth_config *bw;
11
12 u16 if_drives;
13
14 u32 timing_frequency;
15 u32 xtal_clock_khz;
16 u32 vcxo_timer;
17 u32 demod_clock_khz;
18
19 const u8 *microcode_B_fe_buffer;
20 u32 microcode_B_fe_size;
21
22 struct dibGPIOFunction gpio_function[2];
23 struct dibSubbandSelection subband;
24
25 u8 output_mode;
26};
27
28#define DEFAULT_DIB9000_I2C_ADDRESS 18
29
30#if defined(CONFIG_DVB_DIB9000) || (defined(CONFIG_DVB_DIB9000_MODULE) && defined(MODULE))
31extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg);
32extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
33extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe);
34extern struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
35extern int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
36extern int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
37extern int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
38extern int dib9000_firmware_post_pll_init(struct dvb_frontend *fe);
39extern int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
40extern int dib9000_remove_slave_frontend(struct dvb_frontend *fe);
41extern struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
42extern struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe);
43extern int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c);
44extern int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed);
45#else
46static inline struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib9000_config *cfg)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL;
50}
51
52static inline struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
53{
54 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
55 return NULL;
56}
57
58static inline int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
59{
60 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
61 return -ENODEV;
62}
63
64static inline struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
65{
66 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
67 return NULL;
68}
69
70static inline int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
71{
72 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
73 return -ENODEV;
74}
75
76static inline int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
77{
78 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
79 return -ENODEV;
80}
81
82static inline int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
83{
84 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
85 return -ENODEV;
86}
87
88static inline int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
89{
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
91 return -ENODEV;
92}
93
94static inline int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
95{
96 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
97 return -ENODEV;
98}
99
100int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
101{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return -ENODEV;
104}
105
106static inline struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
107{
108 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
109 return NULL;
110}
111
112static inline struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
113{
114 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
115 return NULL;
116}
117
118static inline int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
119{
120 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
121 return -ENODEV;
122}
123
124static inline int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
125{
126 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
127 return -ENODEV;
128}
129#endif
130
131#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index 2311c0a3406c..f6938f97feb4 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -17,9 +17,145 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
17 struct i2c_msg msg = { 17 struct i2c_msg msg = {
18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4 18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
19 }; 19 };
20
20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 21 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
21} 22}
22 23
24static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
25{
26 u8 wb[2] = { reg >> 8, reg & 0xff };
27 u8 rb[2];
28 struct i2c_msg msg[2] = {
29 {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2},
30 {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2},
31 };
32
33 if (i2c_transfer(mst->i2c_adap, msg, 2) != 2)
34 dprintk("i2c read error on %d", reg);
35
36 return (rb[0] << 8) | rb[1];
37}
38
39static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
40{
41 int i = 100;
42 u16 status;
43
44 while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
45 ;
46
47 /* i2c timed out */
48 if (i == 0)
49 return -EREMOTEIO;
50
51 /* no acknowledge */
52 if ((status & 0x0080) == 0)
53 return -EREMOTEIO;
54
55 return 0;
56}
57
58static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
59{
60 u16 data;
61 u16 da;
62 u16 i;
63 u16 txlen = msg->len, len;
64 const u8 *b = msg->buf;
65
66 while (txlen) {
67 dibx000_read_word(mst, mst->base_reg + 2);
68
69 len = txlen > 8 ? 8 : txlen;
70 for (i = 0; i < len; i += 2) {
71 data = *b++ << 8;
72 if (i+1 < len)
73 data |= *b++;
74 dibx000_write_word(mst, mst->base_reg, data);
75 }
76 da = (((u8) (msg->addr)) << 9) |
77 (1 << 8) |
78 (1 << 7) |
79 (0 << 6) |
80 (0 << 5) |
81 ((len & 0x7) << 2) |
82 (0 << 1) |
83 (0 << 0);
84
85 if (txlen == msg->len)
86 da |= 1 << 5; /* start */
87
88 if (txlen-len == 0 && stop)
89 da |= 1 << 6; /* stop */
90
91 dibx000_write_word(mst, mst->base_reg+1, da);
92
93 if (dibx000_is_i2c_done(mst) != 0)
94 return -EREMOTEIO;
95 txlen -= len;
96 }
97
98 return 0;
99}
100
101static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
102{
103 u16 da;
104 u8 *b = msg->buf;
105 u16 rxlen = msg->len, len;
106
107 while (rxlen) {
108 len = rxlen > 8 ? 8 : rxlen;
109 da = (((u8) (msg->addr)) << 9) |
110 (1 << 8) |
111 (1 << 7) |
112 (0 << 6) |
113 (0 << 5) |
114 ((len & 0x7) << 2) |
115 (1 << 1) |
116 (0 << 0);
117
118 if (rxlen == msg->len)
119 da |= 1 << 5; /* start */
120
121 if (rxlen-len == 0)
122 da |= 1 << 6; /* stop */
123 dibx000_write_word(mst, mst->base_reg+1, da);
124
125 if (dibx000_is_i2c_done(mst) != 0)
126 return -EREMOTEIO;
127
128 rxlen -= len;
129
130 while (len) {
131 da = dibx000_read_word(mst, mst->base_reg);
132 *b++ = (da >> 8) & 0xff;
133 len--;
134 if (len >= 1) {
135 *b++ = da & 0xff;
136 len--;
137 }
138 }
139 }
140
141 return 0;
142}
143
144int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
145{
146 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
147
148 if (mst->device_rev < DIB7000MC && speed < 235)
149 speed = 235;
150 return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
151
152}
153EXPORT_SYMBOL(dibx000_i2c_set_speed);
154
155static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
156{
157 return I2C_FUNC_I2C;
158}
23 159
24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, 160static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
25 enum dibx000_i2c_interface intf) 161 enum dibx000_i2c_interface intf)
@@ -32,6 +168,60 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
32 return 0; 168 return 0;
33} 169}
34 170
171static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
172{
173 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
174 int msg_index;
175 int ret = 0;
176
177 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
178 for (msg_index = 0; msg_index < num; msg_index++) {
179 if (msg[msg_index].flags & I2C_M_RD) {
180 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
181 if (ret != 0)
182 return 0;
183 } else {
184 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
185 if (ret != 0)
186 return 0;
187 }
188 }
189
190 return num;
191}
192
193static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
194{
195 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
196 int msg_index;
197 int ret = 0;
198
199 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
200 for (msg_index = 0; msg_index < num; msg_index++) {
201 if (msg[msg_index].flags & I2C_M_RD) {
202 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
203 if (ret != 0)
204 return 0;
205 } else {
206 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
207 if (ret != 0)
208 return 0;
209 }
210 }
211
212 return num;
213}
214
215static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
216 .master_xfer = dibx000_i2c_master_xfer_gpio12,
217 .functionality = dibx000_i2c_func,
218};
219
220static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
221 .master_xfer = dibx000_i2c_master_xfer_gpio34,
222 .functionality = dibx000_i2c_func,
223};
224
35static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], 225static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
36 u8 addr, int onoff) 226 u8 addr, int onoff)
37{ 227{
@@ -54,11 +244,37 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
54 return 0; 244 return 0;
55} 245}
56 246
57static u32 dibx000_i2c_func(struct i2c_adapter *adapter) 247static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
248 struct i2c_msg msg[], int num)
58{ 249{
59 return I2C_FUNC_I2C; 250 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
251 struct i2c_msg m[2 + num];
252 u8 tx_open[4], tx_close[4];
253
254 memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
255
256 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
257
258 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
259 m[0].addr = mst->i2c_addr;
260 m[0].buf = tx_open;
261 m[0].len = 4;
262
263 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
264
265 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
266 m[num + 1].addr = mst->i2c_addr;
267 m[num + 1].buf = tx_close;
268 m[num + 1].len = 4;
269
270 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
60} 271}
61 272
273static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
274 .master_xfer = dibx000_i2c_gated_gpio67_xfer,
275 .functionality = dibx000_i2c_func,
276};
277
62static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, 278static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
63 struct i2c_msg msg[], int num) 279 struct i2c_msg msg[], int num)
64{ 280{
@@ -91,8 +307,8 @@ static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
91}; 307};
92 308
93struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, 309struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
94 enum dibx000_i2c_interface intf, 310 enum dibx000_i2c_interface intf,
95 int gating) 311 int gating)
96{ 312{
97 struct i2c_adapter *i2c = NULL; 313 struct i2c_adapter *i2c = NULL;
98 314
@@ -101,6 +317,18 @@ struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
101 if (gating) 317 if (gating)
102 i2c = &mst->gated_tuner_i2c_adap; 318 i2c = &mst->gated_tuner_i2c_adap;
103 break; 319 break;
320 case DIBX000_I2C_INTERFACE_GPIO_1_2:
321 if (!gating)
322 i2c = &mst->master_i2c_adap_gpio12;
323 break;
324 case DIBX000_I2C_INTERFACE_GPIO_3_4:
325 if (!gating)
326 i2c = &mst->master_i2c_adap_gpio34;
327 break;
328 case DIBX000_I2C_INTERFACE_GPIO_6_7:
329 if (gating)
330 i2c = &mst->master_i2c_adap_gpio67;
331 break;
104 default: 332 default:
105 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); 333 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
106 break; 334 break;
@@ -126,8 +354,8 @@ void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
126EXPORT_SYMBOL(dibx000_reset_i2c_master); 354EXPORT_SYMBOL(dibx000_reset_i2c_master);
127 355
128static int i2c_adapter_init(struct i2c_adapter *i2c_adap, 356static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
129 struct i2c_algorithm *algo, const char *name, 357 struct i2c_algorithm *algo, const char *name,
130 struct dibx000_i2c_master *mst) 358 struct dibx000_i2c_master *mst)
131{ 359{
132 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); 360 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
133 i2c_adap->algo = algo; 361 i2c_adap->algo = algo;
@@ -139,7 +367,7 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
139} 367}
140 368
141int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, 369int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
142 struct i2c_adapter *i2c_adap, u8 i2c_addr) 370 struct i2c_adapter *i2c_adap, u8 i2c_addr)
143{ 371{
144 u8 tx[4]; 372 u8 tx[4];
145 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 }; 373 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
@@ -153,11 +381,33 @@ int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
153 else 381 else
154 mst->base_reg = 768; 382 mst->base_reg = 768;
155 383
384 mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
385 if (i2c_adapter_init
386 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
387 "DiBX000 tuner I2C bus", mst) != 0)
388 printk(KERN_ERR
389 "DiBX000: could not initialize the tuner i2c_adapter\n");
390
391 mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
392 if (i2c_adapter_init
393 (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
394 "DiBX000 master GPIO12 I2C bus", mst) != 0)
395 printk(KERN_ERR
396 "DiBX000: could not initialize the master i2c_adapter\n");
397
398 mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
399 if (i2c_adapter_init
400 (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
401 "DiBX000 master GPIO34 I2C bus", mst) != 0)
402 printk(KERN_ERR
403 "DiBX000: could not initialize the master i2c_adapter\n");
404
405 mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
156 if (i2c_adapter_init 406 if (i2c_adapter_init
157 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, 407 (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
158 "DiBX000 tuner I2C bus", mst) != 0) 408 "DiBX000 master GPIO67 I2C bus", mst) != 0)
159 printk(KERN_ERR 409 printk(KERN_ERR
160 "DiBX000: could not initialize the tuner i2c_adapter\n"); 410 "DiBX000: could not initialize the master i2c_adapter\n");
161 411
162 /* initialize the i2c-master by closing the gate */ 412 /* initialize the i2c-master by closing the gate */
163 dibx000_i2c_gate_ctrl(mst, tx, 0, 0); 413 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
@@ -170,16 +420,19 @@ EXPORT_SYMBOL(dibx000_init_i2c_master);
170void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) 420void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
171{ 421{
172 i2c_del_adapter(&mst->gated_tuner_i2c_adap); 422 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
423 i2c_del_adapter(&mst->master_i2c_adap_gpio12);
424 i2c_del_adapter(&mst->master_i2c_adap_gpio34);
425 i2c_del_adapter(&mst->master_i2c_adap_gpio67);
173} 426}
174EXPORT_SYMBOL(dibx000_exit_i2c_master); 427EXPORT_SYMBOL(dibx000_exit_i2c_master);
175 428
176 429
177u32 systime(void) 430u32 systime(void)
178{ 431{
179 struct timespec t; 432 struct timespec t;
180 433
181 t = current_kernel_time(); 434 t = current_kernel_time();
182 return (t.tv_sec * 10000) + (t.tv_nsec / 100000); 435 return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
183} 436}
184EXPORT_SYMBOL(systime); 437EXPORT_SYMBOL(systime);
185 438
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index 4f5d141a308d..977d343369aa 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -4,7 +4,8 @@
4enum dibx000_i2c_interface { 4enum dibx000_i2c_interface {
5 DIBX000_I2C_INTERFACE_TUNER = 0, 5 DIBX000_I2C_INTERFACE_TUNER = 0,
6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1, 6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2 7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2,
8 DIBX000_I2C_INTERFACE_GPIO_6_7 = 3
8}; 9};
9 10
10struct dibx000_i2c_master { 11struct dibx000_i2c_master {
@@ -17,8 +18,11 @@ struct dibx000_i2c_master {
17 18
18 enum dibx000_i2c_interface selected_interface; 19 enum dibx000_i2c_interface selected_interface;
19 20
20// struct i2c_adapter tuner_i2c_adap; 21/* struct i2c_adapter tuner_i2c_adap; */
21 struct i2c_adapter gated_tuner_i2c_adap; 22 struct i2c_adapter gated_tuner_i2c_adap;
23 struct i2c_adapter master_i2c_adap_gpio12;
24 struct i2c_adapter master_i2c_adap_gpio34;
25 struct i2c_adapter master_i2c_adap_gpio67;
22 26
23 struct i2c_adapter *i2c_adap; 27 struct i2c_adapter *i2c_adap;
24 u8 i2c_addr; 28 u8 i2c_addr;
@@ -27,14 +31,15 @@ struct dibx000_i2c_master {
27}; 31};
28 32
29extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, 33extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
30 u16 device_rev, struct i2c_adapter *i2c_adap, 34 u16 device_rev, struct i2c_adapter *i2c_adap,
31 u8 i2c_addr); 35 u8 i2c_addr);
32extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master 36extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
33 *mst, 37 *mst,
34 enum dibx000_i2c_interface 38 enum dibx000_i2c_interface
35 intf, int gating); 39 intf, int gating);
36extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); 40extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
37extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst); 41extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
42extern int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed);
38 43
39extern u32 systime(void); 44extern u32 systime(void);
40 45
@@ -42,7 +47,7 @@ extern u32 systime(void);
42#define BAND_UHF 0x02 47#define BAND_UHF 0x02
43#define BAND_VHF 0x04 48#define BAND_VHF 0x04
44#define BAND_SBAND 0x08 49#define BAND_SBAND 0x08
45#define BAND_FM 0x10 50#define BAND_FM 0x10
46#define BAND_CBAND 0x20 51#define BAND_CBAND 0x20
47 52
48#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \ 53#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
@@ -135,9 +140,9 @@ enum dibx000_adc_states {
135 DIBX000_VBG_DISABLE, 140 DIBX000_VBG_DISABLE,
136}; 141};
137 142
138#define BANDWIDTH_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \ 143#define BANDWIDTH_TO_KHZ(v) ((v) == BANDWIDTH_8_MHZ ? 8000 : \
139 (v) == BANDWIDTH_7_MHZ ? 7000 : \ 144 (v) == BANDWIDTH_7_MHZ ? 7000 : \
140 (v) == BANDWIDTH_6_MHZ ? 6000 : 8000 ) 145 (v) == BANDWIDTH_6_MHZ ? 6000 : 8000)
141 146
142#define BANDWIDTH_TO_INDEX(v) ( \ 147#define BANDWIDTH_TO_INDEX(v) ( \
143 (v) == 8000 ? BANDWIDTH_8_MHZ : \ 148 (v) == 8000 ? BANDWIDTH_8_MHZ : \
@@ -153,53 +158,57 @@ enum dibx000_adc_states {
153#define OUTMODE_MPEG2_FIFO 5 158#define OUTMODE_MPEG2_FIFO 5
154#define OUTMODE_ANALOG_ADC 6 159#define OUTMODE_ANALOG_ADC 6
155 160
161#define INPUT_MODE_OFF 0x11
162#define INPUT_MODE_DIVERSITY 0x12
163#define INPUT_MODE_MPEG 0x13
164
156enum frontend_tune_state { 165enum frontend_tune_state {
157 CT_TUNER_START = 10, 166 CT_TUNER_START = 10,
158 CT_TUNER_STEP_0, 167 CT_TUNER_STEP_0,
159 CT_TUNER_STEP_1, 168 CT_TUNER_STEP_1,
160 CT_TUNER_STEP_2, 169 CT_TUNER_STEP_2,
161 CT_TUNER_STEP_3, 170 CT_TUNER_STEP_3,
162 CT_TUNER_STEP_4, 171 CT_TUNER_STEP_4,
163 CT_TUNER_STEP_5, 172 CT_TUNER_STEP_5,
164 CT_TUNER_STEP_6, 173 CT_TUNER_STEP_6,
165 CT_TUNER_STEP_7, 174 CT_TUNER_STEP_7,
166 CT_TUNER_STOP, 175 CT_TUNER_STOP,
167 176
168 CT_AGC_START = 20, 177 CT_AGC_START = 20,
169 CT_AGC_STEP_0, 178 CT_AGC_STEP_0,
170 CT_AGC_STEP_1, 179 CT_AGC_STEP_1,
171 CT_AGC_STEP_2, 180 CT_AGC_STEP_2,
172 CT_AGC_STEP_3, 181 CT_AGC_STEP_3,
173 CT_AGC_STEP_4, 182 CT_AGC_STEP_4,
174 CT_AGC_STOP, 183 CT_AGC_STOP,
175 184
176 CT_DEMOD_START = 30, 185 CT_DEMOD_START = 30,
177 CT_DEMOD_STEP_1, 186 CT_DEMOD_STEP_1,
178 CT_DEMOD_STEP_2, 187 CT_DEMOD_STEP_2,
179 CT_DEMOD_STEP_3, 188 CT_DEMOD_STEP_3,
180 CT_DEMOD_STEP_4, 189 CT_DEMOD_STEP_4,
181 CT_DEMOD_STEP_5, 190 CT_DEMOD_STEP_5,
182 CT_DEMOD_STEP_6, 191 CT_DEMOD_STEP_6,
183 CT_DEMOD_STEP_7, 192 CT_DEMOD_STEP_7,
184 CT_DEMOD_STEP_8, 193 CT_DEMOD_STEP_8,
185 CT_DEMOD_STEP_9, 194 CT_DEMOD_STEP_9,
186 CT_DEMOD_STEP_10, 195 CT_DEMOD_STEP_10,
187 CT_DEMOD_SEARCH_NEXT = 41, 196 CT_DEMOD_SEARCH_NEXT = 41,
188 CT_DEMOD_STEP_LOCKED, 197 CT_DEMOD_STEP_LOCKED,
189 CT_DEMOD_STOP, 198 CT_DEMOD_STOP,
190 199
191 CT_DONE = 100, 200 CT_DONE = 100,
192 CT_SHUTDOWN, 201 CT_SHUTDOWN,
193 202
194}; 203};
195 204
196struct dvb_frontend_parametersContext { 205struct dvb_frontend_parametersContext {
197#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01 206#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01
198#define CHANNEL_STATUS_PARAMETERS_SET 0x02 207#define CHANNEL_STATUS_PARAMETERS_SET 0x02
199 u8 status; 208 u8 status;
200 u32 tune_time_estimation[2]; 209 u32 tune_time_estimation[2];
201 s32 tps_available; 210 s32 tps_available;
202 u16 tps[9]; 211 u16 tps[9];
203}; 212};
204 213
205#define FE_STATUS_TUNE_FAILED 0 214#define FE_STATUS_TUNE_FAILED 0
@@ -216,4 +225,49 @@ struct dvb_frontend_parametersContext {
216 225
217#define ABS(x) ((x < 0) ? (-x) : (x)) 226#define ABS(x) ((x < 0) ? (-x) : (x))
218 227
228#define DATA_BUS_ACCESS_MODE_8BIT 0x01
229#define DATA_BUS_ACCESS_MODE_16BIT 0x02
230#define DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT 0x10
231
232struct dibGPIOFunction {
233#define BOARD_GPIO_COMPONENT_BUS_ADAPTER 1
234#define BOARD_GPIO_COMPONENT_DEMOD 2
235 u8 component;
236
237#define BOARD_GPIO_FUNCTION_BOARD_ON 1
238#define BOARD_GPIO_FUNCTION_BOARD_OFF 2
239#define BOARD_GPIO_FUNCTION_COMPONENT_ON 3
240#define BOARD_GPIO_FUNCTION_COMPONENT_OFF 4
241#define BOARD_GPIO_FUNCTION_SUBBAND_PWM 5
242#define BOARD_GPIO_FUNCTION_SUBBAND_GPIO 6
243 u8 function;
244
245/* mask, direction and value are used specify which GPIO to change GPIO0
246 * is LSB and possible GPIO31 is MSB. The same bit-position as in the
247 * mask is used for the direction and the value. Direction == 1 is OUT,
248 * 0 == IN. For direction "OUT" value is either 1 or 0, for direction IN
249 * value has no meaning.
250 *
251 * In case of BOARD_GPIO_FUNCTION_PWM mask is giving the GPIO to be
252 * used to do the PWM. Direction gives the PWModulator to be used.
253 * Value gives the PWM value in device-dependent scale.
254 */
255 u32 mask;
256 u32 direction;
257 u32 value;
258};
259
260#define MAX_NB_SUBBANDS 8
261struct dibSubbandSelection {
262 u8 size; /* Actual number of subbands. */
263 struct {
264 u16 f_mhz;
265 struct dibGPIOFunction gpio;
266 } subband[MAX_NB_SUBBANDS];
267};
268
269#define DEMOD_TIMF_SET 0x00
270#define DEMOD_TIMF_GET 0x01
271#define DEMOD_TIMF_UPDATE 0x02
272
219#endif 273#endif
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
index fc61d9230db8..90bf573308b0 100644
--- a/drivers/media/dvb/frontends/ds3000.c
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -229,31 +229,11 @@ static u8 ds3000_dvbs2_init_tab[] = {
229 0xb8, 0x00, 229 0xb8, 0x00,
230}; 230};
231 231
232/* DS3000 doesn't need some parameters as input and auto-detects them */
233/* save input from the application of those parameters */
234struct ds3000_tuning {
235 u32 frequency;
236 u32 symbol_rate;
237 fe_spectral_inversion_t inversion;
238 enum fe_code_rate fec;
239
240 /* input values */
241 u8 inversion_val;
242 fe_modulation_t delivery;
243 u8 rolloff;
244};
245
246struct ds3000_state { 232struct ds3000_state {
247 struct i2c_adapter *i2c; 233 struct i2c_adapter *i2c;
248 const struct ds3000_config *config; 234 const struct ds3000_config *config;
249
250 struct dvb_frontend frontend; 235 struct dvb_frontend frontend;
251
252 struct ds3000_tuning dcur;
253 struct ds3000_tuning dnxt;
254
255 u8 skip_fw_load; 236 u8 skip_fw_load;
256
257 /* previous uncorrected block counter for DVB-S2 */ 237 /* previous uncorrected block counter for DVB-S2 */
258 u16 prevUCBS2; 238 u16 prevUCBS2;
259}; 239};
@@ -305,7 +285,7 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg,
305 struct i2c_msg msg; 285 struct i2c_msg msg;
306 u8 *buf; 286 u8 *buf;
307 287
308 buf = kmalloc(3, GFP_KERNEL); 288 buf = kmalloc(33, GFP_KERNEL);
309 if (buf == NULL) { 289 if (buf == NULL) {
310 printk(KERN_ERR "Unable to kmalloc\n"); 290 printk(KERN_ERR "Unable to kmalloc\n");
311 ret = -ENOMEM; 291 ret = -ENOMEM;
@@ -317,10 +297,10 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg,
317 msg.addr = state->config->demod_address; 297 msg.addr = state->config->demod_address;
318 msg.flags = 0; 298 msg.flags = 0;
319 msg.buf = buf; 299 msg.buf = buf;
320 msg.len = 3; 300 msg.len = 33;
321 301
322 for (i = 0; i < len; i += 2) { 302 for (i = 0; i < len; i += 32) {
323 memcpy(buf + 1, data + i, 2); 303 memcpy(buf + 1, data + i, 32);
324 304
325 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len); 305 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
326 306
@@ -401,45 +381,6 @@ static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
401 return b1[0]; 381 return b1[0];
402} 382}
403 383
404static int ds3000_set_inversion(struct ds3000_state *state,
405 fe_spectral_inversion_t inversion)
406{
407 dprintk("%s(%d)\n", __func__, inversion);
408
409 switch (inversion) {
410 case INVERSION_OFF:
411 case INVERSION_ON:
412 case INVERSION_AUTO:
413 break;
414 default:
415 return -EINVAL;
416 }
417
418 state->dnxt.inversion = inversion;
419
420 return 0;
421}
422
423static int ds3000_set_symbolrate(struct ds3000_state *state, u32 rate)
424{
425 int ret = 0;
426
427 dprintk("%s()\n", __func__);
428
429 dprintk("%s() symbol_rate = %d\n", __func__, state->dnxt.symbol_rate);
430
431 /* check if symbol rate is within limits */
432 if ((state->dnxt.symbol_rate >
433 state->frontend.ops.info.symbol_rate_max) ||
434 (state->dnxt.symbol_rate <
435 state->frontend.ops.info.symbol_rate_min))
436 ret = -EOPNOTSUPP;
437
438 state->dnxt.symbol_rate = rate;
439
440 return ret;
441}
442
443static int ds3000_load_firmware(struct dvb_frontend *fe, 384static int ds3000_load_firmware(struct dvb_frontend *fe,
444 const struct firmware *fw); 385 const struct firmware *fw);
445 386
@@ -509,23 +450,31 @@ static int ds3000_load_firmware(struct dvb_frontend *fe,
509 return 0; 450 return 0;
510} 451}
511 452
512static void ds3000_dump_registers(struct dvb_frontend *fe) 453static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
513{ 454{
514 struct ds3000_state *state = fe->demodulator_priv; 455 struct ds3000_state *state = fe->demodulator_priv;
515 int x, y, reg = 0, val; 456 u8 data;
516 457
517 for (y = 0; y < 16; y++) { 458 dprintk("%s(%d)\n", __func__, voltage);
518 dprintk("%s: %02x: ", __func__, y); 459
519 for (x = 0; x < 16; x++) { 460 data = ds3000_readreg(state, 0xa2);
520 reg = (y << 4) + x; 461 data |= 0x03; /* bit0 V/H, bit1 off/on */
521 val = ds3000_readreg(state, reg); 462
522 if (x != 15) 463 switch (voltage) {
523 dprintk("%02x ", val); 464 case SEC_VOLTAGE_18:
524 else 465 data &= ~0x03;
525 dprintk("%02x\n", val); 466 break;
526 } 467 case SEC_VOLTAGE_13:
468 data &= ~0x03;
469 data |= 0x01;
470 break;
471 case SEC_VOLTAGE_OFF:
472 break;
527 } 473 }
528 dprintk("%s: -- DS3000 DUMP DONE --\n", __func__); 474
475 ds3000_writereg(state, 0xa2, data);
476
477 return 0;
529} 478}
530 479
531static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status) 480static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
@@ -562,16 +511,6 @@ static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
562 return 0; 511 return 0;
563} 512}
564 513
565#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK)
566static int ds3000_is_tuned(struct dvb_frontend *fe)
567{
568 fe_status_t tunerstat;
569
570 ds3000_read_status(fe, &tunerstat);
571
572 return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED);
573}
574
575/* read DS3000 BER value */ 514/* read DS3000 BER value */
576static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber) 515static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
577{ 516{
@@ -792,13 +731,6 @@ static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
792 return 0; 731 return 0;
793} 732}
794 733
795/* Overwrite the current tuning params, we are about to tune */
796static void ds3000_clone_params(struct dvb_frontend *fe)
797{
798 struct ds3000_state *state = fe->demodulator_priv;
799 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
800}
801
802static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 734static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
803{ 735{
804 struct ds3000_state *state = fe->demodulator_priv; 736 struct ds3000_state *state = fe->demodulator_priv;
@@ -1016,287 +948,298 @@ static int ds3000_get_property(struct dvb_frontend *fe,
1016 return 0; 948 return 0;
1017} 949}
1018 950
1019static int ds3000_tune(struct dvb_frontend *fe, 951static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
952 s32 carrier_offset_khz)
953{
954 struct ds3000_state *state = fe->demodulator_priv;
955 s32 tmp;
956
957 tmp = carrier_offset_khz;
958 tmp *= 65536;
959 tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
960
961 if (tmp < 0)
962 tmp += 65536;
963
964 ds3000_writereg(state, 0x5f, tmp >> 8);
965 ds3000_writereg(state, 0x5e, tmp & 0xff);
966
967 return 0;
968}
969
970static int ds3000_set_frontend(struct dvb_frontend *fe,
1020 struct dvb_frontend_parameters *p) 971 struct dvb_frontend_parameters *p)
1021{ 972{
1022 struct ds3000_state *state = fe->demodulator_priv; 973 struct ds3000_state *state = fe->demodulator_priv;
1023 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 974 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1024 975
1025 int ret = 0, retune, i; 976 int i;
1026 u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf; 977 fe_status_t status;
978 u8 mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf, div4;
979 s32 offset_khz;
1027 u16 value, ndiv; 980 u16 value, ndiv;
1028 u32 f3db; 981 u32 f3db;
1029 982
1030 dprintk("%s() ", __func__); 983 dprintk("%s() ", __func__);
1031 984
1032 /* Load the firmware if required */ 985 if (state->config->set_ts_params)
1033 ret = ds3000_firmware_ondemand(fe); 986 state->config->set_ts_params(fe, 0);
1034 if (ret != 0) { 987 /* Tune */
1035 printk(KERN_ERR "%s: Unable initialise the firmware\n", 988 /* unknown */
1036 __func__); 989 ds3000_tuner_writereg(state, 0x07, 0x02);
1037 return ret; 990 ds3000_tuner_writereg(state, 0x10, 0x00);
991 ds3000_tuner_writereg(state, 0x60, 0x79);
992 ds3000_tuner_writereg(state, 0x08, 0x01);
993 ds3000_tuner_writereg(state, 0x00, 0x01);
994 div4 = 0;
995
996 /* calculate and set freq divider */
997 if (p->frequency < 1146000) {
998 ds3000_tuner_writereg(state, 0x10, 0x11);
999 div4 = 1;
1000 ndiv = ((p->frequency * (6 + 8) * 4) +
1001 (DS3000_XTAL_FREQ / 2)) /
1002 DS3000_XTAL_FREQ - 1024;
1003 } else {
1004 ds3000_tuner_writereg(state, 0x10, 0x01);
1005 ndiv = ((p->frequency * (6 + 8) * 2) +
1006 (DS3000_XTAL_FREQ / 2)) /
1007 DS3000_XTAL_FREQ - 1024;
1038 } 1008 }
1039 1009
1040 state->dnxt.delivery = c->modulation; 1010 ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
1041 state->dnxt.frequency = c->frequency; 1011 ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
1042 state->dnxt.rolloff = 2; /* fixme */ 1012
1043 state->dnxt.fec = c->fec_inner; 1013 /* set pll */
1014 ds3000_tuner_writereg(state, 0x03, 0x06);
1015 ds3000_tuner_writereg(state, 0x51, 0x0f);
1016 ds3000_tuner_writereg(state, 0x51, 0x1f);
1017 ds3000_tuner_writereg(state, 0x50, 0x10);
1018 ds3000_tuner_writereg(state, 0x50, 0x00);
1019 msleep(5);
1020
1021 /* unknown */
1022 ds3000_tuner_writereg(state, 0x51, 0x17);
1023 ds3000_tuner_writereg(state, 0x51, 0x1f);
1024 ds3000_tuner_writereg(state, 0x50, 0x08);
1025 ds3000_tuner_writereg(state, 0x50, 0x00);
1026 msleep(5);
1027
1028 value = ds3000_tuner_readreg(state, 0x3d);
1029 value &= 0x0f;
1030 if ((value > 4) && (value < 15)) {
1031 value -= 3;
1032 if (value < 4)
1033 value = 4;
1034 value = ((value << 3) | 0x01) & 0x79;
1035 }
1044 1036
1045 ret = ds3000_set_inversion(state, p->inversion); 1037 ds3000_tuner_writereg(state, 0x60, value);
1046 if (ret != 0) 1038 ds3000_tuner_writereg(state, 0x51, 0x17);
1047 return ret; 1039 ds3000_tuner_writereg(state, 0x51, 0x1f);
1040 ds3000_tuner_writereg(state, 0x50, 0x08);
1041 ds3000_tuner_writereg(state, 0x50, 0x00);
1042
1043 /* set low-pass filter period */
1044 ds3000_tuner_writereg(state, 0x04, 0x2e);
1045 ds3000_tuner_writereg(state, 0x51, 0x1b);
1046 ds3000_tuner_writereg(state, 0x51, 0x1f);
1047 ds3000_tuner_writereg(state, 0x50, 0x04);
1048 ds3000_tuner_writereg(state, 0x50, 0x00);
1049 msleep(5);
1050
1051 f3db = ((c->symbol_rate / 1000) << 2) / 5 + 2000;
1052 if ((c->symbol_rate / 1000) < 5000)
1053 f3db += 3000;
1054 if (f3db < 7000)
1055 f3db = 7000;
1056 if (f3db > 40000)
1057 f3db = 40000;
1058
1059 /* set low-pass filter baseband */
1060 value = ds3000_tuner_readreg(state, 0x26);
1061 mlpf = 0x2e * 207 / ((value << 1) + 151);
1062 mlpf_max = mlpf * 135 / 100;
1063 mlpf_min = mlpf * 78 / 100;
1064 if (mlpf_max > 63)
1065 mlpf_max = 63;
1066
1067 /* rounded to the closest integer */
1068 nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
1069 / (2766 * DS3000_XTAL_FREQ);
1070 if (nlpf > 23)
1071 nlpf = 23;
1072 if (nlpf < 1)
1073 nlpf = 1;
1074
1075 /* rounded to the closest integer */
1076 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1077 (1000 * f3db / 2)) / (1000 * f3db);
1078
1079 if (mlpf_new < mlpf_min) {
1080 nlpf++;
1081 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1082 (1000 * f3db / 2)) / (1000 * f3db);
1083 }
1048 1084
1049 ret = ds3000_set_symbolrate(state, c->symbol_rate); 1085 if (mlpf_new > mlpf_max)
1050 if (ret != 0) 1086 mlpf_new = mlpf_max;
1051 return ret; 1087
1088 ds3000_tuner_writereg(state, 0x04, mlpf_new);
1089 ds3000_tuner_writereg(state, 0x06, nlpf);
1090 ds3000_tuner_writereg(state, 0x51, 0x1b);
1091 ds3000_tuner_writereg(state, 0x51, 0x1f);
1092 ds3000_tuner_writereg(state, 0x50, 0x04);
1093 ds3000_tuner_writereg(state, 0x50, 0x00);
1094 msleep(5);
1095
1096 /* unknown */
1097 ds3000_tuner_writereg(state, 0x51, 0x1e);
1098 ds3000_tuner_writereg(state, 0x51, 0x1f);
1099 ds3000_tuner_writereg(state, 0x50, 0x01);
1100 ds3000_tuner_writereg(state, 0x50, 0x00);
1101 msleep(60);
1102
1103 offset_khz = (ndiv - ndiv % 2 + 1024) * DS3000_XTAL_FREQ
1104 / (6 + 8) / (div4 + 1) / 2 - p->frequency;
1105
1106 /* ds3000 global reset */
1107 ds3000_writereg(state, 0x07, 0x80);
1108 ds3000_writereg(state, 0x07, 0x00);
1109 /* ds3000 build-in uC reset */
1110 ds3000_writereg(state, 0xb2, 0x01);
1111 /* ds3000 software reset */
1112 ds3000_writereg(state, 0x00, 0x01);
1052 1113
1053 /* discard the 'current' tuning parameters and prepare to tune */ 1114 switch (c->delivery_system) {
1054 ds3000_clone_params(fe); 1115 case SYS_DVBS:
1055 1116 /* initialise the demod in DVB-S mode */
1056 retune = 1; /* try 1 times */ 1117 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
1057 dprintk("%s: retune = %d\n", __func__, retune); 1118 ds3000_writereg(state,
1058 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); 1119 ds3000_dvbs_init_tab[i],
1059 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); 1120 ds3000_dvbs_init_tab[i + 1]);
1060 dprintk("%s: FEC = %d \n", __func__, 1121 value = ds3000_readreg(state, 0xfe);
1061 state->dcur.fec); 1122 value &= 0xc0;
1062 dprintk("%s: Inversion = %d\n", __func__, state->dcur.inversion); 1123 value |= 0x1b;
1063 1124 ds3000_writereg(state, 0xfe, value);
1064 do { 1125 break;
1065 /* Reset status register */ 1126 case SYS_DVBS2:
1066 status = 0; 1127 /* initialise the demod in DVB-S2 mode */
1067 /* Tune */ 1128 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
1068 /* TS2020 init */ 1129 ds3000_writereg(state,
1069 ds3000_tuner_writereg(state, 0x42, 0x73); 1130 ds3000_dvbs2_init_tab[i],
1070 ds3000_tuner_writereg(state, 0x05, 0x01); 1131 ds3000_dvbs2_init_tab[i + 1]);
1071 ds3000_tuner_writereg(state, 0x62, 0xf5); 1132 ds3000_writereg(state, 0xfe, 0x98);
1072 /* unknown */ 1133 break;
1073 ds3000_tuner_writereg(state, 0x07, 0x02); 1134 default:
1074 ds3000_tuner_writereg(state, 0x10, 0x00); 1135 return 1;
1075 ds3000_tuner_writereg(state, 0x60, 0x79); 1136 }
1076 ds3000_tuner_writereg(state, 0x08, 0x01);
1077 ds3000_tuner_writereg(state, 0x00, 0x01);
1078 /* calculate and set freq divider */
1079 if (state->dcur.frequency < 1146000) {
1080 ds3000_tuner_writereg(state, 0x10, 0x11);
1081 ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
1082 (DS3000_XTAL_FREQ / 2)) /
1083 DS3000_XTAL_FREQ - 1024;
1084 } else {
1085 ds3000_tuner_writereg(state, 0x10, 0x01);
1086 ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
1087 (DS3000_XTAL_FREQ / 2)) /
1088 DS3000_XTAL_FREQ - 1024;
1089 }
1090 1137
1091 ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8); 1138 /* enable 27MHz clock output */
1092 ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff); 1139 ds3000_writereg(state, 0x29, 0x80);
1093 1140 /* enable ac coupling */
1094 /* set pll */ 1141 ds3000_writereg(state, 0x25, 0x8a);
1095 ds3000_tuner_writereg(state, 0x03, 0x06); 1142
1096 ds3000_tuner_writereg(state, 0x51, 0x0f); 1143 /* enhance symbol rate performance */
1097 ds3000_tuner_writereg(state, 0x51, 0x1f); 1144 if ((c->symbol_rate / 1000) <= 5000) {
1098 ds3000_tuner_writereg(state, 0x50, 0x10); 1145 value = 29777 / (c->symbol_rate / 1000) + 1;
1099 ds3000_tuner_writereg(state, 0x50, 0x00); 1146 if (value % 2 != 0)
1100 msleep(5); 1147 value++;
1101 1148 ds3000_writereg(state, 0xc3, 0x0d);
1102 /* unknown */ 1149 ds3000_writereg(state, 0xc8, value);
1103 ds3000_tuner_writereg(state, 0x51, 0x17); 1150 ds3000_writereg(state, 0xc4, 0x10);
1104 ds3000_tuner_writereg(state, 0x51, 0x1f); 1151 ds3000_writereg(state, 0xc7, 0x0e);
1105 ds3000_tuner_writereg(state, 0x50, 0x08); 1152 } else if ((c->symbol_rate / 1000) <= 10000) {
1106 ds3000_tuner_writereg(state, 0x50, 0x00); 1153 value = 92166 / (c->symbol_rate / 1000) + 1;
1107 msleep(5); 1154 if (value % 2 != 0)
1108 1155 value++;
1109 value = ds3000_tuner_readreg(state, 0x3d); 1156 ds3000_writereg(state, 0xc3, 0x07);
1110 value &= 0x0f; 1157 ds3000_writereg(state, 0xc8, value);
1111 if ((value > 4) && (value < 15)) { 1158 ds3000_writereg(state, 0xc4, 0x09);
1112 value -= 3; 1159 ds3000_writereg(state, 0xc7, 0x12);
1113 if (value < 4) 1160 } else if ((c->symbol_rate / 1000) <= 20000) {
1114 value = 4; 1161 value = 64516 / (c->symbol_rate / 1000) + 1;
1115 value = ((value << 3) | 0x01) & 0x79; 1162 ds3000_writereg(state, 0xc3, value);
1116 } 1163 ds3000_writereg(state, 0xc8, 0x0e);
1164 ds3000_writereg(state, 0xc4, 0x07);
1165 ds3000_writereg(state, 0xc7, 0x18);
1166 } else {
1167 value = 129032 / (c->symbol_rate / 1000) + 1;
1168 ds3000_writereg(state, 0xc3, value);
1169 ds3000_writereg(state, 0xc8, 0x0a);
1170 ds3000_writereg(state, 0xc4, 0x05);
1171 ds3000_writereg(state, 0xc7, 0x24);
1172 }
1117 1173
1118 ds3000_tuner_writereg(state, 0x60, value); 1174 /* normalized symbol rate rounded to the closest integer */
1119 ds3000_tuner_writereg(state, 0x51, 0x17); 1175 value = (((c->symbol_rate / 1000) << 16) +
1120 ds3000_tuner_writereg(state, 0x51, 0x1f); 1176 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
1121 ds3000_tuner_writereg(state, 0x50, 0x08); 1177 ds3000_writereg(state, 0x61, value & 0x00ff);
1122 ds3000_tuner_writereg(state, 0x50, 0x00); 1178 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
1123
1124 /* set low-pass filter period */
1125 ds3000_tuner_writereg(state, 0x04, 0x2e);
1126 ds3000_tuner_writereg(state, 0x51, 0x1b);
1127 ds3000_tuner_writereg(state, 0x51, 0x1f);
1128 ds3000_tuner_writereg(state, 0x50, 0x04);
1129 ds3000_tuner_writereg(state, 0x50, 0x00);
1130 msleep(5);
1131
1132 f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
1133 if ((state->dcur.symbol_rate / 1000) < 5000)
1134 f3db += 3000;
1135 if (f3db < 7000)
1136 f3db = 7000;
1137 if (f3db > 40000)
1138 f3db = 40000;
1139
1140 /* set low-pass filter baseband */
1141 value = ds3000_tuner_readreg(state, 0x26);
1142 mlpf = 0x2e * 207 / ((value << 1) + 151);
1143 mlpf_max = mlpf * 135 / 100;
1144 mlpf_min = mlpf * 78 / 100;
1145 if (mlpf_max > 63)
1146 mlpf_max = 63;
1147
1148 /* rounded to the closest integer */
1149 nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
1150 / (2766 * DS3000_XTAL_FREQ);
1151 if (nlpf > 23)
1152 nlpf = 23;
1153 if (nlpf < 1)
1154 nlpf = 1;
1155
1156 /* rounded to the closest integer */
1157 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1158 (1000 * f3db / 2)) / (1000 * f3db);
1159 1179
1160 if (mlpf_new < mlpf_min) { 1180 /* co-channel interference cancellation disabled */
1161 nlpf++; 1181 ds3000_writereg(state, 0x56, 0x00);
1162 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) + 1182
1163 (1000 * f3db / 2)) / (1000 * f3db); 1183 /* equalizer disabled */
1164 } 1184 ds3000_writereg(state, 0x76, 0x00);
1165 1185
1166 if (mlpf_new > mlpf_max) 1186 /*ds3000_writereg(state, 0x08, 0x03);
1167 mlpf_new = mlpf_max; 1187 ds3000_writereg(state, 0xfd, 0x22);
1168 1188 ds3000_writereg(state, 0x08, 0x07);
1169 ds3000_tuner_writereg(state, 0x04, mlpf_new); 1189 ds3000_writereg(state, 0xfd, 0x42);
1170 ds3000_tuner_writereg(state, 0x06, nlpf); 1190 ds3000_writereg(state, 0x08, 0x07);*/
1171 ds3000_tuner_writereg(state, 0x51, 0x1b);
1172 ds3000_tuner_writereg(state, 0x51, 0x1f);
1173 ds3000_tuner_writereg(state, 0x50, 0x04);
1174 ds3000_tuner_writereg(state, 0x50, 0x00);
1175 msleep(5);
1176
1177 /* unknown */
1178 ds3000_tuner_writereg(state, 0x51, 0x1e);
1179 ds3000_tuner_writereg(state, 0x51, 0x1f);
1180 ds3000_tuner_writereg(state, 0x50, 0x01);
1181 ds3000_tuner_writereg(state, 0x50, 0x00);
1182 msleep(60);
1183
1184 /* ds3000 global reset */
1185 ds3000_writereg(state, 0x07, 0x80);
1186 ds3000_writereg(state, 0x07, 0x00);
1187 /* ds3000 build-in uC reset */
1188 ds3000_writereg(state, 0xb2, 0x01);
1189 /* ds3000 software reset */
1190 ds3000_writereg(state, 0x00, 0x01);
1191 1191
1192 if (state->config->ci_mode) {
1192 switch (c->delivery_system) { 1193 switch (c->delivery_system) {
1193 case SYS_DVBS: 1194 case SYS_DVBS:
1194 /* initialise the demod in DVB-S mode */ 1195 default:
1195 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2) 1196 ds3000_writereg(state, 0xfd, 0x80);
1196 ds3000_writereg(state, 1197 break;
1197 ds3000_dvbs_init_tab[i],
1198 ds3000_dvbs_init_tab[i + 1]);
1199 value = ds3000_readreg(state, 0xfe);
1200 value &= 0xc0;
1201 value |= 0x1b;
1202 ds3000_writereg(state, 0xfe, value);
1203 break;
1204 case SYS_DVBS2: 1198 case SYS_DVBS2:
1205 /* initialise the demod in DVB-S2 mode */ 1199 ds3000_writereg(state, 0xfd, 0x01);
1206 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
1207 ds3000_writereg(state,
1208 ds3000_dvbs2_init_tab[i],
1209 ds3000_dvbs2_init_tab[i + 1]);
1210 ds3000_writereg(state, 0xfe, 0x54);
1211 break; 1200 break;
1212 default:
1213 return 1;
1214 } 1201 }
1202 }
1215 1203
1216 /* enable 27MHz clock output */ 1204 /* ds3000 out of software reset */
1217 ds3000_writereg(state, 0x29, 0x80); 1205 ds3000_writereg(state, 0x00, 0x00);
1218 /* enable ac coupling */ 1206 /* start ds3000 build-in uC */
1219 ds3000_writereg(state, 0x25, 0x8a); 1207 ds3000_writereg(state, 0xb2, 0x00);
1220
1221 /* enhance symbol rate performance */
1222 if ((state->dcur.symbol_rate / 1000) <= 5000) {
1223 value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
1224 if (value % 2 != 0)
1225 value++;
1226 ds3000_writereg(state, 0xc3, 0x0d);
1227 ds3000_writereg(state, 0xc8, value);
1228 ds3000_writereg(state, 0xc4, 0x10);
1229 ds3000_writereg(state, 0xc7, 0x0e);
1230 } else if ((state->dcur.symbol_rate / 1000) <= 10000) {
1231 value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
1232 if (value % 2 != 0)
1233 value++;
1234 ds3000_writereg(state, 0xc3, 0x07);
1235 ds3000_writereg(state, 0xc8, value);
1236 ds3000_writereg(state, 0xc4, 0x09);
1237 ds3000_writereg(state, 0xc7, 0x12);
1238 } else if ((state->dcur.symbol_rate / 1000) <= 20000) {
1239 value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
1240 ds3000_writereg(state, 0xc3, value);
1241 ds3000_writereg(state, 0xc8, 0x0e);
1242 ds3000_writereg(state, 0xc4, 0x07);
1243 ds3000_writereg(state, 0xc7, 0x18);
1244 } else {
1245 value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
1246 ds3000_writereg(state, 0xc3, value);
1247 ds3000_writereg(state, 0xc8, 0x0a);
1248 ds3000_writereg(state, 0xc4, 0x05);
1249 ds3000_writereg(state, 0xc7, 0x24);
1250 }
1251 1208
1252 /* normalized symbol rate rounded to the closest integer */ 1209 ds3000_set_carrier_offset(fe, offset_khz);
1253 value = (((state->dcur.symbol_rate / 1000) << 16) +
1254 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
1255 ds3000_writereg(state, 0x61, value & 0x00ff);
1256 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
1257
1258 /* co-channel interference cancellation disabled */
1259 ds3000_writereg(state, 0x56, 0x00);
1260
1261 /* equalizer disabled */
1262 ds3000_writereg(state, 0x76, 0x00);
1263
1264 /*ds3000_writereg(state, 0x08, 0x03);
1265 ds3000_writereg(state, 0xfd, 0x22);
1266 ds3000_writereg(state, 0x08, 0x07);
1267 ds3000_writereg(state, 0xfd, 0x42);
1268 ds3000_writereg(state, 0x08, 0x07);*/
1269
1270 /* ds3000 out of software reset */
1271 ds3000_writereg(state, 0x00, 0x00);
1272 /* start ds3000 build-in uC */
1273 ds3000_writereg(state, 0xb2, 0x00);
1274
1275 /* TODO: calculate and set carrier offset */
1276
1277 /* wait before retrying */
1278 for (i = 0; i < 30 ; i++) {
1279 if (ds3000_is_tuned(fe)) {
1280 dprintk("%s: Tuned\n", __func__);
1281 ds3000_dump_registers(fe);
1282 goto tuned;
1283 }
1284 msleep(1);
1285 }
1286 1210
1287 dprintk("%s: Not tuned\n", __func__); 1211 for (i = 0; i < 30 ; i++) {
1288 ds3000_dump_registers(fe); 1212 ds3000_read_status(fe, &status);
1213 if (status && FE_HAS_LOCK)
1214 break;
1289 1215
1290 } while (--retune); 1216 msleep(10);
1217 }
1291 1218
1292tuned: 1219 return 0;
1293 return ret; 1220}
1221
1222static int ds3000_tune(struct dvb_frontend *fe,
1223 struct dvb_frontend_parameters *p,
1224 unsigned int mode_flags,
1225 unsigned int *delay,
1226 fe_status_t *status)
1227{
1228 if (p) {
1229 int ret = ds3000_set_frontend(fe, p);
1230 if (ret)
1231 return ret;
1232 }
1233
1234 *delay = HZ / 5;
1235
1236 return ds3000_read_status(fe, status);
1294} 1237}
1295 1238
1296static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe) 1239static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1297{ 1240{
1298 dprintk("%s()\n", __func__); 1241 dprintk("%s()\n", __func__);
1299 return DVBFE_ALGO_SW; 1242 return DVBFE_ALGO_HW;
1300} 1243}
1301 1244
1302/* 1245/*
@@ -1306,7 +1249,25 @@ static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1306 */ 1249 */
1307static int ds3000_initfe(struct dvb_frontend *fe) 1250static int ds3000_initfe(struct dvb_frontend *fe)
1308{ 1251{
1252 struct ds3000_state *state = fe->demodulator_priv;
1253 int ret;
1254
1309 dprintk("%s()\n", __func__); 1255 dprintk("%s()\n", __func__);
1256 /* hard reset */
1257 ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
1258 msleep(1);
1259
1260 /* TS2020 init */
1261 ds3000_tuner_writereg(state, 0x42, 0x73);
1262 ds3000_tuner_writereg(state, 0x05, 0x01);
1263 ds3000_tuner_writereg(state, 0x62, 0xf5);
1264 /* Load the firmware if required */
1265 ret = ds3000_firmware_ondemand(fe);
1266 if (ret != 0) {
1267 printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
1268 return ret;
1269 }
1270
1310 return 0; 1271 return 0;
1311} 1272}
1312 1273
@@ -1345,6 +1306,7 @@ static struct dvb_frontend_ops ds3000_ops = {
1345 .read_signal_strength = ds3000_read_signal_strength, 1306 .read_signal_strength = ds3000_read_signal_strength,
1346 .read_snr = ds3000_read_snr, 1307 .read_snr = ds3000_read_snr,
1347 .read_ucblocks = ds3000_read_ucblocks, 1308 .read_ucblocks = ds3000_read_ucblocks,
1309 .set_voltage = ds3000_set_voltage,
1348 .set_tone = ds3000_set_tone, 1310 .set_tone = ds3000_set_tone,
1349 .diseqc_send_master_cmd = ds3000_send_diseqc_msg, 1311 .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
1350 .diseqc_send_burst = ds3000_diseqc_send_burst, 1312 .diseqc_send_burst = ds3000_diseqc_send_burst,
@@ -1352,7 +1314,8 @@ static struct dvb_frontend_ops ds3000_ops = {
1352 1314
1353 .set_property = ds3000_set_property, 1315 .set_property = ds3000_set_property,
1354 .get_property = ds3000_get_property, 1316 .get_property = ds3000_get_property,
1355 .set_frontend = ds3000_tune, 1317 .set_frontend = ds3000_set_frontend,
1318 .tune = ds3000_tune,
1356}; 1319};
1357 1320
1358module_param(debug, int, 0644); 1321module_param(debug, int, 0644);
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h
index 67f67038740a..1b736888ea37 100644
--- a/drivers/media/dvb/frontends/ds3000.h
+++ b/drivers/media/dvb/frontends/ds3000.h
@@ -27,6 +27,9 @@
27struct ds3000_config { 27struct ds3000_config {
28 /* the demodulator's i2c address */ 28 /* the demodulator's i2c address */
29 u8 demod_address; 29 u8 demod_address;
30 u8 ci_mode;
31 /* Set device param to start dma */
32 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
30}; 33};
31 34
32#if defined(CONFIG_DVB_DS3000) || \ 35#if defined(CONFIG_DVB_DS3000) || \
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 4d4d0bb5920a..62a65efdf8d6 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -64,6 +64,7 @@ struct dvb_pll_desc {
64 void (*set)(struct dvb_frontend *fe, u8 *buf, 64 void (*set)(struct dvb_frontend *fe, u8 *buf,
65 const struct dvb_frontend_parameters *params); 65 const struct dvb_frontend_parameters *params);
66 u8 *initdata; 66 u8 *initdata;
67 u8 *initdata2;
67 u8 *sleepdata; 68 u8 *sleepdata;
68 int count; 69 int count;
69 struct { 70 struct {
@@ -321,26 +322,73 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
321static void opera1_bw(struct dvb_frontend *fe, u8 *buf, 322static void opera1_bw(struct dvb_frontend *fe, u8 *buf,
322 const struct dvb_frontend_parameters *params) 323 const struct dvb_frontend_parameters *params)
323{ 324{
324 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) 325 struct dvb_pll_priv *priv = fe->tuner_priv;
325 buf[2] |= 0x08; 326 u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000;
327 struct i2c_msg msg = {
328 .addr = priv->pll_i2c_address,
329 .flags = 0,
330 .buf = buf,
331 .len = 4
332 };
333 int result;
334 u8 lpf;
335
336 if (fe->ops.i2c_gate_ctrl)
337 fe->ops.i2c_gate_ctrl(fe, 1);
338
339 result = i2c_transfer(priv->i2c, &msg, 1);
340 if (result != 1)
341 printk(KERN_ERR "%s: i2c_transfer failed:%d",
342 __func__, result);
343
344 if (b_w <= 10000)
345 lpf = 0xc;
346 else if (b_w <= 12000)
347 lpf = 0x2;
348 else if (b_w <= 14000)
349 lpf = 0xa;
350 else if (b_w <= 16000)
351 lpf = 0x6;
352 else if (b_w <= 18000)
353 lpf = 0xe;
354 else if (b_w <= 20000)
355 lpf = 0x1;
356 else if (b_w <= 22000)
357 lpf = 0x9;
358 else if (b_w <= 24000)
359 lpf = 0x5;
360 else if (b_w <= 26000)
361 lpf = 0xd;
362 else if (b_w <= 28000)
363 lpf = 0x3;
364 else
365 lpf = 0xb;
366 buf[2] ^= 0x1c; /* Flip bits 3-5 */
367 /* Set lpf */
368 buf[2] |= ((lpf >> 2) & 0x3) << 3;
369 buf[3] |= (lpf & 0x3) << 2;
370
371 return;
326} 372}
327 373
328static struct dvb_pll_desc dvb_pll_opera1 = { 374static struct dvb_pll_desc dvb_pll_opera1 = {
329 .name = "Opera Tuner", 375 .name = "Opera Tuner",
330 .min = 900000, 376 .min = 900000,
331 .max = 2250000, 377 .max = 2250000,
378 .initdata = (u8[]){ 4, 0x08, 0xe5, 0xe1, 0x00 },
379 .initdata2 = (u8[]){ 4, 0x08, 0xe5, 0xe5, 0x00 },
332 .iffreq= 0, 380 .iffreq= 0,
333 .set = opera1_bw, 381 .set = opera1_bw,
334 .count = 8, 382 .count = 8,
335 .entries = { 383 .entries = {
336 { 1064000, 500, 0xe5, 0xc6 }, 384 { 1064000, 500, 0xf9, 0xc2 },
337 { 1169000, 500, 0xe5, 0xe6 }, 385 { 1169000, 500, 0xf9, 0xe2 },
338 { 1299000, 500, 0xe5, 0x24 }, 386 { 1299000, 500, 0xf9, 0x20 },
339 { 1444000, 500, 0xe5, 0x44 }, 387 { 1444000, 500, 0xf9, 0x40 },
340 { 1606000, 500, 0xe5, 0x64 }, 388 { 1606000, 500, 0xf9, 0x60 },
341 { 1777000, 500, 0xe5, 0x84 }, 389 { 1777000, 500, 0xf9, 0x80 },
342 { 1941000, 500, 0xe5, 0xa4 }, 390 { 1941000, 500, 0xf9, 0xa0 },
343 { 2250000, 500, 0xe5, 0xc4 }, 391 { 2250000, 500, 0xf9, 0xc0 },
344 } 392 }
345}; 393};
346 394
@@ -648,8 +696,17 @@ static int dvb_pll_init(struct dvb_frontend *fe)
648 int result; 696 int result;
649 if (fe->ops.i2c_gate_ctrl) 697 if (fe->ops.i2c_gate_ctrl)
650 fe->ops.i2c_gate_ctrl(fe, 1); 698 fe->ops.i2c_gate_ctrl(fe, 1);
651 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { 699 result = i2c_transfer(priv->i2c, &msg, 1);
700 if (result != 1)
652 return result; 701 return result;
702 if (priv->pll_desc->initdata2) {
703 msg.buf = priv->pll_desc->initdata2 + 1;
704 msg.len = priv->pll_desc->initdata2[0];
705 if (fe->ops.i2c_gate_ctrl)
706 fe->ops.i2c_gate_ctrl(fe, 1);
707 result = i2c_transfer(priv->i2c, &msg, 1);
708 if (result != 1)
709 return result;
653 } 710 }
654 return 0; 711 return 0;
655 } 712 }
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
index 63db8fd2754c..e3fe17fd96fb 100644
--- a/drivers/media/dvb/frontends/stv0288.c
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -367,8 +367,11 @@ static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
367 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); 367 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
368 368
369 *status = 0; 369 *status = 0;
370 370 if (sync & 0x80)
371 if ((sync & 0x08) == 0x08) { 371 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
372 if (sync & 0x10)
373 *status |= FE_HAS_VITERBI;
374 if (sync & 0x08) {
372 *status |= FE_HAS_LOCK; 375 *status |= FE_HAS_LOCK;
373 dprintk("stv0288 has locked\n"); 376 dprintk("stv0288 has locked\n");
374 } 377 }
diff --git a/drivers/media/dvb/frontends/stv0367.c b/drivers/media/dvb/frontends/stv0367.c
new file mode 100644
index 000000000000..4e0e6a873b8c
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367.c
@@ -0,0 +1,3459 @@
1/*
2 * stv0367.c
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30#include <linux/i2c.h>
31
32#include "stv0367.h"
33#include "stv0367_regs.h"
34#include "stv0367_priv.h"
35
36static int stvdebug;
37module_param_named(debug, stvdebug, int, 0644);
38
39static int i2cdebug;
40module_param_named(i2c_debug, i2cdebug, int, 0644);
41
42#define dprintk(args...) \
43 do { \
44 if (stvdebug) \
45 printk(KERN_DEBUG args); \
46 } while (0)
47 /* DVB-C */
48
49struct stv0367cab_state {
50 enum stv0367_cab_signal_type state;
51 u32 mclk;
52 u32 adc_clk;
53 s32 search_range;
54 s32 derot_offset;
55 /* results */
56 int locked; /* channel found */
57 u32 freq_khz; /* found frequency (in kHz) */
58 u32 symbol_rate; /* found symbol rate (in Bds) */
59 enum stv0367cab_mod modulation; /* modulation */
60 fe_spectral_inversion_t spect_inv; /* Spectrum Inversion */
61};
62
63struct stv0367ter_state {
64 /* DVB-T */
65 enum stv0367_ter_signal_type state;
66 enum stv0367_ter_if_iq_mode if_iq_mode;
67 enum stv0367_ter_mode mode;/* mode 2K or 8K */
68 fe_guard_interval_t guard;
69 enum stv0367_ter_hierarchy hierarchy;
70 u32 frequency;
71 fe_spectral_inversion_t sense; /* current search spectrum */
72 u8 force; /* force mode/guard */
73 u8 bw; /* channel width 6, 7 or 8 in MHz */
74 u8 pBW; /* channel width used during previous lock */
75 u32 pBER;
76 u32 pPER;
77 u32 ucblocks;
78 s8 echo_pos; /* echo position */
79 u8 first_lock;
80 u8 unlock_counter;
81 u32 agc_val;
82};
83
84struct stv0367_state {
85 struct dvb_frontend fe;
86 struct i2c_adapter *i2c;
87 /* config settings */
88 const struct stv0367_config *config;
89 u8 chip_id;
90 /* DVB-C */
91 struct stv0367cab_state *cab_state;
92 /* DVB-T */
93 struct stv0367ter_state *ter_state;
94};
95
96struct st_register {
97 u16 addr;
98 u8 value;
99};
100
101/* values for STV4100 XTAL=30M int clk=53.125M*/
102static struct st_register def0367ter[STV0367TER_NBREGS] = {
103 {R367TER_ID, 0x60},
104 {R367TER_I2CRPT, 0xa0},
105 /* {R367TER_I2CRPT, 0x22},*/
106 {R367TER_TOPCTRL, 0x00},/* for xc5000; was 0x02 */
107 {R367TER_IOCFG0, 0x40},
108 {R367TER_DAC0R, 0x00},
109 {R367TER_IOCFG1, 0x00},
110 {R367TER_DAC1R, 0x00},
111 {R367TER_IOCFG2, 0x62},
112 {R367TER_SDFR, 0x00},
113 {R367TER_STATUS, 0xf8},
114 {R367TER_AUX_CLK, 0x0a},
115 {R367TER_FREESYS1, 0x00},
116 {R367TER_FREESYS2, 0x00},
117 {R367TER_FREESYS3, 0x00},
118 {R367TER_GPIO_CFG, 0x55},
119 {R367TER_GPIO_CMD, 0x00},
120 {R367TER_AGC2MAX, 0xff},
121 {R367TER_AGC2MIN, 0x00},
122 {R367TER_AGC1MAX, 0xff},
123 {R367TER_AGC1MIN, 0x00},
124 {R367TER_AGCR, 0xbc},
125 {R367TER_AGC2TH, 0x00},
126 {R367TER_AGC12C, 0x00},
127 {R367TER_AGCCTRL1, 0x85},
128 {R367TER_AGCCTRL2, 0x1f},
129 {R367TER_AGC1VAL1, 0x00},
130 {R367TER_AGC1VAL2, 0x00},
131 {R367TER_AGC2VAL1, 0x6f},
132 {R367TER_AGC2VAL2, 0x05},
133 {R367TER_AGC2PGA, 0x00},
134 {R367TER_OVF_RATE1, 0x00},
135 {R367TER_OVF_RATE2, 0x00},
136 {R367TER_GAIN_SRC1, 0xaa},/* for xc5000; was 0x2b */
137 {R367TER_GAIN_SRC2, 0xd6},/* for xc5000; was 0x04 */
138 {R367TER_INC_DEROT1, 0x55},
139 {R367TER_INC_DEROT2, 0x55},
140 {R367TER_PPM_CPAMP_DIR, 0x2c},
141 {R367TER_PPM_CPAMP_INV, 0x00},
142 {R367TER_FREESTFE_1, 0x00},
143 {R367TER_FREESTFE_2, 0x1c},
144 {R367TER_DCOFFSET, 0x00},
145 {R367TER_EN_PROCESS, 0x05},
146 {R367TER_SDI_SMOOTHER, 0x80},
147 {R367TER_FE_LOOP_OPEN, 0x1c},
148 {R367TER_FREQOFF1, 0x00},
149 {R367TER_FREQOFF2, 0x00},
150 {R367TER_FREQOFF3, 0x00},
151 {R367TER_TIMOFF1, 0x00},
152 {R367TER_TIMOFF2, 0x00},
153 {R367TER_EPQ, 0x02},
154 {R367TER_EPQAUTO, 0x01},
155 {R367TER_SYR_UPDATE, 0xf5},
156 {R367TER_CHPFREE, 0x00},
157 {R367TER_PPM_STATE_MAC, 0x23},
158 {R367TER_INR_THRESHOLD, 0xff},
159 {R367TER_EPQ_TPS_ID_CELL, 0xf9},
160 {R367TER_EPQ_CFG, 0x00},
161 {R367TER_EPQ_STATUS, 0x01},
162 {R367TER_AUTORELOCK, 0x81},
163 {R367TER_BER_THR_VMSB, 0x00},
164 {R367TER_BER_THR_MSB, 0x00},
165 {R367TER_BER_THR_LSB, 0x00},
166 {R367TER_CCD, 0x83},
167 {R367TER_SPECTR_CFG, 0x00},
168 {R367TER_CHC_DUMMY, 0x18},
169 {R367TER_INC_CTL, 0x88},
170 {R367TER_INCTHRES_COR1, 0xb4},
171 {R367TER_INCTHRES_COR2, 0x96},
172 {R367TER_INCTHRES_DET1, 0x0e},
173 {R367TER_INCTHRES_DET2, 0x11},
174 {R367TER_IIR_CELLNB, 0x8d},
175 {R367TER_IIRCX_COEFF1_MSB, 0x00},
176 {R367TER_IIRCX_COEFF1_LSB, 0x00},
177 {R367TER_IIRCX_COEFF2_MSB, 0x09},
178 {R367TER_IIRCX_COEFF2_LSB, 0x18},
179 {R367TER_IIRCX_COEFF3_MSB, 0x14},
180 {R367TER_IIRCX_COEFF3_LSB, 0x9c},
181 {R367TER_IIRCX_COEFF4_MSB, 0x00},
182 {R367TER_IIRCX_COEFF4_LSB, 0x00},
183 {R367TER_IIRCX_COEFF5_MSB, 0x36},
184 {R367TER_IIRCX_COEFF5_LSB, 0x42},
185 {R367TER_FEPATH_CFG, 0x00},
186 {R367TER_PMC1_FUNC, 0x65},
187 {R367TER_PMC1_FOR, 0x00},
188 {R367TER_PMC2_FUNC, 0x00},
189 {R367TER_STATUS_ERR_DA, 0xe0},
190 {R367TER_DIG_AGC_R, 0xfe},
191 {R367TER_COMAGC_TARMSB, 0x0b},
192 {R367TER_COM_AGC_TAR_ENMODE, 0x41},
193 {R367TER_COM_AGC_CFG, 0x3e},
194 {R367TER_COM_AGC_GAIN1, 0x39},
195 {R367TER_AUT_AGC_TARGETMSB, 0x0b},
196 {R367TER_LOCK_DET_MSB, 0x01},
197 {R367TER_AGCTAR_LOCK_LSBS, 0x40},
198 {R367TER_AUT_GAIN_EN, 0xf4},
199 {R367TER_AUT_CFG, 0xf0},
200 {R367TER_LOCKN, 0x23},
201 {R367TER_INT_X_3, 0x00},
202 {R367TER_INT_X_2, 0x03},
203 {R367TER_INT_X_1, 0x8d},
204 {R367TER_INT_X_0, 0xa0},
205 {R367TER_MIN_ERRX_MSB, 0x00},
206 {R367TER_COR_CTL, 0x23},
207 {R367TER_COR_STAT, 0xf6},
208 {R367TER_COR_INTEN, 0x00},
209 {R367TER_COR_INTSTAT, 0x3f},
210 {R367TER_COR_MODEGUARD, 0x03},
211 {R367TER_AGC_CTL, 0x08},
212 {R367TER_AGC_MANUAL1, 0x00},
213 {R367TER_AGC_MANUAL2, 0x00},
214 {R367TER_AGC_TARG, 0x16},
215 {R367TER_AGC_GAIN1, 0x53},
216 {R367TER_AGC_GAIN2, 0x1d},
217 {R367TER_RESERVED_1, 0x00},
218 {R367TER_RESERVED_2, 0x00},
219 {R367TER_RESERVED_3, 0x00},
220 {R367TER_CAS_CTL, 0x44},
221 {R367TER_CAS_FREQ, 0xb3},
222 {R367TER_CAS_DAGCGAIN, 0x12},
223 {R367TER_SYR_CTL, 0x04},
224 {R367TER_SYR_STAT, 0x10},
225 {R367TER_SYR_NCO1, 0x00},
226 {R367TER_SYR_NCO2, 0x00},
227 {R367TER_SYR_OFFSET1, 0x00},
228 {R367TER_SYR_OFFSET2, 0x00},
229 {R367TER_FFT_CTL, 0x00},
230 {R367TER_SCR_CTL, 0x70},
231 {R367TER_PPM_CTL1, 0xf8},
232 {R367TER_TRL_CTL, 0x14},/* for xc5000; was 0xac */
233 {R367TER_TRL_NOMRATE1, 0xae},/* for xc5000; was 0x1e */
234 {R367TER_TRL_NOMRATE2, 0x56},/* for xc5000; was 0x58 */
235 {R367TER_TRL_TIME1, 0x1d},
236 {R367TER_TRL_TIME2, 0xfc},
237 {R367TER_CRL_CTL, 0x24},
238 {R367TER_CRL_FREQ1, 0xad},
239 {R367TER_CRL_FREQ2, 0x9d},
240 {R367TER_CRL_FREQ3, 0xff},
241 {R367TER_CHC_CTL, 0x01},
242 {R367TER_CHC_SNR, 0xf0},
243 {R367TER_BDI_CTL, 0x00},
244 {R367TER_DMP_CTL, 0x00},
245 {R367TER_TPS_RCVD1, 0x30},
246 {R367TER_TPS_RCVD2, 0x02},
247 {R367TER_TPS_RCVD3, 0x01},
248 {R367TER_TPS_RCVD4, 0x00},
249 {R367TER_TPS_ID_CELL1, 0x00},
250 {R367TER_TPS_ID_CELL2, 0x00},
251 {R367TER_TPS_RCVD5_SET1, 0x02},
252 {R367TER_TPS_SET2, 0x02},
253 {R367TER_TPS_SET3, 0x01},
254 {R367TER_TPS_CTL, 0x00},
255 {R367TER_CTL_FFTOSNUM, 0x34},
256 {R367TER_TESTSELECT, 0x09},
257 {R367TER_MSC_REV, 0x0a},
258 {R367TER_PIR_CTL, 0x00},
259 {R367TER_SNR_CARRIER1, 0xa1},
260 {R367TER_SNR_CARRIER2, 0x9a},
261 {R367TER_PPM_CPAMP, 0x2c},
262 {R367TER_TSM_AP0, 0x00},
263 {R367TER_TSM_AP1, 0x00},
264 {R367TER_TSM_AP2 , 0x00},
265 {R367TER_TSM_AP3, 0x00},
266 {R367TER_TSM_AP4, 0x00},
267 {R367TER_TSM_AP5, 0x00},
268 {R367TER_TSM_AP6, 0x00},
269 {R367TER_TSM_AP7, 0x00},
270 {R367TER_TSTRES, 0x00},
271 {R367TER_ANACTRL, 0x0D},/* PLL stoped, restart at init!!! */
272 {R367TER_TSTBUS, 0x00},
273 {R367TER_TSTRATE, 0x00},
274 {R367TER_CONSTMODE, 0x01},
275 {R367TER_CONSTCARR1, 0x00},
276 {R367TER_CONSTCARR2, 0x00},
277 {R367TER_ICONSTEL, 0x0a},
278 {R367TER_QCONSTEL, 0x15},
279 {R367TER_TSTBISTRES0, 0x00},
280 {R367TER_TSTBISTRES1, 0x00},
281 {R367TER_TSTBISTRES2, 0x28},
282 {R367TER_TSTBISTRES3, 0x00},
283 {R367TER_RF_AGC1, 0xff},
284 {R367TER_RF_AGC2, 0x83},
285 {R367TER_ANADIGCTRL, 0x19},
286 {R367TER_PLLMDIV, 0x01},/* for xc5000; was 0x0c */
287 {R367TER_PLLNDIV, 0x06},/* for xc5000; was 0x55 */
288 {R367TER_PLLSETUP, 0x18},
289 {R367TER_DUAL_AD12, 0x0C},/* for xc5000 AGC voltage 1.6V */
290 {R367TER_TSTBIST, 0x00},
291 {R367TER_PAD_COMP_CTRL, 0x00},
292 {R367TER_PAD_COMP_WR, 0x00},
293 {R367TER_PAD_COMP_RD, 0xe0},
294 {R367TER_SYR_TARGET_FFTADJT_MSB, 0x00},
295 {R367TER_SYR_TARGET_FFTADJT_LSB, 0x00},
296 {R367TER_SYR_TARGET_CHCADJT_MSB, 0x00},
297 {R367TER_SYR_TARGET_CHCADJT_LSB, 0x00},
298 {R367TER_SYR_FLAG, 0x00},
299 {R367TER_CRL_TARGET1, 0x00},
300 {R367TER_CRL_TARGET2, 0x00},
301 {R367TER_CRL_TARGET3, 0x00},
302 {R367TER_CRL_TARGET4, 0x00},
303 {R367TER_CRL_FLAG, 0x00},
304 {R367TER_TRL_TARGET1, 0x00},
305 {R367TER_TRL_TARGET2, 0x00},
306 {R367TER_TRL_CHC, 0x00},
307 {R367TER_CHC_SNR_TARG, 0x00},
308 {R367TER_TOP_TRACK, 0x00},
309 {R367TER_TRACKER_FREE1, 0x00},
310 {R367TER_ERROR_CRL1, 0x00},
311 {R367TER_ERROR_CRL2, 0x00},
312 {R367TER_ERROR_CRL3, 0x00},
313 {R367TER_ERROR_CRL4, 0x00},
314 {R367TER_DEC_NCO1, 0x2c},
315 {R367TER_DEC_NCO2, 0x0f},
316 {R367TER_DEC_NCO3, 0x20},
317 {R367TER_SNR, 0xf1},
318 {R367TER_SYR_FFTADJ1, 0x00},
319 {R367TER_SYR_FFTADJ2, 0x00},
320 {R367TER_SYR_CHCADJ1, 0x00},
321 {R367TER_SYR_CHCADJ2, 0x00},
322 {R367TER_SYR_OFF, 0x00},
323 {R367TER_PPM_OFFSET1, 0x00},
324 {R367TER_PPM_OFFSET2, 0x03},
325 {R367TER_TRACKER_FREE2, 0x00},
326 {R367TER_DEBG_LT10, 0x00},
327 {R367TER_DEBG_LT11, 0x00},
328 {R367TER_DEBG_LT12, 0x00},
329 {R367TER_DEBG_LT13, 0x00},
330 {R367TER_DEBG_LT14, 0x00},
331 {R367TER_DEBG_LT15, 0x00},
332 {R367TER_DEBG_LT16, 0x00},
333 {R367TER_DEBG_LT17, 0x00},
334 {R367TER_DEBG_LT18, 0x00},
335 {R367TER_DEBG_LT19, 0x00},
336 {R367TER_DEBG_LT1A, 0x00},
337 {R367TER_DEBG_LT1B, 0x00},
338 {R367TER_DEBG_LT1C, 0x00},
339 {R367TER_DEBG_LT1D, 0x00},
340 {R367TER_DEBG_LT1E, 0x00},
341 {R367TER_DEBG_LT1F, 0x00},
342 {R367TER_RCCFGH, 0x00},
343 {R367TER_RCCFGM, 0x00},
344 {R367TER_RCCFGL, 0x00},
345 {R367TER_RCINSDELH, 0x00},
346 {R367TER_RCINSDELM, 0x00},
347 {R367TER_RCINSDELL, 0x00},
348 {R367TER_RCSTATUS, 0x00},
349 {R367TER_RCSPEED, 0x6f},
350 {R367TER_RCDEBUGM, 0xe7},
351 {R367TER_RCDEBUGL, 0x9b},
352 {R367TER_RCOBSCFG, 0x00},
353 {R367TER_RCOBSM, 0x00},
354 {R367TER_RCOBSL, 0x00},
355 {R367TER_RCFECSPY, 0x00},
356 {R367TER_RCFSPYCFG, 0x00},
357 {R367TER_RCFSPYDATA, 0x00},
358 {R367TER_RCFSPYOUT, 0x00},
359 {R367TER_RCFSTATUS, 0x00},
360 {R367TER_RCFGOODPACK, 0x00},
361 {R367TER_RCFPACKCNT, 0x00},
362 {R367TER_RCFSPYMISC, 0x00},
363 {R367TER_RCFBERCPT4, 0x00},
364 {R367TER_RCFBERCPT3, 0x00},
365 {R367TER_RCFBERCPT2, 0x00},
366 {R367TER_RCFBERCPT1, 0x00},
367 {R367TER_RCFBERCPT0, 0x00},
368 {R367TER_RCFBERERR2, 0x00},
369 {R367TER_RCFBERERR1, 0x00},
370 {R367TER_RCFBERERR0, 0x00},
371 {R367TER_RCFSTATESM, 0x00},
372 {R367TER_RCFSTATESL, 0x00},
373 {R367TER_RCFSPYBER, 0x00},
374 {R367TER_RCFSPYDISTM, 0x00},
375 {R367TER_RCFSPYDISTL, 0x00},
376 {R367TER_RCFSPYOBS7, 0x00},
377 {R367TER_RCFSPYOBS6, 0x00},
378 {R367TER_RCFSPYOBS5, 0x00},
379 {R367TER_RCFSPYOBS4, 0x00},
380 {R367TER_RCFSPYOBS3, 0x00},
381 {R367TER_RCFSPYOBS2, 0x00},
382 {R367TER_RCFSPYOBS1, 0x00},
383 {R367TER_RCFSPYOBS0, 0x00},
384 {R367TER_TSGENERAL, 0x00},
385 {R367TER_RC1SPEED, 0x6f},
386 {R367TER_TSGSTATUS, 0x18},
387 {R367TER_FECM, 0x01},
388 {R367TER_VTH12, 0xff},
389 {R367TER_VTH23, 0xa1},
390 {R367TER_VTH34, 0x64},
391 {R367TER_VTH56, 0x40},
392 {R367TER_VTH67, 0x00},
393 {R367TER_VTH78, 0x2c},
394 {R367TER_VITCURPUN, 0x12},
395 {R367TER_VERROR, 0x01},
396 {R367TER_PRVIT, 0x3f},
397 {R367TER_VAVSRVIT, 0x00},
398 {R367TER_VSTATUSVIT, 0xbd},
399 {R367TER_VTHINUSE, 0xa1},
400 {R367TER_KDIV12, 0x20},
401 {R367TER_KDIV23, 0x40},
402 {R367TER_KDIV34, 0x20},
403 {R367TER_KDIV56, 0x30},
404 {R367TER_KDIV67, 0x00},
405 {R367TER_KDIV78, 0x30},
406 {R367TER_SIGPOWER, 0x54},
407 {R367TER_DEMAPVIT, 0x40},
408 {R367TER_VITSCALE, 0x00},
409 {R367TER_FFEC1PRG, 0x00},
410 {R367TER_FVITCURPUN, 0x12},
411 {R367TER_FVERROR, 0x01},
412 {R367TER_FVSTATUSVIT, 0xbd},
413 {R367TER_DEBUG_LT1, 0x00},
414 {R367TER_DEBUG_LT2, 0x00},
415 {R367TER_DEBUG_LT3, 0x00},
416 {R367TER_TSTSFMET, 0x00},
417 {R367TER_SELOUT, 0x00},
418 {R367TER_TSYNC, 0x00},
419 {R367TER_TSTERR, 0x00},
420 {R367TER_TSFSYNC, 0x00},
421 {R367TER_TSTSFERR, 0x00},
422 {R367TER_TSTTSSF1, 0x01},
423 {R367TER_TSTTSSF2, 0x1f},
424 {R367TER_TSTTSSF3, 0x00},
425 {R367TER_TSTTS1, 0x00},
426 {R367TER_TSTTS2, 0x1f},
427 {R367TER_TSTTS3, 0x01},
428 {R367TER_TSTTS4, 0x00},
429 {R367TER_TSTTSRC, 0x00},
430 {R367TER_TSTTSRS, 0x00},
431 {R367TER_TSSTATEM, 0xb0},
432 {R367TER_TSSTATEL, 0x40},
433 {R367TER_TSCFGH, 0xC0},
434 {R367TER_TSCFGM, 0xc0},/* for xc5000; was 0x00 */
435 {R367TER_TSCFGL, 0x20},
436 {R367TER_TSSYNC, 0x00},
437 {R367TER_TSINSDELH, 0x00},
438 {R367TER_TSINSDELM, 0x00},
439 {R367TER_TSINSDELL, 0x00},
440 {R367TER_TSDIVN, 0x03},
441 {R367TER_TSDIVPM, 0x00},
442 {R367TER_TSDIVPL, 0x00},
443 {R367TER_TSDIVQM, 0x00},
444 {R367TER_TSDIVQL, 0x00},
445 {R367TER_TSDILSTKM, 0x00},
446 {R367TER_TSDILSTKL, 0x00},
447 {R367TER_TSSPEED, 0x40},/* for xc5000; was 0x6f */
448 {R367TER_TSSTATUS, 0x81},
449 {R367TER_TSSTATUS2, 0x6a},
450 {R367TER_TSBITRATEM, 0x0f},
451 {R367TER_TSBITRATEL, 0xc6},
452 {R367TER_TSPACKLENM, 0x00},
453 {R367TER_TSPACKLENL, 0xfc},
454 {R367TER_TSBLOCLENM, 0x0a},
455 {R367TER_TSBLOCLENL, 0x80},
456 {R367TER_TSDLYH, 0x90},
457 {R367TER_TSDLYM, 0x68},
458 {R367TER_TSDLYL, 0x01},
459 {R367TER_TSNPDAV, 0x00},
460 {R367TER_TSBUFSTATH, 0x00},
461 {R367TER_TSBUFSTATM, 0x00},
462 {R367TER_TSBUFSTATL, 0x00},
463 {R367TER_TSDEBUGM, 0xcf},
464 {R367TER_TSDEBUGL, 0x1e},
465 {R367TER_TSDLYSETH, 0x00},
466 {R367TER_TSDLYSETM, 0x68},
467 {R367TER_TSDLYSETL, 0x00},
468 {R367TER_TSOBSCFG, 0x00},
469 {R367TER_TSOBSM, 0x47},
470 {R367TER_TSOBSL, 0x1f},
471 {R367TER_ERRCTRL1, 0x95},
472 {R367TER_ERRCNT1H, 0x80},
473 {R367TER_ERRCNT1M, 0x00},
474 {R367TER_ERRCNT1L, 0x00},
475 {R367TER_ERRCTRL2, 0x95},
476 {R367TER_ERRCNT2H, 0x00},
477 {R367TER_ERRCNT2M, 0x00},
478 {R367TER_ERRCNT2L, 0x00},
479 {R367TER_FECSPY, 0x88},
480 {R367TER_FSPYCFG, 0x2c},
481 {R367TER_FSPYDATA, 0x3a},
482 {R367TER_FSPYOUT, 0x06},
483 {R367TER_FSTATUS, 0x61},
484 {R367TER_FGOODPACK, 0xff},
485 {R367TER_FPACKCNT, 0xff},
486 {R367TER_FSPYMISC, 0x66},
487 {R367TER_FBERCPT4, 0x00},
488 {R367TER_FBERCPT3, 0x00},
489 {R367TER_FBERCPT2, 0x36},
490 {R367TER_FBERCPT1, 0x36},
491 {R367TER_FBERCPT0, 0x14},
492 {R367TER_FBERERR2, 0x00},
493 {R367TER_FBERERR1, 0x03},
494 {R367TER_FBERERR0, 0x28},
495 {R367TER_FSTATESM, 0x00},
496 {R367TER_FSTATESL, 0x02},
497 {R367TER_FSPYBER, 0x00},
498 {R367TER_FSPYDISTM, 0x01},
499 {R367TER_FSPYDISTL, 0x9f},
500 {R367TER_FSPYOBS7, 0xc9},
501 {R367TER_FSPYOBS6, 0x99},
502 {R367TER_FSPYOBS5, 0x08},
503 {R367TER_FSPYOBS4, 0xec},
504 {R367TER_FSPYOBS3, 0x01},
505 {R367TER_FSPYOBS2, 0x0f},
506 {R367TER_FSPYOBS1, 0xf5},
507 {R367TER_FSPYOBS0, 0x08},
508 {R367TER_SFDEMAP, 0x40},
509 {R367TER_SFERROR, 0x00},
510 {R367TER_SFAVSR, 0x30},
511 {R367TER_SFECSTATUS, 0xcc},
512 {R367TER_SFKDIV12, 0x20},
513 {R367TER_SFKDIV23, 0x40},
514 {R367TER_SFKDIV34, 0x20},
515 {R367TER_SFKDIV56, 0x20},
516 {R367TER_SFKDIV67, 0x00},
517 {R367TER_SFKDIV78, 0x20},
518 {R367TER_SFDILSTKM, 0x00},
519 {R367TER_SFDILSTKL, 0x00},
520 {R367TER_SFSTATUS, 0xb5},
521 {R367TER_SFDLYH, 0x90},
522 {R367TER_SFDLYM, 0x60},
523 {R367TER_SFDLYL, 0x01},
524 {R367TER_SFDLYSETH, 0xc0},
525 {R367TER_SFDLYSETM, 0x60},
526 {R367TER_SFDLYSETL, 0x00},
527 {R367TER_SFOBSCFG, 0x00},
528 {R367TER_SFOBSM, 0x47},
529 {R367TER_SFOBSL, 0x05},
530 {R367TER_SFECINFO, 0x40},
531 {R367TER_SFERRCTRL, 0x74},
532 {R367TER_SFERRCNTH, 0x80},
533 {R367TER_SFERRCNTM , 0x00},
534 {R367TER_SFERRCNTL, 0x00},
535 {R367TER_SYMBRATEM, 0x2f},
536 {R367TER_SYMBRATEL, 0x50},
537 {R367TER_SYMBSTATUS, 0x7f},
538 {R367TER_SYMBCFG, 0x00},
539 {R367TER_SYMBFIFOM, 0xf4},
540 {R367TER_SYMBFIFOL, 0x0d},
541 {R367TER_SYMBOFFSM, 0xf0},
542 {R367TER_SYMBOFFSL, 0x2d},
543 {R367TER_DEBUG_LT4, 0x00},
544 {R367TER_DEBUG_LT5, 0x00},
545 {R367TER_DEBUG_LT6, 0x00},
546 {R367TER_DEBUG_LT7, 0x00},
547 {R367TER_DEBUG_LT8, 0x00},
548 {R367TER_DEBUG_LT9, 0x00},
549};
550
551#define RF_LOOKUP_TABLE_SIZE 31
552#define RF_LOOKUP_TABLE2_SIZE 16
553/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
554s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
555 {/*AGC1*/
556 48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
557 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
558 76, 77, 78, 80, 83, 85, 88,
559 }, {/*RF(dbm)*/
560 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
561 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47,
562 49, 50, 52, 53, 54, 55, 56,
563 }
564};
565/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
566s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
567 {/*AGC2*/
568 28, 29, 31, 32, 34, 35, 36, 37,
569 38, 39, 40, 41, 42, 43, 44, 45,
570 }, {/*RF(dbm)*/
571 57, 58, 59, 60, 61, 62, 63, 64,
572 65, 66, 67, 68, 69, 70, 71, 72,
573 }
574};
575
576static struct st_register def0367cab[STV0367CAB_NBREGS] = {
577 {R367CAB_ID, 0x60},
578 {R367CAB_I2CRPT, 0xa0},
579 /*{R367CAB_I2CRPT, 0x22},*/
580 {R367CAB_TOPCTRL, 0x10},
581 {R367CAB_IOCFG0, 0x80},
582 {R367CAB_DAC0R, 0x00},
583 {R367CAB_IOCFG1, 0x00},
584 {R367CAB_DAC1R, 0x00},
585 {R367CAB_IOCFG2, 0x00},
586 {R367CAB_SDFR, 0x00},
587 {R367CAB_AUX_CLK, 0x00},
588 {R367CAB_FREESYS1, 0x00},
589 {R367CAB_FREESYS2, 0x00},
590 {R367CAB_FREESYS3, 0x00},
591 {R367CAB_GPIO_CFG, 0x55},
592 {R367CAB_GPIO_CMD, 0x01},
593 {R367CAB_TSTRES, 0x00},
594 {R367CAB_ANACTRL, 0x0d},/* was 0x00 need to check - I.M.L.*/
595 {R367CAB_TSTBUS, 0x00},
596 {R367CAB_RF_AGC1, 0xea},
597 {R367CAB_RF_AGC2, 0x82},
598 {R367CAB_ANADIGCTRL, 0x0b},
599 {R367CAB_PLLMDIV, 0x01},
600 {R367CAB_PLLNDIV, 0x08},
601 {R367CAB_PLLSETUP, 0x18},
602 {R367CAB_DUAL_AD12, 0x0C}, /* for xc5000 AGC voltage 1.6V */
603 {R367CAB_TSTBIST, 0x00},
604 {R367CAB_CTRL_1, 0x00},
605 {R367CAB_CTRL_2, 0x03},
606 {R367CAB_IT_STATUS1, 0x2b},
607 {R367CAB_IT_STATUS2, 0x08},
608 {R367CAB_IT_EN1, 0x00},
609 {R367CAB_IT_EN2, 0x00},
610 {R367CAB_CTRL_STATUS, 0x04},
611 {R367CAB_TEST_CTL, 0x00},
612 {R367CAB_AGC_CTL, 0x73},
613 {R367CAB_AGC_IF_CFG, 0x50},
614 {R367CAB_AGC_RF_CFG, 0x00},
615 {R367CAB_AGC_PWM_CFG, 0x03},
616 {R367CAB_AGC_PWR_REF_L, 0x5a},
617 {R367CAB_AGC_PWR_REF_H, 0x00},
618 {R367CAB_AGC_RF_TH_L, 0xff},
619 {R367CAB_AGC_RF_TH_H, 0x07},
620 {R367CAB_AGC_IF_LTH_L, 0x00},
621 {R367CAB_AGC_IF_LTH_H, 0x08},
622 {R367CAB_AGC_IF_HTH_L, 0xff},
623 {R367CAB_AGC_IF_HTH_H, 0x07},
624 {R367CAB_AGC_PWR_RD_L, 0xa0},
625 {R367CAB_AGC_PWR_RD_M, 0xe9},
626 {R367CAB_AGC_PWR_RD_H, 0x03},
627 {R367CAB_AGC_PWM_IFCMD_L, 0xe4},
628 {R367CAB_AGC_PWM_IFCMD_H, 0x00},
629 {R367CAB_AGC_PWM_RFCMD_L, 0xff},
630 {R367CAB_AGC_PWM_RFCMD_H, 0x07},
631 {R367CAB_IQDEM_CFG, 0x01},
632 {R367CAB_MIX_NCO_LL, 0x22},
633 {R367CAB_MIX_NCO_HL, 0x96},
634 {R367CAB_MIX_NCO_HH, 0x55},
635 {R367CAB_SRC_NCO_LL, 0xff},
636 {R367CAB_SRC_NCO_LH, 0x0c},
637 {R367CAB_SRC_NCO_HL, 0xf5},
638 {R367CAB_SRC_NCO_HH, 0x20},
639 {R367CAB_IQDEM_GAIN_SRC_L, 0x06},
640 {R367CAB_IQDEM_GAIN_SRC_H, 0x01},
641 {R367CAB_IQDEM_DCRM_CFG_LL, 0xfe},
642 {R367CAB_IQDEM_DCRM_CFG_LH, 0xff},
643 {R367CAB_IQDEM_DCRM_CFG_HL, 0x0f},
644 {R367CAB_IQDEM_DCRM_CFG_HH, 0x00},
645 {R367CAB_IQDEM_ADJ_COEFF0, 0x34},
646 {R367CAB_IQDEM_ADJ_COEFF1, 0xae},
647 {R367CAB_IQDEM_ADJ_COEFF2, 0x46},
648 {R367CAB_IQDEM_ADJ_COEFF3, 0x77},
649 {R367CAB_IQDEM_ADJ_COEFF4, 0x96},
650 {R367CAB_IQDEM_ADJ_COEFF5, 0x69},
651 {R367CAB_IQDEM_ADJ_COEFF6, 0xc7},
652 {R367CAB_IQDEM_ADJ_COEFF7, 0x01},
653 {R367CAB_IQDEM_ADJ_EN, 0x04},
654 {R367CAB_IQDEM_ADJ_AGC_REF, 0x94},
655 {R367CAB_ALLPASSFILT1, 0xc9},
656 {R367CAB_ALLPASSFILT2, 0x2d},
657 {R367CAB_ALLPASSFILT3, 0xa3},
658 {R367CAB_ALLPASSFILT4, 0xfb},
659 {R367CAB_ALLPASSFILT5, 0xf6},
660 {R367CAB_ALLPASSFILT6, 0x45},
661 {R367CAB_ALLPASSFILT7, 0x6f},
662 {R367CAB_ALLPASSFILT8, 0x7e},
663 {R367CAB_ALLPASSFILT9, 0x05},
664 {R367CAB_ALLPASSFILT10, 0x0a},
665 {R367CAB_ALLPASSFILT11, 0x51},
666 {R367CAB_TRL_AGC_CFG, 0x20},
667 {R367CAB_TRL_LPF_CFG, 0x28},
668 {R367CAB_TRL_LPF_ACQ_GAIN, 0x44},
669 {R367CAB_TRL_LPF_TRK_GAIN, 0x22},
670 {R367CAB_TRL_LPF_OUT_GAIN, 0x03},
671 {R367CAB_TRL_LOCKDET_LTH, 0x04},
672 {R367CAB_TRL_LOCKDET_HTH, 0x11},
673 {R367CAB_TRL_LOCKDET_TRGVAL, 0x20},
674 {R367CAB_IQ_QAM, 0x01},
675 {R367CAB_FSM_STATE, 0xa0},
676 {R367CAB_FSM_CTL, 0x08},
677 {R367CAB_FSM_STS, 0x0c},
678 {R367CAB_FSM_SNR0_HTH, 0x00},
679 {R367CAB_FSM_SNR1_HTH, 0x00},
680 {R367CAB_FSM_SNR2_HTH, 0x23},/* 0x00 */
681 {R367CAB_FSM_SNR0_LTH, 0x00},
682 {R367CAB_FSM_SNR1_LTH, 0x00},
683 {R367CAB_FSM_EQA1_HTH, 0x00},
684 {R367CAB_FSM_TEMPO, 0x32},
685 {R367CAB_FSM_CONFIG, 0x03},
686 {R367CAB_EQU_I_TESTTAP_L, 0x11},
687 {R367CAB_EQU_I_TESTTAP_M, 0x00},
688 {R367CAB_EQU_I_TESTTAP_H, 0x00},
689 {R367CAB_EQU_TESTAP_CFG, 0x00},
690 {R367CAB_EQU_Q_TESTTAP_L, 0xff},
691 {R367CAB_EQU_Q_TESTTAP_M, 0x00},
692 {R367CAB_EQU_Q_TESTTAP_H, 0x00},
693 {R367CAB_EQU_TAP_CTRL, 0x00},
694 {R367CAB_EQU_CTR_CRL_CONTROL_L, 0x11},
695 {R367CAB_EQU_CTR_CRL_CONTROL_H, 0x05},
696 {R367CAB_EQU_CTR_HIPOW_L, 0x00},
697 {R367CAB_EQU_CTR_HIPOW_H, 0x00},
698 {R367CAB_EQU_I_EQU_LO, 0xef},
699 {R367CAB_EQU_I_EQU_HI, 0x00},
700 {R367CAB_EQU_Q_EQU_LO, 0xee},
701 {R367CAB_EQU_Q_EQU_HI, 0x00},
702 {R367CAB_EQU_MAPPER, 0xc5},
703 {R367CAB_EQU_SWEEP_RATE, 0x80},
704 {R367CAB_EQU_SNR_LO, 0x64},
705 {R367CAB_EQU_SNR_HI, 0x03},
706 {R367CAB_EQU_GAMMA_LO, 0x00},
707 {R367CAB_EQU_GAMMA_HI, 0x00},
708 {R367CAB_EQU_ERR_GAIN, 0x36},
709 {R367CAB_EQU_RADIUS, 0xaa},
710 {R367CAB_EQU_FFE_MAINTAP, 0x00},
711 {R367CAB_EQU_FFE_LEAKAGE, 0x63},
712 {R367CAB_EQU_FFE_MAINTAP_POS, 0xdf},
713 {R367CAB_EQU_GAIN_WIDE, 0x88},
714 {R367CAB_EQU_GAIN_NARROW, 0x41},
715 {R367CAB_EQU_CTR_LPF_GAIN, 0xd1},
716 {R367CAB_EQU_CRL_LPF_GAIN, 0xa7},
717 {R367CAB_EQU_GLOBAL_GAIN, 0x06},
718 {R367CAB_EQU_CRL_LD_SEN, 0x85},
719 {R367CAB_EQU_CRL_LD_VAL, 0xe2},
720 {R367CAB_EQU_CRL_TFR, 0x20},
721 {R367CAB_EQU_CRL_BISTH_LO, 0x00},
722 {R367CAB_EQU_CRL_BISTH_HI, 0x00},
723 {R367CAB_EQU_SWEEP_RANGE_LO, 0x00},
724 {R367CAB_EQU_SWEEP_RANGE_HI, 0x00},
725 {R367CAB_EQU_CRL_LIMITER, 0x40},
726 {R367CAB_EQU_MODULUS_MAP, 0x90},
727 {R367CAB_EQU_PNT_GAIN, 0xa7},
728 {R367CAB_FEC_AC_CTR_0, 0x16},
729 {R367CAB_FEC_AC_CTR_1, 0x0b},
730 {R367CAB_FEC_AC_CTR_2, 0x88},
731 {R367CAB_FEC_AC_CTR_3, 0x02},
732 {R367CAB_FEC_STATUS, 0x12},
733 {R367CAB_RS_COUNTER_0, 0x7d},
734 {R367CAB_RS_COUNTER_1, 0xd0},
735 {R367CAB_RS_COUNTER_2, 0x19},
736 {R367CAB_RS_COUNTER_3, 0x0b},
737 {R367CAB_RS_COUNTER_4, 0xa3},
738 {R367CAB_RS_COUNTER_5, 0x00},
739 {R367CAB_BERT_0, 0x01},
740 {R367CAB_BERT_1, 0x25},
741 {R367CAB_BERT_2, 0x41},
742 {R367CAB_BERT_3, 0x39},
743 {R367CAB_OUTFORMAT_0, 0xc2},
744 {R367CAB_OUTFORMAT_1, 0x22},
745 {R367CAB_SMOOTHER_2, 0x28},
746 {R367CAB_TSMF_CTRL_0, 0x01},
747 {R367CAB_TSMF_CTRL_1, 0xc6},
748 {R367CAB_TSMF_CTRL_3, 0x43},
749 {R367CAB_TS_ON_ID_0, 0x00},
750 {R367CAB_TS_ON_ID_1, 0x00},
751 {R367CAB_TS_ON_ID_2, 0x00},
752 {R367CAB_TS_ON_ID_3, 0x00},
753 {R367CAB_RE_STATUS_0, 0x00},
754 {R367CAB_RE_STATUS_1, 0x00},
755 {R367CAB_RE_STATUS_2, 0x00},
756 {R367CAB_RE_STATUS_3, 0x00},
757 {R367CAB_TS_STATUS_0, 0x00},
758 {R367CAB_TS_STATUS_1, 0x00},
759 {R367CAB_TS_STATUS_2, 0xa0},
760 {R367CAB_TS_STATUS_3, 0x00},
761 {R367CAB_T_O_ID_0, 0x00},
762 {R367CAB_T_O_ID_1, 0x00},
763 {R367CAB_T_O_ID_2, 0x00},
764 {R367CAB_T_O_ID_3, 0x00},
765};
766
767static
768int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
769{
770 u8 buf[len + 2];
771 struct i2c_msg msg = {
772 .addr = state->config->demod_address,
773 .flags = 0,
774 .buf = buf,
775 .len = len + 2
776 };
777 int ret;
778
779 buf[0] = MSB(reg);
780 buf[1] = LSB(reg);
781 memcpy(buf + 2, data, len);
782
783 if (i2cdebug)
784 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
785
786 ret = i2c_transfer(state->i2c, &msg, 1);
787 if (ret != 1)
788 printk(KERN_ERR "%s: i2c write error!\n", __func__);
789
790 return (ret != 1) ? -EREMOTEIO : 0;
791}
792
793static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
794{
795 return stv0367_writeregs(state, reg, &data, 1);
796}
797
798static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
799{
800 u8 b0[] = { 0, 0 };
801 u8 b1[] = { 0 };
802 struct i2c_msg msg[] = {
803 {
804 .addr = state->config->demod_address,
805 .flags = 0,
806 .buf = b0,
807 .len = 2
808 }, {
809 .addr = state->config->demod_address,
810 .flags = I2C_M_RD,
811 .buf = b1,
812 .len = 1
813 }
814 };
815 int ret;
816
817 b0[0] = MSB(reg);
818 b0[1] = LSB(reg);
819
820 ret = i2c_transfer(state->i2c, msg, 2);
821 if (ret != 2)
822 printk(KERN_ERR "%s: i2c read error\n", __func__);
823
824 if (i2cdebug)
825 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
826
827 return b1[0];
828}
829
830static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
831{
832 u8 position = 0, i = 0;
833
834 (*mask) = label & 0xff;
835
836 while ((position == 0) && (i < 8)) {
837 position = ((*mask) >> i) & 0x01;
838 i++;
839 }
840
841 (*pos) = (i - 1);
842}
843
844static void stv0367_writebits(struct stv0367_state *state, u32 label, u8 val)
845{
846 u8 reg, mask, pos;
847
848 reg = stv0367_readreg(state, (label >> 16) & 0xffff);
849 extract_mask_pos(label, &mask, &pos);
850
851 val = mask & (val << pos);
852
853 reg = (reg & (~mask)) | val;
854 stv0367_writereg(state, (label >> 16) & 0xffff, reg);
855
856}
857
858static void stv0367_setbits(u8 *reg, u32 label, u8 val)
859{
860 u8 mask, pos;
861
862 extract_mask_pos(label, &mask, &pos);
863
864 val = mask & (val << pos);
865
866 (*reg) = ((*reg) & (~mask)) | val;
867}
868
869static u8 stv0367_readbits(struct stv0367_state *state, u32 label)
870{
871 u8 val = 0xff;
872 u8 mask, pos;
873
874 extract_mask_pos(label, &mask, &pos);
875
876 val = stv0367_readreg(state, label >> 16);
877 val = (val & mask) >> pos;
878
879 return val;
880}
881
882u8 stv0367_getbits(u8 reg, u32 label)
883{
884 u8 mask, pos;
885
886 extract_mask_pos(label, &mask, &pos);
887
888 return (reg & mask) >> pos;
889}
890
891static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
892{
893 struct stv0367_state *state = fe->demodulator_priv;
894 u8 tmp = stv0367_readreg(state, R367TER_I2CRPT);
895
896 dprintk("%s:\n", __func__);
897
898 if (enable) {
899 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 0);
900 stv0367_setbits(&tmp, F367TER_I2CT_ON, 1);
901 } else {
902 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 1);
903 stv0367_setbits(&tmp, F367TER_I2CT_ON, 0);
904 }
905
906 stv0367_writereg(state, R367TER_I2CRPT, tmp);
907
908 return 0;
909}
910
911static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
912{
913 struct dvb_frontend_ops *frontend_ops = NULL;
914 struct dvb_tuner_ops *tuner_ops = NULL;
915 u32 freq = 0;
916 int err = 0;
917
918 dprintk("%s:\n", __func__);
919
920
921 if (&fe->ops)
922 frontend_ops = &fe->ops;
923 if (&frontend_ops->tuner_ops)
924 tuner_ops = &frontend_ops->tuner_ops;
925 if (tuner_ops->get_frequency) {
926 err = tuner_ops->get_frequency(fe, &freq);
927 if (err < 0) {
928 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
929 return err;
930 }
931
932 dprintk("%s: frequency=%d\n", __func__, freq);
933
934 } else
935 return -1;
936
937 return freq;
938}
939
940static u16 CellsCoeffs_8MHz_367cofdm[3][6][5] = {
941 {
942 {0x10EF, 0xE205, 0x10EF, 0xCE49, 0x6DA7}, /* CELL 1 COEFFS 27M*/
943 {0x2151, 0xc557, 0x2151, 0xc705, 0x6f93}, /* CELL 2 COEFFS */
944 {0x2503, 0xc000, 0x2503, 0xc375, 0x7194}, /* CELL 3 COEFFS */
945 {0x20E9, 0xca94, 0x20e9, 0xc153, 0x7194}, /* CELL 4 COEFFS */
946 {0x06EF, 0xF852, 0x06EF, 0xC057, 0x7207}, /* CELL 5 COEFFS */
947 {0x0000, 0x0ECC, 0x0ECC, 0x0000, 0x3647} /* CELL 6 COEFFS */
948 }, {
949 {0x10A0, 0xE2AF, 0x10A1, 0xCE76, 0x6D6D}, /* CELL 1 COEFFS 25M*/
950 {0x20DC, 0xC676, 0x20D9, 0xC80A, 0x6F29},
951 {0x2532, 0xC000, 0x251D, 0xC391, 0x706F},
952 {0x1F7A, 0xCD2B, 0x2032, 0xC15E, 0x711F},
953 {0x0698, 0xFA5E, 0x0568, 0xC059, 0x7193},
954 {0x0000, 0x0918, 0x149C, 0x0000, 0x3642} /* CELL 6 COEFFS */
955 }, {
956 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
957 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
958 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
959 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
960 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
961 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
962 }
963};
964
965static u16 CellsCoeffs_7MHz_367cofdm[3][6][5] = {
966 {
967 {0x12CA, 0xDDAF, 0x12CA, 0xCCEB, 0x6FB1}, /* CELL 1 COEFFS 27M*/
968 {0x2329, 0xC000, 0x2329, 0xC6B0, 0x725F}, /* CELL 2 COEFFS */
969 {0x2394, 0xC000, 0x2394, 0xC2C7, 0x7410}, /* CELL 3 COEFFS */
970 {0x251C, 0xC000, 0x251C, 0xC103, 0x74D9}, /* CELL 4 COEFFS */
971 {0x0804, 0xF546, 0x0804, 0xC040, 0x7544}, /* CELL 5 COEFFS */
972 {0x0000, 0x0CD9, 0x0CD9, 0x0000, 0x370A} /* CELL 6 COEFFS */
973 }, {
974 {0x1285, 0xDE47, 0x1285, 0xCD17, 0x6F76}, /*25M*/
975 {0x234C, 0xC000, 0x2348, 0xC6DA, 0x7206},
976 {0x23B4, 0xC000, 0x23AC, 0xC2DB, 0x73B3},
977 {0x253D, 0xC000, 0x25B6, 0xC10B, 0x747F},
978 {0x0721, 0xF79C, 0x065F, 0xC041, 0x74EB},
979 {0x0000, 0x08FA, 0x1162, 0x0000, 0x36FF}
980 }, {
981 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
982 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
983 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
984 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
985 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
986 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
987 }
988};
989
990static u16 CellsCoeffs_6MHz_367cofdm[3][6][5] = {
991 {
992 {0x1699, 0xD5B8, 0x1699, 0xCBC3, 0x713B}, /* CELL 1 COEFFS 27M*/
993 {0x2245, 0xC000, 0x2245, 0xC568, 0x74D5}, /* CELL 2 COEFFS */
994 {0x227F, 0xC000, 0x227F, 0xC1FC, 0x76C6}, /* CELL 3 COEFFS */
995 {0x235E, 0xC000, 0x235E, 0xC0A7, 0x778A}, /* CELL 4 COEFFS */
996 {0x0ECB, 0xEA0B, 0x0ECB, 0xC027, 0x77DD}, /* CELL 5 COEFFS */
997 {0x0000, 0x0B68, 0x0B68, 0x0000, 0xC89A}, /* CELL 6 COEFFS */
998 }, {
999 {0x1655, 0xD64E, 0x1658, 0xCBEF, 0x70FE}, /*25M*/
1000 {0x225E, 0xC000, 0x2256, 0xC589, 0x7489},
1001 {0x2293, 0xC000, 0x2295, 0xC209, 0x767E},
1002 {0x2377, 0xC000, 0x23AA, 0xC0AB, 0x7746},
1003 {0x0DC7, 0xEBC8, 0x0D07, 0xC027, 0x7799},
1004 {0x0000, 0x0888, 0x0E9C, 0x0000, 0x3757}
1005
1006 }, {
1007 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
1008 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1009 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1010 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1011 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1012 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
1013 }
1014};
1015
1016static u32 stv0367ter_get_mclk(struct stv0367_state *state, u32 ExtClk_Hz)
1017{
1018 u32 mclk_Hz = 0; /* master clock frequency (Hz) */
1019 u32 m, n, p;
1020
1021 dprintk("%s:\n", __func__);
1022
1023 if (stv0367_readbits(state, F367TER_BYPASS_PLLXN) == 0) {
1024 n = (u32)stv0367_readbits(state, F367TER_PLL_NDIV);
1025 if (n == 0)
1026 n = n + 1;
1027
1028 m = (u32)stv0367_readbits(state, F367TER_PLL_MDIV);
1029 if (m == 0)
1030 m = m + 1;
1031
1032 p = (u32)stv0367_readbits(state, F367TER_PLL_PDIV);
1033 if (p > 5)
1034 p = 5;
1035
1036 mclk_Hz = ((ExtClk_Hz / 2) * n) / (m * (1 << p));
1037
1038 dprintk("N=%d M=%d P=%d mclk_Hz=%d ExtClk_Hz=%d\n",
1039 n, m, p, mclk_Hz, ExtClk_Hz);
1040 } else
1041 mclk_Hz = ExtClk_Hz;
1042
1043 dprintk("%s: mclk_Hz=%d\n", __func__, mclk_Hz);
1044
1045 return mclk_Hz;
1046}
1047
1048static int stv0367ter_filt_coeff_init(struct stv0367_state *state,
1049 u16 CellsCoeffs[3][6][5], u32 DemodXtal)
1050{
1051 int i, j, k, freq;
1052
1053 dprintk("%s:\n", __func__);
1054
1055 freq = stv0367ter_get_mclk(state, DemodXtal);
1056
1057 if (freq == 53125000)
1058 k = 1; /* equivalent to Xtal 25M on 362*/
1059 else if (freq == 54000000)
1060 k = 0; /* equivalent to Xtal 27M on 362*/
1061 else if (freq == 52500000)
1062 k = 2; /* equivalent to Xtal 30M on 362*/
1063 else
1064 return 0;
1065
1066 for (i = 1; i <= 6; i++) {
1067 stv0367_writebits(state, F367TER_IIR_CELL_NB, i - 1);
1068
1069 for (j = 1; j <= 5; j++) {
1070 stv0367_writereg(state,
1071 (R367TER_IIRCX_COEFF1_MSB + 2 * (j - 1)),
1072 MSB(CellsCoeffs[k][i-1][j-1]));
1073 stv0367_writereg(state,
1074 (R367TER_IIRCX_COEFF1_LSB + 2 * (j - 1)),
1075 LSB(CellsCoeffs[k][i-1][j-1]));
1076 }
1077 }
1078
1079 return 1;
1080
1081}
1082
1083static void stv0367ter_agc_iir_lock_detect_set(struct stv0367_state *state)
1084{
1085 dprintk("%s:\n", __func__);
1086
1087 stv0367_writebits(state, F367TER_LOCK_DETECT_LSB, 0x00);
1088
1089 /* Lock detect 1 */
1090 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x00);
1091 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1092 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1093
1094 /* Lock detect 2 */
1095 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x01);
1096 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1097 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1098
1099 /* Lock detect 3 */
1100 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x02);
1101 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1102 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1103
1104 /* Lock detect 4 */
1105 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x03);
1106 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1107 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1108
1109}
1110
1111static int stv0367_iir_filt_init(struct stv0367_state *state, u8 Bandwidth,
1112 u32 DemodXtalValue)
1113{
1114 dprintk("%s:\n", __func__);
1115
1116 stv0367_writebits(state, F367TER_NRST_IIR, 0);
1117
1118 switch (Bandwidth) {
1119 case 6:
1120 if (!stv0367ter_filt_coeff_init(state,
1121 CellsCoeffs_6MHz_367cofdm,
1122 DemodXtalValue))
1123 return 0;
1124 break;
1125 case 7:
1126 if (!stv0367ter_filt_coeff_init(state,
1127 CellsCoeffs_7MHz_367cofdm,
1128 DemodXtalValue))
1129 return 0;
1130 break;
1131 case 8:
1132 if (!stv0367ter_filt_coeff_init(state,
1133 CellsCoeffs_8MHz_367cofdm,
1134 DemodXtalValue))
1135 return 0;
1136 break;
1137 default:
1138 return 0;
1139 }
1140
1141 stv0367_writebits(state, F367TER_NRST_IIR, 1);
1142
1143 return 1;
1144}
1145
1146static void stv0367ter_agc_iir_rst(struct stv0367_state *state)
1147{
1148
1149 u8 com_n;
1150
1151 dprintk("%s:\n", __func__);
1152
1153 com_n = stv0367_readbits(state, F367TER_COM_N);
1154
1155 stv0367_writebits(state, F367TER_COM_N, 0x07);
1156
1157 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x00);
1158 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x00);
1159
1160 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x01);
1161 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x01);
1162
1163 stv0367_writebits(state, F367TER_COM_N, com_n);
1164
1165}
1166
1167static int stv0367ter_duration(s32 mode, int tempo1, int tempo2, int tempo3)
1168{
1169 int local_tempo = 0;
1170 switch (mode) {
1171 case 0:
1172 local_tempo = tempo1;
1173 break;
1174 case 1:
1175 local_tempo = tempo2;
1176 break ;
1177
1178 case 2:
1179 local_tempo = tempo3;
1180 break;
1181
1182 default:
1183 break;
1184 }
1185 /* msleep(local_tempo); */
1186 return local_tempo;
1187}
1188
1189static enum
1190stv0367_ter_signal_type stv0367ter_check_syr(struct stv0367_state *state)
1191{
1192 int wd = 100;
1193 unsigned short int SYR_var;
1194 s32 SYRStatus;
1195
1196 dprintk("%s:\n", __func__);
1197
1198 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1199
1200 while ((!SYR_var) && (wd > 0)) {
1201 usleep_range(2000, 3000);
1202 wd -= 2;
1203 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1204 }
1205
1206 if (!SYR_var)
1207 SYRStatus = FE_TER_NOSYMBOL;
1208 else
1209 SYRStatus = FE_TER_SYMBOLOK;
1210
1211 dprintk("stv0367ter_check_syr SYRStatus %s\n",
1212 SYR_var == 0 ? "No Symbol" : "OK");
1213
1214 return SYRStatus;
1215}
1216
1217static enum
1218stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state,
1219 s32 FFTmode)
1220{
1221
1222 s32 CPAMPvalue = 0, CPAMPStatus, CPAMPMin;
1223 int wd = 0;
1224
1225 dprintk("%s:\n", __func__);
1226
1227 switch (FFTmode) {
1228 case 0: /*2k mode*/
1229 CPAMPMin = 20;
1230 wd = 10;
1231 break;
1232 case 1: /*8k mode*/
1233 CPAMPMin = 80;
1234 wd = 55;
1235 break;
1236 case 2: /*4k mode*/
1237 CPAMPMin = 40;
1238 wd = 30;
1239 break;
1240 default:
1241 CPAMPMin = 0xffff; /*drives to NOCPAMP */
1242 break;
1243 }
1244
1245 dprintk("%s: CPAMPMin=%d wd=%d\n", __func__, CPAMPMin, wd);
1246
1247 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1248 while ((CPAMPvalue < CPAMPMin) && (wd > 0)) {
1249 usleep_range(1000, 2000);
1250 wd -= 1;
1251 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1252 /*dprintk("CPAMPvalue= %d at wd=%d\n",CPAMPvalue,wd); */
1253 }
1254 dprintk("******last CPAMPvalue= %d at wd=%d\n", CPAMPvalue, wd);
1255 if (CPAMPvalue < CPAMPMin) {
1256 CPAMPStatus = FE_TER_NOCPAMP;
1257 printk(KERN_ERR "CPAMP failed\n");
1258 } else {
1259 printk(KERN_ERR "CPAMP OK !\n");
1260 CPAMPStatus = FE_TER_CPAMPOK;
1261 }
1262
1263 return CPAMPStatus;
1264}
1265
1266enum
1267stv0367_ter_signal_type stv0367ter_lock_algo(struct stv0367_state *state)
1268{
1269 enum stv0367_ter_signal_type ret_flag;
1270 short int wd, tempo;
1271 u8 try, u_var1 = 0, u_var2 = 0, u_var3 = 0, u_var4 = 0, mode, guard;
1272 u8 tmp, tmp2;
1273
1274 dprintk("%s:\n", __func__);
1275
1276 if (state == NULL)
1277 return FE_TER_SWNOK;
1278
1279 try = 0;
1280 do {
1281 ret_flag = FE_TER_LOCKOK;
1282
1283 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1284
1285 if (state->config->if_iq_mode != 0)
1286 stv0367_writebits(state, F367TER_COM_N, 0x07);
1287
1288 stv0367_writebits(state, F367TER_GUARD, 3);/* suggest 2k 1/4 */
1289 stv0367_writebits(state, F367TER_MODE, 0);
1290 stv0367_writebits(state, F367TER_SYR_TR_DIS, 0);
1291 usleep_range(5000, 10000);
1292
1293 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1294
1295
1296 if (stv0367ter_check_syr(state) == FE_TER_NOSYMBOL)
1297 return FE_TER_NOSYMBOL;
1298 else { /*
1299 if chip locked on wrong mode first try,
1300 it must lock correctly second try */
1301 mode = stv0367_readbits(state, F367TER_SYR_MODE);
1302 if (stv0367ter_check_cpamp(state, mode) ==
1303 FE_TER_NOCPAMP) {
1304 if (try == 0)
1305 ret_flag = FE_TER_NOCPAMP;
1306
1307 }
1308 }
1309
1310 try++;
1311 } while ((try < 10) && (ret_flag != FE_TER_LOCKOK));
1312
1313 tmp = stv0367_readreg(state, R367TER_SYR_STAT);
1314 tmp2 = stv0367_readreg(state, R367TER_STATUS);
1315 dprintk("state=%p\n", state);
1316 dprintk("LOCK OK! mode=%d SYR_STAT=0x%x R367TER_STATUS=0x%x\n",
1317 mode, tmp, tmp2);
1318
1319 tmp = stv0367_readreg(state, R367TER_PRVIT);
1320 tmp2 = stv0367_readreg(state, R367TER_I2CRPT);
1321 dprintk("PRVIT=0x%x I2CRPT=0x%x\n", tmp, tmp2);
1322
1323 tmp = stv0367_readreg(state, R367TER_GAIN_SRC1);
1324 dprintk("GAIN_SRC1=0x%x\n", tmp);
1325
1326 if ((mode != 0) && (mode != 1) && (mode != 2))
1327 return FE_TER_SWNOK;
1328
1329 /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */
1330
1331 /*supress EPQ auto for SYR_GARD 1/16 or 1/32
1332 and set channel predictor in automatic */
1333#if 0
1334 switch (guard) {
1335
1336 case 0:
1337 case 1:
1338 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1339 stv0367_writereg(state, R367TER_CHC_CTL, 0x01);
1340 break;
1341 case 2:
1342 case 3:
1343 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1344 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1345 break;
1346
1347 default:
1348 return FE_TER_SWNOK;
1349 }
1350#endif
1351
1352 /*reset fec an reedsolo FOR 367 only*/
1353 stv0367_writebits(state, F367TER_RST_SFEC, 1);
1354 stv0367_writebits(state, F367TER_RST_REEDSOLO, 1);
1355 usleep_range(1000, 2000);
1356 stv0367_writebits(state, F367TER_RST_SFEC, 0);
1357 stv0367_writebits(state, F367TER_RST_REEDSOLO, 0);
1358
1359 u_var1 = stv0367_readbits(state, F367TER_LK);
1360 u_var2 = stv0367_readbits(state, F367TER_PRF);
1361 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1362 /* u_var4=stv0367_readbits(state,F367TER_TSFIFO_LINEOK); */
1363
1364 wd = stv0367ter_duration(mode, 125, 500, 250);
1365 tempo = stv0367ter_duration(mode, 4, 16, 8);
1366
1367 /*while ( ((!u_var1)||(!u_var2)||(!u_var3)||(!u_var4)) && (wd>=0)) */
1368 while (((!u_var1) || (!u_var2) || (!u_var3)) && (wd >= 0)) {
1369 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1370 wd -= tempo;
1371 u_var1 = stv0367_readbits(state, F367TER_LK);
1372 u_var2 = stv0367_readbits(state, F367TER_PRF);
1373 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1374 /*u_var4=stv0367_readbits(state, F367TER_TSFIFO_LINEOK); */
1375 }
1376
1377 if (!u_var1)
1378 return FE_TER_NOLOCK;
1379
1380
1381 if (!u_var2)
1382 return FE_TER_NOPRFOUND;
1383
1384 if (!u_var3)
1385 return FE_TER_NOTPS;
1386
1387 guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1388 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1389 switch (guard) {
1390 case 0:
1391 case 1:
1392 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1393 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x1);*/
1394 stv0367_writebits(state, F367TER_SYR_FILTER, 0);
1395 break;
1396 case 2:
1397 case 3:
1398 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1399 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x11);*/
1400 stv0367_writebits(state, F367TER_SYR_FILTER, 1);
1401 break;
1402
1403 default:
1404 return FE_TER_SWNOK;
1405 }
1406
1407 /* apply Sfec workaround if 8K 64QAM CR!=1/2*/
1408 if ((stv0367_readbits(state, F367TER_TPS_CONST) == 2) &&
1409 (mode == 1) &&
1410 (stv0367_readbits(state, F367TER_TPS_HPCODE) != 0)) {
1411 stv0367_writereg(state, R367TER_SFDLYSETH, 0xc0);
1412 stv0367_writereg(state, R367TER_SFDLYSETM, 0x60);
1413 stv0367_writereg(state, R367TER_SFDLYSETL, 0x0);
1414 } else
1415 stv0367_writereg(state, R367TER_SFDLYSETH, 0x0);
1416
1417 wd = stv0367ter_duration(mode, 125, 500, 250);
1418 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1419
1420 while ((!u_var4) && (wd >= 0)) {
1421 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1422 wd -= tempo;
1423 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1424 }
1425
1426 if (!u_var4)
1427 return FE_TER_NOLOCK;
1428
1429 /* for 367 leave COM_N at 0x7 for IQ_mode*/
1430 /*if(ter_state->if_iq_mode!=FE_TER_NORMAL_IF_TUNER) {
1431 tempo=0;
1432 while ((stv0367_readbits(state,F367TER_COM_USEGAINTRK)!=1) &&
1433 (stv0367_readbits(state,F367TER_COM_AGCLOCK)!=1)&&(tempo<100)) {
1434 ChipWaitOrAbort(state,1);
1435 tempo+=1;
1436 }
1437
1438 stv0367_writebits(state,F367TER_COM_N,0x17);
1439 } */
1440
1441 stv0367_writebits(state, F367TER_SYR_TR_DIS, 1);
1442
1443 dprintk("FE_TER_LOCKOK !!!\n");
1444
1445 return FE_TER_LOCKOK;
1446
1447}
1448
1449static void stv0367ter_set_ts_mode(struct stv0367_state *state,
1450 enum stv0367_ts_mode PathTS)
1451{
1452
1453 dprintk("%s:\n", __func__);
1454
1455 if (state == NULL)
1456 return;
1457
1458 stv0367_writebits(state, F367TER_TS_DIS, 0);
1459 switch (PathTS) {
1460 default:
1461 /*for removing warning :default we can assume in parallel mode*/
1462 case STV0367_PARALLEL_PUNCT_CLOCK:
1463 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 0);
1464 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 0);
1465 break;
1466 case STV0367_SERIAL_PUNCT_CLOCK:
1467 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 1);
1468 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 1);
1469 break;
1470 }
1471}
1472
1473static void stv0367ter_set_clk_pol(struct stv0367_state *state,
1474 enum stv0367_clk_pol clock)
1475{
1476
1477 dprintk("%s:\n", __func__);
1478
1479 if (state == NULL)
1480 return;
1481
1482 switch (clock) {
1483 case STV0367_RISINGEDGE_CLOCK:
1484 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 1);
1485 break;
1486 case STV0367_FALLINGEDGE_CLOCK:
1487 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1488 break;
1489 /*case FE_TER_CLOCK_POLARITY_DEFAULT:*/
1490 default:
1491 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1492 break;
1493 }
1494}
1495
1496#if 0
1497static void stv0367ter_core_sw(struct stv0367_state *state)
1498{
1499
1500 dprintk("%s:\n", __func__);
1501
1502 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1503 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1504 msleep(350);
1505}
1506#endif
1507static int stv0367ter_standby(struct dvb_frontend *fe, u8 standby_on)
1508{
1509 struct stv0367_state *state = fe->demodulator_priv;
1510
1511 dprintk("%s:\n", __func__);
1512
1513 if (standby_on) {
1514 stv0367_writebits(state, F367TER_STDBY, 1);
1515 stv0367_writebits(state, F367TER_STDBY_FEC, 1);
1516 stv0367_writebits(state, F367TER_STDBY_CORE, 1);
1517 } else {
1518 stv0367_writebits(state, F367TER_STDBY, 0);
1519 stv0367_writebits(state, F367TER_STDBY_FEC, 0);
1520 stv0367_writebits(state, F367TER_STDBY_CORE, 0);
1521 }
1522
1523 return 0;
1524}
1525
1526static int stv0367ter_sleep(struct dvb_frontend *fe)
1527{
1528 return stv0367ter_standby(fe, 1);
1529}
1530
1531int stv0367ter_init(struct dvb_frontend *fe)
1532{
1533 struct stv0367_state *state = fe->demodulator_priv;
1534 struct stv0367ter_state *ter_state = state->ter_state;
1535 int i;
1536
1537 dprintk("%s:\n", __func__);
1538
1539 ter_state->pBER = 0;
1540
1541 for (i = 0; i < STV0367TER_NBREGS; i++)
1542 stv0367_writereg(state, def0367ter[i].addr,
1543 def0367ter[i].value);
1544
1545 switch (state->config->xtal) {
1546 /*set internal freq to 53.125MHz */
1547 case 25000000:
1548 stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
1549 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1550 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1551 break;
1552 default:
1553 case 27000000:
1554 dprintk("FE_STV0367TER_SetCLKgen for 27Mhz\n");
1555 stv0367_writereg(state, R367TER_PLLMDIV, 0x1);
1556 stv0367_writereg(state, R367TER_PLLNDIV, 0x8);
1557 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1558 break;
1559 case 30000000:
1560 stv0367_writereg(state, R367TER_PLLMDIV, 0xc);
1561 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1562 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1563 break;
1564 }
1565
1566 stv0367_writereg(state, R367TER_I2CRPT, 0xa0);
1567 stv0367_writereg(state, R367TER_ANACTRL, 0x00);
1568
1569 /*Set TS1 and TS2 to serial or parallel mode */
1570 stv0367ter_set_ts_mode(state, state->config->ts_mode);
1571 stv0367ter_set_clk_pol(state, state->config->clk_pol);
1572
1573 state->chip_id = stv0367_readreg(state, R367TER_ID);
1574 ter_state->first_lock = 0;
1575 ter_state->unlock_counter = 2;
1576
1577 return 0;
1578}
1579
1580static int stv0367ter_algo(struct dvb_frontend *fe,
1581 struct dvb_frontend_parameters *param)
1582{
1583 struct stv0367_state *state = fe->demodulator_priv;
1584 struct stv0367ter_state *ter_state = state->ter_state;
1585 int offset = 0, tempo = 0;
1586 u8 u_var;
1587 u8 /*constell,*/ counter, tps_rcvd[2];
1588 s8 step;
1589 s32 timing_offset = 0;
1590 u32 trl_nomrate = 0, InternalFreq = 0, temp = 0;
1591
1592 dprintk("%s:\n", __func__);
1593
1594 ter_state->frequency = param->frequency;
1595 ter_state->force = FE_TER_FORCENONE
1596 + stv0367_readbits(state, F367TER_FORCE) * 2;
1597 ter_state->if_iq_mode = state->config->if_iq_mode;
1598 switch (state->config->if_iq_mode) {
1599 case FE_TER_NORMAL_IF_TUNER: /* Normal IF mode */
1600 dprintk("ALGO: FE_TER_NORMAL_IF_TUNER selected\n");
1601 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1602 stv0367_writebits(state, F367TER_LONGPATH_IF, 0);
1603 stv0367_writebits(state, F367TER_DEMUX_SWAP, 0);
1604 break;
1605 case FE_TER_LONGPATH_IF_TUNER: /* Long IF mode */
1606 dprintk("ALGO: FE_TER_LONGPATH_IF_TUNER selected\n");
1607 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1608 stv0367_writebits(state, F367TER_LONGPATH_IF, 1);
1609 stv0367_writebits(state, F367TER_DEMUX_SWAP, 1);
1610 break;
1611 case FE_TER_IQ_TUNER: /* IQ mode */
1612 dprintk("ALGO: FE_TER_IQ_TUNER selected\n");
1613 stv0367_writebits(state, F367TER_TUNER_BB, 1);
1614 stv0367_writebits(state, F367TER_PPM_INVSEL, 0);
1615 break;
1616 default:
1617 printk(KERN_ERR "ALGO: wrong TUNER type selected\n");
1618 return -EINVAL;
1619 }
1620
1621 usleep_range(5000, 7000);
1622
1623 switch (param->inversion) {
1624 case INVERSION_AUTO:
1625 default:
1626 dprintk("%s: inversion AUTO\n", __func__);
1627 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1628 stv0367_writebits(state, F367TER_IQ_INVERT,
1629 ter_state->sense);
1630 else
1631 stv0367_writebits(state, F367TER_INV_SPECTR,
1632 ter_state->sense);
1633
1634 break;
1635 case INVERSION_ON:
1636 case INVERSION_OFF:
1637 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1638 stv0367_writebits(state, F367TER_IQ_INVERT,
1639 param->inversion);
1640 else
1641 stv0367_writebits(state, F367TER_INV_SPECTR,
1642 param->inversion);
1643
1644 break;
1645 }
1646
1647 if ((ter_state->if_iq_mode != FE_TER_NORMAL_IF_TUNER) &&
1648 (ter_state->pBW != ter_state->bw)) {
1649 stv0367ter_agc_iir_lock_detect_set(state);
1650
1651 /*set fine agc target to 180 for LPIF or IQ mode*/
1652 /* set Q_AGCTarget */
1653 stv0367_writebits(state, F367TER_SEL_IQNTAR, 1);
1654 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1655 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1656
1657 /* set Q_AGCTarget */
1658 stv0367_writebits(state, F367TER_SEL_IQNTAR, 0);
1659 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1660 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1661
1662 if (!stv0367_iir_filt_init(state, ter_state->bw,
1663 state->config->xtal))
1664 return -EINVAL;
1665 /*set IIR filter once for 6,7 or 8MHz BW*/
1666 ter_state->pBW = ter_state->bw;
1667
1668 stv0367ter_agc_iir_rst(state);
1669 }
1670
1671 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1672 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x01);
1673 else
1674 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x00);
1675
1676 InternalFreq = stv0367ter_get_mclk(state, state->config->xtal) / 1000;
1677 temp = (int)
1678 ((((ter_state->bw * 64 * (1 << 15) * 100)
1679 / (InternalFreq)) * 10) / 7);
1680
1681 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, temp % 2);
1682 temp = temp / 2;
1683 stv0367_writebits(state, F367TER_TRL_NOMRATE_HI, temp / 256);
1684 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, temp % 256);
1685
1686 temp = stv0367_readbits(state, F367TER_TRL_NOMRATE_HI) * 512 +
1687 stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 +
1688 stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB);
1689 temp = (int)(((1 << 17) * ter_state->bw * 1000) / (7 * (InternalFreq)));
1690 stv0367_writebits(state, F367TER_GAIN_SRC_HI, temp / 256);
1691 stv0367_writebits(state, F367TER_GAIN_SRC_LO, temp % 256);
1692 temp = stv0367_readbits(state, F367TER_GAIN_SRC_HI) * 256 +
1693 stv0367_readbits(state, F367TER_GAIN_SRC_LO);
1694
1695 temp = (int)
1696 ((InternalFreq - state->config->if_khz) * (1 << 16)
1697 / (InternalFreq));
1698
1699 dprintk("DEROT temp=0x%x\n", temp);
1700 stv0367_writebits(state, F367TER_INC_DEROT_HI, temp / 256);
1701 stv0367_writebits(state, F367TER_INC_DEROT_LO, temp % 256);
1702
1703 ter_state->echo_pos = 0;
1704 ter_state->ucblocks = 0; /* liplianin */
1705 ter_state->pBER = 0; /* liplianin */
1706 stv0367_writebits(state, F367TER_LONG_ECHO, ter_state->echo_pos);
1707
1708 if (stv0367ter_lock_algo(state) != FE_TER_LOCKOK)
1709 return 0;
1710
1711 ter_state->state = FE_TER_LOCKOK;
1712 /* update results */
1713 tps_rcvd[0] = stv0367_readreg(state, R367TER_TPS_RCVD2);
1714 tps_rcvd[1] = stv0367_readreg(state, R367TER_TPS_RCVD3);
1715
1716 ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE);
1717 ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1718
1719 ter_state->first_lock = 1; /* we know sense now :) */
1720
1721 ter_state->agc_val =
1722 (stv0367_readbits(state, F367TER_AGC1_VAL_LO) << 16) +
1723 (stv0367_readbits(state, F367TER_AGC1_VAL_HI) << 24) +
1724 stv0367_readbits(state, F367TER_AGC2_VAL_LO) +
1725 (stv0367_readbits(state, F367TER_AGC2_VAL_HI) << 8);
1726
1727 /* Carrier offset calculation */
1728 stv0367_writebits(state, F367TER_FREEZE, 1);
1729 offset = (stv0367_readbits(state, F367TER_CRL_FOFFSET_VHI) << 16) ;
1730 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_HI) << 8);
1731 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_LO));
1732 stv0367_writebits(state, F367TER_FREEZE, 0);
1733 if (offset > 8388607)
1734 offset -= 16777216;
1735
1736 offset = offset * 2 / 16384;
1737
1738 if (ter_state->mode == FE_TER_MODE_2K)
1739 offset = (offset * 4464) / 1000;/*** 1 FFT BIN=4.464khz***/
1740 else if (ter_state->mode == FE_TER_MODE_4K)
1741 offset = (offset * 223) / 100;/*** 1 FFT BIN=2.23khz***/
1742 else if (ter_state->mode == FE_TER_MODE_8K)
1743 offset = (offset * 111) / 100;/*** 1 FFT BIN=1.1khz***/
1744
1745 if (stv0367_readbits(state, F367TER_PPM_INVSEL) == 1) {
1746 if ((stv0367_readbits(state, F367TER_INV_SPECTR) ==
1747 (stv0367_readbits(state,
1748 F367TER_STATUS_INV_SPECRUM) == 1)))
1749 offset = offset * -1;
1750 }
1751
1752 if (ter_state->bw == 6)
1753 offset = (offset * 6) / 8;
1754 else if (ter_state->bw == 7)
1755 offset = (offset * 7) / 8;
1756
1757 ter_state->frequency += offset;
1758
1759 tempo = 10; /* exit even if timing_offset stays null */
1760 while ((timing_offset == 0) && (tempo > 0)) {
1761 usleep_range(10000, 20000); /*was 20ms */
1762 /* fine tuning of timing offset if required */
1763 timing_offset = stv0367_readbits(state, F367TER_TRL_TOFFSET_LO)
1764 + 256 * stv0367_readbits(state,
1765 F367TER_TRL_TOFFSET_HI);
1766 if (timing_offset >= 32768)
1767 timing_offset -= 65536;
1768 trl_nomrate = (512 * stv0367_readbits(state,
1769 F367TER_TRL_NOMRATE_HI)
1770 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2
1771 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB));
1772
1773 timing_offset = ((signed)(1000000 / trl_nomrate) *
1774 timing_offset) / 2048;
1775 tempo--;
1776 }
1777
1778 if (timing_offset <= 0) {
1779 timing_offset = (timing_offset - 11) / 22;
1780 step = -1;
1781 } else {
1782 timing_offset = (timing_offset + 11) / 22;
1783 step = 1;
1784 }
1785
1786 for (counter = 0; counter < abs(timing_offset); counter++) {
1787 trl_nomrate += step;
1788 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB,
1789 trl_nomrate % 2);
1790 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO,
1791 trl_nomrate / 2);
1792 usleep_range(1000, 2000);
1793 }
1794
1795 usleep_range(5000, 6000);
1796 /* unlocks could happen in case of trl centring big step,
1797 then a core off/on restarts demod */
1798 u_var = stv0367_readbits(state, F367TER_LK);
1799
1800 if (!u_var) {
1801 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1802 msleep(20);
1803 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1804 }
1805
1806 return 0;
1807}
1808
1809static int stv0367ter_set_frontend(struct dvb_frontend *fe,
1810 struct dvb_frontend_parameters *param)
1811{
1812 struct dvb_ofdm_parameters *op = &param->u.ofdm;
1813 struct stv0367_state *state = fe->demodulator_priv;
1814 struct stv0367ter_state *ter_state = state->ter_state;
1815
1816 /*u8 trials[2]; */
1817 s8 num_trials, index;
1818 u8 SenseTrials[] = { INVERSION_ON, INVERSION_OFF };
1819
1820 stv0367ter_init(fe);
1821
1822 if (fe->ops.tuner_ops.set_params) {
1823 if (fe->ops.i2c_gate_ctrl)
1824 fe->ops.i2c_gate_ctrl(fe, 1);
1825 fe->ops.tuner_ops.set_params(fe, param);
1826 if (fe->ops.i2c_gate_ctrl)
1827 fe->ops.i2c_gate_ctrl(fe, 0);
1828 }
1829
1830 switch (op->transmission_mode) {
1831 default:
1832 case TRANSMISSION_MODE_AUTO:
1833 case TRANSMISSION_MODE_2K:
1834 ter_state->mode = FE_TER_MODE_2K;
1835 break;
1836/* case TRANSMISSION_MODE_4K:
1837 pLook.mode = FE_TER_MODE_4K;
1838 break;*/
1839 case TRANSMISSION_MODE_8K:
1840 ter_state->mode = FE_TER_MODE_8K;
1841 break;
1842 }
1843
1844 switch (op->guard_interval) {
1845 default:
1846 case GUARD_INTERVAL_1_32:
1847 case GUARD_INTERVAL_1_16:
1848 case GUARD_INTERVAL_1_8:
1849 case GUARD_INTERVAL_1_4:
1850 ter_state->guard = op->guard_interval;
1851 break;
1852 case GUARD_INTERVAL_AUTO:
1853 ter_state->guard = GUARD_INTERVAL_1_32;
1854 break;
1855 }
1856
1857 switch (op->bandwidth) {
1858 case BANDWIDTH_6_MHZ:
1859 ter_state->bw = FE_TER_CHAN_BW_6M;
1860 break;
1861 case BANDWIDTH_7_MHZ:
1862 ter_state->bw = FE_TER_CHAN_BW_7M;
1863 break;
1864 case BANDWIDTH_8_MHZ:
1865 default:
1866 ter_state->bw = FE_TER_CHAN_BW_8M;
1867 }
1868
1869 ter_state->hierarchy = FE_TER_HIER_NONE;
1870
1871 switch (param->inversion) {
1872 case INVERSION_OFF:
1873 case INVERSION_ON:
1874 num_trials = 1;
1875 break;
1876 default:
1877 num_trials = 2;
1878 if (ter_state->first_lock)
1879 num_trials = 1;
1880 break;
1881 }
1882
1883 ter_state->state = FE_TER_NOLOCK;
1884 index = 0;
1885
1886 while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) {
1887 if (!ter_state->first_lock) {
1888 if (param->inversion == INVERSION_AUTO)
1889 ter_state->sense = SenseTrials[index];
1890
1891 }
1892 stv0367ter_algo(fe,/* &pLook, result,*/ param);
1893
1894 if ((ter_state->state == FE_TER_LOCKOK) &&
1895 (param->inversion == INVERSION_AUTO) &&
1896 (index == 1)) {
1897 /* invert spectrum sense */
1898 SenseTrials[index] = SenseTrials[0];
1899 SenseTrials[(index + 1) % 2] = (SenseTrials[1] + 1) % 2;
1900 }
1901
1902 index++;
1903 }
1904
1905 return 0;
1906}
1907
1908static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1909{
1910 struct stv0367_state *state = fe->demodulator_priv;
1911 struct stv0367ter_state *ter_state = state->ter_state;
1912 u32 errs = 0;
1913
1914 /*wait for counting completion*/
1915 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) {
1916 errs =
1917 ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
1918 * (1 << 16))
1919 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
1920 * (1 << 8))
1921 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
1922 ter_state->ucblocks = errs;
1923 }
1924
1925 (*ucblocks) = ter_state->ucblocks;
1926
1927 return 0;
1928}
1929
1930static int stv0367ter_get_frontend(struct dvb_frontend *fe,
1931 struct dvb_frontend_parameters *param)
1932{
1933 struct stv0367_state *state = fe->demodulator_priv;
1934 struct stv0367ter_state *ter_state = state->ter_state;
1935 struct dvb_ofdm_parameters *op = &param->u.ofdm;
1936 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1937
1938 int error = 0;
1939 enum stv0367_ter_mode mode;
1940 int constell = 0,/* snr = 0,*/ Data = 0;
1941
1942 param->frequency = stv0367_get_tuner_freq(fe);
1943 if ((int)param->frequency < 0)
1944 param->frequency = c->frequency;
1945
1946 constell = stv0367_readbits(state, F367TER_TPS_CONST);
1947 if (constell == 0)
1948 op->constellation = QPSK;
1949 else if (constell == 1)
1950 op->constellation = QAM_16;
1951 else
1952 op->constellation = QAM_64;
1953
1954 param->inversion = stv0367_readbits(state, F367TER_INV_SPECTR);
1955
1956 /* Get the Hierarchical mode */
1957 Data = stv0367_readbits(state, F367TER_TPS_HIERMODE);
1958
1959 switch (Data) {
1960 case 0:
1961 op->hierarchy_information = HIERARCHY_NONE;
1962 break;
1963 case 1:
1964 op->hierarchy_information = HIERARCHY_1;
1965 break;
1966 case 2:
1967 op->hierarchy_information = HIERARCHY_2;
1968 break;
1969 case 3:
1970 op->hierarchy_information = HIERARCHY_4;
1971 break;
1972 default:
1973 op->hierarchy_information = HIERARCHY_AUTO;
1974 break; /* error */
1975 }
1976
1977 /* Get the FEC Rate */
1978 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1979 Data = stv0367_readbits(state, F367TER_TPS_LPCODE);
1980 else
1981 Data = stv0367_readbits(state, F367TER_TPS_HPCODE);
1982
1983 switch (Data) {
1984 case 0:
1985 op->code_rate_HP = FEC_1_2;
1986 break;
1987 case 1:
1988 op->code_rate_HP = FEC_2_3;
1989 break;
1990 case 2:
1991 op->code_rate_HP = FEC_3_4;
1992 break;
1993 case 3:
1994 op->code_rate_HP = FEC_5_6;
1995 break;
1996 case 4:
1997 op->code_rate_HP = FEC_7_8;
1998 break;
1999 default:
2000 op->code_rate_HP = FEC_AUTO;
2001 break; /* error */
2002 }
2003
2004 mode = stv0367_readbits(state, F367TER_SYR_MODE);
2005
2006 switch (mode) {
2007 case FE_TER_MODE_2K:
2008 op->transmission_mode = TRANSMISSION_MODE_2K;
2009 break;
2010/* case FE_TER_MODE_4K:
2011 op->transmission_mode = TRANSMISSION_MODE_4K;
2012 break;*/
2013 case FE_TER_MODE_8K:
2014 op->transmission_mode = TRANSMISSION_MODE_8K;
2015 break;
2016 default:
2017 op->transmission_mode = TRANSMISSION_MODE_AUTO;
2018 }
2019
2020 op->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
2021
2022 return error;
2023}
2024
2025static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
2026{
2027 struct stv0367_state *state = fe->demodulator_priv;
2028 u32 snru32 = 0;
2029 int cpt = 0;
2030 u8 cut = stv0367_readbits(state, F367TER_IDENTIFICATIONREG);
2031
2032 while (cpt < 10) {
2033 usleep_range(2000, 3000);
2034 if (cut == 0x50) /*cut 1.0 cut 1.1*/
2035 snru32 += stv0367_readbits(state, F367TER_CHCSNR) / 4;
2036 else /*cu2.0*/
2037 snru32 += 125 * stv0367_readbits(state, F367TER_CHCSNR);
2038
2039 cpt++;
2040 }
2041
2042 snru32 /= 10;/*average on 10 values*/
2043
2044 *snr = snru32 / 1000;
2045
2046 return 0;
2047}
2048
2049#if 0
2050static int stv0367ter_status(struct dvb_frontend *fe)
2051{
2052
2053 struct stv0367_state *state = fe->demodulator_priv;
2054 struct stv0367ter_state *ter_state = state->ter_state;
2055 int locked = FALSE;
2056
2057 locked = (stv0367_readbits(state, F367TER_LK));
2058 if (!locked)
2059 ter_state->unlock_counter += 1;
2060 else
2061 ter_state->unlock_counter = 0;
2062
2063 if (ter_state->unlock_counter > 2) {
2064 if (!stv0367_readbits(state, F367TER_TPS_LOCK) ||
2065 (!stv0367_readbits(state, F367TER_LK))) {
2066 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
2067 usleep_range(2000, 3000);
2068 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
2069 msleep(350);
2070 locked = (stv0367_readbits(state, F367TER_TPS_LOCK)) &&
2071 (stv0367_readbits(state, F367TER_LK));
2072 }
2073
2074 }
2075
2076 return locked;
2077}
2078#endif
2079static int stv0367ter_read_status(struct dvb_frontend *fe, fe_status_t *status)
2080{
2081 struct stv0367_state *state = fe->demodulator_priv;
2082
2083 dprintk("%s:\n", __func__);
2084
2085 *status = 0;
2086
2087 if (stv0367_readbits(state, F367TER_LK)) {
2088 *status |= FE_HAS_LOCK;
2089 dprintk("%s: stv0367 has locked\n", __func__);
2090 }
2091
2092 return 0;
2093}
2094
2095static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
2096{
2097 struct stv0367_state *state = fe->demodulator_priv;
2098 struct stv0367ter_state *ter_state = state->ter_state;
2099 u32 Errors = 0, tber = 0, temporary = 0;
2100 int abc = 0, def = 0;
2101
2102
2103 /*wait for counting completion*/
2104 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0)
2105 Errors = ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT)
2106 * (1 << 16))
2107 + ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT_HI)
2108 * (1 << 8))
2109 + ((u32)stv0367_readbits(state,
2110 F367TER_SFEC_ERR_CNT_LO));
2111 /*measurement not completed, load previous value*/
2112 else {
2113 tber = ter_state->pBER;
2114 return 0;
2115 }
2116
2117 abc = stv0367_readbits(state, F367TER_SFEC_ERR_SOURCE);
2118 def = stv0367_readbits(state, F367TER_SFEC_NUM_EVENT);
2119
2120 if (Errors == 0) {
2121 tber = 0;
2122 } else if (abc == 0x7) {
2123 if (Errors <= 4) {
2124 temporary = (Errors * 1000000000) / (8 * (1 << 14));
2125 temporary = temporary;
2126 } else if (Errors <= 42) {
2127 temporary = (Errors * 100000000) / (8 * (1 << 14));
2128 temporary = temporary * 10;
2129 } else if (Errors <= 429) {
2130 temporary = (Errors * 10000000) / (8 * (1 << 14));
2131 temporary = temporary * 100;
2132 } else if (Errors <= 4294) {
2133 temporary = (Errors * 1000000) / (8 * (1 << 14));
2134 temporary = temporary * 1000;
2135 } else if (Errors <= 42949) {
2136 temporary = (Errors * 100000) / (8 * (1 << 14));
2137 temporary = temporary * 10000;
2138 } else if (Errors <= 429496) {
2139 temporary = (Errors * 10000) / (8 * (1 << 14));
2140 temporary = temporary * 100000;
2141 } else { /*if (Errors<4294967) 2^22 max error*/
2142 temporary = (Errors * 1000) / (8 * (1 << 14));
2143 temporary = temporary * 100000; /* still to *10 */
2144 }
2145
2146 /* Byte error*/
2147 if (def == 2)
2148 /*tber=Errors/(8*(1 <<14));*/
2149 tber = temporary;
2150 else if (def == 3)
2151 /*tber=Errors/(8*(1 <<16));*/
2152 tber = temporary / 4;
2153 else if (def == 4)
2154 /*tber=Errors/(8*(1 <<18));*/
2155 tber = temporary / 16;
2156 else if (def == 5)
2157 /*tber=Errors/(8*(1 <<20));*/
2158 tber = temporary / 64;
2159 else if (def == 6)
2160 /*tber=Errors/(8*(1 <<22));*/
2161 tber = temporary / 256;
2162 else
2163 /* should not pass here*/
2164 tber = 0;
2165
2166 if ((Errors < 4294967) && (Errors > 429496))
2167 tber *= 10;
2168
2169 }
2170
2171 /* save actual value */
2172 ter_state->pBER = tber;
2173
2174 (*ber) = tber;
2175
2176 return 0;
2177}
2178#if 0
2179static u32 stv0367ter_get_per(struct stv0367_state *state)
2180{
2181 struct stv0367ter_state *ter_state = state->ter_state;
2182 u32 Errors = 0, Per = 0, temporary = 0;
2183 int abc = 0, def = 0, cpt = 0;
2184
2185 while (((stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 1) &&
2186 (cpt < 400)) || ((Errors == 0) && (cpt < 400))) {
2187 usleep_range(1000, 2000);
2188 Errors = ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
2189 * (1 << 16))
2190 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
2191 * (1 << 8))
2192 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
2193 cpt++;
2194 }
2195 abc = stv0367_readbits(state, F367TER_ERR_SRC1);
2196 def = stv0367_readbits(state, F367TER_NUM_EVT1);
2197
2198 if (Errors == 0)
2199 Per = 0;
2200 else if (abc == 0x9) {
2201 if (Errors <= 4) {
2202 temporary = (Errors * 1000000000) / (8 * (1 << 8));
2203 temporary = temporary;
2204 } else if (Errors <= 42) {
2205 temporary = (Errors * 100000000) / (8 * (1 << 8));
2206 temporary = temporary * 10;
2207 } else if (Errors <= 429) {
2208 temporary = (Errors * 10000000) / (8 * (1 << 8));
2209 temporary = temporary * 100;
2210 } else if (Errors <= 4294) {
2211 temporary = (Errors * 1000000) / (8 * (1 << 8));
2212 temporary = temporary * 1000;
2213 } else if (Errors <= 42949) {
2214 temporary = (Errors * 100000) / (8 * (1 << 8));
2215 temporary = temporary * 10000;
2216 } else { /*if(Errors<=429496) 2^16 errors max*/
2217 temporary = (Errors * 10000) / (8 * (1 << 8));
2218 temporary = temporary * 100000;
2219 }
2220
2221 /* pkt error*/
2222 if (def == 2)
2223 /*Per=Errors/(1 << 8);*/
2224 Per = temporary;
2225 else if (def == 3)
2226 /*Per=Errors/(1 << 10);*/
2227 Per = temporary / 4;
2228 else if (def == 4)
2229 /*Per=Errors/(1 << 12);*/
2230 Per = temporary / 16;
2231 else if (def == 5)
2232 /*Per=Errors/(1 << 14);*/
2233 Per = temporary / 64;
2234 else if (def == 6)
2235 /*Per=Errors/(1 << 16);*/
2236 Per = temporary / 256;
2237 else
2238 Per = 0;
2239
2240 }
2241 /* save actual value */
2242 ter_state->pPER = Per;
2243
2244 return Per;
2245}
2246#endif
2247static int stv0367_get_tune_settings(struct dvb_frontend *fe,
2248 struct dvb_frontend_tune_settings
2249 *fe_tune_settings)
2250{
2251 fe_tune_settings->min_delay_ms = 1000;
2252 fe_tune_settings->step_size = 0;
2253 fe_tune_settings->max_drift = 0;
2254
2255 return 0;
2256}
2257
2258static void stv0367_release(struct dvb_frontend *fe)
2259{
2260 struct stv0367_state *state = fe->demodulator_priv;
2261
2262 kfree(state->ter_state);
2263 kfree(state->cab_state);
2264 kfree(state);
2265}
2266
2267static struct dvb_frontend_ops stv0367ter_ops = {
2268 .info = {
2269 .name = "ST STV0367 DVB-T",
2270 .type = FE_OFDM,
2271 .frequency_min = 47000000,
2272 .frequency_max = 862000000,
2273 .frequency_stepsize = 15625,
2274 .frequency_tolerance = 0,
2275 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
2276 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
2277 FE_CAN_FEC_AUTO |
2278 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
2279 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
2280 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
2281 FE_CAN_INVERSION_AUTO |
2282 FE_CAN_MUTE_TS
2283 },
2284 .release = stv0367_release,
2285 .init = stv0367ter_init,
2286 .sleep = stv0367ter_sleep,
2287 .i2c_gate_ctrl = stv0367ter_gate_ctrl,
2288 .set_frontend = stv0367ter_set_frontend,
2289 .get_frontend = stv0367ter_get_frontend,
2290 .get_tune_settings = stv0367_get_tune_settings,
2291 .read_status = stv0367ter_read_status,
2292 .read_ber = stv0367ter_read_ber,/* too slow */
2293/* .read_signal_strength = stv0367_read_signal_strength,*/
2294 .read_snr = stv0367ter_read_snr,
2295 .read_ucblocks = stv0367ter_read_ucblocks,
2296};
2297
2298struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
2299 struct i2c_adapter *i2c)
2300{
2301 struct stv0367_state *state = NULL;
2302 struct stv0367ter_state *ter_state = NULL;
2303
2304 /* allocate memory for the internal state */
2305 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
2306 if (state == NULL)
2307 goto error;
2308 ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL);
2309 if (ter_state == NULL)
2310 goto error;
2311
2312 /* setup the state */
2313 state->i2c = i2c;
2314 state->config = config;
2315 state->ter_state = ter_state;
2316 state->fe.ops = stv0367ter_ops;
2317 state->fe.demodulator_priv = state;
2318 state->chip_id = stv0367_readreg(state, 0xf000);
2319
2320 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
2321
2322 /* check if the demod is there */
2323 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
2324 goto error;
2325
2326 return &state->fe;
2327
2328error:
2329 kfree(ter_state);
2330 kfree(state);
2331 return NULL;
2332}
2333EXPORT_SYMBOL(stv0367ter_attach);
2334
2335static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
2336{
2337 struct stv0367_state *state = fe->demodulator_priv;
2338
2339 dprintk("%s:\n", __func__);
2340
2341 stv0367_writebits(state, F367CAB_I2CT_ON, (enable > 0) ? 1 : 0);
2342
2343 return 0;
2344}
2345
2346static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz)
2347{
2348 struct stv0367_state *state = fe->demodulator_priv;
2349 u32 mclk_Hz = 0;/* master clock frequency (Hz) */
2350 u32 M, N, P;
2351
2352
2353 if (stv0367_readbits(state, F367CAB_BYPASS_PLLXN) == 0) {
2354 N = (u32)stv0367_readbits(state, F367CAB_PLL_NDIV);
2355 if (N == 0)
2356 N = N + 1;
2357
2358 M = (u32)stv0367_readbits(state, F367CAB_PLL_MDIV);
2359 if (M == 0)
2360 M = M + 1;
2361
2362 P = (u32)stv0367_readbits(state, F367CAB_PLL_PDIV);
2363
2364 if (P > 5)
2365 P = 5;
2366
2367 mclk_Hz = ((ExtClk_Hz / 2) * N) / (M * (1 << P));
2368 dprintk("stv0367cab_get_mclk BYPASS_PLLXN mclk_Hz=%d\n",
2369 mclk_Hz);
2370 } else
2371 mclk_Hz = ExtClk_Hz;
2372
2373 dprintk("stv0367cab_get_mclk final mclk_Hz=%d\n", mclk_Hz);
2374
2375 return mclk_Hz;
2376}
2377
2378static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
2379{
2380 u32 ADCClk_Hz = ExtClk_Hz;
2381
2382 ADCClk_Hz = stv0367cab_get_mclk(fe, ExtClk_Hz);
2383
2384 return ADCClk_Hz;
2385}
2386
2387enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
2388 u32 SymbolRate,
2389 enum stv0367cab_mod QAMSize)
2390{
2391 /* Set QAM size */
2392 stv0367_writebits(state, F367CAB_QAM_MODE, QAMSize);
2393
2394 /* Set Registers settings specific to the QAM size */
2395 switch (QAMSize) {
2396 case FE_CAB_MOD_QAM4:
2397 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2398 break;
2399 case FE_CAB_MOD_QAM16:
2400 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x64);
2401 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2402 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2403 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2404 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2405 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2406 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2407 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x8a);
2408 break;
2409 case FE_CAB_MOD_QAM32:
2410 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2411 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x6e);
2412 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2413 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2414 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xb7);
2415 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x9d);
2416 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2417 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2418 break;
2419 case FE_CAB_MOD_QAM64:
2420 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x82);
2421 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2422 if (SymbolRate > 45000000) {
2423 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2424 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2425 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa5);
2426 } else if (SymbolRate > 25000000) {
2427 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2428 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2429 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2430 } else {
2431 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2432 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2433 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2434 }
2435 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2436 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2437 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x99);
2438 break;
2439 case FE_CAB_MOD_QAM128:
2440 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2441 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x76);
2442 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2443 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xb1);
2444 if (SymbolRate > 45000000)
2445 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2446 else if (SymbolRate > 25000000)
2447 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2448 else
2449 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0x97);
2450
2451 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x8e);
2452 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2453 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2454 break;
2455 case FE_CAB_MOD_QAM256:
2456 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x94);
2457 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2458 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2459 if (SymbolRate > 45000000)
2460 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2461 else if (SymbolRate > 25000000)
2462 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2463 else
2464 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2465
2466 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2467 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x85);
2468 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2469 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2470 break;
2471 case FE_CAB_MOD_QAM512:
2472 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2473 break;
2474 case FE_CAB_MOD_QAM1024:
2475 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2476 break;
2477 default:
2478 break;
2479 }
2480
2481 return QAMSize;
2482}
2483
2484static u32 stv0367cab_set_derot_freq(struct stv0367_state *state,
2485 u32 adc_hz, s32 derot_hz)
2486{
2487 u32 sampled_if = 0;
2488 u32 adc_khz;
2489
2490 adc_khz = adc_hz / 1000;
2491
2492 dprintk("%s: adc_hz=%d derot_hz=%d\n", __func__, adc_hz, derot_hz);
2493
2494 if (adc_khz != 0) {
2495 if (derot_hz < 1000000)
2496 derot_hz = adc_hz / 4; /* ZIF operation */
2497 if (derot_hz > adc_hz)
2498 derot_hz = derot_hz - adc_hz;
2499 sampled_if = (u32)derot_hz / 1000;
2500 sampled_if *= 32768;
2501 sampled_if /= adc_khz;
2502 sampled_if *= 256;
2503 }
2504
2505 if (sampled_if > 8388607)
2506 sampled_if = 8388607;
2507
2508 dprintk("%s: sampled_if=0x%x\n", __func__, sampled_if);
2509
2510 stv0367_writereg(state, R367CAB_MIX_NCO_LL, sampled_if);
2511 stv0367_writereg(state, R367CAB_MIX_NCO_HL, (sampled_if >> 8));
2512 stv0367_writebits(state, F367CAB_MIX_NCO_INC_HH, (sampled_if >> 16));
2513
2514 return derot_hz;
2515}
2516
2517static u32 stv0367cab_get_derot_freq(struct stv0367_state *state, u32 adc_hz)
2518{
2519 u32 sampled_if;
2520
2521 sampled_if = stv0367_readbits(state, F367CAB_MIX_NCO_INC_LL) +
2522 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HL) << 8) +
2523 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HH) << 16);
2524
2525 sampled_if /= 256;
2526 sampled_if *= (adc_hz / 1000);
2527 sampled_if += 1;
2528 sampled_if /= 32768;
2529
2530 return sampled_if;
2531}
2532
2533static u32 stv0367cab_set_srate(struct stv0367_state *state, u32 adc_hz,
2534 u32 mclk_hz, u32 SymbolRate,
2535 enum stv0367cab_mod QAMSize)
2536{
2537 u32 QamSizeCorr = 0;
2538 u32 u32_tmp = 0, u32_tmp1 = 0;
2539 u32 adp_khz;
2540
2541 dprintk("%s:\n", __func__);
2542
2543 /* Set Correction factor of SRC gain */
2544 switch (QAMSize) {
2545 case FE_CAB_MOD_QAM4:
2546 QamSizeCorr = 1110;
2547 break;
2548 case FE_CAB_MOD_QAM16:
2549 QamSizeCorr = 1032;
2550 break;
2551 case FE_CAB_MOD_QAM32:
2552 QamSizeCorr = 954;
2553 break;
2554 case FE_CAB_MOD_QAM64:
2555 QamSizeCorr = 983;
2556 break;
2557 case FE_CAB_MOD_QAM128:
2558 QamSizeCorr = 957;
2559 break;
2560 case FE_CAB_MOD_QAM256:
2561 QamSizeCorr = 948;
2562 break;
2563 case FE_CAB_MOD_QAM512:
2564 QamSizeCorr = 0;
2565 break;
2566 case FE_CAB_MOD_QAM1024:
2567 QamSizeCorr = 944;
2568 break;
2569 default:
2570 break;
2571 }
2572
2573 /* Transfer ratio calculation */
2574 if (adc_hz != 0) {
2575 u32_tmp = 256 * SymbolRate;
2576 u32_tmp = u32_tmp / adc_hz;
2577 }
2578 stv0367_writereg(state, R367CAB_EQU_CRL_TFR, (u8)u32_tmp);
2579
2580 /* Symbol rate and SRC gain calculation */
2581 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2582 if (adp_khz != 0) {
2583 u32_tmp = SymbolRate;
2584 u32_tmp1 = SymbolRate;
2585
2586 if (u32_tmp < 2097152) { /* 2097152 = 2^21 */
2587 /* Symbol rate calculation */
2588 u32_tmp *= 2048; /* 2048 = 2^11 */
2589 u32_tmp = u32_tmp / adp_khz;
2590 u32_tmp = u32_tmp * 16384; /* 16384 = 2^14 */
2591 u32_tmp /= 125 ; /* 125 = 1000/2^3 */
2592 u32_tmp = u32_tmp * 8; /* 8 = 2^3 */
2593
2594 /* SRC Gain Calculation */
2595 u32_tmp1 *= 2048; /* *2*2^10 */
2596 u32_tmp1 /= 439; /* *2/878 */
2597 u32_tmp1 *= 256; /* *2^8 */
2598 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2599 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2600 u32_tmp1 = u32_tmp1 / 10000000;
2601
2602 } else if (u32_tmp < 4194304) { /* 4194304 = 2**22 */
2603 /* Symbol rate calculation */
2604 u32_tmp *= 1024 ; /* 1024 = 2**10 */
2605 u32_tmp = u32_tmp / adp_khz;
2606 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2607 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2608 u32_tmp = u32_tmp * 16; /* 16 = 2**4 */
2609
2610 /* SRC Gain Calculation */
2611 u32_tmp1 *= 1024; /* *2*2^9 */
2612 u32_tmp1 /= 439; /* *2/878 */
2613 u32_tmp1 *= 256; /* *2^8 */
2614 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz)*/
2615 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2616 u32_tmp1 = u32_tmp1 / 5000000;
2617 } else if (u32_tmp < 8388607) { /* 8388607 = 2**23 */
2618 /* Symbol rate calculation */
2619 u32_tmp *= 512 ; /* 512 = 2**9 */
2620 u32_tmp = u32_tmp / adp_khz;
2621 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2622 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2623 u32_tmp = u32_tmp * 32; /* 32 = 2**5 */
2624
2625 /* SRC Gain Calculation */
2626 u32_tmp1 *= 512; /* *2*2^8 */
2627 u32_tmp1 /= 439; /* *2/878 */
2628 u32_tmp1 *= 256; /* *2^8 */
2629 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2630 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2631 u32_tmp1 = u32_tmp1 / 2500000;
2632 } else {
2633 /* Symbol rate calculation */
2634 u32_tmp *= 256 ; /* 256 = 2**8 */
2635 u32_tmp = u32_tmp / adp_khz;
2636 u32_tmp = u32_tmp * 16384; /* 16384 = 2**13 */
2637 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2638 u32_tmp = u32_tmp * 64; /* 64 = 2**6 */
2639
2640 /* SRC Gain Calculation */
2641 u32_tmp1 *= 256; /* 2*2^7 */
2642 u32_tmp1 /= 439; /* *2/878 */
2643 u32_tmp1 *= 256; /* *2^8 */
2644 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2645 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2646 u32_tmp1 = u32_tmp1 / 1250000;
2647 }
2648 }
2649#if 0
2650 /* Filters' coefficients are calculated and written
2651 into registers only if the filters are enabled */
2652 if (stv0367_readbits(state, F367CAB_ADJ_EN)) {
2653 stv0367cab_SetIirAdjacentcoefficient(state, mclk_hz,
2654 SymbolRate);
2655 /* AllPass filter must be enabled
2656 when the adjacents filter is used */
2657 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 1);
2658 stv0367cab_SetAllPasscoefficient(state, mclk_hz, SymbolRate);
2659 } else
2660 /* AllPass filter must be disabled
2661 when the adjacents filter is not used */
2662#endif
2663 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2664
2665 stv0367_writereg(state, R367CAB_SRC_NCO_LL, u32_tmp);
2666 stv0367_writereg(state, R367CAB_SRC_NCO_LH, (u32_tmp >> 8));
2667 stv0367_writereg(state, R367CAB_SRC_NCO_HL, (u32_tmp >> 16));
2668 stv0367_writereg(state, R367CAB_SRC_NCO_HH, (u32_tmp >> 24));
2669
2670 stv0367_writereg(state, R367CAB_IQDEM_GAIN_SRC_L, u32_tmp1 & 0x00ff);
2671 stv0367_writebits(state, F367CAB_GAIN_SRC_HI, (u32_tmp1 >> 8) & 0x00ff);
2672
2673 return SymbolRate ;
2674}
2675
2676static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz)
2677{
2678 u32 regsym;
2679 u32 adp_khz;
2680
2681 regsym = stv0367_readreg(state, R367CAB_SRC_NCO_LL) +
2682 (stv0367_readreg(state, R367CAB_SRC_NCO_LH) << 8) +
2683 (stv0367_readreg(state, R367CAB_SRC_NCO_HL) << 16) +
2684 (stv0367_readreg(state, R367CAB_SRC_NCO_HH) << 24);
2685
2686 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2687
2688 if (regsym < 134217728) { /* 134217728L = 2**27*/
2689 regsym = regsym * 32; /* 32 = 2**5 */
2690 regsym = regsym / 32768; /* 32768L = 2**15 */
2691 regsym = adp_khz * regsym; /* AdpClk in kHz */
2692 regsym = regsym / 128; /* 128 = 2**7 */
2693 regsym *= 125 ; /* 125 = 1000/2**3 */
2694 regsym /= 2048 ; /* 2048 = 2**11 */
2695 } else if (regsym < 268435456) { /* 268435456L = 2**28 */
2696 regsym = regsym * 16; /* 16 = 2**4 */
2697 regsym = regsym / 32768; /* 32768L = 2**15 */
2698 regsym = adp_khz * regsym; /* AdpClk in kHz */
2699 regsym = regsym / 128; /* 128 = 2**7 */
2700 regsym *= 125 ; /* 125 = 1000/2**3*/
2701 regsym /= 1024 ; /* 256 = 2**10*/
2702 } else if (regsym < 536870912) { /* 536870912L = 2**29*/
2703 regsym = regsym * 8; /* 8 = 2**3 */
2704 regsym = regsym / 32768; /* 32768L = 2**15 */
2705 regsym = adp_khz * regsym; /* AdpClk in kHz */
2706 regsym = regsym / 128; /* 128 = 2**7 */
2707 regsym *= 125 ; /* 125 = 1000/2**3 */
2708 regsym /= 512 ; /* 128 = 2**9 */
2709 } else {
2710 regsym = regsym * 4; /* 4 = 2**2 */
2711 regsym = regsym / 32768; /* 32768L = 2**15 */
2712 regsym = adp_khz * regsym; /* AdpClk in kHz */
2713 regsym = regsym / 128; /* 128 = 2**7 */
2714 regsym *= 125 ; /* 125 = 1000/2**3 */
2715 regsym /= 256 ; /* 64 = 2**8 */
2716 }
2717
2718 return regsym;
2719}
2720
2721static int stv0367cab_read_status(struct dvb_frontend *fe, fe_status_t *status)
2722{
2723 struct stv0367_state *state = fe->demodulator_priv;
2724
2725 dprintk("%s:\n", __func__);
2726
2727 *status = 0;
2728
2729 if (stv0367_readbits(state, F367CAB_QAMFEC_LOCK)) {
2730 *status |= FE_HAS_LOCK;
2731 dprintk("%s: stv0367 has locked\n", __func__);
2732 }
2733
2734 return 0;
2735}
2736
2737static int stv0367cab_standby(struct dvb_frontend *fe, u8 standby_on)
2738{
2739 struct stv0367_state *state = fe->demodulator_priv;
2740
2741 dprintk("%s:\n", __func__);
2742
2743 if (standby_on) {
2744 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x03);
2745 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x01);
2746 stv0367_writebits(state, F367CAB_STDBY, 1);
2747 stv0367_writebits(state, F367CAB_STDBY_CORE, 1);
2748 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 0);
2749 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 0);
2750 stv0367_writebits(state, F367CAB_POFFQ, 1);
2751 stv0367_writebits(state, F367CAB_POFFI, 1);
2752 } else {
2753 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x00);
2754 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x00);
2755 stv0367_writebits(state, F367CAB_STDBY, 0);
2756 stv0367_writebits(state, F367CAB_STDBY_CORE, 0);
2757 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 1);
2758 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 1);
2759 stv0367_writebits(state, F367CAB_POFFQ, 0);
2760 stv0367_writebits(state, F367CAB_POFFI, 0);
2761 }
2762
2763 return 0;
2764}
2765
2766static int stv0367cab_sleep(struct dvb_frontend *fe)
2767{
2768 return stv0367cab_standby(fe, 1);
2769}
2770
2771int stv0367cab_init(struct dvb_frontend *fe)
2772{
2773 struct stv0367_state *state = fe->demodulator_priv;
2774 struct stv0367cab_state *cab_state = state->cab_state;
2775 int i;
2776
2777 dprintk("%s:\n", __func__);
2778
2779 for (i = 0; i < STV0367CAB_NBREGS; i++)
2780 stv0367_writereg(state, def0367cab[i].addr,
2781 def0367cab[i].value);
2782
2783 switch (state->config->ts_mode) {
2784 case STV0367_DVBCI_CLOCK:
2785 dprintk("Setting TSMode = STV0367_DVBCI_CLOCK\n");
2786 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x03);
2787 break;
2788 case STV0367_SERIAL_PUNCT_CLOCK:
2789 case STV0367_SERIAL_CONT_CLOCK:
2790 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x01);
2791 break;
2792 case STV0367_PARALLEL_PUNCT_CLOCK:
2793 case STV0367_OUTPUTMODE_DEFAULT:
2794 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x00);
2795 break;
2796 }
2797
2798 switch (state->config->clk_pol) {
2799 case STV0367_RISINGEDGE_CLOCK:
2800 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x00);
2801 break;
2802 case STV0367_FALLINGEDGE_CLOCK:
2803 case STV0367_CLOCKPOLARITY_DEFAULT:
2804 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x01);
2805 break;
2806 }
2807
2808 stv0367_writebits(state, F367CAB_SYNC_STRIP, 0x00);
2809
2810 stv0367_writebits(state, F367CAB_CT_NBST, 0x01);
2811
2812 stv0367_writebits(state, F367CAB_TS_SWAP, 0x01);
2813
2814 stv0367_writebits(state, F367CAB_FIFO_BYPASS, 0x00);
2815
2816 stv0367_writereg(state, R367CAB_ANACTRL, 0x00);/*PLL enabled and used */
2817
2818 cab_state->mclk = stv0367cab_get_mclk(fe, state->config->xtal);
2819 cab_state->adc_clk = stv0367cab_get_adc_freq(fe, state->config->xtal);
2820
2821 return 0;
2822}
2823static
2824enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
2825 struct dvb_frontend_parameters *param)
2826{
2827 struct dvb_qam_parameters *op = &param->u.qam;
2828 struct stv0367cab_state *cab_state = state->cab_state;
2829 enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC;
2830 u32 QAMFEC_Lock, QAM_Lock, u32_tmp,
2831 LockTime, TRLTimeOut, AGCTimeOut, CRLSymbols,
2832 CRLTimeOut, EQLTimeOut, DemodTimeOut, FECTimeOut;
2833 u8 TrackAGCAccum;
2834 s32 tmp;
2835
2836 dprintk("%s:\n", __func__);
2837
2838 /* Timeouts calculation */
2839 /* A max lock time of 25 ms is allowed for delayed AGC */
2840 AGCTimeOut = 25;
2841 /* 100000 symbols needed by the TRL as a maximum value */
2842 TRLTimeOut = 100000000 / op->symbol_rate;
2843 /* CRLSymbols is the needed number of symbols to achieve a lock
2844 within [-4%, +4%] of the symbol rate.
2845 CRL timeout is calculated
2846 for a lock within [-search_range, +search_range].
2847 EQL timeout can be changed depending on
2848 the micro-reflections we want to handle.
2849 A characterization must be performed
2850 with these echoes to get new timeout values.
2851 */
2852 switch (op->modulation) {
2853 case QAM_16:
2854 CRLSymbols = 150000;
2855 EQLTimeOut = 100;
2856 break;
2857 case QAM_32:
2858 CRLSymbols = 250000;
2859 EQLTimeOut = 100;
2860 break;
2861 case QAM_64:
2862 CRLSymbols = 200000;
2863 EQLTimeOut = 100;
2864 break;
2865 case QAM_128:
2866 CRLSymbols = 250000;
2867 EQLTimeOut = 100;
2868 break;
2869 case QAM_256:
2870 CRLSymbols = 250000;
2871 EQLTimeOut = 100;
2872 break;
2873 default:
2874 CRLSymbols = 200000;
2875 EQLTimeOut = 100;
2876 break;
2877 }
2878#if 0
2879 if (pIntParams->search_range < 0) {
2880 CRLTimeOut = (25 * CRLSymbols *
2881 (-pIntParams->search_range / 1000)) /
2882 (pIntParams->symbol_rate / 1000);
2883 } else
2884#endif
2885 CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) /
2886 (op->symbol_rate / 1000);
2887
2888 CRLTimeOut = (1000 * CRLTimeOut) / op->symbol_rate;
2889 /* Timeouts below 50ms are coerced */
2890 if (CRLTimeOut < 50)
2891 CRLTimeOut = 50;
2892 /* A maximum of 100 TS packets is needed to get FEC lock even in case
2893 the spectrum inversion needs to be changed.
2894 This is equal to 20 ms in case of the lowest symbol rate of 0.87Msps
2895 */
2896 FECTimeOut = 20;
2897 DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut;
2898
2899 dprintk("%s: DemodTimeOut=%d\n", __func__, DemodTimeOut);
2900
2901 /* Reset the TRL to ensure nothing starts until the
2902 AGC is stable which ensures a better lock time
2903 */
2904 stv0367_writereg(state, R367CAB_CTRL_1, 0x04);
2905 /* Set AGC accumulation time to minimum and lock threshold to maximum
2906 in order to speed up the AGC lock */
2907 TrackAGCAccum = stv0367_readbits(state, F367CAB_AGC_ACCUMRSTSEL);
2908 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, 0x0);
2909 /* Modulus Mapper is disabled */
2910 stv0367_writebits(state, F367CAB_MODULUSMAP_EN, 0);
2911 /* Disable the sweep function */
2912 stv0367_writebits(state, F367CAB_SWEEP_EN, 0);
2913 /* The sweep function is never used, Sweep rate must be set to 0 */
2914 /* Set the derotator frequency in Hz */
2915 stv0367cab_set_derot_freq(state, cab_state->adc_clk,
2916 (1000 * (s32)state->config->if_khz + cab_state->derot_offset));
2917 /* Disable the Allpass Filter when the symbol rate is out of range */
2918 if ((op->symbol_rate > 10800000) | (op->symbol_rate < 1800000)) {
2919 stv0367_writebits(state, F367CAB_ADJ_EN, 0);
2920 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2921 }
2922#if 0
2923 /* Check if the tuner is locked */
2924 tuner_lock = stv0367cab_tuner_get_status(fe);
2925 if (tuner_lock == 0)
2926 return FE_367CAB_NOTUNER;
2927#endif
2928 /* Relase the TRL to start demodulator acquisition */
2929 /* Wait for QAM lock */
2930 LockTime = 0;
2931 stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
2932 do {
2933 QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS);
2934 if ((LockTime >= (DemodTimeOut - EQLTimeOut)) &&
2935 (QAM_Lock == 0x04))
2936 /*
2937 * We don't wait longer, the frequency/phase offset
2938 * must be too big
2939 */
2940 LockTime = DemodTimeOut;
2941 else if ((LockTime >= (AGCTimeOut + TRLTimeOut)) &&
2942 (QAM_Lock == 0x02))
2943 /*
2944 * We don't wait longer, either there is no signal or
2945 * it is not the right symbol rate or it is an analog
2946 * carrier
2947 */
2948 {
2949 LockTime = DemodTimeOut;
2950 u32_tmp = stv0367_readbits(state,
2951 F367CAB_AGC_PWR_WORD_LO) +
2952 (stv0367_readbits(state,
2953 F367CAB_AGC_PWR_WORD_ME) << 8) +
2954 (stv0367_readbits(state,
2955 F367CAB_AGC_PWR_WORD_HI) << 16);
2956 if (u32_tmp >= 131072)
2957 u32_tmp = 262144 - u32_tmp;
2958 u32_tmp = u32_tmp / (1 << (11 - stv0367_readbits(state,
2959 F367CAB_AGC_IF_BWSEL)));
2960
2961 if (u32_tmp < stv0367_readbits(state,
2962 F367CAB_AGC_PWRREF_LO) +
2963 256 * stv0367_readbits(state,
2964 F367CAB_AGC_PWRREF_HI) - 10)
2965 QAM_Lock = 0x0f;
2966 } else {
2967 usleep_range(10000, 20000);
2968 LockTime += 10;
2969 }
2970 dprintk("QAM_Lock=0x%x LockTime=%d\n", QAM_Lock, LockTime);
2971 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2972
2973 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2974
2975 } while (((QAM_Lock != 0x0c) && (QAM_Lock != 0x0b)) &&
2976 (LockTime < DemodTimeOut));
2977
2978 dprintk("QAM_Lock=0x%x\n", QAM_Lock);
2979
2980 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2981 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2982 tmp = stv0367_readreg(state, R367CAB_IT_STATUS2);
2983 dprintk("R367CAB_IT_STATUS2=0x%x\n", tmp);
2984
2985 tmp = stv0367cab_get_derot_freq(state, cab_state->adc_clk);
2986 dprintk("stv0367cab_get_derot_freq=0x%x\n", tmp);
2987
2988 if ((QAM_Lock == 0x0c) || (QAM_Lock == 0x0b)) {
2989 /* Wait for FEC lock */
2990 LockTime = 0;
2991 do {
2992 usleep_range(5000, 7000);
2993 LockTime += 5;
2994 QAMFEC_Lock = stv0367_readbits(state,
2995 F367CAB_QAMFEC_LOCK);
2996 } while (!QAMFEC_Lock && (LockTime < FECTimeOut));
2997 } else
2998 QAMFEC_Lock = 0;
2999
3000 if (QAMFEC_Lock) {
3001 signalType = FE_CAB_DATAOK;
3002 cab_state->modulation = op->modulation;
3003 cab_state->spect_inv = stv0367_readbits(state,
3004 F367CAB_QUAD_INV);
3005#if 0
3006/* not clear for me */
3007 if (state->config->if_khz != 0) {
3008 if (state->config->if_khz > cab_state->adc_clk / 1000) {
3009 cab_state->freq_khz =
3010 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3011 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3012 - cab_state->adc_clk / 1000 + state->config->if_khz;
3013 } else {
3014 cab_state->freq_khz =
3015 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3016 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3017 + state->config->if_khz;
3018 }
3019 } else {
3020 cab_state->freq_khz =
3021 FE_Cab_TunerGetFrequency(pIntParams->hTuner) +
3022 stv0367cab_get_derot_freq(state,
3023 cab_state->adc_clk) -
3024 cab_state->adc_clk / 4000;
3025 }
3026#endif
3027 cab_state->symbol_rate = stv0367cab_GetSymbolRate(state,
3028 cab_state->mclk);
3029 cab_state->locked = 1;
3030
3031 /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/
3032 } else {
3033 switch (QAM_Lock) {
3034 case 1:
3035 signalType = FE_CAB_NOAGC;
3036 break;
3037 case 2:
3038 signalType = FE_CAB_NOTIMING;
3039 break;
3040 case 3:
3041 signalType = FE_CAB_TIMINGOK;
3042 break;
3043 case 4:
3044 signalType = FE_CAB_NOCARRIER;
3045 break;
3046 case 5:
3047 signalType = FE_CAB_CARRIEROK;
3048 break;
3049 case 7:
3050 signalType = FE_CAB_NOBLIND;
3051 break;
3052 case 8:
3053 signalType = FE_CAB_BLINDOK;
3054 break;
3055 case 10:
3056 signalType = FE_CAB_NODEMOD;
3057 break;
3058 case 11:
3059 signalType = FE_CAB_DEMODOK;
3060 break;
3061 case 12:
3062 signalType = FE_CAB_DEMODOK;
3063 break;
3064 case 13:
3065 signalType = FE_CAB_NODEMOD;
3066 break;
3067 case 14:
3068 signalType = FE_CAB_NOBLIND;
3069 break;
3070 case 15:
3071 signalType = FE_CAB_NOSIGNAL;
3072 break;
3073 default:
3074 break;
3075 }
3076
3077 }
3078
3079 /* Set the AGC control values to tracking values */
3080 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum);
3081 return signalType;
3082}
3083
3084static int stv0367cab_set_frontend(struct dvb_frontend *fe,
3085 struct dvb_frontend_parameters *param)
3086{
3087 struct stv0367_state *state = fe->demodulator_priv;
3088 struct stv0367cab_state *cab_state = state->cab_state;
3089 struct dvb_qam_parameters *op = &param->u.qam;
3090 enum stv0367cab_mod QAMSize = 0;
3091
3092 dprintk("%s: freq = %d, srate = %d\n", __func__,
3093 param->frequency, op->symbol_rate);
3094
3095 cab_state->derot_offset = 0;
3096
3097 switch (op->modulation) {
3098 case QAM_16:
3099 QAMSize = FE_CAB_MOD_QAM16;
3100 break;
3101 case QAM_32:
3102 QAMSize = FE_CAB_MOD_QAM32;
3103 break;
3104 case QAM_64:
3105 QAMSize = FE_CAB_MOD_QAM64;
3106 break;
3107 case QAM_128:
3108 QAMSize = FE_CAB_MOD_QAM128;
3109 break;
3110 case QAM_256:
3111 QAMSize = FE_CAB_MOD_QAM256;
3112 break;
3113 default:
3114 break;
3115 }
3116
3117 stv0367cab_init(fe);
3118
3119 /* Tuner Frequency Setting */
3120 if (fe->ops.tuner_ops.set_params) {
3121 if (fe->ops.i2c_gate_ctrl)
3122 fe->ops.i2c_gate_ctrl(fe, 1);
3123 fe->ops.tuner_ops.set_params(fe, param);
3124 if (fe->ops.i2c_gate_ctrl)
3125 fe->ops.i2c_gate_ctrl(fe, 0);
3126 }
3127
3128 stv0367cab_SetQamSize(
3129 state,
3130 op->symbol_rate,
3131 QAMSize);
3132
3133 stv0367cab_set_srate(state,
3134 cab_state->adc_clk,
3135 cab_state->mclk,
3136 op->symbol_rate,
3137 QAMSize);
3138 /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */
3139 cab_state->state = stv0367cab_algo(state, param);
3140 return 0;
3141}
3142
3143static int stv0367cab_get_frontend(struct dvb_frontend *fe,
3144 struct dvb_frontend_parameters *param)
3145{
3146 struct stv0367_state *state = fe->demodulator_priv;
3147 struct stv0367cab_state *cab_state = state->cab_state;
3148 struct dvb_qam_parameters *op = &param->u.qam;
3149
3150 enum stv0367cab_mod QAMSize;
3151
3152 dprintk("%s:\n", __func__);
3153
3154 op->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk);
3155
3156 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3157 switch (QAMSize) {
3158 case FE_CAB_MOD_QAM16:
3159 op->modulation = QAM_16;
3160 break;
3161 case FE_CAB_MOD_QAM32:
3162 op->modulation = QAM_32;
3163 break;
3164 case FE_CAB_MOD_QAM64:
3165 op->modulation = QAM_64;
3166 break;
3167 case FE_CAB_MOD_QAM128:
3168 op->modulation = QAM_128;
3169 break;
3170 case QAM_256:
3171 op->modulation = QAM_256;
3172 break;
3173 default:
3174 break;
3175 }
3176
3177 param->frequency = stv0367_get_tuner_freq(fe);
3178
3179 dprintk("%s: tuner frequency = %d\n", __func__, param->frequency);
3180
3181 if (state->config->if_khz == 0) {
3182 param->frequency +=
3183 (stv0367cab_get_derot_freq(state, cab_state->adc_clk) -
3184 cab_state->adc_clk / 4000);
3185 return 0;
3186 }
3187
3188 if (state->config->if_khz > cab_state->adc_clk / 1000)
3189 param->frequency += (state->config->if_khz
3190 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3191 - cab_state->adc_clk / 1000);
3192 else
3193 param->frequency += (state->config->if_khz
3194 - stv0367cab_get_derot_freq(state, cab_state->adc_clk));
3195
3196 return 0;
3197}
3198
3199#if 0
3200void stv0367cab_GetErrorCount(state, enum stv0367cab_mod QAMSize,
3201 u32 symbol_rate, FE_367qam_Monitor *Monitor_results)
3202{
3203 stv0367cab_OptimiseNByteAndGetBER(state, QAMSize, symbol_rate, Monitor_results);
3204 stv0367cab_GetPacketsCount(state, Monitor_results);
3205
3206 return;
3207}
3208
3209static int stv0367cab_read_ber(struct dvb_frontend *fe, u32 *ber)
3210{
3211 struct stv0367_state *state = fe->demodulator_priv;
3212
3213 return 0;
3214}
3215#endif
3216static s32 stv0367cab_get_rf_lvl(struct stv0367_state *state)
3217{
3218 s32 rfLevel = 0;
3219 s32 RfAgcPwm = 0, IfAgcPwm = 0;
3220 u8 i;
3221
3222 stv0367_writebits(state, F367CAB_STDBY_ADCGP, 0x0);
3223
3224 RfAgcPwm =
3225 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_LO) & 0x03) +
3226 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_HI) << 2);
3227 RfAgcPwm = 100 * RfAgcPwm / 1023;
3228
3229 IfAgcPwm =
3230 stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_LO) +
3231 (stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_HI) << 8);
3232 if (IfAgcPwm >= 2048)
3233 IfAgcPwm -= 2048;
3234 else
3235 IfAgcPwm += 2048;
3236
3237 IfAgcPwm = 100 * IfAgcPwm / 4095;
3238
3239 /* For DTT75467 on NIM */
3240 if (RfAgcPwm < 90 && IfAgcPwm < 28) {
3241 for (i = 0; i < RF_LOOKUP_TABLE_SIZE; i++) {
3242 if (RfAgcPwm <= stv0367cab_RF_LookUp1[0][i]) {
3243 rfLevel = (-1) * stv0367cab_RF_LookUp1[1][i];
3244 break;
3245 }
3246 }
3247 if (i == RF_LOOKUP_TABLE_SIZE)
3248 rfLevel = -56;
3249 } else { /*if IF AGC>10*/
3250 for (i = 0; i < RF_LOOKUP_TABLE2_SIZE; i++) {
3251 if (IfAgcPwm <= stv0367cab_RF_LookUp2[0][i]) {
3252 rfLevel = (-1) * stv0367cab_RF_LookUp2[1][i];
3253 break;
3254 }
3255 }
3256 if (i == RF_LOOKUP_TABLE2_SIZE)
3257 rfLevel = -72;
3258 }
3259 return rfLevel;
3260}
3261
3262static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength)
3263{
3264 struct stv0367_state *state = fe->demodulator_priv;
3265
3266 s32 signal = stv0367cab_get_rf_lvl(state);
3267
3268 dprintk("%s: signal=%d dBm\n", __func__, signal);
3269
3270 if (signal <= -72)
3271 *strength = 65535;
3272 else
3273 *strength = (22 + signal) * (-1311);
3274
3275 dprintk("%s: strength=%d\n", __func__, (*strength));
3276
3277 return 0;
3278}
3279
3280static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
3281{
3282 struct stv0367_state *state = fe->demodulator_priv;
3283 u32 noisepercentage;
3284 enum stv0367cab_mod QAMSize;
3285 u32 regval = 0, temp = 0;
3286 int power, i;
3287
3288 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3289 switch (QAMSize) {
3290 case FE_CAB_MOD_QAM4:
3291 power = 21904;
3292 break;
3293 case FE_CAB_MOD_QAM16:
3294 power = 20480;
3295 break;
3296 case FE_CAB_MOD_QAM32:
3297 power = 23040;
3298 break;
3299 case FE_CAB_MOD_QAM64:
3300 power = 21504;
3301 break;
3302 case FE_CAB_MOD_QAM128:
3303 power = 23616;
3304 break;
3305 case FE_CAB_MOD_QAM256:
3306 power = 21760;
3307 break;
3308 case FE_CAB_MOD_QAM512:
3309 power = 1;
3310 break;
3311 case FE_CAB_MOD_QAM1024:
3312 power = 21280;
3313 break;
3314 default:
3315 power = 1;
3316 break;
3317 }
3318
3319 for (i = 0; i < 10; i++) {
3320 regval += (stv0367_readbits(state, F367CAB_SNR_LO)
3321 + 256 * stv0367_readbits(state, F367CAB_SNR_HI));
3322 }
3323
3324 regval /= 10; /*for average over 10 times in for loop above*/
3325 if (regval != 0) {
3326 temp = power
3327 * (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER)));
3328 temp /= regval;
3329 }
3330
3331 /* table values, not needed to calculate logarithms */
3332 if (temp >= 5012)
3333 noisepercentage = 100;
3334 else if (temp >= 3981)
3335 noisepercentage = 93;
3336 else if (temp >= 3162)
3337 noisepercentage = 86;
3338 else if (temp >= 2512)
3339 noisepercentage = 79;
3340 else if (temp >= 1995)
3341 noisepercentage = 72;
3342 else if (temp >= 1585)
3343 noisepercentage = 65;
3344 else if (temp >= 1259)
3345 noisepercentage = 58;
3346 else if (temp >= 1000)
3347 noisepercentage = 50;
3348 else if (temp >= 794)
3349 noisepercentage = 43;
3350 else if (temp >= 501)
3351 noisepercentage = 36;
3352 else if (temp >= 316)
3353 noisepercentage = 29;
3354 else if (temp >= 200)
3355 noisepercentage = 22;
3356 else if (temp >= 158)
3357 noisepercentage = 14;
3358 else if (temp >= 126)
3359 noisepercentage = 7;
3360 else
3361 noisepercentage = 0;
3362
3363 dprintk("%s: noisepercentage=%d\n", __func__, noisepercentage);
3364
3365 *snr = (noisepercentage * 65535) / 100;
3366
3367 return 0;
3368}
3369
3370static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks)
3371{
3372 struct stv0367_state *state = fe->demodulator_priv;
3373 int corrected, tscount;
3374
3375 *ucblocks = (stv0367_readreg(state, R367CAB_RS_COUNTER_5) << 8)
3376 | stv0367_readreg(state, R367CAB_RS_COUNTER_4);
3377 corrected = (stv0367_readreg(state, R367CAB_RS_COUNTER_3) << 8)
3378 | stv0367_readreg(state, R367CAB_RS_COUNTER_2);
3379 tscount = (stv0367_readreg(state, R367CAB_RS_COUNTER_2) << 8)
3380 | stv0367_readreg(state, R367CAB_RS_COUNTER_1);
3381
3382 dprintk("%s: uncorrected blocks=%d corrected blocks=%d tscount=%d\n",
3383 __func__, *ucblocks, corrected, tscount);
3384
3385 return 0;
3386};
3387
3388static struct dvb_frontend_ops stv0367cab_ops = {
3389 .info = {
3390 .name = "ST STV0367 DVB-C",
3391 .type = FE_QAM,
3392 .frequency_min = 47000000,
3393 .frequency_max = 862000000,
3394 .frequency_stepsize = 62500,
3395 .symbol_rate_min = 870000,
3396 .symbol_rate_max = 11700000,
3397 .caps = 0x400 |/* FE_CAN_QAM_4 */
3398 FE_CAN_QAM_16 | FE_CAN_QAM_32 |
3399 FE_CAN_QAM_64 | FE_CAN_QAM_128 |
3400 FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
3401 },
3402 .release = stv0367_release,
3403 .init = stv0367cab_init,
3404 .sleep = stv0367cab_sleep,
3405 .i2c_gate_ctrl = stv0367cab_gate_ctrl,
3406 .set_frontend = stv0367cab_set_frontend,
3407 .get_frontend = stv0367cab_get_frontend,
3408 .read_status = stv0367cab_read_status,
3409/* .read_ber = stv0367cab_read_ber, */
3410 .read_signal_strength = stv0367cab_read_strength,
3411 .read_snr = stv0367cab_read_snr,
3412 .read_ucblocks = stv0367cab_read_ucblcks,
3413 .get_tune_settings = stv0367_get_tune_settings,
3414};
3415
3416struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
3417 struct i2c_adapter *i2c)
3418{
3419 struct stv0367_state *state = NULL;
3420 struct stv0367cab_state *cab_state = NULL;
3421
3422 /* allocate memory for the internal state */
3423 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
3424 if (state == NULL)
3425 goto error;
3426 cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL);
3427 if (cab_state == NULL)
3428 goto error;
3429
3430 /* setup the state */
3431 state->i2c = i2c;
3432 state->config = config;
3433 cab_state->search_range = 280000;
3434 state->cab_state = cab_state;
3435 state->fe.ops = stv0367cab_ops;
3436 state->fe.demodulator_priv = state;
3437 state->chip_id = stv0367_readreg(state, 0xf000);
3438
3439 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
3440
3441 /* check if the demod is there */
3442 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
3443 goto error;
3444
3445 return &state->fe;
3446
3447error:
3448 kfree(cab_state);
3449 kfree(state);
3450 return NULL;
3451}
3452EXPORT_SYMBOL(stv0367cab_attach);
3453
3454MODULE_PARM_DESC(debug, "Set debug");
3455MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
3456
3457MODULE_AUTHOR("Igor M. Liplianin");
3458MODULE_DESCRIPTION("ST STV0367 DVB-C/T demodulator driver");
3459MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0367.h b/drivers/media/dvb/frontends/stv0367.h
new file mode 100644
index 000000000000..93cc4a57eea0
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367.h
@@ -0,0 +1,66 @@
1/*
2 * stv0367.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0367_H
27#define STV0367_H
28
29#include <linux/dvb/frontend.h>
30#include "dvb_frontend.h"
31
32struct stv0367_config {
33 u8 demod_address;
34 u32 xtal;
35 u32 if_khz;/*4500*/
36 int if_iq_mode;
37 int ts_mode;
38 int clk_pol;
39};
40
41#if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \
42 && defined(MODULE))
43extern struct
44dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
45 struct i2c_adapter *i2c);
46extern struct
47dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
48 struct i2c_adapter *i2c);
49#else
50static inline struct
51dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
52 struct i2c_adapter *i2c)
53{
54 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
55 return NULL;
56}
57static inline struct
58dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
59 struct i2c_adapter *i2c)
60{
61 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
62 return NULL;
63}
64#endif
65
66#endif
diff --git a/drivers/media/dvb/frontends/stv0367_priv.h b/drivers/media/dvb/frontends/stv0367_priv.h
new file mode 100644
index 000000000000..995db0689ddd
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367_priv.h
@@ -0,0 +1,212 @@
1/*
2 * stv0367_priv.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25/* Common driver error constants */
26
27#ifndef STV0367_PRIV_H
28#define STV0367_PRIV_H
29
30#ifndef TRUE
31 #define TRUE (1 == 1)
32#endif
33#ifndef FALSE
34 #define FALSE (!TRUE)
35#endif
36
37#ifndef NULL
38#define NULL 0
39#endif
40
41/* MACRO definitions */
42#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
43#define MAX(X, Y) ((X) >= (Y) ? (X) : (Y))
44#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y))
45#define INRANGE(X, Y, Z) \
46 ((((X) <= (Y)) && ((Y) <= (Z))) || \
47 (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
48
49#ifndef MAKEWORD
50#define MAKEWORD(X, Y) (((X) << 8) + (Y))
51#endif
52
53#define LSB(X) (((X) & 0xff))
54#define MSB(Y) (((Y) >> 8) & 0xff)
55#define MMSB(Y)(((Y) >> 16) & 0xff)
56
57enum stv0367_ter_signal_type {
58 FE_TER_NOAGC = 0,
59 FE_TER_AGCOK = 5,
60 FE_TER_NOTPS = 6,
61 FE_TER_TPSOK = 7,
62 FE_TER_NOSYMBOL = 8,
63 FE_TER_BAD_CPQ = 9,
64 FE_TER_PRFOUNDOK = 10,
65 FE_TER_NOPRFOUND = 11,
66 FE_TER_LOCKOK = 12,
67 FE_TER_NOLOCK = 13,
68 FE_TER_SYMBOLOK = 15,
69 FE_TER_CPAMPOK = 16,
70 FE_TER_NOCPAMP = 17,
71 FE_TER_SWNOK = 18
72};
73
74enum stv0367_ts_mode {
75 STV0367_OUTPUTMODE_DEFAULT,
76 STV0367_SERIAL_PUNCT_CLOCK,
77 STV0367_SERIAL_CONT_CLOCK,
78 STV0367_PARALLEL_PUNCT_CLOCK,
79 STV0367_DVBCI_CLOCK
80};
81
82enum stv0367_clk_pol {
83 STV0367_CLOCKPOLARITY_DEFAULT,
84 STV0367_RISINGEDGE_CLOCK,
85 STV0367_FALLINGEDGE_CLOCK
86};
87
88enum stv0367_ter_bw {
89 FE_TER_CHAN_BW_6M = 6,
90 FE_TER_CHAN_BW_7M = 7,
91 FE_TER_CHAN_BW_8M = 8
92};
93
94#if 0
95enum FE_TER_Rate_TPS {
96 FE_TER_TPS_1_2 = 0,
97 FE_TER_TPS_2_3 = 1,
98 FE_TER_TPS_3_4 = 2,
99 FE_TER_TPS_5_6 = 3,
100 FE_TER_TPS_7_8 = 4
101};
102#endif
103
104enum stv0367_ter_mode {
105 FE_TER_MODE_2K,
106 FE_TER_MODE_8K,
107 FE_TER_MODE_4K
108};
109#if 0
110enum FE_TER_Hierarchy_Alpha {
111 FE_TER_HIER_ALPHA_NONE, /* Regular modulation */
112 FE_TER_HIER_ALPHA_1, /* Hierarchical modulation a = 1*/
113 FE_TER_HIER_ALPHA_2, /* Hierarchical modulation a = 2*/
114 FE_TER_HIER_ALPHA_4 /* Hierarchical modulation a = 4*/
115};
116#endif
117enum stv0367_ter_hierarchy {
118 FE_TER_HIER_NONE, /*Hierarchy None*/
119 FE_TER_HIER_LOW_PRIO, /*Hierarchy : Low Priority*/
120 FE_TER_HIER_HIGH_PRIO, /*Hierarchy : High Priority*/
121 FE_TER_HIER_PRIO_ANY /*Hierarchy :Any*/
122};
123
124#if 0
125enum fe_stv0367_ter_spec {
126 FE_TER_INVERSION_NONE = 0,
127 FE_TER_INVERSION = 1,
128 FE_TER_INVERSION_AUTO = 2,
129 FE_TER_INVERSION_UNK = 4
130};
131#endif
132
133enum stv0367_ter_if_iq_mode {
134 FE_TER_NORMAL_IF_TUNER = 0,
135 FE_TER_LONGPATH_IF_TUNER = 1,
136 FE_TER_IQ_TUNER = 2
137
138};
139
140#if 0
141enum FE_TER_FECRate {
142 FE_TER_FEC_NONE = 0x00, /* no FEC rate specified */
143 FE_TER_FEC_ALL = 0xFF, /* Logical OR of all FECs */
144 FE_TER_FEC_1_2 = 1,
145 FE_TER_FEC_2_3 = (1 << 1),
146 FE_TER_FEC_3_4 = (1 << 2),
147 FE_TER_FEC_4_5 = (1 << 3),
148 FE_TER_FEC_5_6 = (1 << 4),
149 FE_TER_FEC_6_7 = (1 << 5),
150 FE_TER_FEC_7_8 = (1 << 6),
151 FE_TER_FEC_8_9 = (1 << 7)
152};
153
154enum FE_TER_Rate {
155 FE_TER_FE_1_2 = 0,
156 FE_TER_FE_2_3 = 1,
157 FE_TER_FE_3_4 = 2,
158 FE_TER_FE_5_6 = 3,
159 FE_TER_FE_6_7 = 4,
160 FE_TER_FE_7_8 = 5
161};
162#endif
163
164enum stv0367_ter_force {
165 FE_TER_FORCENONE = 0,
166 FE_TER_FORCE_M_G = 1
167};
168
169enum stv0367cab_mod {
170 FE_CAB_MOD_QAM4,
171 FE_CAB_MOD_QAM16,
172 FE_CAB_MOD_QAM32,
173 FE_CAB_MOD_QAM64,
174 FE_CAB_MOD_QAM128,
175 FE_CAB_MOD_QAM256,
176 FE_CAB_MOD_QAM512,
177 FE_CAB_MOD_QAM1024
178};
179#if 0
180enum {
181 FE_CAB_FEC_A = 1, /* J83 Annex A */
182 FE_CAB_FEC_B = (1 << 1),/* J83 Annex B */
183 FE_CAB_FEC_C = (1 << 2) /* J83 Annex C */
184} FE_CAB_FECType_t;
185#endif
186struct stv0367_cab_signal_info {
187 int locked;
188 u32 frequency; /* kHz */
189 u32 symbol_rate; /* Mbds */
190 enum stv0367cab_mod modulation;
191 fe_spectral_inversion_t spect_inv;
192 s32 Power_dBmx10; /* Power of the RF signal (dBm x 10) */
193 u32 CN_dBx10; /* Carrier to noise ratio (dB x 10) */
194 u32 BER; /* Bit error rate (x 10000000) */
195};
196
197enum stv0367_cab_signal_type {
198 FE_CAB_NOTUNER,
199 FE_CAB_NOAGC,
200 FE_CAB_NOSIGNAL,
201 FE_CAB_NOTIMING,
202 FE_CAB_TIMINGOK,
203 FE_CAB_NOCARRIER,
204 FE_CAB_CARRIEROK,
205 FE_CAB_NOBLIND,
206 FE_CAB_BLINDOK,
207 FE_CAB_NODEMOD,
208 FE_CAB_DEMODOK,
209 FE_CAB_DATAOK
210};
211
212#endif
diff --git a/drivers/media/dvb/frontends/stv0367_regs.h b/drivers/media/dvb/frontends/stv0367_regs.h
new file mode 100644
index 000000000000..a96fbdc7e25e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367_regs.h
@@ -0,0 +1,3614 @@
1/*
2 * stv0367_regs.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0367_REGS_H
27#define STV0367_REGS_H
28
29/* ID */
30#define R367TER_ID 0xf000
31#define F367TER_IDENTIFICATIONREG 0xf00000ff
32
33/* I2CRPT */
34#define R367TER_I2CRPT 0xf001
35#define F367TER_I2CT_ON 0xf0010080
36#define F367TER_ENARPT_LEVEL 0xf0010070
37#define F367TER_SCLT_DELAY 0xf0010008
38#define F367TER_SCLT_NOD 0xf0010004
39#define F367TER_STOP_ENABLE 0xf0010002
40#define F367TER_SDAT_NOD 0xf0010001
41
42/* TOPCTRL */
43#define R367TER_TOPCTRL 0xf002
44#define F367TER_STDBY 0xf0020080
45#define F367TER_STDBY_FEC 0xf0020040
46#define F367TER_STDBY_CORE 0xf0020020
47#define F367TER_QAM_COFDM 0xf0020010
48#define F367TER_TS_DIS 0xf0020008
49#define F367TER_DIR_CLK_216 0xf0020004
50#define F367TER_TUNER_BB 0xf0020002
51#define F367TER_DVBT_H 0xf0020001
52
53/* IOCFG0 */
54#define R367TER_IOCFG0 0xf003
55#define F367TER_OP0_SD 0xf0030080
56#define F367TER_OP0_VAL 0xf0030040
57#define F367TER_OP0_OD 0xf0030020
58#define F367TER_OP0_INV 0xf0030010
59#define F367TER_OP0_DACVALUE_HI 0xf003000f
60
61/* DAc0R */
62#define R367TER_DAC0R 0xf004
63#define F367TER_OP0_DACVALUE_LO 0xf00400ff
64
65/* IOCFG1 */
66#define R367TER_IOCFG1 0xf005
67#define F367TER_IP0 0xf0050040
68#define F367TER_OP1_OD 0xf0050020
69#define F367TER_OP1_INV 0xf0050010
70#define F367TER_OP1_DACVALUE_HI 0xf005000f
71
72/* DAC1R */
73#define R367TER_DAC1R 0xf006
74#define F367TER_OP1_DACVALUE_LO 0xf00600ff
75
76/* IOCFG2 */
77#define R367TER_IOCFG2 0xf007
78#define F367TER_OP2_LOCK_CONF 0xf00700e0
79#define F367TER_OP2_OD 0xf0070010
80#define F367TER_OP2_VAL 0xf0070008
81#define F367TER_OP1_LOCK_CONF 0xf0070007
82
83/* SDFR */
84#define R367TER_SDFR 0xf008
85#define F367TER_OP0_FREQ 0xf00800f0
86#define F367TER_OP1_FREQ 0xf008000f
87
88/* STATUS */
89#define R367TER_STATUS 0xf009
90#define F367TER_TPS_LOCK 0xf0090080
91#define F367TER_SYR_LOCK 0xf0090040
92#define F367TER_AGC_LOCK 0xf0090020
93#define F367TER_PRF 0xf0090010
94#define F367TER_LK 0xf0090008
95#define F367TER_PR 0xf0090007
96
97/* AUX_CLK */
98#define R367TER_AUX_CLK 0xf00a
99#define F367TER_AUXFEC_CTL 0xf00a00c0
100#define F367TER_DIS_CKX4 0xf00a0020
101#define F367TER_CKSEL 0xf00a0018
102#define F367TER_CKDIV_PROG 0xf00a0006
103#define F367TER_AUXCLK_ENA 0xf00a0001
104
105/* FREESYS1 */
106#define R367TER_FREESYS1 0xf00b
107#define F367TER_FREE_SYS1 0xf00b00ff
108
109/* FREESYS2 */
110#define R367TER_FREESYS2 0xf00c
111#define F367TER_FREE_SYS2 0xf00c00ff
112
113/* FREESYS3 */
114#define R367TER_FREESYS3 0xf00d
115#define F367TER_FREE_SYS3 0xf00d00ff
116
117/* GPIO_CFG */
118#define R367TER_GPIO_CFG 0xf00e
119#define F367TER_GPIO7_NOD 0xf00e0080
120#define F367TER_GPIO7_CFG 0xf00e0040
121#define F367TER_GPIO6_NOD 0xf00e0020
122#define F367TER_GPIO6_CFG 0xf00e0010
123#define F367TER_GPIO5_NOD 0xf00e0008
124#define F367TER_GPIO5_CFG 0xf00e0004
125#define F367TER_GPIO4_NOD 0xf00e0002
126#define F367TER_GPIO4_CFG 0xf00e0001
127
128/* GPIO_CMD */
129#define R367TER_GPIO_CMD 0xf00f
130#define F367TER_GPIO7_VAL 0xf00f0008
131#define F367TER_GPIO6_VAL 0xf00f0004
132#define F367TER_GPIO5_VAL 0xf00f0002
133#define F367TER_GPIO4_VAL 0xf00f0001
134
135/* AGC2MAX */
136#define R367TER_AGC2MAX 0xf010
137#define F367TER_AGC2_MAX 0xf01000ff
138
139/* AGC2MIN */
140#define R367TER_AGC2MIN 0xf011
141#define F367TER_AGC2_MIN 0xf01100ff
142
143/* AGC1MAX */
144#define R367TER_AGC1MAX 0xf012
145#define F367TER_AGC1_MAX 0xf01200ff
146
147/* AGC1MIN */
148#define R367TER_AGC1MIN 0xf013
149#define F367TER_AGC1_MIN 0xf01300ff
150
151/* AGCR */
152#define R367TER_AGCR 0xf014
153#define F367TER_RATIO_A 0xf01400e0
154#define F367TER_RATIO_B 0xf0140018
155#define F367TER_RATIO_C 0xf0140007
156
157/* AGC2TH */
158#define R367TER_AGC2TH 0xf015
159#define F367TER_AGC2_THRES 0xf01500ff
160
161/* AGC12c */
162#define R367TER_AGC12C 0xf016
163#define F367TER_AGC1_IV 0xf0160080
164#define F367TER_AGC1_OD 0xf0160040
165#define F367TER_AGC1_LOAD 0xf0160020
166#define F367TER_AGC2_IV 0xf0160010
167#define F367TER_AGC2_OD 0xf0160008
168#define F367TER_AGC2_LOAD 0xf0160004
169#define F367TER_AGC12_MODE 0xf0160003
170
171/* AGCCTRL1 */
172#define R367TER_AGCCTRL1 0xf017
173#define F367TER_DAGC_ON 0xf0170080
174#define F367TER_INVERT_AGC12 0xf0170040
175#define F367TER_AGC1_MODE 0xf0170008
176#define F367TER_AGC2_MODE 0xf0170007
177
178/* AGCCTRL2 */
179#define R367TER_AGCCTRL2 0xf018
180#define F367TER_FRZ2_CTRL 0xf0180060
181#define F367TER_FRZ1_CTRL 0xf0180018
182#define F367TER_TIME_CST 0xf0180007
183
184/* AGC1VAL1 */
185#define R367TER_AGC1VAL1 0xf019
186#define F367TER_AGC1_VAL_LO 0xf01900ff
187
188/* AGC1VAL2 */
189#define R367TER_AGC1VAL2 0xf01a
190#define F367TER_AGC1_VAL_HI 0xf01a000f
191
192/* AGC2VAL1 */
193#define R367TER_AGC2VAL1 0xf01b
194#define F367TER_AGC2_VAL_LO 0xf01b00ff
195
196/* AGC2VAL2 */
197#define R367TER_AGC2VAL2 0xf01c
198#define F367TER_AGC2_VAL_HI 0xf01c000f
199
200/* AGC2PGA */
201#define R367TER_AGC2PGA 0xf01d
202#define F367TER_AGC2_PGA 0xf01d00ff
203
204/* OVF_RATE1 */
205#define R367TER_OVF_RATE1 0xf01e
206#define F367TER_OVF_RATE_HI 0xf01e000f
207
208/* OVF_RATE2 */
209#define R367TER_OVF_RATE2 0xf01f
210#define F367TER_OVF_RATE_LO 0xf01f00ff
211
212/* GAIN_SRC1 */
213#define R367TER_GAIN_SRC1 0xf020
214#define F367TER_INV_SPECTR 0xf0200080
215#define F367TER_IQ_INVERT 0xf0200040
216#define F367TER_INR_BYPASS 0xf0200020
217#define F367TER_STATUS_INV_SPECRUM 0xf0200010
218#define F367TER_GAIN_SRC_HI 0xf020000f
219
220/* GAIN_SRC2 */
221#define R367TER_GAIN_SRC2 0xf021
222#define F367TER_GAIN_SRC_LO 0xf02100ff
223
224/* INC_DEROT1 */
225#define R367TER_INC_DEROT1 0xf022
226#define F367TER_INC_DEROT_HI 0xf02200ff
227
228/* INC_DEROT2 */
229#define R367TER_INC_DEROT2 0xf023
230#define F367TER_INC_DEROT_LO 0xf02300ff
231
232/* PPM_CPAMP_DIR */
233#define R367TER_PPM_CPAMP_DIR 0xf024
234#define F367TER_PPM_CPAMP_DIRECT 0xf02400ff
235
236/* PPM_CPAMP_INV */
237#define R367TER_PPM_CPAMP_INV 0xf025
238#define F367TER_PPM_CPAMP_INVER 0xf02500ff
239
240/* FREESTFE_1 */
241#define R367TER_FREESTFE_1 0xf026
242#define F367TER_SYMBOL_NUMBER_INC 0xf02600c0
243#define F367TER_SEL_LSB 0xf0260004
244#define F367TER_AVERAGE_ON 0xf0260002
245#define F367TER_DC_ADJ 0xf0260001
246
247/* FREESTFE_2 */
248#define R367TER_FREESTFE_2 0xf027
249#define F367TER_SEL_SRCOUT 0xf02700c0
250#define F367TER_SEL_SYRTHR 0xf027001f
251
252/* DCOFFSET */
253#define R367TER_DCOFFSET 0xf028
254#define F367TER_SELECT_I_Q 0xf0280080
255#define F367TER_DC_OFFSET 0xf028007f
256
257/* EN_PROCESS */
258#define R367TER_EN_PROCESS 0xf029
259#define F367TER_FREE 0xf02900f0
260#define F367TER_ENAB_MANUAL 0xf0290001
261
262/* SDI_SMOOTHER */
263#define R367TER_SDI_SMOOTHER 0xf02a
264#define F367TER_DIS_SMOOTH 0xf02a0080
265#define F367TER_SDI_INC_SMOOTHER 0xf02a007f
266
267/* FE_LOOP_OPEN */
268#define R367TER_FE_LOOP_OPEN 0xf02b
269#define F367TER_TRL_LOOP_OP 0xf02b0002
270#define F367TER_CRL_LOOP_OP 0xf02b0001
271
272/* FREQOFF1 */
273#define R367TER_FREQOFF1 0xf02c
274#define F367TER_FREQ_OFFSET_LOOP_OPEN_VHI 0xf02c00ff
275
276/* FREQOFF2 */
277#define R367TER_FREQOFF2 0xf02d
278#define F367TER_FREQ_OFFSET_LOOP_OPEN_HI 0xf02d00ff
279
280/* FREQOFF3 */
281#define R367TER_FREQOFF3 0xf02e
282#define F367TER_FREQ_OFFSET_LOOP_OPEN_LO 0xf02e00ff
283
284/* TIMOFF1 */
285#define R367TER_TIMOFF1 0xf02f
286#define F367TER_TIM_OFFSET_LOOP_OPEN_HI 0xf02f00ff
287
288/* TIMOFF2 */
289#define R367TER_TIMOFF2 0xf030
290#define F367TER_TIM_OFFSET_LOOP_OPEN_LO 0xf03000ff
291
292/* EPQ */
293#define R367TER_EPQ 0xf031
294#define F367TER_EPQ1 0xf03100ff
295
296/* EPQAUTO */
297#define R367TER_EPQAUTO 0xf032
298#define F367TER_EPQ2 0xf03200ff
299
300/* SYR_UPDATE */
301#define R367TER_SYR_UPDATE 0xf033
302#define F367TER_SYR_PROTV 0xf0330080
303#define F367TER_SYR_PROTV_GAIN 0xf0330060
304#define F367TER_SYR_FILTER 0xf0330010
305#define F367TER_SYR_TRACK_THRES 0xf033000c
306
307/* CHPFREE */
308#define R367TER_CHPFREE 0xf034
309#define F367TER_CHP_FREE 0xf03400ff
310
311/* PPM_STATE_MAC */
312#define R367TER_PPM_STATE_MAC 0xf035
313#define F367TER_PPM_STATE_MACHINE_DECODER 0xf035003f
314
315/* INR_THRESHOLD */
316#define R367TER_INR_THRESHOLD 0xf036
317#define F367TER_INR_THRESH 0xf03600ff
318
319/* EPQ_TPS_ID_CELL */
320#define R367TER_EPQ_TPS_ID_CELL 0xf037
321#define F367TER_ENABLE_LGTH_TO_CF 0xf0370080
322#define F367TER_DIS_TPS_RSVD 0xf0370040
323#define F367TER_DIS_BCH 0xf0370020
324#define F367TER_DIS_ID_CEL 0xf0370010
325#define F367TER_TPS_ADJUST_SYM 0xf037000f
326
327/* EPQ_CFG */
328#define R367TER_EPQ_CFG 0xf038
329#define F367TER_EPQ_RANGE 0xf0380002
330#define F367TER_EPQ_SOFT 0xf0380001
331
332/* EPQ_STATUS */
333#define R367TER_EPQ_STATUS 0xf039
334#define F367TER_SLOPE_INC 0xf03900fc
335#define F367TER_TPS_FIELD 0xf0390003
336
337/* AUTORELOCK */
338#define R367TER_AUTORELOCK 0xf03a
339#define F367TER_BYPASS_BER_TEMPO 0xf03a0080
340#define F367TER_BER_TEMPO 0xf03a0070
341#define F367TER_BYPASS_COFDM_TEMPO 0xf03a0008
342#define F367TER_COFDM_TEMPO 0xf03a0007
343
344/* BER_THR_VMSB */
345#define R367TER_BER_THR_VMSB 0xf03b
346#define F367TER_BER_THRESHOLD_HI 0xf03b00ff
347
348/* BER_THR_MSB */
349#define R367TER_BER_THR_MSB 0xf03c
350#define F367TER_BER_THRESHOLD_MID 0xf03c00ff
351
352/* BER_THR_LSB */
353#define R367TER_BER_THR_LSB 0xf03d
354#define F367TER_BER_THRESHOLD_LO 0xf03d00ff
355
356/* CCD */
357#define R367TER_CCD 0xf03e
358#define F367TER_CCD_DETECTED 0xf03e0080
359#define F367TER_CCD_RESET 0xf03e0040
360#define F367TER_CCD_THRESHOLD 0xf03e000f
361
362/* SPECTR_CFG */
363#define R367TER_SPECTR_CFG 0xf03f
364#define F367TER_SPECT_CFG 0xf03f0003
365
366/* CONSTMU_MSB */
367#define R367TER_CONSTMU_MSB 0xf040
368#define F367TER_CONSTMU_FREEZE 0xf0400080
369#define F367TER_CONSTNU_FORCE_EN 0xf0400040
370#define F367TER_CONST_MU_MSB 0xf040003f
371
372/* CONSTMU_LSB */
373#define R367TER_CONSTMU_LSB 0xf041
374#define F367TER_CONST_MU_LSB 0xf04100ff
375
376/* CONSTMU_MAX_MSB */
377#define R367TER_CONSTMU_MAX_MSB 0xf042
378#define F367TER_CONST_MU_MAX_MSB 0xf042003f
379
380/* CONSTMU_MAX_LSB */
381#define R367TER_CONSTMU_MAX_LSB 0xf043
382#define F367TER_CONST_MU_MAX_LSB 0xf04300ff
383
384/* ALPHANOISE */
385#define R367TER_ALPHANOISE 0xf044
386#define F367TER_USE_ALLFILTER 0xf0440080
387#define F367TER_INTER_ON 0xf0440040
388#define F367TER_ALPHA_NOISE 0xf044001f
389
390/* MAXGP_MSB */
391#define R367TER_MAXGP_MSB 0xf045
392#define F367TER_MUFILTER_LENGTH 0xf04500f0
393#define F367TER_MAX_GP_MSB 0xf045000f
394
395/* MAXGP_LSB */
396#define R367TER_MAXGP_LSB 0xf046
397#define F367TER_MAX_GP_LSB 0xf04600ff
398
399/* ALPHAMSB */
400#define R367TER_ALPHAMSB 0xf047
401#define F367TER_CHC_DATARATE 0xf04700c0
402#define F367TER_ALPHA_MSB 0xf047003f
403
404/* ALPHALSB */
405#define R367TER_ALPHALSB 0xf048
406#define F367TER_ALPHA_LSB 0xf04800ff
407
408/* PILOT_ACCU */
409#define R367TER_PILOT_ACCU 0xf049
410#define F367TER_USE_SCAT4ADDAPT 0xf0490080
411#define F367TER_PILOT_ACC 0xf049001f
412
413/* PILOTMU_ACCU */
414#define R367TER_PILOTMU_ACCU 0xf04a
415#define F367TER_DISCARD_BAD_SP 0xf04a0080
416#define F367TER_DISCARD_BAD_CP 0xf04a0040
417#define F367TER_PILOT_MU_ACCU 0xf04a001f
418
419/* FILT_CHANNEL_EST */
420#define R367TER_FILT_CHANNEL_EST 0xf04b
421#define F367TER_USE_FILT_PILOT 0xf04b0080
422#define F367TER_FILT_CHANNEL 0xf04b007f
423
424/* ALPHA_NOPISE_FREQ */
425#define R367TER_ALPHA_NOPISE_FREQ 0xf04c
426#define F367TER_NOISE_FREQ_FILT 0xf04c0040
427#define F367TER_ALPHA_NOISE_FREQ 0xf04c003f
428
429/* RATIO_PILOT */
430#define R367TER_RATIO_PILOT 0xf04d
431#define F367TER_RATIO_MEAN_SP 0xf04d00f0
432#define F367TER_RATIO_MEAN_CP 0xf04d000f
433
434/* CHC_CTL */
435#define R367TER_CHC_CTL 0xf04e
436#define F367TER_TRACK_EN 0xf04e0080
437#define F367TER_NOISE_NORM_EN 0xf04e0040
438#define F367TER_FORCE_CHC_RESET 0xf04e0020
439#define F367TER_SHORT_TIME 0xf04e0010
440#define F367TER_FORCE_STATE_EN 0xf04e0008
441#define F367TER_FORCE_STATE 0xf04e0007
442
443/* EPQ_ADJUST */
444#define R367TER_EPQ_ADJUST 0xf04f
445#define F367TER_ADJUST_SCAT_IND 0xf04f00c0
446#define F367TER_ONE_SYMBOL 0xf04f0010
447#define F367TER_EPQ_DECAY 0xf04f000e
448#define F367TER_HOLD_SLOPE 0xf04f0001
449
450/* EPQ_THRES */
451#define R367TER_EPQ_THRES 0xf050
452#define F367TER_EPQ_THR 0xf05000ff
453
454/* OMEGA_CTL */
455#define R367TER_OMEGA_CTL 0xf051
456#define F367TER_OMEGA_RST 0xf0510080
457#define F367TER_FREEZE_OMEGA 0xf0510040
458#define F367TER_OMEGA_SEL 0xf051003f
459
460/* GP_CTL */
461#define R367TER_GP_CTL 0xf052
462#define F367TER_CHC_STATE 0xf05200e0
463#define F367TER_FREEZE_GP 0xf0520010
464#define F367TER_GP_SEL 0xf052000f
465
466/* MUMSB */
467#define R367TER_MUMSB 0xf053
468#define F367TER_MU_MSB 0xf053007f
469
470/* MULSB */
471#define R367TER_MULSB 0xf054
472#define F367TER_MU_LSB 0xf05400ff
473
474/* GPMSB */
475#define R367TER_GPMSB 0xf055
476#define F367TER_CSI_THRESHOLD 0xf05500e0
477#define F367TER_GP_MSB 0xf055000f
478
479/* GPLSB */
480#define R367TER_GPLSB 0xf056
481#define F367TER_GP_LSB 0xf05600ff
482
483/* OMEGAMSB */
484#define R367TER_OMEGAMSB 0xf057
485#define F367TER_OMEGA_MSB 0xf057007f
486
487/* OMEGALSB */
488#define R367TER_OMEGALSB 0xf058
489#define F367TER_OMEGA_LSB 0xf05800ff
490
491/* SCAT_NB */
492#define R367TER_SCAT_NB 0xf059
493#define F367TER_CHC_TEST 0xf05900f8
494#define F367TER_SCAT_NUMB 0xf0590003
495
496/* CHC_DUMMY */
497#define R367TER_CHC_DUMMY 0xf05a
498#define F367TER_CHC_DUM 0xf05a00ff
499
500/* INC_CTL */
501#define R367TER_INC_CTL 0xf05b
502#define F367TER_INC_BYPASS 0xf05b0080
503#define F367TER_INC_NDEPTH 0xf05b000c
504#define F367TER_INC_MADEPTH 0xf05b0003
505
506/* INCTHRES_COR1 */
507#define R367TER_INCTHRES_COR1 0xf05c
508#define F367TER_INC_THRES_COR1 0xf05c00ff
509
510/* INCTHRES_COR2 */
511#define R367TER_INCTHRES_COR2 0xf05d
512#define F367TER_INC_THRES_COR2 0xf05d00ff
513
514/* INCTHRES_DET1 */
515#define R367TER_INCTHRES_DET1 0xf05e
516#define F367TER_INC_THRES_DET1 0xf05e003f
517
518/* INCTHRES_DET2 */
519#define R367TER_INCTHRES_DET2 0xf05f
520#define F367TER_INC_THRES_DET2 0xf05f003f
521
522/* IIR_CELLNB */
523#define R367TER_IIR_CELLNB 0xf060
524#define F367TER_NRST_IIR 0xf0600080
525#define F367TER_IIR_CELL_NB 0xf0600007
526
527/* IIRCX_COEFF1_MSB */
528#define R367TER_IIRCX_COEFF1_MSB 0xf061
529#define F367TER_IIR_CX_COEFF1_MSB 0xf06100ff
530
531/* IIRCX_COEFF1_LSB */
532#define R367TER_IIRCX_COEFF1_LSB 0xf062
533#define F367TER_IIR_CX_COEFF1_LSB 0xf06200ff
534
535/* IIRCX_COEFF2_MSB */
536#define R367TER_IIRCX_COEFF2_MSB 0xf063
537#define F367TER_IIR_CX_COEFF2_MSB 0xf06300ff
538
539/* IIRCX_COEFF2_LSB */
540#define R367TER_IIRCX_COEFF2_LSB 0xf064
541#define F367TER_IIR_CX_COEFF2_LSB 0xf06400ff
542
543/* IIRCX_COEFF3_MSB */
544#define R367TER_IIRCX_COEFF3_MSB 0xf065
545#define F367TER_IIR_CX_COEFF3_MSB 0xf06500ff
546
547/* IIRCX_COEFF3_LSB */
548#define R367TER_IIRCX_COEFF3_LSB 0xf066
549#define F367TER_IIR_CX_COEFF3_LSB 0xf06600ff
550
551/* IIRCX_COEFF4_MSB */
552#define R367TER_IIRCX_COEFF4_MSB 0xf067
553#define F367TER_IIR_CX_COEFF4_MSB 0xf06700ff
554
555/* IIRCX_COEFF4_LSB */
556#define R367TER_IIRCX_COEFF4_LSB 0xf068
557#define F367TER_IIR_CX_COEFF4_LSB 0xf06800ff
558
559/* IIRCX_COEFF5_MSB */
560#define R367TER_IIRCX_COEFF5_MSB 0xf069
561#define F367TER_IIR_CX_COEFF5_MSB 0xf06900ff
562
563/* IIRCX_COEFF5_LSB */
564#define R367TER_IIRCX_COEFF5_LSB 0xf06a
565#define F367TER_IIR_CX_COEFF5_LSB 0xf06a00ff
566
567/* FEPATH_CFG */
568#define R367TER_FEPATH_CFG 0xf06b
569#define F367TER_DEMUX_SWAP 0xf06b0004
570#define F367TER_DIGAGC_SWAP 0xf06b0002
571#define F367TER_LONGPATH_IF 0xf06b0001
572
573/* PMC1_FUNC */
574#define R367TER_PMC1_FUNC 0xf06c
575#define F367TER_SOFT_RSTN 0xf06c0080
576#define F367TER_PMC1_AVERAGE_TIME 0xf06c0078
577#define F367TER_PMC1_WAIT_TIME 0xf06c0006
578#define F367TER_PMC1_2N_SEL 0xf06c0001
579
580/* PMC1_FOR */
581#define R367TER_PMC1_FOR 0xf06d
582#define F367TER_PMC1_FORCE 0xf06d0080
583#define F367TER_PMC1_FORCE_VALUE 0xf06d007c
584
585/* PMC2_FUNC */
586#define R367TER_PMC2_FUNC 0xf06e
587#define F367TER_PMC2_SOFT_STN 0xf06e0080
588#define F367TER_PMC2_ACCU_TIME 0xf06e0070
589#define F367TER_PMC2_CMDP_MN 0xf06e0008
590#define F367TER_PMC2_SWAP 0xf06e0004
591
592/* STATUS_ERR_DA */
593#define R367TER_STATUS_ERR_DA 0xf06f
594#define F367TER_COM_USEGAINTRK 0xf06f0080
595#define F367TER_COM_AGCLOCK 0xf06f0040
596#define F367TER_AUT_AGCLOCK 0xf06f0020
597#define F367TER_MIN_ERR_X_LSB 0xf06f000f
598
599/* DIG_AGC_R */
600#define R367TER_DIG_AGC_R 0xf070
601#define F367TER_COM_SOFT_RSTN 0xf0700080
602#define F367TER_COM_AGC_ON 0xf0700040
603#define F367TER_COM_EARLY 0xf0700020
604#define F367TER_AUT_SOFT_RESETN 0xf0700010
605#define F367TER_AUT_AGC_ON 0xf0700008
606#define F367TER_AUT_EARLY 0xf0700004
607#define F367TER_AUT_ROT_EN 0xf0700002
608#define F367TER_LOCK_SOFT_RESETN 0xf0700001
609
610/* COMAGC_TARMSB */
611#define R367TER_COMAGC_TARMSB 0xf071
612#define F367TER_COM_AGC_TARGET_MSB 0xf07100ff
613
614/* COM_AGC_TAR_ENMODE */
615#define R367TER_COM_AGC_TAR_ENMODE 0xf072
616#define F367TER_COM_AGC_TARGET_LSB 0xf07200f0
617#define F367TER_COM_ENMODE 0xf072000f
618
619/* COM_AGC_CFG */
620#define R367TER_COM_AGC_CFG 0xf073
621#define F367TER_COM_N 0xf07300f8
622#define F367TER_COM_STABMODE 0xf0730006
623#define F367TER_ERR_SEL 0xf0730001
624
625/* COM_AGC_GAIN1 */
626#define R367TER_COM_AGC_GAIN1 0xf074
627#define F367TER_COM_GAIN1aCK 0xf07400f0
628#define F367TER_COM_GAIN1TRK 0xf074000f
629
630/* AUT_AGC_TARGETMSB */
631#define R367TER_AUT_AGC_TARGETMSB 0xf075
632#define F367TER_AUT_AGC_TARGET_MSB 0xf07500ff
633
634/* LOCK_DET_MSB */
635#define R367TER_LOCK_DET_MSB 0xf076
636#define F367TER_LOCK_DETECT_MSB 0xf07600ff
637
638/* AGCTAR_LOCK_LSBS */
639#define R367TER_AGCTAR_LOCK_LSBS 0xf077
640#define F367TER_AUT_AGC_TARGET_LSB 0xf07700f0
641#define F367TER_LOCK_DETECT_LSB 0xf077000f
642
643/* AUT_GAIN_EN */
644#define R367TER_AUT_GAIN_EN 0xf078
645#define F367TER_AUT_ENMODE 0xf07800f0
646#define F367TER_AUT_GAIN2 0xf078000f
647
648/* AUT_CFG */
649#define R367TER_AUT_CFG 0xf079
650#define F367TER_AUT_N 0xf07900f8
651#define F367TER_INT_CHOICE 0xf0790006
652#define F367TER_INT_LOAD 0xf0790001
653
654/* LOCKN */
655#define R367TER_LOCKN 0xf07a
656#define F367TER_LOCK_N 0xf07a00f8
657#define F367TER_SEL_IQNTAR 0xf07a0004
658#define F367TER_LOCK_DETECT_CHOICE 0xf07a0003
659
660/* INT_X_3 */
661#define R367TER_INT_X_3 0xf07b
662#define F367TER_INT_X3 0xf07b00ff
663
664/* INT_X_2 */
665#define R367TER_INT_X_2 0xf07c
666#define F367TER_INT_X2 0xf07c00ff
667
668/* INT_X_1 */
669#define R367TER_INT_X_1 0xf07d
670#define F367TER_INT_X1 0xf07d00ff
671
672/* INT_X_0 */
673#define R367TER_INT_X_0 0xf07e
674#define F367TER_INT_X0 0xf07e00ff
675
676/* MIN_ERRX_MSB */
677#define R367TER_MIN_ERRX_MSB 0xf07f
678#define F367TER_MIN_ERR_X_MSB 0xf07f00ff
679
680/* COR_CTL */
681#define R367TER_COR_CTL 0xf080
682#define F367TER_CORE_ACTIVE 0xf0800020
683#define F367TER_HOLD 0xf0800010
684#define F367TER_CORE_STATE_CTL 0xf080000f
685
686/* COR_STAT */
687#define R367TER_COR_STAT 0xf081
688#define F367TER_SCATT_LOCKED 0xf0810080
689#define F367TER_TPS_LOCKED 0xf0810040
690#define F367TER_SYR_LOCKED_COR 0xf0810020
691#define F367TER_AGC_LOCKED_STAT 0xf0810010
692#define F367TER_CORE_STATE_STAT 0xf081000f
693
694/* COR_INTEN */
695#define R367TER_COR_INTEN 0xf082
696#define F367TER_INTEN 0xf0820080
697#define F367TER_INTEN_SYR 0xf0820020
698#define F367TER_INTEN_FFT 0xf0820010
699#define F367TER_INTEN_AGC 0xf0820008
700#define F367TER_INTEN_TPS1 0xf0820004
701#define F367TER_INTEN_TPS2 0xf0820002
702#define F367TER_INTEN_TPS3 0xf0820001
703
704/* COR_INTSTAT */
705#define R367TER_COR_INTSTAT 0xf083
706#define F367TER_INTSTAT_SYR 0xf0830020
707#define F367TER_INTSTAT_FFT 0xf0830010
708#define F367TER_INTSAT_AGC 0xf0830008
709#define F367TER_INTSTAT_TPS1 0xf0830004
710#define F367TER_INTSTAT_TPS2 0xf0830002
711#define F367TER_INTSTAT_TPS3 0xf0830001
712
713/* COR_MODEGUARD */
714#define R367TER_COR_MODEGUARD 0xf084
715#define F367TER_FORCE 0xf0840010
716#define F367TER_MODE 0xf084000c
717#define F367TER_GUARD 0xf0840003
718
719/* AGC_CTL */
720#define R367TER_AGC_CTL 0xf085
721#define F367TER_AGC_TIMING_FACTOR 0xf08500e0
722#define F367TER_AGC_LAST 0xf0850010
723#define F367TER_AGC_GAIN 0xf085000c
724#define F367TER_AGC_NEG 0xf0850002
725#define F367TER_AGC_SET 0xf0850001
726
727/* AGC_MANUAL1 */
728#define R367TER_AGC_MANUAL1 0xf086
729#define F367TER_AGC_VAL_LO 0xf08600ff
730
731/* AGC_MANUAL2 */
732#define R367TER_AGC_MANUAL2 0xf087
733#define F367TER_AGC_VAL_HI 0xf087000f
734
735/* AGC_TARG */
736#define R367TER_AGC_TARG 0xf088
737#define F367TER_AGC_TARGET 0xf08800ff
738
739/* AGC_GAIN1 */
740#define R367TER_AGC_GAIN1 0xf089
741#define F367TER_AGC_GAIN_LO 0xf08900ff
742
743/* AGC_GAIN2 */
744#define R367TER_AGC_GAIN2 0xf08a
745#define F367TER_AGC_LOCKED_GAIN2 0xf08a0010
746#define F367TER_AGC_GAIN_HI 0xf08a000f
747
748/* RESERVED_1 */
749#define R367TER_RESERVED_1 0xf08b
750#define F367TER_RESERVED1 0xf08b00ff
751
752/* RESERVED_2 */
753#define R367TER_RESERVED_2 0xf08c
754#define F367TER_RESERVED2 0xf08c00ff
755
756/* RESERVED_3 */
757#define R367TER_RESERVED_3 0xf08d
758#define F367TER_RESERVED3 0xf08d00ff
759
760/* CAS_CTL */
761#define R367TER_CAS_CTL 0xf08e
762#define F367TER_CCS_ENABLE 0xf08e0080
763#define F367TER_ACS_DISABLE 0xf08e0040
764#define F367TER_DAGC_DIS 0xf08e0020
765#define F367TER_DAGC_GAIN 0xf08e0018
766#define F367TER_CCSMU 0xf08e0007
767
768/* CAS_FREQ */
769#define R367TER_CAS_FREQ 0xf08f
770#define F367TER_CCS_FREQ 0xf08f00ff
771
772/* CAS_DAGCGAIN */
773#define R367TER_CAS_DAGCGAIN 0xf090
774#define F367TER_CAS_DAGC_GAIN 0xf09000ff
775
776/* SYR_CTL */
777#define R367TER_SYR_CTL 0xf091
778#define F367TER_SICTH_ENABLE 0xf0910080
779#define F367TER_LONG_ECHO 0xf0910078
780#define F367TER_AUTO_LE_EN 0xf0910004
781#define F367TER_SYR_BYPASS 0xf0910002
782#define F367TER_SYR_TR_DIS 0xf0910001
783
784/* SYR_STAT */
785#define R367TER_SYR_STAT 0xf092
786#define F367TER_SYR_LOCKED_STAT 0xf0920010
787#define F367TER_SYR_MODE 0xf092000c
788#define F367TER_SYR_GUARD 0xf0920003
789
790/* SYR_NCO1 */
791#define R367TER_SYR_NCO1 0xf093
792#define F367TER_SYR_NCO_LO 0xf09300ff
793
794/* SYR_NCO2 */
795#define R367TER_SYR_NCO2 0xf094
796#define F367TER_SYR_NCO_HI 0xf094003f
797
798/* SYR_OFFSET1 */
799#define R367TER_SYR_OFFSET1 0xf095
800#define F367TER_SYR_OFFSET_LO 0xf09500ff
801
802/* SYR_OFFSET2 */
803#define R367TER_SYR_OFFSET2 0xf096
804#define F367TER_SYR_OFFSET_HI 0xf096003f
805
806/* FFT_CTL */
807#define R367TER_FFT_CTL 0xf097
808#define F367TER_SHIFT_FFT_TRIG 0xf0970018
809#define F367TER_FFT_TRIGGER 0xf0970004
810#define F367TER_FFT_MANUAL 0xf0970002
811#define F367TER_IFFT_MODE 0xf0970001
812
813/* SCR_CTL */
814#define R367TER_SCR_CTL 0xf098
815#define F367TER_SYRADJDECAY 0xf0980070
816#define F367TER_SCR_CPEDIS 0xf0980002
817#define F367TER_SCR_DIS 0xf0980001
818
819/* PPM_CTL1 */
820#define R367TER_PPM_CTL1 0xf099
821#define F367TER_PPM_MAXFREQ 0xf0990030
822#define F367TER_PPM_MAXTIM 0xf0990008
823#define F367TER_PPM_INVSEL 0xf0990004
824#define F367TER_PPM_SCATDIS 0xf0990002
825#define F367TER_PPM_BYP 0xf0990001
826
827/* TRL_CTL */
828#define R367TER_TRL_CTL 0xf09a
829#define F367TER_TRL_NOMRATE_LSB 0xf09a0080
830#define F367TER_TRL_GAIN_FACTOR 0xf09a0078
831#define F367TER_TRL_LOOPGAIN 0xf09a0007
832
833/* TRL_NOMRATE1 */
834#define R367TER_TRL_NOMRATE1 0xf09b
835#define F367TER_TRL_NOMRATE_LO 0xf09b00ff
836
837/* TRL_NOMRATE2 */
838#define R367TER_TRL_NOMRATE2 0xf09c
839#define F367TER_TRL_NOMRATE_HI 0xf09c00ff
840
841/* TRL_TIME1 */
842#define R367TER_TRL_TIME1 0xf09d
843#define F367TER_TRL_TOFFSET_LO 0xf09d00ff
844
845/* TRL_TIME2 */
846#define R367TER_TRL_TIME2 0xf09e
847#define F367TER_TRL_TOFFSET_HI 0xf09e00ff
848
849/* CRL_CTL */
850#define R367TER_CRL_CTL 0xf09f
851#define F367TER_CRL_DIS 0xf09f0080
852#define F367TER_CRL_GAIN_FACTOR 0xf09f0078
853#define F367TER_CRL_LOOPGAIN 0xf09f0007
854
855/* CRL_FREQ1 */
856#define R367TER_CRL_FREQ1 0xf0a0
857#define F367TER_CRL_FOFFSET_LO 0xf0a000ff
858
859/* CRL_FREQ2 */
860#define R367TER_CRL_FREQ2 0xf0a1
861#define F367TER_CRL_FOFFSET_HI 0xf0a100ff
862
863/* CRL_FREQ3 */
864#define R367TER_CRL_FREQ3 0xf0a2
865#define F367TER_CRL_FOFFSET_VHI 0xf0a200ff
866
867/* TPS_SFRAME_CTL */
868#define R367TER_TPS_SFRAME_CTL 0xf0a3
869#define F367TER_TPS_SFRAME_SYNC 0xf0a30001
870
871/* CHC_SNR */
872#define R367TER_CHC_SNR 0xf0a4
873#define F367TER_CHCSNR 0xf0a400ff
874
875/* BDI_CTL */
876#define R367TER_BDI_CTL 0xf0a5
877#define F367TER_BDI_LPSEL 0xf0a50002
878#define F367TER_BDI_SERIAL 0xf0a50001
879
880/* DMP_CTL */
881#define R367TER_DMP_CTL 0xf0a6
882#define F367TER_DMP_SCALING_FACTOR 0xf0a6001e
883#define F367TER_DMP_SDDIS 0xf0a60001
884
885/* TPS_RCVD1 */
886#define R367TER_TPS_RCVD1 0xf0a7
887#define F367TER_TPS_CHANGE 0xf0a70040
888#define F367TER_BCH_OK 0xf0a70020
889#define F367TER_TPS_SYNC 0xf0a70010
890#define F367TER_TPS_FRAME 0xf0a70003
891
892/* TPS_RCVD2 */
893#define R367TER_TPS_RCVD2 0xf0a8
894#define F367TER_TPS_HIERMODE 0xf0a80070
895#define F367TER_TPS_CONST 0xf0a80003
896
897/* TPS_RCVD3 */
898#define R367TER_TPS_RCVD3 0xf0a9
899#define F367TER_TPS_LPCODE 0xf0a90070
900#define F367TER_TPS_HPCODE 0xf0a90007
901
902/* TPS_RCVD4 */
903#define R367TER_TPS_RCVD4 0xf0aa
904#define F367TER_TPS_GUARD 0xf0aa0030
905#define F367TER_TPS_MODE 0xf0aa0003
906
907/* TPS_ID_CELL1 */
908#define R367TER_TPS_ID_CELL1 0xf0ab
909#define F367TER_TPS_ID_CELL_LO 0xf0ab00ff
910
911/* TPS_ID_CELL2 */
912#define R367TER_TPS_ID_CELL2 0xf0ac
913#define F367TER_TPS_ID_CELL_HI 0xf0ac00ff
914
915/* TPS_RCVD5_SET1 */
916#define R367TER_TPS_RCVD5_SET1 0xf0ad
917#define F367TER_TPS_NA 0xf0ad00fC
918#define F367TER_TPS_SETFRAME 0xf0ad0003
919
920/* TPS_SET2 */
921#define R367TER_TPS_SET2 0xf0ae
922#define F367TER_TPS_SETHIERMODE 0xf0ae0070
923#define F367TER_TPS_SETCONST 0xf0ae0003
924
925/* TPS_SET3 */
926#define R367TER_TPS_SET3 0xf0af
927#define F367TER_TPS_SETLPCODE 0xf0af0070
928#define F367TER_TPS_SETHPCODE 0xf0af0007
929
930/* TPS_CTL */
931#define R367TER_TPS_CTL 0xf0b0
932#define F367TER_TPS_IMM 0xf0b00004
933#define F367TER_TPS_BCHDIS 0xf0b00002
934#define F367TER_TPS_UPDDIS 0xf0b00001
935
936/* CTL_FFTOSNUM */
937#define R367TER_CTL_FFTOSNUM 0xf0b1
938#define F367TER_SYMBOL_NUMBER 0xf0b1007f
939
940/* TESTSELECT */
941#define R367TER_TESTSELECT 0xf0b2
942#define F367TER_TEST_SELECT 0xf0b2001f
943
944/* MSC_REV */
945#define R367TER_MSC_REV 0xf0b3
946#define F367TER_REV_NUMBER 0xf0b300ff
947
948/* PIR_CTL */
949#define R367TER_PIR_CTL 0xf0b4
950#define F367TER_FREEZE 0xf0b40001
951
952/* SNR_CARRIER1 */
953#define R367TER_SNR_CARRIER1 0xf0b5
954#define F367TER_SNR_CARRIER_LO 0xf0b500ff
955
956/* SNR_CARRIER2 */
957#define R367TER_SNR_CARRIER2 0xf0b6
958#define F367TER_MEAN 0xf0b600c0
959#define F367TER_SNR_CARRIER_HI 0xf0b6001f
960
961/* PPM_CPAMP */
962#define R367TER_PPM_CPAMP 0xf0b7
963#define F367TER_PPM_CPC 0xf0b700ff
964
965/* TSM_AP0 */
966#define R367TER_TSM_AP0 0xf0b8
967#define F367TER_ADDRESS_BYTE_0 0xf0b800ff
968
969/* TSM_AP1 */
970#define R367TER_TSM_AP1 0xf0b9
971#define F367TER_ADDRESS_BYTE_1 0xf0b900ff
972
973/* TSM_AP2 */
974#define R367TER_TSM_AP2 0xf0bA
975#define F367TER_DATA_BYTE_0 0xf0ba00ff
976
977/* TSM_AP3 */
978#define R367TER_TSM_AP3 0xf0bB
979#define F367TER_DATA_BYTE_1 0xf0bb00ff
980
981/* TSM_AP4 */
982#define R367TER_TSM_AP4 0xf0bC
983#define F367TER_DATA_BYTE_2 0xf0bc00ff
984
985/* TSM_AP5 */
986#define R367TER_TSM_AP5 0xf0bD
987#define F367TER_DATA_BYTE_3 0xf0bd00ff
988
989/* TSM_AP6 */
990#define R367TER_TSM_AP6 0xf0bE
991#define F367TER_TSM_AP_6 0xf0be00ff
992
993/* TSM_AP7 */
994#define R367TER_TSM_AP7 0xf0bF
995#define F367TER_MEM_SELECT_BYTE 0xf0bf00ff
996
997/* TSTRES */
998#define R367TER_TSTRES 0xf0c0
999#define F367TER_FRES_DISPLAY 0xf0c00080
1000#define F367TER_FRES_FIFO_AD 0xf0c00020
1001#define F367TER_FRESRS 0xf0c00010
1002#define F367TER_FRESACS 0xf0c00008
1003#define F367TER_FRESFEC 0xf0c00004
1004#define F367TER_FRES_PRIF 0xf0c00002
1005#define F367TER_FRESCORE 0xf0c00001
1006
1007/* ANACTRL */
1008#define R367TER_ANACTRL 0xf0c1
1009#define F367TER_BYPASS_XTAL 0xf0c10040
1010#define F367TER_BYPASS_PLLXN 0xf0c1000c
1011#define F367TER_DIS_PAD_OSC 0xf0c10002
1012#define F367TER_STDBY_PLLXN 0xf0c10001
1013
1014/* TSTBUS */
1015#define R367TER_TSTBUS 0xf0c2
1016#define F367TER_TS_BYTE_CLK_INV 0xf0c20080
1017#define F367TER_CFG_IP 0xf0c20070
1018#define F367TER_CFG_TST 0xf0c2000f
1019
1020/* TSTRATE */
1021#define R367TER_TSTRATE 0xf0c6
1022#define F367TER_FORCEPHA 0xf0c60080
1023#define F367TER_FNEWPHA 0xf0c60010
1024#define F367TER_FROT90 0xf0c60008
1025#define F367TER_FR 0xf0c60007
1026
1027/* CONSTMODE */
1028#define R367TER_CONSTMODE 0xf0cb
1029#define F367TER_TST_PRIF 0xf0cb00e0
1030#define F367TER_CAR_TYPE 0xf0cb0018
1031#define F367TER_CONST_MODE 0xf0cb0003
1032
1033/* CONSTCARR1 */
1034#define R367TER_CONSTCARR1 0xf0cc
1035#define F367TER_CONST_CARR_LO 0xf0cc00ff
1036
1037/* CONSTCARR2 */
1038#define R367TER_CONSTCARR2 0xf0cd
1039#define F367TER_CONST_CARR_HI 0xf0cd001f
1040
1041/* ICONSTEL */
1042#define R367TER_ICONSTEL 0xf0ce
1043#define F367TER_PICONSTEL 0xf0ce00ff
1044
1045/* QCONSTEL */
1046#define R367TER_QCONSTEL 0xf0cf
1047#define F367TER_PQCONSTEL 0xf0cf00ff
1048
1049/* TSTBISTRES0 */
1050#define R367TER_TSTBISTRES0 0xf0d0
1051#define F367TER_BEND_PPM 0xf0d00080
1052#define F367TER_BBAD_PPM 0xf0d00040
1053#define F367TER_BEND_FFTW 0xf0d00020
1054#define F367TER_BBAD_FFTW 0xf0d00010
1055#define F367TER_BEND_FFT_BUF 0xf0d00008
1056#define F367TER_BBAD_FFT_BUF 0xf0d00004
1057#define F367TER_BEND_SYR 0xf0d00002
1058#define F367TER_BBAD_SYR 0xf0d00001
1059
1060/* TSTBISTRES1 */
1061#define R367TER_TSTBISTRES1 0xf0d1
1062#define F367TER_BEND_CHC_CP 0xf0d10080
1063#define F367TER_BBAD_CHC_CP 0xf0d10040
1064#define F367TER_BEND_CHCI 0xf0d10020
1065#define F367TER_BBAD_CHCI 0xf0d10010
1066#define F367TER_BEND_BDI 0xf0d10008
1067#define F367TER_BBAD_BDI 0xf0d10004
1068#define F367TER_BEND_SDI 0xf0d10002
1069#define F367TER_BBAD_SDI 0xf0d10001
1070
1071/* TSTBISTRES2 */
1072#define R367TER_TSTBISTRES2 0xf0d2
1073#define F367TER_BEND_CHC_INC 0xf0d20080
1074#define F367TER_BBAD_CHC_INC 0xf0d20040
1075#define F367TER_BEND_CHC_SPP 0xf0d20020
1076#define F367TER_BBAD_CHC_SPP 0xf0d20010
1077#define F367TER_BEND_CHC_CPP 0xf0d20008
1078#define F367TER_BBAD_CHC_CPP 0xf0d20004
1079#define F367TER_BEND_CHC_SP 0xf0d20002
1080#define F367TER_BBAD_CHC_SP 0xf0d20001
1081
1082/* TSTBISTRES3 */
1083#define R367TER_TSTBISTRES3 0xf0d3
1084#define F367TER_BEND_QAM 0xf0d30080
1085#define F367TER_BBAD_QAM 0xf0d30040
1086#define F367TER_BEND_SFEC_VIT 0xf0d30020
1087#define F367TER_BBAD_SFEC_VIT 0xf0d30010
1088#define F367TER_BEND_SFEC_DLINE 0xf0d30008
1089#define F367TER_BBAD_SFEC_DLINE 0xf0d30004
1090#define F367TER_BEND_SFEC_HW 0xf0d30002
1091#define F367TER_BBAD_SFEC_HW 0xf0d30001
1092
1093/* RF_AGC1 */
1094#define R367TER_RF_AGC1 0xf0d4
1095#define F367TER_RF_AGC1_LEVEL_HI 0xf0d400ff
1096
1097/* RF_AGC2 */
1098#define R367TER_RF_AGC2 0xf0d5
1099#define F367TER_REF_ADGP 0xf0d50080
1100#define F367TER_STDBY_ADCGP 0xf0d50020
1101#define F367TER_CHANNEL_SEL 0xf0d5001c
1102#define F367TER_RF_AGC1_LEVEL_LO 0xf0d50003
1103
1104/* ANADIGCTRL */
1105#define R367TER_ANADIGCTRL 0xf0d7
1106#define F367TER_SEL_CLKDEM 0xf0d70020
1107#define F367TER_EN_BUFFER_Q 0xf0d70010
1108#define F367TER_EN_BUFFER_I 0xf0d70008
1109#define F367TER_ADC_RIS_EGDE 0xf0d70004
1110#define F367TER_SGN_ADC 0xf0d70002
1111#define F367TER_SEL_AD12_SYNC 0xf0d70001
1112
1113/* PLLMDIV */
1114#define R367TER_PLLMDIV 0xf0d8
1115#define F367TER_PLL_MDIV 0xf0d800ff
1116
1117/* PLLNDIV */
1118#define R367TER_PLLNDIV 0xf0d9
1119#define F367TER_PLL_NDIV 0xf0d900ff
1120
1121/* PLLSETUP */
1122#define R367TER_PLLSETUP 0xf0dA
1123#define F367TER_PLL_PDIV 0xf0da0070
1124#define F367TER_PLL_KDIV 0xf0da000f
1125
1126/* DUAL_AD12 */
1127#define R367TER_DUAL_AD12 0xf0dB
1128#define F367TER_FS20M 0xf0db0020
1129#define F367TER_FS50M 0xf0db0010
1130#define F367TER_INMODe0 0xf0db0008
1131#define F367TER_POFFQ 0xf0db0004
1132#define F367TER_POFFI 0xf0db0002
1133#define F367TER_INMODE1 0xf0db0001
1134
1135/* TSTBIST */
1136#define R367TER_TSTBIST 0xf0dC
1137#define F367TER_TST_BYP_CLK 0xf0dc0080
1138#define F367TER_TST_GCLKENA_STD 0xf0dc0040
1139#define F367TER_TST_GCLKENA 0xf0dc0020
1140#define F367TER_TST_MEMBIST 0xf0dc001f
1141
1142/* PAD_COMP_CTRL */
1143#define R367TER_PAD_COMP_CTRL 0xf0dD
1144#define F367TER_COMPTQ 0xf0dd0010
1145#define F367TER_COMPEN 0xf0dd0008
1146#define F367TER_FREEZE2 0xf0dd0004
1147#define F367TER_SLEEP_INHBT 0xf0dd0002
1148#define F367TER_CHIP_SLEEP 0xf0dd0001
1149
1150/* PAD_COMP_WR */
1151#define R367TER_PAD_COMP_WR 0xf0de
1152#define F367TER_WR_ASRC 0xf0de007f
1153
1154/* PAD_COMP_RD */
1155#define R367TER_PAD_COMP_RD 0xf0df
1156#define F367TER_COMPOK 0xf0df0080
1157#define F367TER_RD_ASRC 0xf0df007f
1158
1159/* SYR_TARGET_FFTADJT_MSB */
1160#define R367TER_SYR_TARGET_FFTADJT_MSB 0xf100
1161#define F367TER_SYR_START 0xf1000080
1162#define F367TER_SYR_TARGET_FFTADJ_HI 0xf100000f
1163
1164/* SYR_TARGET_FFTADJT_LSB */
1165#define R367TER_SYR_TARGET_FFTADJT_LSB 0xf101
1166#define F367TER_SYR_TARGET_FFTADJ_LO 0xf10100ff
1167
1168/* SYR_TARGET_CHCADJT_MSB */
1169#define R367TER_SYR_TARGET_CHCADJT_MSB 0xf102
1170#define F367TER_SYR_TARGET_CHCADJ_HI 0xf102000f
1171
1172/* SYR_TARGET_CHCADJT_LSB */
1173#define R367TER_SYR_TARGET_CHCADJT_LSB 0xf103
1174#define F367TER_SYR_TARGET_CHCADJ_LO 0xf10300ff
1175
1176/* SYR_FLAG */
1177#define R367TER_SYR_FLAG 0xf104
1178#define F367TER_TRIG_FLG1 0xf1040080
1179#define F367TER_TRIG_FLG0 0xf1040040
1180#define F367TER_FFT_FLG1 0xf1040008
1181#define F367TER_FFT_FLG0 0xf1040004
1182#define F367TER_CHC_FLG1 0xf1040002
1183#define F367TER_CHC_FLG0 0xf1040001
1184
1185/* CRL_TARGET1 */
1186#define R367TER_CRL_TARGET1 0xf105
1187#define F367TER_CRL_START 0xf1050080
1188#define F367TER_CRL_TARGET_VHI 0xf105000f
1189
1190/* CRL_TARGET2 */
1191#define R367TER_CRL_TARGET2 0xf106
1192#define F367TER_CRL_TARGET_HI 0xf10600ff
1193
1194/* CRL_TARGET3 */
1195#define R367TER_CRL_TARGET3 0xf107
1196#define F367TER_CRL_TARGET_LO 0xf10700ff
1197
1198/* CRL_TARGET4 */
1199#define R367TER_CRL_TARGET4 0xf108
1200#define F367TER_CRL_TARGET_VLO 0xf10800ff
1201
1202/* CRL_FLAG */
1203#define R367TER_CRL_FLAG 0xf109
1204#define F367TER_CRL_FLAG1 0xf1090002
1205#define F367TER_CRL_FLAG0 0xf1090001
1206
1207/* TRL_TARGET1 */
1208#define R367TER_TRL_TARGET1 0xf10a
1209#define F367TER_TRL_TARGET_HI 0xf10a00ff
1210
1211/* TRL_TARGET2 */
1212#define R367TER_TRL_TARGET2 0xf10b
1213#define F367TER_TRL_TARGET_LO 0xf10b00ff
1214
1215/* TRL_CHC */
1216#define R367TER_TRL_CHC 0xf10c
1217#define F367TER_TRL_START 0xf10c0080
1218#define F367TER_CHC_START 0xf10c0040
1219#define F367TER_TRL_FLAG1 0xf10c0002
1220#define F367TER_TRL_FLAG0 0xf10c0001
1221
1222/* CHC_SNR_TARG */
1223#define R367TER_CHC_SNR_TARG 0xf10d
1224#define F367TER_CHC_SNR_TARGET 0xf10d00ff
1225
1226/* TOP_TRACK */
1227#define R367TER_TOP_TRACK 0xf10e
1228#define F367TER_TOP_START 0xf10e0080
1229#define F367TER_FIRST_FLAG 0xf10e0070
1230#define F367TER_TOP_FLAG1 0xf10e0008
1231#define F367TER_TOP_FLAG0 0xf10e0004
1232#define F367TER_CHC_FLAG1 0xf10e0002
1233#define F367TER_CHC_FLAG0 0xf10e0001
1234
1235/* TRACKER_FREE1 */
1236#define R367TER_TRACKER_FREE1 0xf10f
1237#define F367TER_TRACKER_FREE_1 0xf10f00ff
1238
1239/* ERROR_CRL1 */
1240#define R367TER_ERROR_CRL1 0xf110
1241#define F367TER_ERROR_CRL_VHI 0xf11000ff
1242
1243/* ERROR_CRL2 */
1244#define R367TER_ERROR_CRL2 0xf111
1245#define F367TER_ERROR_CRL_HI 0xf11100ff
1246
1247/* ERROR_CRL3 */
1248#define R367TER_ERROR_CRL3 0xf112
1249#define F367TER_ERROR_CRL_LOI 0xf11200ff
1250
1251/* ERROR_CRL4 */
1252#define R367TER_ERROR_CRL4 0xf113
1253#define F367TER_ERROR_CRL_VLO 0xf11300ff
1254
1255/* DEC_NCO1 */
1256#define R367TER_DEC_NCO1 0xf114
1257#define F367TER_DEC_NCO_VHI 0xf11400ff
1258
1259/* DEC_NCO2 */
1260#define R367TER_DEC_NCO2 0xf115
1261#define F367TER_DEC_NCO_HI 0xf11500ff
1262
1263/* DEC_NCO3 */
1264#define R367TER_DEC_NCO3 0xf116
1265#define F367TER_DEC_NCO_LO 0xf11600ff
1266
1267/* SNR */
1268#define R367TER_SNR 0xf117
1269#define F367TER_SNRATIO 0xf11700ff
1270
1271/* SYR_FFTADJ1 */
1272#define R367TER_SYR_FFTADJ1 0xf118
1273#define F367TER_SYR_FFTADJ_HI 0xf11800ff
1274
1275/* SYR_FFTADJ2 */
1276#define R367TER_SYR_FFTADJ2 0xf119
1277#define F367TER_SYR_FFTADJ_LO 0xf11900ff
1278
1279/* SYR_CHCADJ1 */
1280#define R367TER_SYR_CHCADJ1 0xf11a
1281#define F367TER_SYR_CHCADJ_HI 0xf11a00ff
1282
1283/* SYR_CHCADJ2 */
1284#define R367TER_SYR_CHCADJ2 0xf11b
1285#define F367TER_SYR_CHCADJ_LO 0xf11b00ff
1286
1287/* SYR_OFF */
1288#define R367TER_SYR_OFF 0xf11c
1289#define F367TER_SYR_OFFSET 0xf11c00ff
1290
1291/* PPM_OFFSET1 */
1292#define R367TER_PPM_OFFSET1 0xf11d
1293#define F367TER_PPM_OFFSET_HI 0xf11d00ff
1294
1295/* PPM_OFFSET2 */
1296#define R367TER_PPM_OFFSET2 0xf11e
1297#define F367TER_PPM_OFFSET_LO 0xf11e00ff
1298
1299/* TRACKER_FREE2 */
1300#define R367TER_TRACKER_FREE2 0xf11f
1301#define F367TER_TRACKER_FREE_2 0xf11f00ff
1302
1303/* DEBG_LT10 */
1304#define R367TER_DEBG_LT10 0xf120
1305#define F367TER_DEBUG_LT10 0xf12000ff
1306
1307/* DEBG_LT11 */
1308#define R367TER_DEBG_LT11 0xf121
1309#define F367TER_DEBUG_LT11 0xf12100ff
1310
1311/* DEBG_LT12 */
1312#define R367TER_DEBG_LT12 0xf122
1313#define F367TER_DEBUG_LT12 0xf12200ff
1314
1315/* DEBG_LT13 */
1316#define R367TER_DEBG_LT13 0xf123
1317#define F367TER_DEBUG_LT13 0xf12300ff
1318
1319/* DEBG_LT14 */
1320#define R367TER_DEBG_LT14 0xf124
1321#define F367TER_DEBUG_LT14 0xf12400ff
1322
1323/* DEBG_LT15 */
1324#define R367TER_DEBG_LT15 0xf125
1325#define F367TER_DEBUG_LT15 0xf12500ff
1326
1327/* DEBG_LT16 */
1328#define R367TER_DEBG_LT16 0xf126
1329#define F367TER_DEBUG_LT16 0xf12600ff
1330
1331/* DEBG_LT17 */
1332#define R367TER_DEBG_LT17 0xf127
1333#define F367TER_DEBUG_LT17 0xf12700ff
1334
1335/* DEBG_LT18 */
1336#define R367TER_DEBG_LT18 0xf128
1337#define F367TER_DEBUG_LT18 0xf12800ff
1338
1339/* DEBG_LT19 */
1340#define R367TER_DEBG_LT19 0xf129
1341#define F367TER_DEBUG_LT19 0xf12900ff
1342
1343/* DEBG_LT1a */
1344#define R367TER_DEBG_LT1A 0xf12a
1345#define F367TER_DEBUG_LT1A 0xf12a00ff
1346
1347/* DEBG_LT1b */
1348#define R367TER_DEBG_LT1B 0xf12b
1349#define F367TER_DEBUG_LT1B 0xf12b00ff
1350
1351/* DEBG_LT1c */
1352#define R367TER_DEBG_LT1C 0xf12c
1353#define F367TER_DEBUG_LT1C 0xf12c00ff
1354
1355/* DEBG_LT1D */
1356#define R367TER_DEBG_LT1D 0xf12d
1357#define F367TER_DEBUG_LT1D 0xf12d00ff
1358
1359/* DEBG_LT1E */
1360#define R367TER_DEBG_LT1E 0xf12e
1361#define F367TER_DEBUG_LT1E 0xf12e00ff
1362
1363/* DEBG_LT1F */
1364#define R367TER_DEBG_LT1F 0xf12f
1365#define F367TER_DEBUG_LT1F 0xf12f00ff
1366
1367/* RCCFGH */
1368#define R367TER_RCCFGH 0xf200
1369#define F367TER_TSRCFIFO_DVBCI 0xf2000080
1370#define F367TER_TSRCFIFO_SERIAL 0xf2000040
1371#define F367TER_TSRCFIFO_DISABLE 0xf2000020
1372#define F367TER_TSFIFO_2TORC 0xf2000010
1373#define F367TER_TSRCFIFO_HSGNLOUT 0xf2000008
1374#define F367TER_TSRCFIFO_ERRMODE 0xf2000006
1375#define F367TER_RCCFGH_0 0xf2000001
1376
1377/* RCCFGM */
1378#define R367TER_RCCFGM 0xf201
1379#define F367TER_TSRCFIFO_MANSPEED 0xf20100c0
1380#define F367TER_TSRCFIFO_PERMDATA 0xf2010020
1381#define F367TER_TSRCFIFO_NONEWSGNL 0xf2010010
1382#define F367TER_RCBYTE_OVERSAMPLING 0xf201000e
1383#define F367TER_TSRCFIFO_INVDATA 0xf2010001
1384
1385/* RCCFGL */
1386#define R367TER_RCCFGL 0xf202
1387#define F367TER_TSRCFIFO_BCLKDEL1cK 0xf20200c0
1388#define F367TER_RCCFGL_5 0xf2020020
1389#define F367TER_TSRCFIFO_DUTY50 0xf2020010
1390#define F367TER_TSRCFIFO_NSGNL2dATA 0xf2020008
1391#define F367TER_TSRCFIFO_DISSERMUX 0xf2020004
1392#define F367TER_RCCFGL_1 0xf2020002
1393#define F367TER_TSRCFIFO_STOPCKDIS 0xf2020001
1394
1395/* RCINSDELH */
1396#define R367TER_RCINSDELH 0xf203
1397#define F367TER_TSRCDEL_SYNCBYTE 0xf2030080
1398#define F367TER_TSRCDEL_XXHEADER 0xf2030040
1399#define F367TER_TSRCDEL_BBHEADER 0xf2030020
1400#define F367TER_TSRCDEL_DATAFIELD 0xf2030010
1401#define F367TER_TSRCINSDEL_ISCR 0xf2030008
1402#define F367TER_TSRCINSDEL_NPD 0xf2030004
1403#define F367TER_TSRCINSDEL_RSPARITY 0xf2030002
1404#define F367TER_TSRCINSDEL_CRC8 0xf2030001
1405
1406/* RCINSDELM */
1407#define R367TER_RCINSDELM 0xf204
1408#define F367TER_TSRCINS_BBPADDING 0xf2040080
1409#define F367TER_TSRCINS_BCHFEC 0xf2040040
1410#define F367TER_TSRCINS_LDPCFEC 0xf2040020
1411#define F367TER_TSRCINS_EMODCOD 0xf2040010
1412#define F367TER_TSRCINS_TOKEN 0xf2040008
1413#define F367TER_TSRCINS_XXXERR 0xf2040004
1414#define F367TER_TSRCINS_MATYPE 0xf2040002
1415#define F367TER_TSRCINS_UPL 0xf2040001
1416
1417/* RCINSDELL */
1418#define R367TER_RCINSDELL 0xf205
1419#define F367TER_TSRCINS_DFL 0xf2050080
1420#define F367TER_TSRCINS_SYNCD 0xf2050040
1421#define F367TER_TSRCINS_BLOCLEN 0xf2050020
1422#define F367TER_TSRCINS_SIGPCOUNT 0xf2050010
1423#define F367TER_TSRCINS_FIFO 0xf2050008
1424#define F367TER_TSRCINS_REALPACK 0xf2050004
1425#define F367TER_TSRCINS_TSCONFIG 0xf2050002
1426#define F367TER_TSRCINS_LATENCY 0xf2050001
1427
1428/* RCSTATUS */
1429#define R367TER_RCSTATUS 0xf206
1430#define F367TER_TSRCFIFO_LINEOK 0xf2060080
1431#define F367TER_TSRCFIFO_ERROR 0xf2060040
1432#define F367TER_TSRCFIFO_DATA7 0xf2060020
1433#define F367TER_RCSTATUS_4 0xf2060010
1434#define F367TER_TSRCFIFO_DEMODSEL 0xf2060008
1435#define F367TER_TSRC1FIFOSPEED_STORE 0xf2060004
1436#define F367TER_RCSTATUS_1 0xf2060002
1437#define F367TER_TSRCSERIAL_IMPOSSIBLE 0xf2060001
1438
1439/* RCSPEED */
1440#define R367TER_RCSPEED 0xf207
1441#define F367TER_TSRCFIFO_OUTSPEED 0xf20700ff
1442
1443/* RCDEBUGM */
1444#define R367TER_RCDEBUGM 0xf208
1445#define F367TER_SD_UNSYNC 0xf2080080
1446#define F367TER_ULFLOCK_DETECTM 0xf2080040
1447#define F367TER_SUL_SELECTOS 0xf2080020
1448#define F367TER_DILUL_NOSCRBLE 0xf2080010
1449#define F367TER_NUL_SCRB 0xf2080008
1450#define F367TER_UL_SCRB 0xf2080004
1451#define F367TER_SCRAULBAD 0xf2080002
1452#define F367TER_SCRAUL_UNSYNC 0xf2080001
1453
1454/* RCDEBUGL */
1455#define R367TER_RCDEBUGL 0xf209
1456#define F367TER_RS_ERR 0xf2090080
1457#define F367TER_LLFLOCK_DETECTM 0xf2090040
1458#define F367TER_NOT_SUL_SELECTOS 0xf2090020
1459#define F367TER_DILLL_NOSCRBLE 0xf2090010
1460#define F367TER_NLL_SCRB 0xf2090008
1461#define F367TER_LL_SCRB 0xf2090004
1462#define F367TER_SCRALLBAD 0xf2090002
1463#define F367TER_SCRALL_UNSYNC 0xf2090001
1464
1465/* RCOBSCFG */
1466#define R367TER_RCOBSCFG 0xf20a
1467#define F367TER_TSRCFIFO_OBSCFG 0xf20a00ff
1468
1469/* RCOBSM */
1470#define R367TER_RCOBSM 0xf20b
1471#define F367TER_TSRCFIFO_OBSDATA_HI 0xf20b00ff
1472
1473/* RCOBSL */
1474#define R367TER_RCOBSL 0xf20c
1475#define F367TER_TSRCFIFO_OBSDATA_LO 0xf20c00ff
1476
1477/* RCFECSPY */
1478#define R367TER_RCFECSPY 0xf210
1479#define F367TER_SPYRC_ENABLE 0xf2100080
1480#define F367TER_RCNO_SYNCBYTE 0xf2100040
1481#define F367TER_RCSERIAL_MODE 0xf2100020
1482#define F367TER_RCUNUSUAL_PACKET 0xf2100010
1483#define F367TER_BERRCMETER_DATAMODE 0xf210000c
1484#define F367TER_BERRCMETER_LMODE 0xf2100002
1485#define F367TER_BERRCMETER_RESET 0xf2100001
1486
1487/* RCFSPYCFG */
1488#define R367TER_RCFSPYCFG 0xf211
1489#define F367TER_FECSPYRC_INPUT 0xf21100c0
1490#define F367TER_RCRST_ON_ERROR 0xf2110020
1491#define F367TER_RCONE_SHOT 0xf2110010
1492#define F367TER_RCI2C_MODE 0xf211000c
1493#define F367TER_SPYRC_HSTERESIS 0xf2110003
1494
1495/* RCFSPYDATA */
1496#define R367TER_RCFSPYDATA 0xf212
1497#define F367TER_SPYRC_STUFFING 0xf2120080
1498#define F367TER_RCNOERR_PKTJITTER 0xf2120040
1499#define F367TER_SPYRC_CNULLPKT 0xf2120020
1500#define F367TER_SPYRC_OUTDATA_MODE 0xf212001f
1501
1502/* RCFSPYOUT */
1503#define R367TER_RCFSPYOUT 0xf213
1504#define F367TER_FSPYRC_DIRECT 0xf2130080
1505#define F367TER_RCFSPYOUT_6 0xf2130040
1506#define F367TER_SPYRC_OUTDATA_BUS 0xf2130038
1507#define F367TER_RCSTUFF_MODE 0xf2130007
1508
1509/* RCFSTATUS */
1510#define R367TER_RCFSTATUS 0xf214
1511#define F367TER_SPYRC_ENDSIM 0xf2140080
1512#define F367TER_RCVALID_SIM 0xf2140040
1513#define F367TER_RCFOUND_SIGNAL 0xf2140020
1514#define F367TER_RCDSS_SYNCBYTE 0xf2140010
1515#define F367TER_RCRESULT_STATE 0xf214000f
1516
1517/* RCFGOODPACK */
1518#define R367TER_RCFGOODPACK 0xf215
1519#define F367TER_RCGOOD_PACKET 0xf21500ff
1520
1521/* RCFPACKCNT */
1522#define R367TER_RCFPACKCNT 0xf216
1523#define F367TER_RCPACKET_COUNTER 0xf21600ff
1524
1525/* RCFSPYMISC */
1526#define R367TER_RCFSPYMISC 0xf217
1527#define F367TER_RCLABEL_COUNTER 0xf21700ff
1528
1529/* RCFBERCPT4 */
1530#define R367TER_RCFBERCPT4 0xf218
1531#define F367TER_FBERRCMETER_CPT_MMMMSB 0xf21800ff
1532
1533/* RCFBERCPT3 */
1534#define R367TER_RCFBERCPT3 0xf219
1535#define F367TER_FBERRCMETER_CPT_MMMSB 0xf21900ff
1536
1537/* RCFBERCPT2 */
1538#define R367TER_RCFBERCPT2 0xf21a
1539#define F367TER_FBERRCMETER_CPT_MMSB 0xf21a00ff
1540
1541/* RCFBERCPT1 */
1542#define R367TER_RCFBERCPT1 0xf21b
1543#define F367TER_FBERRCMETER_CPT_MSB 0xf21b00ff
1544
1545/* RCFBERCPT0 */
1546#define R367TER_RCFBERCPT0 0xf21c
1547#define F367TER_FBERRCMETER_CPT_LSB 0xf21c00ff
1548
1549/* RCFBERERR2 */
1550#define R367TER_RCFBERERR2 0xf21d
1551#define F367TER_FBERRCMETER_ERR_HI 0xf21d00ff
1552
1553/* RCFBERERR1 */
1554#define R367TER_RCFBERERR1 0xf21e
1555#define F367TER_FBERRCMETER_ERR 0xf21e00ff
1556
1557/* RCFBERERR0 */
1558#define R367TER_RCFBERERR0 0xf21f
1559#define F367TER_FBERRCMETER_ERR_LO 0xf21f00ff
1560
1561/* RCFSTATESM */
1562#define R367TER_RCFSTATESM 0xf220
1563#define F367TER_RCRSTATE_F 0xf2200080
1564#define F367TER_RCRSTATE_E 0xf2200040
1565#define F367TER_RCRSTATE_D 0xf2200020
1566#define F367TER_RCRSTATE_C 0xf2200010
1567#define F367TER_RCRSTATE_B 0xf2200008
1568#define F367TER_RCRSTATE_A 0xf2200004
1569#define F367TER_RCRSTATE_9 0xf2200002
1570#define F367TER_RCRSTATE_8 0xf2200001
1571
1572/* RCFSTATESL */
1573#define R367TER_RCFSTATESL 0xf221
1574#define F367TER_RCRSTATE_7 0xf2210080
1575#define F367TER_RCRSTATE_6 0xf2210040
1576#define F367TER_RCRSTATE_5 0xf2210020
1577#define F367TER_RCRSTATE_4 0xf2210010
1578#define F367TER_RCRSTATE_3 0xf2210008
1579#define F367TER_RCRSTATE_2 0xf2210004
1580#define F367TER_RCRSTATE_1 0xf2210002
1581#define F367TER_RCRSTATE_0 0xf2210001
1582
1583/* RCFSPYBER */
1584#define R367TER_RCFSPYBER 0xf222
1585#define F367TER_RCFSPYBER_7 0xf2220080
1586#define F367TER_SPYRCOBS_XORREAD 0xf2220040
1587#define F367TER_FSPYRCBER_OBSMODE 0xf2220020
1588#define F367TER_FSPYRCBER_SYNCBYT 0xf2220010
1589#define F367TER_FSPYRCBER_UNSYNC 0xf2220008
1590#define F367TER_FSPYRCBER_CTIME 0xf2220007
1591
1592/* RCFSPYDISTM */
1593#define R367TER_RCFSPYDISTM 0xf223
1594#define F367TER_RCPKTTIME_DISTANCE_HI 0xf22300ff
1595
1596/* RCFSPYDISTL */
1597#define R367TER_RCFSPYDISTL 0xf224
1598#define F367TER_RCPKTTIME_DISTANCE_LO 0xf22400ff
1599
1600/* RCFSPYOBS7 */
1601#define R367TER_RCFSPYOBS7 0xf228
1602#define F367TER_RCSPYOBS_SPYFAIL 0xf2280080
1603#define F367TER_RCSPYOBS_SPYFAIL1 0xf2280040
1604#define F367TER_RCSPYOBS_ERROR 0xf2280020
1605#define F367TER_RCSPYOBS_STROUT 0xf2280010
1606#define F367TER_RCSPYOBS_RESULTSTATE1 0xf228000f
1607
1608/* RCFSPYOBS6 */
1609#define R367TER_RCFSPYOBS6 0xf229
1610#define F367TER_RCSPYOBS_RESULTSTATe0 0xf22900f0
1611#define F367TER_RCSPYOBS_RESULTSTATEM1 0xf229000f
1612
1613/* RCFSPYOBS5 */
1614#define R367TER_RCFSPYOBS5 0xf22a
1615#define F367TER_RCSPYOBS_BYTEOFPACKET1 0xf22a00ff
1616
1617/* RCFSPYOBS4 */
1618#define R367TER_RCFSPYOBS4 0xf22b
1619#define F367TER_RCSPYOBS_BYTEVALUE1 0xf22b00ff
1620
1621/* RCFSPYOBS3 */
1622#define R367TER_RCFSPYOBS3 0xf22c
1623#define F367TER_RCSPYOBS_DATA1 0xf22c00ff
1624
1625/* RCFSPYOBS2 */
1626#define R367TER_RCFSPYOBS2 0xf22d
1627#define F367TER_RCSPYOBS_DATa0 0xf22d00ff
1628
1629/* RCFSPYOBS1 */
1630#define R367TER_RCFSPYOBS1 0xf22e
1631#define F367TER_RCSPYOBS_DATAM1 0xf22e00ff
1632
1633/* RCFSPYOBS0 */
1634#define R367TER_RCFSPYOBS0 0xf22f
1635#define F367TER_RCSPYOBS_DATAM2 0xf22f00ff
1636
1637/* TSGENERAL */
1638#define R367TER_TSGENERAL 0xf230
1639#define F367TER_TSGENERAL_7 0xf2300080
1640#define F367TER_TSGENERAL_6 0xf2300040
1641#define F367TER_TSFIFO_BCLK1aLL 0xf2300020
1642#define F367TER_TSGENERAL_4 0xf2300010
1643#define F367TER_MUXSTREAM_OUTMODE 0xf2300008
1644#define F367TER_TSFIFO_PERMPARAL 0xf2300006
1645#define F367TER_RST_REEDSOLO 0xf2300001
1646
1647/* RC1SPEED */
1648#define R367TER_RC1SPEED 0xf231
1649#define F367TER_TSRCFIFO1_OUTSPEED 0xf23100ff
1650
1651/* TSGSTATUS */
1652#define R367TER_TSGSTATUS 0xf232
1653#define F367TER_TSGSTATUS_7 0xf2320080
1654#define F367TER_TSGSTATUS_6 0xf2320040
1655#define F367TER_RSMEM_FULL 0xf2320020
1656#define F367TER_RS_MULTCALC 0xf2320010
1657#define F367TER_RSIN_OVERTIME 0xf2320008
1658#define F367TER_TSFIFO3_DEMODSEL 0xf2320004
1659#define F367TER_TSFIFO2_DEMODSEL 0xf2320002
1660#define F367TER_TSFIFO1_DEMODSEL 0xf2320001
1661
1662
1663/* FECM */
1664#define R367TER_FECM 0xf233
1665#define F367TER_DSS_DVB 0xf2330080
1666#define F367TER_DEMOD_BYPASS 0xf2330040
1667#define F367TER_CMP_SLOWMODE 0xf2330020
1668#define F367TER_DSS_SRCH 0xf2330010
1669#define F367TER_FECM_3 0xf2330008
1670#define F367TER_DIFF_MODEVIT 0xf2330004
1671#define F367TER_SYNCVIT 0xf2330002
1672#define F367TER_I2CSYM 0xf2330001
1673
1674/* VTH12 */
1675#define R367TER_VTH12 0xf234
1676#define F367TER_VTH_12 0xf23400ff
1677
1678/* VTH23 */
1679#define R367TER_VTH23 0xf235
1680#define F367TER_VTH_23 0xf23500ff
1681
1682/* VTH34 */
1683#define R367TER_VTH34 0xf236
1684#define F367TER_VTH_34 0xf23600ff
1685
1686/* VTH56 */
1687#define R367TER_VTH56 0xf237
1688#define F367TER_VTH_56 0xf23700ff
1689
1690/* VTH67 */
1691#define R367TER_VTH67 0xf238
1692#define F367TER_VTH_67 0xf23800ff
1693
1694/* VTH78 */
1695#define R367TER_VTH78 0xf239
1696#define F367TER_VTH_78 0xf23900ff
1697
1698/* VITCURPUN */
1699#define R367TER_VITCURPUN 0xf23a
1700#define F367TER_VIT_MAPPING 0xf23a00e0
1701#define F367TER_VIT_CURPUN 0xf23a001f
1702
1703/* VERROR */
1704#define R367TER_VERROR 0xf23b
1705#define F367TER_REGERR_VIT 0xf23b00ff
1706
1707/* PRVIT */
1708#define R367TER_PRVIT 0xf23c
1709#define F367TER_PRVIT_7 0xf23c0080
1710#define F367TER_DIS_VTHLOCK 0xf23c0040
1711#define F367TER_E7_8VIT 0xf23c0020
1712#define F367TER_E6_7VIT 0xf23c0010
1713#define F367TER_E5_6VIT 0xf23c0008
1714#define F367TER_E3_4VIT 0xf23c0004
1715#define F367TER_E2_3VIT 0xf23c0002
1716#define F367TER_E1_2VIT 0xf23c0001
1717
1718/* VAVSRVIT */
1719#define R367TER_VAVSRVIT 0xf23d
1720#define F367TER_AMVIT 0xf23d0080
1721#define F367TER_FROZENVIT 0xf23d0040
1722#define F367TER_SNVIT 0xf23d0030
1723#define F367TER_TOVVIT 0xf23d000c
1724#define F367TER_HYPVIT 0xf23d0003
1725
1726/* VSTATUSVIT */
1727#define R367TER_VSTATUSVIT 0xf23e
1728#define F367TER_VITERBI_ON 0xf23e0080
1729#define F367TER_END_LOOPVIT 0xf23e0040
1730#define F367TER_VITERBI_DEPRF 0xf23e0020
1731#define F367TER_PRFVIT 0xf23e0010
1732#define F367TER_LOCKEDVIT 0xf23e0008
1733#define F367TER_VITERBI_DELOCK 0xf23e0004
1734#define F367TER_VIT_DEMODSEL 0xf23e0002
1735#define F367TER_VITERBI_COMPOUT 0xf23e0001
1736
1737/* VTHINUSE */
1738#define R367TER_VTHINUSE 0xf23f
1739#define F367TER_VIT_INUSE 0xf23f00ff
1740
1741/* KDIV12 */
1742#define R367TER_KDIV12 0xf240
1743#define F367TER_KDIV12_MANUAL 0xf2400080
1744#define F367TER_K_DIVIDER_12 0xf240007f
1745
1746/* KDIV23 */
1747#define R367TER_KDIV23 0xf241
1748#define F367TER_KDIV23_MANUAL 0xf2410080
1749#define F367TER_K_DIVIDER_23 0xf241007f
1750
1751/* KDIV34 */
1752#define R367TER_KDIV34 0xf242
1753#define F367TER_KDIV34_MANUAL 0xf2420080
1754#define F367TER_K_DIVIDER_34 0xf242007f
1755
1756/* KDIV56 */
1757#define R367TER_KDIV56 0xf243
1758#define F367TER_KDIV56_MANUAL 0xf2430080
1759#define F367TER_K_DIVIDER_56 0xf243007f
1760
1761/* KDIV67 */
1762#define R367TER_KDIV67 0xf244
1763#define F367TER_KDIV67_MANUAL 0xf2440080
1764#define F367TER_K_DIVIDER_67 0xf244007f
1765
1766/* KDIV78 */
1767#define R367TER_KDIV78 0xf245
1768#define F367TER_KDIV78_MANUAL 0xf2450080
1769#define F367TER_K_DIVIDER_78 0xf245007f
1770
1771/* SIGPOWER */
1772#define R367TER_SIGPOWER 0xf246
1773#define F367TER_SIGPOWER_MANUAL 0xf2460080
1774#define F367TER_SIG_POWER 0xf246007f
1775
1776/* DEMAPVIT */
1777#define R367TER_DEMAPVIT 0xf247
1778#define F367TER_DEMAPVIT_7 0xf2470080
1779#define F367TER_K_DIVIDER_VIT 0xf247007f
1780
1781/* VITSCALE */
1782#define R367TER_VITSCALE 0xf248
1783#define F367TER_NVTH_NOSRANGE 0xf2480080
1784#define F367TER_VERROR_MAXMODE 0xf2480040
1785#define F367TER_KDIV_MODE 0xf2480030
1786#define F367TER_NSLOWSN_LOCKED 0xf2480008
1787#define F367TER_DELOCK_PRFLOSS 0xf2480004
1788#define F367TER_DIS_RSFLOCK 0xf2480002
1789#define F367TER_VITSCALE_0 0xf2480001
1790
1791/* FFEC1PRG */
1792#define R367TER_FFEC1PRG 0xf249
1793#define F367TER_FDSS_DVB 0xf2490080
1794#define F367TER_FDSS_SRCH 0xf2490040
1795#define F367TER_FFECPROG_5 0xf2490020
1796#define F367TER_FFECPROG_4 0xf2490010
1797#define F367TER_FFECPROG_3 0xf2490008
1798#define F367TER_FFECPROG_2 0xf2490004
1799#define F367TER_FTS1_DISABLE 0xf2490002
1800#define F367TER_FTS2_DISABLE 0xf2490001
1801
1802/* FVITCURPUN */
1803#define R367TER_FVITCURPUN 0xf24a
1804#define F367TER_FVIT_MAPPING 0xf24a00e0
1805#define F367TER_FVIT_CURPUN 0xf24a001f
1806
1807/* FVERROR */
1808#define R367TER_FVERROR 0xf24b
1809#define F367TER_FREGERR_VIT 0xf24b00ff
1810
1811/* FVSTATUSVIT */
1812#define R367TER_FVSTATUSVIT 0xf24c
1813#define F367TER_FVITERBI_ON 0xf24c0080
1814#define F367TER_F1END_LOOPVIT 0xf24c0040
1815#define F367TER_FVITERBI_DEPRF 0xf24c0020
1816#define F367TER_FPRFVIT 0xf24c0010
1817#define F367TER_FLOCKEDVIT 0xf24c0008
1818#define F367TER_FVITERBI_DELOCK 0xf24c0004
1819#define F367TER_FVIT_DEMODSEL 0xf24c0002
1820#define F367TER_FVITERBI_COMPOUT 0xf24c0001
1821
1822/* DEBUG_LT1 */
1823#define R367TER_DEBUG_LT1 0xf24d
1824#define F367TER_DBG_LT1 0xf24d00ff
1825
1826/* DEBUG_LT2 */
1827#define R367TER_DEBUG_LT2 0xf24e
1828#define F367TER_DBG_LT2 0xf24e00ff
1829
1830/* DEBUG_LT3 */
1831#define R367TER_DEBUG_LT3 0xf24f
1832#define F367TER_DBG_LT3 0xf24f00ff
1833
1834/* TSTSFMET */
1835#define R367TER_TSTSFMET 0xf250
1836#define F367TER_TSTSFEC_METRIQUES 0xf25000ff
1837
1838/* SELOUT */
1839#define R367TER_SELOUT 0xf252
1840#define F367TER_EN_SYNC 0xf2520080
1841#define F367TER_EN_TBUSDEMAP 0xf2520040
1842#define F367TER_SELOUT_5 0xf2520020
1843#define F367TER_SELOUT_4 0xf2520010
1844#define F367TER_TSTSYNCHRO_MODE 0xf2520002
1845
1846/* TSYNC */
1847#define R367TER_TSYNC 0xf253
1848#define F367TER_CURPUN_INCMODE 0xf2530080
1849#define F367TER_CERR_TSTMODE 0xf2530040
1850#define F367TER_SHIFTSOF_MODE 0xf2530030
1851#define F367TER_SLOWPHA_MODE 0xf2530008
1852#define F367TER_PXX_BYPALL 0xf2530004
1853#define F367TER_FROTA45_FIRST 0xf2530002
1854#define F367TER_TST_BCHERROR 0xf2530001
1855
1856/* TSTERR */
1857#define R367TER_TSTERR 0xf254
1858#define F367TER_TST_LONGPKT 0xf2540080
1859#define F367TER_TST_ISSYION 0xf2540040
1860#define F367TER_TST_NPDON 0xf2540020
1861#define F367TER_TSTERR_4 0xf2540010
1862#define F367TER_TRACEBACK_MODE 0xf2540008
1863#define F367TER_TST_RSPARITY 0xf2540004
1864#define F367TER_METRIQUE_MODE 0xf2540003
1865
1866/* TSFSYNC */
1867#define R367TER_TSFSYNC 0xf255
1868#define F367TER_EN_SFECSYNC 0xf2550080
1869#define F367TER_EN_SFECDEMAP 0xf2550040
1870#define F367TER_SFCERR_TSTMODE 0xf2550020
1871#define F367TER_SFECPXX_BYPALL 0xf2550010
1872#define F367TER_SFECTSTSYNCHRO_MODE 0xf255000f
1873
1874/* TSTSFERR */
1875#define R367TER_TSTSFERR 0xf256
1876#define F367TER_TSTSTERR_7 0xf2560080
1877#define F367TER_TSTSTERR_6 0xf2560040
1878#define F367TER_TSTSTERR_5 0xf2560020
1879#define F367TER_TSTSTERR_4 0xf2560010
1880#define F367TER_SFECTRACEBACK_MODE 0xf2560008
1881#define F367TER_SFEC_NCONVPROG 0xf2560004
1882#define F367TER_SFECMETRIQUE_MODE 0xf2560003
1883
1884/* TSTTSSF1 */
1885#define R367TER_TSTTSSF1 0xf258
1886#define F367TER_TSTERSSF 0xf2580080
1887#define F367TER_TSTTSSFEN 0xf2580040
1888#define F367TER_SFEC_OUTMODE 0xf2580030
1889#define F367TER_XLSF_NOFTHRESHOLD 0xf2580008
1890#define F367TER_TSTTSSF_STACKSEL 0xf2580007
1891
1892/* TSTTSSF2 */
1893#define R367TER_TSTTSSF2 0xf259
1894#define F367TER_DILSF_DBBHEADER 0xf2590080
1895#define F367TER_TSTTSSF_DISBUG 0xf2590040
1896#define F367TER_TSTTSSF_NOBADSTART 0xf2590020
1897#define F367TER_TSTTSSF_SELECT 0xf259001f
1898
1899/* TSTTSSF3 */
1900#define R367TER_TSTTSSF3 0xf25a
1901#define F367TER_TSTTSSF3_7 0xf25a0080
1902#define F367TER_TSTTSSF3_6 0xf25a0040
1903#define F367TER_TSTTSSF3_5 0xf25a0020
1904#define F367TER_TSTTSSF3_4 0xf25a0010
1905#define F367TER_TSTTSSF3_3 0xf25a0008
1906#define F367TER_TSTTSSF3_2 0xf25a0004
1907#define F367TER_TSTTSSF3_1 0xf25a0002
1908#define F367TER_DISSF_CLKENABLE 0xf25a0001
1909
1910/* TSTTS1 */
1911#define R367TER_TSTTS1 0xf25c
1912#define F367TER_TSTERS 0xf25c0080
1913#define F367TER_TSFIFO_DSSSYNCB 0xf25c0040
1914#define F367TER_TSTTS_FSPYBEFRS 0xf25c0020
1915#define F367TER_NFORCE_SYNCBYTE 0xf25c0010
1916#define F367TER_XL_NOFTHRESHOLD 0xf25c0008
1917#define F367TER_TSTTS_FRFORCEPKT 0xf25c0004
1918#define F367TER_DESCR_NOTAUTO 0xf25c0002
1919#define F367TER_TSTTSEN 0xf25c0001
1920
1921/* TSTTS2 */
1922#define R367TER_TSTTS2 0xf25d
1923#define F367TER_DIL_DBBHEADER 0xf25d0080
1924#define F367TER_TSTTS_NOBADXXX 0xf25d0040
1925#define F367TER_TSFIFO_DELSPEEDUP 0xf25d0020
1926#define F367TER_TSTTS_SELECT 0xf25d001f
1927
1928/* TSTTS3 */
1929#define R367TER_TSTTS3 0xf25e
1930#define F367TER_TSTTS_NOPKTGAIN 0xf25e0080
1931#define F367TER_TSTTS_NOPKTENE 0xf25e0040
1932#define F367TER_TSTTS_ISOLATION 0xf25e0020
1933#define F367TER_TSTTS_DISBUG 0xf25e0010
1934#define F367TER_TSTTS_NOBADSTART 0xf25e0008
1935#define F367TER_TSTTS_STACKSEL 0xf25e0007
1936
1937/* TSTTS4 */
1938#define R367TER_TSTTS4 0xf25f
1939#define F367TER_TSTTS4_7 0xf25f0080
1940#define F367TER_TSTTS4_6 0xf25f0040
1941#define F367TER_TSTTS4_5 0xf25f0020
1942#define F367TER_TSTTS_DISDSTATE 0xf25f0010
1943#define F367TER_TSTTS_FASTNOSYNC 0xf25f0008
1944#define F367TER_EXT_FECSPYIN 0xf25f0004
1945#define F367TER_TSTTS_NODPZERO 0xf25f0002
1946#define F367TER_TSTTS_NODIV3 0xf25f0001
1947
1948/* TSTTSRC */
1949#define R367TER_TSTTSRC 0xf26c
1950#define F367TER_TSTTSRC_7 0xf26c0080
1951#define F367TER_TSRCFIFO_DSSSYNCB 0xf26c0040
1952#define F367TER_TSRCFIFO_DPUNACTIVE 0xf26c0020
1953#define F367TER_TSRCFIFO_DELSPEEDUP 0xf26c0010
1954#define F367TER_TSTTSRC_NODIV3 0xf26c0008
1955#define F367TER_TSTTSRC_FRFORCEPKT 0xf26c0004
1956#define F367TER_SAT25_SDDORIGINE 0xf26c0002
1957#define F367TER_TSTTSRC_INACTIVE 0xf26c0001
1958
1959/* TSTTSRS */
1960#define R367TER_TSTTSRS 0xf26d
1961#define F367TER_TSTTSRS_7 0xf26d0080
1962#define F367TER_TSTTSRS_6 0xf26d0040
1963#define F367TER_TSTTSRS_5 0xf26d0020
1964#define F367TER_TSTTSRS_4 0xf26d0010
1965#define F367TER_TSTTSRS_3 0xf26d0008
1966#define F367TER_TSTTSRS_2 0xf26d0004
1967#define F367TER_TSTRS_DISRS2 0xf26d0002
1968#define F367TER_TSTRS_DISRS1 0xf26d0001
1969
1970/* TSSTATEM */
1971#define R367TER_TSSTATEM 0xf270
1972#define F367TER_TSDIL_ON 0xf2700080
1973#define F367TER_TSSKIPRS_ON 0xf2700040
1974#define F367TER_TSRS_ON 0xf2700020
1975#define F367TER_TSDESCRAMB_ON 0xf2700010
1976#define F367TER_TSFRAME_MODE 0xf2700008
1977#define F367TER_TS_DISABLE 0xf2700004
1978#define F367TER_TSACM_MODE 0xf2700002
1979#define F367TER_TSOUT_NOSYNC 0xf2700001
1980
1981/* TSSTATEL */
1982#define R367TER_TSSTATEL 0xf271
1983#define F367TER_TSNOSYNCBYTE 0xf2710080
1984#define F367TER_TSPARITY_ON 0xf2710040
1985#define F367TER_TSSYNCOUTRS_ON 0xf2710020
1986#define F367TER_TSDVBS2_MODE 0xf2710010
1987#define F367TER_TSISSYI_ON 0xf2710008
1988#define F367TER_TSNPD_ON 0xf2710004
1989#define F367TER_TSCRC8_ON 0xf2710002
1990#define F367TER_TSDSS_PACKET 0xf2710001
1991
1992/* TSCFGH */
1993#define R367TER_TSCFGH 0xf272
1994#define F367TER_TSFIFO_DVBCI 0xf2720080
1995#define F367TER_TSFIFO_SERIAL 0xf2720040
1996#define F367TER_TSFIFO_TEIUPDATE 0xf2720020
1997#define F367TER_TSFIFO_DUTY50 0xf2720010
1998#define F367TER_TSFIFO_HSGNLOUT 0xf2720008
1999#define F367TER_TSFIFO_ERRMODE 0xf2720006
2000#define F367TER_RST_HWARE 0xf2720001
2001
2002/* TSCFGM */
2003#define R367TER_TSCFGM 0xf273
2004#define F367TER_TSFIFO_MANSPEED 0xf27300c0
2005#define F367TER_TSFIFO_PERMDATA 0xf2730020
2006#define F367TER_TSFIFO_NONEWSGNL 0xf2730010
2007#define F367TER_TSFIFO_BITSPEED 0xf2730008
2008#define F367TER_NPD_SPECDVBS2 0xf2730004
2009#define F367TER_TSFIFO_STOPCKDIS 0xf2730002
2010#define F367TER_TSFIFO_INVDATA 0xf2730001
2011
2012/* TSCFGL */
2013#define R367TER_TSCFGL 0xf274
2014#define F367TER_TSFIFO_BCLKDEL1cK 0xf27400c0
2015#define F367TER_BCHERROR_MODE 0xf2740030
2016#define F367TER_TSFIFO_NSGNL2dATA 0xf2740008
2017#define F367TER_TSFIFO_EMBINDVB 0xf2740004
2018#define F367TER_TSFIFO_DPUNACT 0xf2740002
2019#define F367TER_TSFIFO_NPDOFF 0xf2740001
2020
2021/* TSSYNC */
2022#define R367TER_TSSYNC 0xf275
2023#define F367TER_TSFIFO_PERMUTE 0xf2750080
2024#define F367TER_TSFIFO_FISCR3B 0xf2750060
2025#define F367TER_TSFIFO_SYNCMODE 0xf2750018
2026#define F367TER_TSFIFO_SYNCSEL 0xf2750007
2027
2028/* TSINSDELH */
2029#define R367TER_TSINSDELH 0xf276
2030#define F367TER_TSDEL_SYNCBYTE 0xf2760080
2031#define F367TER_TSDEL_XXHEADER 0xf2760040
2032#define F367TER_TSDEL_BBHEADER 0xf2760020
2033#define F367TER_TSDEL_DATAFIELD 0xf2760010
2034#define F367TER_TSINSDEL_ISCR 0xf2760008
2035#define F367TER_TSINSDEL_NPD 0xf2760004
2036#define F367TER_TSINSDEL_RSPARITY 0xf2760002
2037#define F367TER_TSINSDEL_CRC8 0xf2760001
2038
2039/* TSINSDELM */
2040#define R367TER_TSINSDELM 0xf277
2041#define F367TER_TSINS_BBPADDING 0xf2770080
2042#define F367TER_TSINS_BCHFEC 0xf2770040
2043#define F367TER_TSINS_LDPCFEC 0xf2770020
2044#define F367TER_TSINS_EMODCOD 0xf2770010
2045#define F367TER_TSINS_TOKEN 0xf2770008
2046#define F367TER_TSINS_XXXERR 0xf2770004
2047#define F367TER_TSINS_MATYPE 0xf2770002
2048#define F367TER_TSINS_UPL 0xf2770001
2049
2050/* TSINSDELL */
2051#define R367TER_TSINSDELL 0xf278
2052#define F367TER_TSINS_DFL 0xf2780080
2053#define F367TER_TSINS_SYNCD 0xf2780040
2054#define F367TER_TSINS_BLOCLEN 0xf2780020
2055#define F367TER_TSINS_SIGPCOUNT 0xf2780010
2056#define F367TER_TSINS_FIFO 0xf2780008
2057#define F367TER_TSINS_REALPACK 0xf2780004
2058#define F367TER_TSINS_TSCONFIG 0xf2780002
2059#define F367TER_TSINS_LATENCY 0xf2780001
2060
2061/* TSDIVN */
2062#define R367TER_TSDIVN 0xf279
2063#define F367TER_TSFIFO_LOWSPEED 0xf2790080
2064#define F367TER_BYTE_OVERSAMPLING 0xf2790070
2065#define F367TER_TSMANUAL_PACKETNBR 0xf279000f
2066
2067/* TSDIVPM */
2068#define R367TER_TSDIVPM 0xf27a
2069#define F367TER_TSMANUAL_P_HI 0xf27a00ff
2070
2071/* TSDIVPL */
2072#define R367TER_TSDIVPL 0xf27b
2073#define F367TER_TSMANUAL_P_LO 0xf27b00ff
2074
2075/* TSDIVQM */
2076#define R367TER_TSDIVQM 0xf27c
2077#define F367TER_TSMANUAL_Q_HI 0xf27c00ff
2078
2079/* TSDIVQL */
2080#define R367TER_TSDIVQL 0xf27d
2081#define F367TER_TSMANUAL_Q_LO 0xf27d00ff
2082
2083/* TSDILSTKM */
2084#define R367TER_TSDILSTKM 0xf27e
2085#define F367TER_TSFIFO_DILSTK_HI 0xf27e00ff
2086
2087/* TSDILSTKL */
2088#define R367TER_TSDILSTKL 0xf27f
2089#define F367TER_TSFIFO_DILSTK_LO 0xf27f00ff
2090
2091/* TSSPEED */
2092#define R367TER_TSSPEED 0xf280
2093#define F367TER_TSFIFO_OUTSPEED 0xf28000ff
2094
2095/* TSSTATUS */
2096#define R367TER_TSSTATUS 0xf281
2097#define F367TER_TSFIFO_LINEOK 0xf2810080
2098#define F367TER_TSFIFO_ERROR 0xf2810040
2099#define F367TER_TSFIFO_DATA7 0xf2810020
2100#define F367TER_TSFIFO_NOSYNC 0xf2810010
2101#define F367TER_ISCR_INITIALIZED 0xf2810008
2102#define F367TER_ISCR_UPDATED 0xf2810004
2103#define F367TER_SOFFIFO_UNREGUL 0xf2810002
2104#define F367TER_DIL_READY 0xf2810001
2105
2106/* TSSTATUS2 */
2107#define R367TER_TSSTATUS2 0xf282
2108#define F367TER_TSFIFO_DEMODSEL 0xf2820080
2109#define F367TER_TSFIFOSPEED_STORE 0xf2820040
2110#define F367TER_DILXX_RESET 0xf2820020
2111#define F367TER_TSSERIAL_IMPOSSIBLE 0xf2820010
2112#define F367TER_TSFIFO_UNDERSPEED 0xf2820008
2113#define F367TER_BITSPEED_EVENT 0xf2820004
2114#define F367TER_UL_SCRAMBDETECT 0xf2820002
2115#define F367TER_ULDTV67_FALSELOCK 0xf2820001
2116
2117/* TSBITRATEM */
2118#define R367TER_TSBITRATEM 0xf283
2119#define F367TER_TSFIFO_BITRATE_HI 0xf28300ff
2120
2121/* TSBITRATEL */
2122#define R367TER_TSBITRATEL 0xf284
2123#define F367TER_TSFIFO_BITRATE_LO 0xf28400ff
2124
2125/* TSPACKLENM */
2126#define R367TER_TSPACKLENM 0xf285
2127#define F367TER_TSFIFO_PACKCPT 0xf28500e0
2128#define F367TER_DIL_RPLEN_HI 0xf285001f
2129
2130/* TSPACKLENL */
2131#define R367TER_TSPACKLENL 0xf286
2132#define F367TER_DIL_RPLEN_LO 0xf28600ff
2133
2134/* TSBLOCLENM */
2135#define R367TER_TSBLOCLENM 0xf287
2136#define F367TER_TSFIFO_PFLEN_HI 0xf28700ff
2137
2138/* TSBLOCLENL */
2139#define R367TER_TSBLOCLENL 0xf288
2140#define F367TER_TSFIFO_PFLEN_LO 0xf28800ff
2141
2142/* TSDLYH */
2143#define R367TER_TSDLYH 0xf289
2144#define F367TER_SOFFIFO_TSTIMEVALID 0xf2890080
2145#define F367TER_SOFFIFO_SPEEDUP 0xf2890040
2146#define F367TER_SOFFIFO_STOP 0xf2890020
2147#define F367TER_SOFFIFO_REGULATED 0xf2890010
2148#define F367TER_SOFFIFO_REALSBOFF_HI 0xf289000f
2149
2150/* TSDLYM */
2151#define R367TER_TSDLYM 0xf28a
2152#define F367TER_SOFFIFO_REALSBOFF_MED 0xf28a00ff
2153
2154/* TSDLYL */
2155#define R367TER_TSDLYL 0xf28b
2156#define F367TER_SOFFIFO_REALSBOFF_LO 0xf28b00ff
2157
2158/* TSNPDAV */
2159#define R367TER_TSNPDAV 0xf28c
2160#define F367TER_TSNPD_AVERAGE 0xf28c00ff
2161
2162/* TSBUFSTATH */
2163#define R367TER_TSBUFSTATH 0xf28d
2164#define F367TER_TSISCR_3BYTES 0xf28d0080
2165#define F367TER_TSISCR_NEWDATA 0xf28d0040
2166#define F367TER_TSISCR_BUFSTAT_HI 0xf28d003f
2167
2168/* TSBUFSTATM */
2169#define R367TER_TSBUFSTATM 0xf28e
2170#define F367TER_TSISCR_BUFSTAT_MED 0xf28e00ff
2171
2172/* TSBUFSTATL */
2173#define R367TER_TSBUFSTATL 0xf28f
2174#define F367TER_TSISCR_BUFSTAT_LO 0xf28f00ff
2175
2176/* TSDEBUGM */
2177#define R367TER_TSDEBUGM 0xf290
2178#define F367TER_TSFIFO_ILLPACKET 0xf2900080
2179#define F367TER_DIL_NOSYNC 0xf2900040
2180#define F367TER_DIL_ISCR 0xf2900020
2181#define F367TER_DILOUT_BSYNCB 0xf2900010
2182#define F367TER_TSFIFO_EMPTYPKT 0xf2900008
2183#define F367TER_TSFIFO_EMPTYRD 0xf2900004
2184#define F367TER_SOFFIFO_STOPM 0xf2900002
2185#define F367TER_SOFFIFO_SPEEDUPM 0xf2900001
2186
2187/* TSDEBUGL */
2188#define R367TER_TSDEBUGL 0xf291
2189#define F367TER_TSFIFO_PACKLENFAIL 0xf2910080
2190#define F367TER_TSFIFO_SYNCBFAIL 0xf2910040
2191#define F367TER_TSFIFO_VITLIBRE 0xf2910020
2192#define F367TER_TSFIFO_BOOSTSPEEDM 0xf2910010
2193#define F367TER_TSFIFO_UNDERSPEEDM 0xf2910008
2194#define F367TER_TSFIFO_ERROR_EVNT 0xf2910004
2195#define F367TER_TSFIFO_FULL 0xf2910002
2196#define F367TER_TSFIFO_OVERFLOWM 0xf2910001
2197
2198/* TSDLYSETH */
2199#define R367TER_TSDLYSETH 0xf292
2200#define F367TER_SOFFIFO_OFFSET 0xf29200e0
2201#define F367TER_SOFFIFO_SYMBOFFSET_HI 0xf292001f
2202
2203/* TSDLYSETM */
2204#define R367TER_TSDLYSETM 0xf293
2205#define F367TER_SOFFIFO_SYMBOFFSET_MED 0xf29300ff
2206
2207/* TSDLYSETL */
2208#define R367TER_TSDLYSETL 0xf294
2209#define F367TER_SOFFIFO_SYMBOFFSET_LO 0xf29400ff
2210
2211/* TSOBSCFG */
2212#define R367TER_TSOBSCFG 0xf295
2213#define F367TER_TSFIFO_OBSCFG 0xf29500ff
2214
2215/* TSOBSM */
2216#define R367TER_TSOBSM 0xf296
2217#define F367TER_TSFIFO_OBSDATA_HI 0xf29600ff
2218
2219/* TSOBSL */
2220#define R367TER_TSOBSL 0xf297
2221#define F367TER_TSFIFO_OBSDATA_LO 0xf29700ff
2222
2223/* ERRCTRL1 */
2224#define R367TER_ERRCTRL1 0xf298
2225#define F367TER_ERR_SRC1 0xf29800f0
2226#define F367TER_ERRCTRL1_3 0xf2980008
2227#define F367TER_NUM_EVT1 0xf2980007
2228
2229/* ERRCNT1H */
2230#define R367TER_ERRCNT1H 0xf299
2231#define F367TER_ERRCNT1_OLDVALUE 0xf2990080
2232#define F367TER_ERR_CNT1 0xf299007f
2233
2234/* ERRCNT1M */
2235#define R367TER_ERRCNT1M 0xf29a
2236#define F367TER_ERR_CNT1_HI 0xf29a00ff
2237
2238/* ERRCNT1L */
2239#define R367TER_ERRCNT1L 0xf29b
2240#define F367TER_ERR_CNT1_LO 0xf29b00ff
2241
2242/* ERRCTRL2 */
2243#define R367TER_ERRCTRL2 0xf29c
2244#define F367TER_ERR_SRC2 0xf29c00f0
2245#define F367TER_ERRCTRL2_3 0xf29c0008
2246#define F367TER_NUM_EVT2 0xf29c0007
2247
2248/* ERRCNT2H */
2249#define R367TER_ERRCNT2H 0xf29d
2250#define F367TER_ERRCNT2_OLDVALUE 0xf29d0080
2251#define F367TER_ERR_CNT2_HI 0xf29d007f
2252
2253/* ERRCNT2M */
2254#define R367TER_ERRCNT2M 0xf29e
2255#define F367TER_ERR_CNT2_MED 0xf29e00ff
2256
2257/* ERRCNT2L */
2258#define R367TER_ERRCNT2L 0xf29f
2259#define F367TER_ERR_CNT2_LO 0xf29f00ff
2260
2261/* FECSPY */
2262#define R367TER_FECSPY 0xf2a0
2263#define F367TER_SPY_ENABLE 0xf2a00080
2264#define F367TER_NO_SYNCBYTE 0xf2a00040
2265#define F367TER_SERIAL_MODE 0xf2a00020
2266#define F367TER_UNUSUAL_PACKET 0xf2a00010
2267#define F367TER_BERMETER_DATAMODE 0xf2a0000c
2268#define F367TER_BERMETER_LMODE 0xf2a00002
2269#define F367TER_BERMETER_RESET 0xf2a00001
2270
2271/* FSPYCFG */
2272#define R367TER_FSPYCFG 0xf2a1
2273#define F367TER_FECSPY_INPUT 0xf2a100c0
2274#define F367TER_RST_ON_ERROR 0xf2a10020
2275#define F367TER_ONE_SHOT 0xf2a10010
2276#define F367TER_I2C_MOD 0xf2a1000c
2277#define F367TER_SPY_HYSTERESIS 0xf2a10003
2278
2279/* FSPYDATA */
2280#define R367TER_FSPYDATA 0xf2a2
2281#define F367TER_SPY_STUFFING 0xf2a20080
2282#define F367TER_NOERROR_PKTJITTER 0xf2a20040
2283#define F367TER_SPY_CNULLPKT 0xf2a20020
2284#define F367TER_SPY_OUTDATA_MODE 0xf2a2001f
2285
2286/* FSPYOUT */
2287#define R367TER_FSPYOUT 0xf2a3
2288#define F367TER_FSPY_DIRECT 0xf2a30080
2289#define F367TER_FSPYOUT_6 0xf2a30040
2290#define F367TER_SPY_OUTDATA_BUS 0xf2a30038
2291#define F367TER_STUFF_MODE 0xf2a30007
2292
2293/* FSTATUS */
2294#define R367TER_FSTATUS 0xf2a4
2295#define F367TER_SPY_ENDSIM 0xf2a40080
2296#define F367TER_VALID_SIM 0xf2a40040
2297#define F367TER_FOUND_SIGNAL 0xf2a40020
2298#define F367TER_DSS_SYNCBYTE 0xf2a40010
2299#define F367TER_RESULT_STATE 0xf2a4000f
2300
2301/* FGOODPACK */
2302#define R367TER_FGOODPACK 0xf2a5
2303#define F367TER_FGOOD_PACKET 0xf2a500ff
2304
2305/* FPACKCNT */
2306#define R367TER_FPACKCNT 0xf2a6
2307#define F367TER_FPACKET_COUNTER 0xf2a600ff
2308
2309/* FSPYMISC */
2310#define R367TER_FSPYMISC 0xf2a7
2311#define F367TER_FLABEL_COUNTER 0xf2a700ff
2312
2313/* FBERCPT4 */
2314#define R367TER_FBERCPT4 0xf2a8
2315#define F367TER_FBERMETER_CPT5 0xf2a800ff
2316
2317/* FBERCPT3 */
2318#define R367TER_FBERCPT3 0xf2a9
2319#define F367TER_FBERMETER_CPT4 0xf2a900ff
2320
2321/* FBERCPT2 */
2322#define R367TER_FBERCPT2 0xf2aa
2323#define F367TER_FBERMETER_CPT3 0xf2aa00ff
2324
2325/* FBERCPT1 */
2326#define R367TER_FBERCPT1 0xf2ab
2327#define F367TER_FBERMETER_CPT2 0xf2ab00ff
2328
2329/* FBERCPT0 */
2330#define R367TER_FBERCPT0 0xf2ac
2331#define F367TER_FBERMETER_CPT1 0xf2ac00ff
2332
2333/* FBERERR2 */
2334#define R367TER_FBERERR2 0xf2ad
2335#define F367TER_FBERMETER_ERR_HI 0xf2ad00ff
2336
2337/* FBERERR1 */
2338#define R367TER_FBERERR1 0xf2ae
2339#define F367TER_FBERMETER_ERR_MED 0xf2ae00ff
2340
2341/* FBERERR0 */
2342#define R367TER_FBERERR0 0xf2af
2343#define F367TER_FBERMETER_ERR_LO 0xf2af00ff
2344
2345/* FSTATESM */
2346#define R367TER_FSTATESM 0xf2b0
2347#define F367TER_RSTATE_F 0xf2b00080
2348#define F367TER_RSTATE_E 0xf2b00040
2349#define F367TER_RSTATE_D 0xf2b00020
2350#define F367TER_RSTATE_C 0xf2b00010
2351#define F367TER_RSTATE_B 0xf2b00008
2352#define F367TER_RSTATE_A 0xf2b00004
2353#define F367TER_RSTATE_9 0xf2b00002
2354#define F367TER_RSTATE_8 0xf2b00001
2355
2356/* FSTATESL */
2357#define R367TER_FSTATESL 0xf2b1
2358#define F367TER_RSTATE_7 0xf2b10080
2359#define F367TER_RSTATE_6 0xf2b10040
2360#define F367TER_RSTATE_5 0xf2b10020
2361#define F367TER_RSTATE_4 0xf2b10010
2362#define F367TER_RSTATE_3 0xf2b10008
2363#define F367TER_RSTATE_2 0xf2b10004
2364#define F367TER_RSTATE_1 0xf2b10002
2365#define F367TER_RSTATE_0 0xf2b10001
2366
2367/* FSPYBER */
2368#define R367TER_FSPYBER 0xf2b2
2369#define F367TER_FSPYBER_7 0xf2b20080
2370#define F367TER_FSPYOBS_XORREAD 0xf2b20040
2371#define F367TER_FSPYBER_OBSMODE 0xf2b20020
2372#define F367TER_FSPYBER_SYNCBYTE 0xf2b20010
2373#define F367TER_FSPYBER_UNSYNC 0xf2b20008
2374#define F367TER_FSPYBER_CTIME 0xf2b20007
2375
2376/* FSPYDISTM */
2377#define R367TER_FSPYDISTM 0xf2b3
2378#define F367TER_PKTTIME_DISTANCE_HI 0xf2b300ff
2379
2380/* FSPYDISTL */
2381#define R367TER_FSPYDISTL 0xf2b4
2382#define F367TER_PKTTIME_DISTANCE_LO 0xf2b400ff
2383
2384/* FSPYOBS7 */
2385#define R367TER_FSPYOBS7 0xf2b8
2386#define F367TER_FSPYOBS_SPYFAIL 0xf2b80080
2387#define F367TER_FSPYOBS_SPYFAIL1 0xf2b80040
2388#define F367TER_FSPYOBS_ERROR 0xf2b80020
2389#define F367TER_FSPYOBS_STROUT 0xf2b80010
2390#define F367TER_FSPYOBS_RESULTSTATE1 0xf2b8000f
2391
2392/* FSPYOBS6 */
2393#define R367TER_FSPYOBS6 0xf2b9
2394#define F367TER_FSPYOBS_RESULTSTATe0 0xf2b900f0
2395#define F367TER_FSPYOBS_RESULTSTATEM1 0xf2b9000f
2396
2397/* FSPYOBS5 */
2398#define R367TER_FSPYOBS5 0xf2ba
2399#define F367TER_FSPYOBS_BYTEOFPACKET1 0xf2ba00ff
2400
2401/* FSPYOBS4 */
2402#define R367TER_FSPYOBS4 0xf2bb
2403#define F367TER_FSPYOBS_BYTEVALUE1 0xf2bb00ff
2404
2405/* FSPYOBS3 */
2406#define R367TER_FSPYOBS3 0xf2bc
2407#define F367TER_FSPYOBS_DATA1 0xf2bc00ff
2408
2409/* FSPYOBS2 */
2410#define R367TER_FSPYOBS2 0xf2bd
2411#define F367TER_FSPYOBS_DATa0 0xf2bd00ff
2412
2413/* FSPYOBS1 */
2414#define R367TER_FSPYOBS1 0xf2be
2415#define F367TER_FSPYOBS_DATAM1 0xf2be00ff
2416
2417/* FSPYOBS0 */
2418#define R367TER_FSPYOBS0 0xf2bf
2419#define F367TER_FSPYOBS_DATAM2 0xf2bf00ff
2420
2421/* SFDEMAP */
2422#define R367TER_SFDEMAP 0xf2c0
2423#define F367TER_SFDEMAP_7 0xf2c00080
2424#define F367TER_SFEC_K_DIVIDER_VIT 0xf2c0007f
2425
2426/* SFERROR */
2427#define R367TER_SFERROR 0xf2c1
2428#define F367TER_SFEC_REGERR_VIT 0xf2c100ff
2429
2430/* SFAVSR */
2431#define R367TER_SFAVSR 0xf2c2
2432#define F367TER_SFEC_SUMERRORS 0xf2c20080
2433#define F367TER_SERROR_MAXMODE 0xf2c20040
2434#define F367TER_SN_SFEC 0xf2c20030
2435#define F367TER_KDIV_MODE_SFEC 0xf2c2000c
2436#define F367TER_SFAVSR_1 0xf2c20002
2437#define F367TER_SFAVSR_0 0xf2c20001
2438
2439/* SFECSTATUS */
2440#define R367TER_SFECSTATUS 0xf2c3
2441#define F367TER_SFEC_ON 0xf2c30080
2442#define F367TER_SFSTATUS_6 0xf2c30040
2443#define F367TER_SFSTATUS_5 0xf2c30020
2444#define F367TER_SFSTATUS_4 0xf2c30010
2445#define F367TER_LOCKEDSFEC 0xf2c30008
2446#define F367TER_SFEC_DELOCK 0xf2c30004
2447#define F367TER_SFEC_DEMODSEL1 0xf2c30002
2448#define F367TER_SFEC_OVFON 0xf2c30001
2449
2450/* SFKDIV12 */
2451#define R367TER_SFKDIV12 0xf2c4
2452#define F367TER_SFECKDIV12_MAN 0xf2c40080
2453#define F367TER_SFEC_K_DIVIDER_12 0xf2c4007f
2454
2455/* SFKDIV23 */
2456#define R367TER_SFKDIV23 0xf2c5
2457#define F367TER_SFECKDIV23_MAN 0xf2c50080
2458#define F367TER_SFEC_K_DIVIDER_23 0xf2c5007f
2459
2460/* SFKDIV34 */
2461#define R367TER_SFKDIV34 0xf2c6
2462#define F367TER_SFECKDIV34_MAN 0xf2c60080
2463#define F367TER_SFEC_K_DIVIDER_34 0xf2c6007f
2464
2465/* SFKDIV56 */
2466#define R367TER_SFKDIV56 0xf2c7
2467#define F367TER_SFECKDIV56_MAN 0xf2c70080
2468#define F367TER_SFEC_K_DIVIDER_56 0xf2c7007f
2469
2470/* SFKDIV67 */
2471#define R367TER_SFKDIV67 0xf2c8
2472#define F367TER_SFECKDIV67_MAN 0xf2c80080
2473#define F367TER_SFEC_K_DIVIDER_67 0xf2c8007f
2474
2475/* SFKDIV78 */
2476#define R367TER_SFKDIV78 0xf2c9
2477#define F367TER_SFECKDIV78_MAN 0xf2c90080
2478#define F367TER_SFEC_K_DIVIDER_78 0xf2c9007f
2479
2480/* SFDILSTKM */
2481#define R367TER_SFDILSTKM 0xf2ca
2482#define F367TER_SFEC_PACKCPT 0xf2ca00e0
2483#define F367TER_SFEC_DILSTK_HI 0xf2ca001f
2484
2485/* SFDILSTKL */
2486#define R367TER_SFDILSTKL 0xf2cb
2487#define F367TER_SFEC_DILSTK_LO 0xf2cb00ff
2488
2489/* SFSTATUS */
2490#define R367TER_SFSTATUS 0xf2cc
2491#define F367TER_SFEC_LINEOK 0xf2cc0080
2492#define F367TER_SFEC_ERROR 0xf2cc0040
2493#define F367TER_SFEC_DATA7 0xf2cc0020
2494#define F367TER_SFEC_OVERFLOW 0xf2cc0010
2495#define F367TER_SFEC_DEMODSEL2 0xf2cc0008
2496#define F367TER_SFEC_NOSYNC 0xf2cc0004
2497#define F367TER_SFEC_UNREGULA 0xf2cc0002
2498#define F367TER_SFEC_READY 0xf2cc0001
2499
2500/* SFDLYH */
2501#define R367TER_SFDLYH 0xf2cd
2502#define F367TER_SFEC_TSTIMEVALID 0xf2cd0080
2503#define F367TER_SFEC_SPEEDUP 0xf2cd0040
2504#define F367TER_SFEC_STOP 0xf2cd0020
2505#define F367TER_SFEC_REGULATED 0xf2cd0010
2506#define F367TER_SFEC_REALSYMBOFFSET 0xf2cd000f
2507
2508/* SFDLYM */
2509#define R367TER_SFDLYM 0xf2ce
2510#define F367TER_SFEC_REALSYMBOFFSET_HI 0xf2ce00ff
2511
2512/* SFDLYL */
2513#define R367TER_SFDLYL 0xf2cf
2514#define F367TER_SFEC_REALSYMBOFFSET_LO 0xf2cf00ff
2515
2516/* SFDLYSETH */
2517#define R367TER_SFDLYSETH 0xf2d0
2518#define F367TER_SFEC_OFFSET 0xf2d000e0
2519#define F367TER_SFECDLYSETH_4 0xf2d00010
2520#define F367TER_RST_SFEC 0xf2d00008
2521#define F367TER_SFECDLYSETH_2 0xf2d00004
2522#define F367TER_SFEC_DISABLE 0xf2d00002
2523#define F367TER_SFEC_UNREGUL 0xf2d00001
2524
2525/* SFDLYSETM */
2526#define R367TER_SFDLYSETM 0xf2d1
2527#define F367TER_SFECDLYSETM_7 0xf2d10080
2528#define F367TER_SFEC_SYMBOFFSET_HI 0xf2d1007f
2529
2530/* SFDLYSETL */
2531#define R367TER_SFDLYSETL 0xf2d2
2532#define F367TER_SFEC_SYMBOFFSET_LO 0xf2d200ff
2533
2534/* SFOBSCFG */
2535#define R367TER_SFOBSCFG 0xf2d3
2536#define F367TER_SFEC_OBSCFG 0xf2d300ff
2537
2538/* SFOBSM */
2539#define R367TER_SFOBSM 0xf2d4
2540#define F367TER_SFEC_OBSDATA_HI 0xf2d400ff
2541
2542/* SFOBSL */
2543#define R367TER_SFOBSL 0xf2d5
2544#define F367TER_SFEC_OBSDATA_LO 0xf2d500ff
2545
2546/* SFECINFO */
2547#define R367TER_SFECINFO 0xf2d6
2548#define F367TER_SFECINFO_7 0xf2d60080
2549#define F367TER_SFEC_SYNCDLSB 0xf2d60070
2550#define F367TER_SFCE_S1cPHASE 0xf2d6000f
2551
2552/* SFERRCTRL */
2553#define R367TER_SFERRCTRL 0xf2d8
2554#define F367TER_SFEC_ERR_SOURCE 0xf2d800f0
2555#define F367TER_SFERRCTRL_3 0xf2d80008
2556#define F367TER_SFEC_NUM_EVENT 0xf2d80007
2557
2558/* SFERRCNTH */
2559#define R367TER_SFERRCNTH 0xf2d9
2560#define F367TER_SFERRC_OLDVALUE 0xf2d90080
2561#define F367TER_SFEC_ERR_CNT 0xf2d9007f
2562
2563/* SFERRCNTM */
2564#define R367TER_SFERRCNTM 0xf2da
2565#define F367TER_SFEC_ERR_CNT_HI 0xf2da00ff
2566
2567/* SFERRCNTL */
2568#define R367TER_SFERRCNTL 0xf2db
2569#define F367TER_SFEC_ERR_CNT_LO 0xf2db00ff
2570
2571/* SYMBRATEM */
2572#define R367TER_SYMBRATEM 0xf2e0
2573#define F367TER_DEFGEN_SYMBRATE_HI 0xf2e000ff
2574
2575/* SYMBRATEL */
2576#define R367TER_SYMBRATEL 0xf2e1
2577#define F367TER_DEFGEN_SYMBRATE_LO 0xf2e100ff
2578
2579/* SYMBSTATUS */
2580#define R367TER_SYMBSTATUS 0xf2e2
2581#define F367TER_SYMBDLINE2_OFF 0xf2e20080
2582#define F367TER_SDDL_REINIT1 0xf2e20040
2583#define F367TER_SDD_REINIT1 0xf2e20020
2584#define F367TER_TOKENID_ERROR 0xf2e20010
2585#define F367TER_SYMBRATE_OVERFLOW 0xf2e20008
2586#define F367TER_SYMBRATE_UNDERFLOW 0xf2e20004
2587#define F367TER_TOKENID_RSTEVENT 0xf2e20002
2588#define F367TER_TOKENID_RESET1 0xf2e20001
2589
2590/* SYMBCFG */
2591#define R367TER_SYMBCFG 0xf2e3
2592#define F367TER_SYMBCFG_7 0xf2e30080
2593#define F367TER_SYMBCFG_6 0xf2e30040
2594#define F367TER_SYMBCFG_5 0xf2e30020
2595#define F367TER_SYMBCFG_4 0xf2e30010
2596#define F367TER_SYMRATE_FSPEED 0xf2e3000c
2597#define F367TER_SYMRATE_SSPEED 0xf2e30003
2598
2599/* SYMBFIFOM */
2600#define R367TER_SYMBFIFOM 0xf2e4
2601#define F367TER_SYMBFIFOM_7 0xf2e40080
2602#define F367TER_SYMBFIFOM_6 0xf2e40040
2603#define F367TER_DEFGEN_SYMFIFO_HI 0xf2e4003f
2604
2605/* SYMBFIFOL */
2606#define R367TER_SYMBFIFOL 0xf2e5
2607#define F367TER_DEFGEN_SYMFIFO_LO 0xf2e500ff
2608
2609/* SYMBOFFSM */
2610#define R367TER_SYMBOFFSM 0xf2e6
2611#define F367TER_TOKENID_RESET2 0xf2e60080
2612#define F367TER_SDDL_REINIT2 0xf2e60040
2613#define F367TER_SDD_REINIT2 0xf2e60020
2614#define F367TER_SYMBOFFSM_4 0xf2e60010
2615#define F367TER_SYMBOFFSM_3 0xf2e60008
2616#define F367TER_DEFGEN_SYMBOFFSET_HI 0xf2e60007
2617
2618/* SYMBOFFSL */
2619#define R367TER_SYMBOFFSL 0xf2e7
2620#define F367TER_DEFGEN_SYMBOFFSET_LO 0xf2e700ff
2621
2622/* DEBUG_LT4 */
2623#define R367TER_DEBUG_LT4 0xf400
2624#define F367TER_F_DEBUG_LT4 0xf40000ff
2625
2626/* DEBUG_LT5 */
2627#define R367TER_DEBUG_LT5 0xf401
2628#define F367TER_F_DEBUG_LT5 0xf40100ff
2629
2630/* DEBUG_LT6 */
2631#define R367TER_DEBUG_LT6 0xf402
2632#define F367TER_F_DEBUG_LT6 0xf40200ff
2633
2634/* DEBUG_LT7 */
2635#define R367TER_DEBUG_LT7 0xf403
2636#define F367TER_F_DEBUG_LT7 0xf40300ff
2637
2638/* DEBUG_LT8 */
2639#define R367TER_DEBUG_LT8 0xf404
2640#define F367TER_F_DEBUG_LT8 0xf40400ff
2641
2642/* DEBUG_LT9 */
2643#define R367TER_DEBUG_LT9 0xf405
2644#define F367TER_F_DEBUG_LT9 0xf40500ff
2645
2646#define STV0367TER_NBREGS 445
2647
2648/* ID */
2649#define R367CAB_ID 0xf000
2650#define F367CAB_IDENTIFICATIONREGISTER 0xf00000ff
2651
2652/* I2CRPT */
2653#define R367CAB_I2CRPT 0xf001
2654#define F367CAB_I2CT_ON 0xf0010080
2655#define F367CAB_ENARPT_LEVEL 0xf0010070
2656#define F367CAB_SCLT_DELAY 0xf0010008
2657#define F367CAB_SCLT_NOD 0xf0010004
2658#define F367CAB_STOP_ENABLE 0xf0010002
2659#define F367CAB_SDAT_NOD 0xf0010001
2660
2661/* TOPCTRL */
2662#define R367CAB_TOPCTRL 0xf002
2663#define F367CAB_STDBY 0xf0020080
2664#define F367CAB_STDBY_CORE 0xf0020020
2665#define F367CAB_QAM_COFDM 0xf0020010
2666#define F367CAB_TS_DIS 0xf0020008
2667#define F367CAB_DIR_CLK_216 0xf0020004
2668
2669/* IOCFG0 */
2670#define R367CAB_IOCFG0 0xf003
2671#define F367CAB_OP0_SD 0xf0030080
2672#define F367CAB_OP0_VAL 0xf0030040
2673#define F367CAB_OP0_OD 0xf0030020
2674#define F367CAB_OP0_INV 0xf0030010
2675#define F367CAB_OP0_DACVALUE_HI 0xf003000f
2676
2677/* DAc0R */
2678#define R367CAB_DAC0R 0xf004
2679#define F367CAB_OP0_DACVALUE_LO 0xf00400ff
2680
2681/* IOCFG1 */
2682#define R367CAB_IOCFG1 0xf005
2683#define F367CAB_IP0 0xf0050040
2684#define F367CAB_OP1_OD 0xf0050020
2685#define F367CAB_OP1_INV 0xf0050010
2686#define F367CAB_OP1_DACVALUE_HI 0xf005000f
2687
2688/* DAC1R */
2689#define R367CAB_DAC1R 0xf006
2690#define F367CAB_OP1_DACVALUE_LO 0xf00600ff
2691
2692/* IOCFG2 */
2693#define R367CAB_IOCFG2 0xf007
2694#define F367CAB_OP2_LOCK_CONF 0xf00700e0
2695#define F367CAB_OP2_OD 0xf0070010
2696#define F367CAB_OP2_VAL 0xf0070008
2697#define F367CAB_OP1_LOCK_CONF 0xf0070007
2698
2699/* SDFR */
2700#define R367CAB_SDFR 0xf008
2701#define F367CAB_OP0_FREQ 0xf00800f0
2702#define F367CAB_OP1_FREQ 0xf008000f
2703
2704/* AUX_CLK */
2705#define R367CAB_AUX_CLK 0xf00a
2706#define F367CAB_AUXFEC_CTL 0xf00a00c0
2707#define F367CAB_DIS_CKX4 0xf00a0020
2708#define F367CAB_CKSEL 0xf00a0018
2709#define F367CAB_CKDIV_PROG 0xf00a0006
2710#define F367CAB_AUXCLK_ENA 0xf00a0001
2711
2712/* FREESYS1 */
2713#define R367CAB_FREESYS1 0xf00b
2714#define F367CAB_FREESYS_1 0xf00b00ff
2715
2716/* FREESYS2 */
2717#define R367CAB_FREESYS2 0xf00c
2718#define F367CAB_FREESYS_2 0xf00c00ff
2719
2720/* FREESYS3 */
2721#define R367CAB_FREESYS3 0xf00d
2722#define F367CAB_FREESYS_3 0xf00d00ff
2723
2724/* GPIO_CFG */
2725#define R367CAB_GPIO_CFG 0xf00e
2726#define F367CAB_GPIO7_OD 0xf00e0080
2727#define F367CAB_GPIO7_CFG 0xf00e0040
2728#define F367CAB_GPIO6_OD 0xf00e0020
2729#define F367CAB_GPIO6_CFG 0xf00e0010
2730#define F367CAB_GPIO5_OD 0xf00e0008
2731#define F367CAB_GPIO5_CFG 0xf00e0004
2732#define F367CAB_GPIO4_OD 0xf00e0002
2733#define F367CAB_GPIO4_CFG 0xf00e0001
2734
2735/* GPIO_CMD */
2736#define R367CAB_GPIO_CMD 0xf00f
2737#define F367CAB_GPIO7_VAL 0xf00f0008
2738#define F367CAB_GPIO6_VAL 0xf00f0004
2739#define F367CAB_GPIO5_VAL 0xf00f0002
2740#define F367CAB_GPIO4_VAL 0xf00f0001
2741
2742/* TSTRES */
2743#define R367CAB_TSTRES 0xf0c0
2744#define F367CAB_FRES_DISPLAY 0xf0c00080
2745#define F367CAB_FRES_FIFO_AD 0xf0c00020
2746#define F367CAB_FRESRS 0xf0c00010
2747#define F367CAB_FRESACS 0xf0c00008
2748#define F367CAB_FRESFEC 0xf0c00004
2749#define F367CAB_FRES_PRIF 0xf0c00002
2750#define F367CAB_FRESCORE 0xf0c00001
2751
2752/* ANACTRL */
2753#define R367CAB_ANACTRL 0xf0c1
2754#define F367CAB_BYPASS_XTAL 0xf0c10040
2755#define F367CAB_BYPASS_PLLXN 0xf0c1000c
2756#define F367CAB_DIS_PAD_OSC 0xf0c10002
2757#define F367CAB_STDBY_PLLXN 0xf0c10001
2758
2759/* TSTBUS */
2760#define R367CAB_TSTBUS 0xf0c2
2761#define F367CAB_TS_BYTE_CLK_INV 0xf0c20080
2762#define F367CAB_CFG_IP 0xf0c20070
2763#define F367CAB_CFG_TST 0xf0c2000f
2764
2765/* RF_AGC1 */
2766#define R367CAB_RF_AGC1 0xf0d4
2767#define F367CAB_RF_AGC1_LEVEL_HI 0xf0d400ff
2768
2769/* RF_AGC2 */
2770#define R367CAB_RF_AGC2 0xf0d5
2771#define F367CAB_REF_ADGP 0xf0d50080
2772#define F367CAB_STDBY_ADCGP 0xf0d50020
2773#define F367CAB_RF_AGC1_LEVEL_LO 0xf0d50003
2774
2775/* ANADIGCTRL */
2776#define R367CAB_ANADIGCTRL 0xf0d7
2777#define F367CAB_SEL_CLKDEM 0xf0d70020
2778#define F367CAB_EN_BUFFER_Q 0xf0d70010
2779#define F367CAB_EN_BUFFER_I 0xf0d70008
2780#define F367CAB_ADC_RIS_EGDE 0xf0d70004
2781#define F367CAB_SGN_ADC 0xf0d70002
2782#define F367CAB_SEL_AD12_SYNC 0xf0d70001
2783
2784/* PLLMDIV */
2785#define R367CAB_PLLMDIV 0xf0d8
2786#define F367CAB_PLL_MDIV 0xf0d800ff
2787
2788/* PLLNDIV */
2789#define R367CAB_PLLNDIV 0xf0d9
2790#define F367CAB_PLL_NDIV 0xf0d900ff
2791
2792/* PLLSETUP */
2793#define R367CAB_PLLSETUP 0xf0da
2794#define F367CAB_PLL_PDIV 0xf0da0070
2795#define F367CAB_PLL_KDIV 0xf0da000f
2796
2797/* DUAL_AD12 */
2798#define R367CAB_DUAL_AD12 0xf0db
2799#define F367CAB_FS20M 0xf0db0020
2800#define F367CAB_FS50M 0xf0db0010
2801#define F367CAB_INMODe0 0xf0db0008
2802#define F367CAB_POFFQ 0xf0db0004
2803#define F367CAB_POFFI 0xf0db0002
2804#define F367CAB_INMODE1 0xf0db0001
2805
2806/* TSTBIST */
2807#define R367CAB_TSTBIST 0xf0dc
2808#define F367CAB_TST_BYP_CLK 0xf0dc0080
2809#define F367CAB_TST_GCLKENA_STD 0xf0dc0040
2810#define F367CAB_TST_GCLKENA 0xf0dc0020
2811#define F367CAB_TST_MEMBIST 0xf0dc001f
2812
2813/* CTRL_1 */
2814#define R367CAB_CTRL_1 0xf402
2815#define F367CAB_SOFT_RST 0xf4020080
2816#define F367CAB_EQU_RST 0xf4020008
2817#define F367CAB_CRL_RST 0xf4020004
2818#define F367CAB_TRL_RST 0xf4020002
2819#define F367CAB_AGC_RST 0xf4020001
2820
2821/* CTRL_2 */
2822#define R367CAB_CTRL_2 0xf403
2823#define F367CAB_DEINT_RST 0xf4030008
2824#define F367CAB_RS_RST 0xf4030004
2825
2826/* IT_STATUS1 */
2827#define R367CAB_IT_STATUS1 0xf408
2828#define F367CAB_SWEEP_OUT 0xf4080080
2829#define F367CAB_FSM_CRL 0xf4080040
2830#define F367CAB_CRL_LOCK 0xf4080020
2831#define F367CAB_MFSM 0xf4080010
2832#define F367CAB_TRL_LOCK 0xf4080008
2833#define F367CAB_TRL_AGC_LIMIT 0xf4080004
2834#define F367CAB_ADJ_AGC_LOCK 0xf4080002
2835#define F367CAB_AGC_QAM_LOCK 0xf4080001
2836
2837/* IT_STATUS2 */
2838#define R367CAB_IT_STATUS2 0xf409
2839#define F367CAB_TSMF_CNT 0xf4090080
2840#define F367CAB_TSMF_EOF 0xf4090040
2841#define F367CAB_TSMF_RDY 0xf4090020
2842#define F367CAB_FEC_NOCORR 0xf4090010
2843#define F367CAB_SYNCSTATE 0xf4090008
2844#define F367CAB_DEINT_LOCK 0xf4090004
2845#define F367CAB_FADDING_FRZ 0xf4090002
2846#define F367CAB_TAPMON_ALARM 0xf4090001
2847
2848/* IT_EN1 */
2849#define R367CAB_IT_EN1 0xf40a
2850#define F367CAB_SWEEP_OUTE 0xf40a0080
2851#define F367CAB_FSM_CRLE 0xf40a0040
2852#define F367CAB_CRL_LOCKE 0xf40a0020
2853#define F367CAB_MFSME 0xf40a0010
2854#define F367CAB_TRL_LOCKE 0xf40a0008
2855#define F367CAB_TRL_AGC_LIMITE 0xf40a0004
2856#define F367CAB_ADJ_AGC_LOCKE 0xf40a0002
2857#define F367CAB_AGC_LOCKE 0xf40a0001
2858
2859/* IT_EN2 */
2860#define R367CAB_IT_EN2 0xf40b
2861#define F367CAB_TSMF_CNTE 0xf40b0080
2862#define F367CAB_TSMF_EOFE 0xf40b0040
2863#define F367CAB_TSMF_RDYE 0xf40b0020
2864#define F367CAB_FEC_NOCORRE 0xf40b0010
2865#define F367CAB_SYNCSTATEE 0xf40b0008
2866#define F367CAB_DEINT_LOCKE 0xf40b0004
2867#define F367CAB_FADDING_FRZE 0xf40b0002
2868#define F367CAB_TAPMON_ALARME 0xf40b0001
2869
2870/* CTRL_STATUS */
2871#define R367CAB_CTRL_STATUS 0xf40c
2872#define F367CAB_QAMFEC_LOCK 0xf40c0004
2873#define F367CAB_TSMF_LOCK 0xf40c0002
2874#define F367CAB_TSMF_ERROR 0xf40c0001
2875
2876/* TEST_CTL */
2877#define R367CAB_TEST_CTL 0xf40f
2878#define F367CAB_TST_BLK_SEL 0xf40f0060
2879#define F367CAB_TST_BUS_SEL 0xf40f001f
2880
2881/* AGC_CTL */
2882#define R367CAB_AGC_CTL 0xf410
2883#define F367CAB_AGC_LCK_TH 0xf41000f0
2884#define F367CAB_AGC_ACCUMRSTSEL 0xf4100007
2885
2886/* AGC_IF_CFG */
2887#define R367CAB_AGC_IF_CFG 0xf411
2888#define F367CAB_AGC_IF_BWSEL 0xf41100f0
2889#define F367CAB_AGC_IF_FREEZE 0xf4110002
2890
2891/* AGC_RF_CFG */
2892#define R367CAB_AGC_RF_CFG 0xf412
2893#define F367CAB_AGC_RF_BWSEL 0xf4120070
2894#define F367CAB_AGC_RF_FREEZE 0xf4120002
2895
2896/* AGC_PWM_CFG */
2897#define R367CAB_AGC_PWM_CFG 0xf413
2898#define F367CAB_AGC_RF_PWM_TST 0xf4130080
2899#define F367CAB_AGC_RF_PWM_INV 0xf4130040
2900#define F367CAB_AGC_IF_PWM_TST 0xf4130008
2901#define F367CAB_AGC_IF_PWM_INV 0xf4130004
2902#define F367CAB_AGC_PWM_CLKDIV 0xf4130003
2903
2904/* AGC_PWR_REF_L */
2905#define R367CAB_AGC_PWR_REF_L 0xf414
2906#define F367CAB_AGC_PWRREF_LO 0xf41400ff
2907
2908/* AGC_PWR_REF_H */
2909#define R367CAB_AGC_PWR_REF_H 0xf415
2910#define F367CAB_AGC_PWRREF_HI 0xf4150003
2911
2912/* AGC_RF_TH_L */
2913#define R367CAB_AGC_RF_TH_L 0xf416
2914#define F367CAB_AGC_RF_TH_LO 0xf41600ff
2915
2916/* AGC_RF_TH_H */
2917#define R367CAB_AGC_RF_TH_H 0xf417
2918#define F367CAB_AGC_RF_TH_HI 0xf417000f
2919
2920/* AGC_IF_LTH_L */
2921#define R367CAB_AGC_IF_LTH_L 0xf418
2922#define F367CAB_AGC_IF_THLO_LO 0xf41800ff
2923
2924/* AGC_IF_LTH_H */
2925#define R367CAB_AGC_IF_LTH_H 0xf419
2926#define F367CAB_AGC_IF_THLO_HI 0xf419000f
2927
2928/* AGC_IF_HTH_L */
2929#define R367CAB_AGC_IF_HTH_L 0xf41a
2930#define F367CAB_AGC_IF_THHI_LO 0xf41a00ff
2931
2932/* AGC_IF_HTH_H */
2933#define R367CAB_AGC_IF_HTH_H 0xf41b
2934#define F367CAB_AGC_IF_THHI_HI 0xf41b000f
2935
2936/* AGC_PWR_RD_L */
2937#define R367CAB_AGC_PWR_RD_L 0xf41c
2938#define F367CAB_AGC_PWR_WORD_LO 0xf41c00ff
2939
2940/* AGC_PWR_RD_M */
2941#define R367CAB_AGC_PWR_RD_M 0xf41d
2942#define F367CAB_AGC_PWR_WORD_ME 0xf41d00ff
2943
2944/* AGC_PWR_RD_H */
2945#define R367CAB_AGC_PWR_RD_H 0xf41e
2946#define F367CAB_AGC_PWR_WORD_HI 0xf41e0003
2947
2948/* AGC_PWM_IFCMD_L */
2949#define R367CAB_AGC_PWM_IFCMD_L 0xf420
2950#define F367CAB_AGC_IF_PWMCMD_LO 0xf42000ff
2951
2952/* AGC_PWM_IFCMD_H */
2953#define R367CAB_AGC_PWM_IFCMD_H 0xf421
2954#define F367CAB_AGC_IF_PWMCMD_HI 0xf421000f
2955
2956/* AGC_PWM_RFCMD_L */
2957#define R367CAB_AGC_PWM_RFCMD_L 0xf422
2958#define F367CAB_AGC_RF_PWMCMD_LO 0xf42200ff
2959
2960/* AGC_PWM_RFCMD_H */
2961#define R367CAB_AGC_PWM_RFCMD_H 0xf423
2962#define F367CAB_AGC_RF_PWMCMD_HI 0xf423000f
2963
2964/* IQDEM_CFG */
2965#define R367CAB_IQDEM_CFG 0xf424
2966#define F367CAB_IQDEM_CLK_SEL 0xf4240004
2967#define F367CAB_IQDEM_INVIQ 0xf4240002
2968#define F367CAB_IQDEM_A2dTYPE 0xf4240001
2969
2970/* MIX_NCO_LL */
2971#define R367CAB_MIX_NCO_LL 0xf425
2972#define F367CAB_MIX_NCO_INC_LL 0xf42500ff
2973
2974/* MIX_NCO_HL */
2975#define R367CAB_MIX_NCO_HL 0xf426
2976#define F367CAB_MIX_NCO_INC_HL 0xf42600ff
2977
2978/* MIX_NCO_HH */
2979#define R367CAB_MIX_NCO_HH 0xf427
2980#define F367CAB_MIX_NCO_INVCNST 0xf4270080
2981#define F367CAB_MIX_NCO_INC_HH 0xf427007f
2982
2983/* SRC_NCO_LL */
2984#define R367CAB_SRC_NCO_LL 0xf428
2985#define F367CAB_SRC_NCO_INC_LL 0xf42800ff
2986
2987/* SRC_NCO_LH */
2988#define R367CAB_SRC_NCO_LH 0xf429
2989#define F367CAB_SRC_NCO_INC_LH 0xf42900ff
2990
2991/* SRC_NCO_HL */
2992#define R367CAB_SRC_NCO_HL 0xf42a
2993#define F367CAB_SRC_NCO_INC_HL 0xf42a00ff
2994
2995/* SRC_NCO_HH */
2996#define R367CAB_SRC_NCO_HH 0xf42b
2997#define F367CAB_SRC_NCO_INC_HH 0xf42b007f
2998
2999/* IQDEM_GAIN_SRC_L */
3000#define R367CAB_IQDEM_GAIN_SRC_L 0xf42c
3001#define F367CAB_GAIN_SRC_LO 0xf42c00ff
3002
3003/* IQDEM_GAIN_SRC_H */
3004#define R367CAB_IQDEM_GAIN_SRC_H 0xf42d
3005#define F367CAB_GAIN_SRC_HI 0xf42d0003
3006
3007/* IQDEM_DCRM_CFG_LL */
3008#define R367CAB_IQDEM_DCRM_CFG_LL 0xf430
3009#define F367CAB_DCRM0_DCIN_L 0xf43000ff
3010
3011/* IQDEM_DCRM_CFG_LH */
3012#define R367CAB_IQDEM_DCRM_CFG_LH 0xf431
3013#define F367CAB_DCRM1_I_DCIN_L 0xf43100fc
3014#define F367CAB_DCRM0_DCIN_H 0xf4310003
3015
3016/* IQDEM_DCRM_CFG_HL */
3017#define R367CAB_IQDEM_DCRM_CFG_HL 0xf432
3018#define F367CAB_DCRM1_Q_DCIN_L 0xf43200f0
3019#define F367CAB_DCRM1_I_DCIN_H 0xf432000f
3020
3021/* IQDEM_DCRM_CFG_HH */
3022#define R367CAB_IQDEM_DCRM_CFG_HH 0xf433
3023#define F367CAB_DCRM1_FRZ 0xf4330080
3024#define F367CAB_DCRM0_FRZ 0xf4330040
3025#define F367CAB_DCRM1_Q_DCIN_H 0xf433003f
3026
3027/* IQDEM_ADJ_COEFf0 */
3028#define R367CAB_IQDEM_ADJ_COEFF0 0xf434
3029#define F367CAB_ADJIIR_COEFF10_L 0xf43400ff
3030
3031/* IQDEM_ADJ_COEFF1 */
3032#define R367CAB_IQDEM_ADJ_COEFF1 0xf435
3033#define F367CAB_ADJIIR_COEFF11_L 0xf43500fc
3034#define F367CAB_ADJIIR_COEFF10_H 0xf4350003
3035
3036/* IQDEM_ADJ_COEFF2 */
3037#define R367CAB_IQDEM_ADJ_COEFF2 0xf436
3038#define F367CAB_ADJIIR_COEFF12_L 0xf43600f0
3039#define F367CAB_ADJIIR_COEFF11_H 0xf436000f
3040
3041/* IQDEM_ADJ_COEFF3 */
3042#define R367CAB_IQDEM_ADJ_COEFF3 0xf437
3043#define F367CAB_ADJIIR_COEFF20_L 0xf43700c0
3044#define F367CAB_ADJIIR_COEFF12_H 0xf437003f
3045
3046/* IQDEM_ADJ_COEFF4 */
3047#define R367CAB_IQDEM_ADJ_COEFF4 0xf438
3048#define F367CAB_ADJIIR_COEFF20_H 0xf43800ff
3049
3050/* IQDEM_ADJ_COEFF5 */
3051#define R367CAB_IQDEM_ADJ_COEFF5 0xf439
3052#define F367CAB_ADJIIR_COEFF21_L 0xf43900ff
3053
3054/* IQDEM_ADJ_COEFF6 */
3055#define R367CAB_IQDEM_ADJ_COEFF6 0xf43a
3056#define F367CAB_ADJIIR_COEFF22_L 0xf43a00fc
3057#define F367CAB_ADJIIR_COEFF21_H 0xf43a0003
3058
3059/* IQDEM_ADJ_COEFF7 */
3060#define R367CAB_IQDEM_ADJ_COEFF7 0xf43b
3061#define F367CAB_ADJIIR_COEFF22_H 0xf43b000f
3062
3063/* IQDEM_ADJ_EN */
3064#define R367CAB_IQDEM_ADJ_EN 0xf43c
3065#define F367CAB_ALLPASSFILT_EN 0xf43c0008
3066#define F367CAB_ADJ_AGC_EN 0xf43c0004
3067#define F367CAB_ADJ_COEFF_FRZ 0xf43c0002
3068#define F367CAB_ADJ_EN 0xf43c0001
3069
3070/* IQDEM_ADJ_AGC_REF */
3071#define R367CAB_IQDEM_ADJ_AGC_REF 0xf43d
3072#define F367CAB_ADJ_AGC_REF 0xf43d00ff
3073
3074/* ALLPASSFILT1 */
3075#define R367CAB_ALLPASSFILT1 0xf440
3076#define F367CAB_ALLPASSFILT_COEFF1_LO 0xf44000ff
3077
3078/* ALLPASSFILT2 */
3079#define R367CAB_ALLPASSFILT2 0xf441
3080#define F367CAB_ALLPASSFILT_COEFF1_ME 0xf44100ff
3081
3082/* ALLPASSFILT3 */
3083#define R367CAB_ALLPASSFILT3 0xf442
3084#define F367CAB_ALLPASSFILT_COEFF2_LO 0xf44200c0
3085#define F367CAB_ALLPASSFILT_COEFF1_HI 0xf442003f
3086
3087/* ALLPASSFILT4 */
3088#define R367CAB_ALLPASSFILT4 0xf443
3089#define F367CAB_ALLPASSFILT_COEFF2_MEL 0xf44300ff
3090
3091/* ALLPASSFILT5 */
3092#define R367CAB_ALLPASSFILT5 0xf444
3093#define F367CAB_ALLPASSFILT_COEFF2_MEH 0xf44400ff
3094
3095/* ALLPASSFILT6 */
3096#define R367CAB_ALLPASSFILT6 0xf445
3097#define F367CAB_ALLPASSFILT_COEFF3_LO 0xf44500f0
3098#define F367CAB_ALLPASSFILT_COEFF2_HI 0xf445000f
3099
3100/* ALLPASSFILT7 */
3101#define R367CAB_ALLPASSFILT7 0xf446
3102#define F367CAB_ALLPASSFILT_COEFF3_MEL 0xf44600ff
3103
3104/* ALLPASSFILT8 */
3105#define R367CAB_ALLPASSFILT8 0xf447
3106#define F367CAB_ALLPASSFILT_COEFF3_MEH 0xf44700ff
3107
3108/* ALLPASSFILT9 */
3109#define R367CAB_ALLPASSFILT9 0xf448
3110#define F367CAB_ALLPASSFILT_COEFF4_LO 0xf44800fc
3111#define F367CAB_ALLPASSFILT_COEFF3_HI 0xf4480003
3112
3113/* ALLPASSFILT10 */
3114#define R367CAB_ALLPASSFILT10 0xf449
3115#define F367CAB_ALLPASSFILT_COEFF4_ME 0xf44900ff
3116
3117/* ALLPASSFILT11 */
3118#define R367CAB_ALLPASSFILT11 0xf44a
3119#define F367CAB_ALLPASSFILT_COEFF4_HI 0xf44a00ff
3120
3121/* TRL_AGC_CFG */
3122#define R367CAB_TRL_AGC_CFG 0xf450
3123#define F367CAB_TRL_AGC_FREEZE 0xf4500080
3124#define F367CAB_TRL_AGC_REF 0xf450007f
3125
3126/* TRL_LPF_CFG */
3127#define R367CAB_TRL_LPF_CFG 0xf454
3128#define F367CAB_NYQPOINT_INV 0xf4540040
3129#define F367CAB_TRL_SHIFT 0xf4540030
3130#define F367CAB_NYQ_COEFF_SEL 0xf454000c
3131#define F367CAB_TRL_LPF_FREEZE 0xf4540002
3132#define F367CAB_TRL_LPF_CRT 0xf4540001
3133
3134/* TRL_LPF_ACQ_GAIN */
3135#define R367CAB_TRL_LPF_ACQ_GAIN 0xf455
3136#define F367CAB_TRL_GDIR_ACQ 0xf4550070
3137#define F367CAB_TRL_GINT_ACQ 0xf4550007
3138
3139/* TRL_LPF_TRK_GAIN */
3140#define R367CAB_TRL_LPF_TRK_GAIN 0xf456
3141#define F367CAB_TRL_GDIR_TRK 0xf4560070
3142#define F367CAB_TRL_GINT_TRK 0xf4560007
3143
3144/* TRL_LPF_OUT_GAIN */
3145#define R367CAB_TRL_LPF_OUT_GAIN 0xf457
3146#define F367CAB_TRL_GAIN_OUT 0xf4570007
3147
3148/* TRL_LOCKDET_LTH */
3149#define R367CAB_TRL_LOCKDET_LTH 0xf458
3150#define F367CAB_TRL_LCK_THLO 0xf4580007
3151
3152/* TRL_LOCKDET_HTH */
3153#define R367CAB_TRL_LOCKDET_HTH 0xf459
3154#define F367CAB_TRL_LCK_THHI 0xf45900ff
3155
3156/* TRL_LOCKDET_TRGVAL */
3157#define R367CAB_TRL_LOCKDET_TRGVAL 0xf45a
3158#define F367CAB_TRL_LCK_TRG 0xf45a00ff
3159
3160/* IQ_QAM */
3161#define R367CAB_IQ_QAM 0xf45c
3162#define F367CAB_IQ_INPUT 0xf45c0008
3163#define F367CAB_DETECT_MODE 0xf45c0007
3164
3165/* FSM_STATE */
3166#define R367CAB_FSM_STATE 0xf460
3167#define F367CAB_CRL_DFE 0xf4600080
3168#define F367CAB_DFE_START 0xf4600040
3169#define F367CAB_CTRLG_START 0xf4600030
3170#define F367CAB_FSM_FORCESTATE 0xf460000f
3171
3172/* FSM_CTL */
3173#define R367CAB_FSM_CTL 0xf461
3174#define F367CAB_FEC2_EN 0xf4610040
3175#define F367CAB_SIT_EN 0xf4610020
3176#define F367CAB_TRL_AHEAD 0xf4610010
3177#define F367CAB_TRL2_EN 0xf4610008
3178#define F367CAB_FSM_EQA1_EN 0xf4610004
3179#define F367CAB_FSM_BKP_DIS 0xf4610002
3180#define F367CAB_FSM_FORCE_EN 0xf4610001
3181
3182/* FSM_STS */
3183#define R367CAB_FSM_STS 0xf462
3184#define F367CAB_FSM_STATUS 0xf462000f
3185
3186/* FSM_SNR0_HTH */
3187#define R367CAB_FSM_SNR0_HTH 0xf463
3188#define F367CAB_SNR0_HTH 0xf46300ff
3189
3190/* FSM_SNR1_HTH */
3191#define R367CAB_FSM_SNR1_HTH 0xf464
3192#define F367CAB_SNR1_HTH 0xf46400ff
3193
3194/* FSM_SNR2_HTH */
3195#define R367CAB_FSM_SNR2_HTH 0xf465
3196#define F367CAB_SNR2_HTH 0xf46500ff
3197
3198/* FSM_SNR0_LTH */
3199#define R367CAB_FSM_SNR0_LTH 0xf466
3200#define F367CAB_SNR0_LTH 0xf46600ff
3201
3202/* FSM_SNR1_LTH */
3203#define R367CAB_FSM_SNR1_LTH 0xf467
3204#define F367CAB_SNR1_LTH 0xf46700ff
3205
3206/* FSM_EQA1_HTH */
3207#define R367CAB_FSM_EQA1_HTH 0xf468
3208#define F367CAB_SNR3_HTH_LO 0xf46800f0
3209#define F367CAB_EQA1_HTH 0xf468000f
3210
3211/* FSM_TEMPO */
3212#define R367CAB_FSM_TEMPO 0xf469
3213#define F367CAB_SIT 0xf46900c0
3214#define F367CAB_WST 0xf4690038
3215#define F367CAB_ELT 0xf4690006
3216#define F367CAB_SNR3_HTH_HI 0xf4690001
3217
3218/* FSM_CONFIG */
3219#define R367CAB_FSM_CONFIG 0xf46a
3220#define F367CAB_FEC2_DFEOFF 0xf46a0004
3221#define F367CAB_PRIT_STATE 0xf46a0002
3222#define F367CAB_MODMAP_STATE 0xf46a0001
3223
3224/* EQU_I_TESTTAP_L */
3225#define R367CAB_EQU_I_TESTTAP_L 0xf474
3226#define F367CAB_I_TEST_TAP_L 0xf47400ff
3227
3228/* EQU_I_TESTTAP_M */
3229#define R367CAB_EQU_I_TESTTAP_M 0xf475
3230#define F367CAB_I_TEST_TAP_M 0xf47500ff
3231
3232/* EQU_I_TESTTAP_H */
3233#define R367CAB_EQU_I_TESTTAP_H 0xf476
3234#define F367CAB_I_TEST_TAP_H 0xf476001f
3235
3236/* EQU_TESTAP_CFG */
3237#define R367CAB_EQU_TESTAP_CFG 0xf477
3238#define F367CAB_TEST_FFE_DFE_SEL 0xf4770040
3239#define F367CAB_TEST_TAP_SELECT 0xf477003f
3240
3241/* EQU_Q_TESTTAP_L */
3242#define R367CAB_EQU_Q_TESTTAP_L 0xf478
3243#define F367CAB_Q_TEST_TAP_L 0xf47800ff
3244
3245/* EQU_Q_TESTTAP_M */
3246#define R367CAB_EQU_Q_TESTTAP_M 0xf479
3247#define F367CAB_Q_TEST_TAP_M 0xf47900ff
3248
3249/* EQU_Q_TESTTAP_H */
3250#define R367CAB_EQU_Q_TESTTAP_H 0xf47a
3251#define F367CAB_Q_TEST_TAP_H 0xf47a001f
3252
3253/* EQU_TAP_CTRL */
3254#define R367CAB_EQU_TAP_CTRL 0xf47b
3255#define F367CAB_MTAP_FRZ 0xf47b0010
3256#define F367CAB_PRE_FREEZE 0xf47b0008
3257#define F367CAB_DFE_TAPMON_EN 0xf47b0004
3258#define F367CAB_FFE_TAPMON_EN 0xf47b0002
3259#define F367CAB_MTAP_ONLY 0xf47b0001
3260
3261/* EQU_CTR_CRL_CONTROL_L */
3262#define R367CAB_EQU_CTR_CRL_CONTROL_L 0xf47c
3263#define F367CAB_EQU_CTR_CRL_CONTROL_LO 0xf47c00ff
3264
3265/* EQU_CTR_CRL_CONTROL_H */
3266#define R367CAB_EQU_CTR_CRL_CONTROL_H 0xf47d
3267#define F367CAB_EQU_CTR_CRL_CONTROL_HI 0xf47d00ff
3268
3269/* EQU_CTR_HIPOW_L */
3270#define R367CAB_EQU_CTR_HIPOW_L 0xf47e
3271#define F367CAB_CTR_HIPOW_L 0xf47e00ff
3272
3273/* EQU_CTR_HIPOW_H */
3274#define R367CAB_EQU_CTR_HIPOW_H 0xf47f
3275#define F367CAB_CTR_HIPOW_H 0xf47f00ff
3276
3277/* EQU_I_EQU_LO */
3278#define R367CAB_EQU_I_EQU_LO 0xf480
3279#define F367CAB_EQU_I_EQU_L 0xf48000ff
3280
3281/* EQU_I_EQU_HI */
3282#define R367CAB_EQU_I_EQU_HI 0xf481
3283#define F367CAB_EQU_I_EQU_H 0xf4810003
3284
3285/* EQU_Q_EQU_LO */
3286#define R367CAB_EQU_Q_EQU_LO 0xf482
3287#define F367CAB_EQU_Q_EQU_L 0xf48200ff
3288
3289/* EQU_Q_EQU_HI */
3290#define R367CAB_EQU_Q_EQU_HI 0xf483
3291#define F367CAB_EQU_Q_EQU_H 0xf4830003
3292
3293/* EQU_MAPPER */
3294#define R367CAB_EQU_MAPPER 0xf484
3295#define F367CAB_QUAD_AUTO 0xf4840080
3296#define F367CAB_QUAD_INV 0xf4840040
3297#define F367CAB_QAM_MODE 0xf4840007
3298
3299/* EQU_SWEEP_RATE */
3300#define R367CAB_EQU_SWEEP_RATE 0xf485
3301#define F367CAB_SNR_PER 0xf48500c0
3302#define F367CAB_SWEEP_RATE 0xf485003f
3303
3304/* EQU_SNR_LO */
3305#define R367CAB_EQU_SNR_LO 0xf486
3306#define F367CAB_SNR_LO 0xf48600ff
3307
3308/* EQU_SNR_HI */
3309#define R367CAB_EQU_SNR_HI 0xf487
3310#define F367CAB_SNR_HI 0xf48700ff
3311
3312/* EQU_GAMMA_LO */
3313#define R367CAB_EQU_GAMMA_LO 0xf488
3314#define F367CAB_GAMMA_LO 0xf48800ff
3315
3316/* EQU_GAMMA_HI */
3317#define R367CAB_EQU_GAMMA_HI 0xf489
3318#define F367CAB_GAMMA_ME 0xf48900ff
3319
3320/* EQU_ERR_GAIN */
3321#define R367CAB_EQU_ERR_GAIN 0xf48a
3322#define F367CAB_EQA1MU 0xf48a0070
3323#define F367CAB_CRL2MU 0xf48a000e
3324#define F367CAB_GAMMA_HI 0xf48a0001
3325
3326/* EQU_RADIUS */
3327#define R367CAB_EQU_RADIUS 0xf48b
3328#define F367CAB_RADIUS 0xf48b00ff
3329
3330/* EQU_FFE_MAINTAP */
3331#define R367CAB_EQU_FFE_MAINTAP 0xf48c
3332#define F367CAB_FFE_MAINTAP_INIT 0xf48c00ff
3333
3334/* EQU_FFE_LEAKAGE */
3335#define R367CAB_EQU_FFE_LEAKAGE 0xf48e
3336#define F367CAB_LEAK_PER 0xf48e00f0
3337#define F367CAB_EQU_OUTSEL 0xf48e0002
3338#define F367CAB_PNT2dFE 0xf48e0001
3339
3340/* EQU_FFE_MAINTAP_POS */
3341#define R367CAB_EQU_FFE_MAINTAP_POS 0xf48f
3342#define F367CAB_FFE_LEAK_EN 0xf48f0080
3343#define F367CAB_DFE_LEAK_EN 0xf48f0040
3344#define F367CAB_FFE_MAINTAP_POS 0xf48f003f
3345
3346/* EQU_GAIN_WIDE */
3347#define R367CAB_EQU_GAIN_WIDE 0xf490
3348#define F367CAB_DFE_GAIN_WIDE 0xf49000f0
3349#define F367CAB_FFE_GAIN_WIDE 0xf490000f
3350
3351/* EQU_GAIN_NARROW */
3352#define R367CAB_EQU_GAIN_NARROW 0xf491
3353#define F367CAB_DFE_GAIN_NARROW 0xf49100f0
3354#define F367CAB_FFE_GAIN_NARROW 0xf491000f
3355
3356/* EQU_CTR_LPF_GAIN */
3357#define R367CAB_EQU_CTR_LPF_GAIN 0xf492
3358#define F367CAB_CTR_GTO 0xf4920080
3359#define F367CAB_CTR_GDIR 0xf4920070
3360#define F367CAB_SWEEP_EN 0xf4920008
3361#define F367CAB_CTR_GINT 0xf4920007
3362
3363/* EQU_CRL_LPF_GAIN */
3364#define R367CAB_EQU_CRL_LPF_GAIN 0xf493
3365#define F367CAB_CRL_GTO 0xf4930080
3366#define F367CAB_CRL_GDIR 0xf4930070
3367#define F367CAB_SWEEP_DIR 0xf4930008
3368#define F367CAB_CRL_GINT 0xf4930007
3369
3370/* EQU_GLOBAL_GAIN */
3371#define R367CAB_EQU_GLOBAL_GAIN 0xf494
3372#define F367CAB_CRL_GAIN 0xf49400f8
3373#define F367CAB_CTR_INC_GAIN 0xf4940004
3374#define F367CAB_CTR_FRAC 0xf4940003
3375
3376/* EQU_CRL_LD_SEN */
3377#define R367CAB_EQU_CRL_LD_SEN 0xf495
3378#define F367CAB_CTR_BADPOINT_EN 0xf4950080
3379#define F367CAB_CTR_GAIN 0xf4950070
3380#define F367CAB_LIMANEN 0xf4950008
3381#define F367CAB_CRL_LD_SEN 0xf4950007
3382
3383/* EQU_CRL_LD_VAL */
3384#define R367CAB_EQU_CRL_LD_VAL 0xf496
3385#define F367CAB_CRL_BISTH_LIMIT 0xf4960080
3386#define F367CAB_CARE_EN 0xf4960040
3387#define F367CAB_CRL_LD_PER 0xf4960030
3388#define F367CAB_CRL_LD_WST 0xf496000c
3389#define F367CAB_CRL_LD_TFS 0xf4960003
3390
3391/* EQU_CRL_TFR */
3392#define R367CAB_EQU_CRL_TFR 0xf497
3393#define F367CAB_CRL_LD_TFR 0xf49700ff
3394
3395/* EQU_CRL_BISTH_LO */
3396#define R367CAB_EQU_CRL_BISTH_LO 0xf498
3397#define F367CAB_CRL_BISTH_LO 0xf49800ff
3398
3399/* EQU_CRL_BISTH_HI */
3400#define R367CAB_EQU_CRL_BISTH_HI 0xf499
3401#define F367CAB_CRL_BISTH_HI 0xf49900ff
3402
3403/* EQU_SWEEP_RANGE_LO */
3404#define R367CAB_EQU_SWEEP_RANGE_LO 0xf49a
3405#define F367CAB_SWEEP_RANGE_LO 0xf49a00ff
3406
3407/* EQU_SWEEP_RANGE_HI */
3408#define R367CAB_EQU_SWEEP_RANGE_HI 0xf49b
3409#define F367CAB_SWEEP_RANGE_HI 0xf49b00ff
3410
3411/* EQU_CRL_LIMITER */
3412#define R367CAB_EQU_CRL_LIMITER 0xf49c
3413#define F367CAB_BISECTOR_EN 0xf49c0080
3414#define F367CAB_PHEST128_EN 0xf49c0040
3415#define F367CAB_CRL_LIM 0xf49c003f
3416
3417/* EQU_MODULUS_MAP */
3418#define R367CAB_EQU_MODULUS_MAP 0xf49d
3419#define F367CAB_PNT_DEPTH 0xf49d00e0
3420#define F367CAB_MODULUS_CMP 0xf49d001f
3421
3422/* EQU_PNT_GAIN */
3423#define R367CAB_EQU_PNT_GAIN 0xf49e
3424#define F367CAB_PNT_EN 0xf49e0080
3425#define F367CAB_MODULUSMAP_EN 0xf49e0040
3426#define F367CAB_PNT_GAIN 0xf49e003f
3427
3428/* FEC_AC_CTR_0 */
3429#define R367CAB_FEC_AC_CTR_0 0xf4a8
3430#define F367CAB_BE_BYPASS 0xf4a80020
3431#define F367CAB_REFRESH47 0xf4a80010
3432#define F367CAB_CT_NBST 0xf4a80008
3433#define F367CAB_TEI_ENA 0xf4a80004
3434#define F367CAB_DS_ENA 0xf4a80002
3435#define F367CAB_TSMF_EN 0xf4a80001
3436
3437/* FEC_AC_CTR_1 */
3438#define R367CAB_FEC_AC_CTR_1 0xf4a9
3439#define F367CAB_DEINT_DEPTH 0xf4a900ff
3440
3441/* FEC_AC_CTR_2 */
3442#define R367CAB_FEC_AC_CTR_2 0xf4aa
3443#define F367CAB_DEINT_M 0xf4aa00f8
3444#define F367CAB_DIS_UNLOCK 0xf4aa0004
3445#define F367CAB_DESCR_MODE 0xf4aa0003
3446
3447/* FEC_AC_CTR_3 */
3448#define R367CAB_FEC_AC_CTR_3 0xf4ab
3449#define F367CAB_DI_UNLOCK 0xf4ab0080
3450#define F367CAB_DI_FREEZE 0xf4ab0040
3451#define F367CAB_MISMATCH 0xf4ab0030
3452#define F367CAB_ACQ_MODE 0xf4ab000c
3453#define F367CAB_TRK_MODE 0xf4ab0003
3454
3455/* FEC_STATUS */
3456#define R367CAB_FEC_STATUS 0xf4ac
3457#define F367CAB_DEINT_SMCNTR 0xf4ac00e0
3458#define F367CAB_DEINT_SYNCSTATE 0xf4ac0018
3459#define F367CAB_DEINT_SYNLOST 0xf4ac0004
3460#define F367CAB_DESCR_SYNCSTATE 0xf4ac0002
3461
3462/* RS_COUNTER_0 */
3463#define R367CAB_RS_COUNTER_0 0xf4ae
3464#define F367CAB_BK_CT_L 0xf4ae00ff
3465
3466/* RS_COUNTER_1 */
3467#define R367CAB_RS_COUNTER_1 0xf4af
3468#define F367CAB_BK_CT_H 0xf4af00ff
3469
3470/* RS_COUNTER_2 */
3471#define R367CAB_RS_COUNTER_2 0xf4b0
3472#define F367CAB_CORR_CT_L 0xf4b000ff
3473
3474/* RS_COUNTER_3 */
3475#define R367CAB_RS_COUNTER_3 0xf4b1
3476#define F367CAB_CORR_CT_H 0xf4b100ff
3477
3478/* RS_COUNTER_4 */
3479#define R367CAB_RS_COUNTER_4 0xf4b2
3480#define F367CAB_UNCORR_CT_L 0xf4b200ff
3481
3482/* RS_COUNTER_5 */
3483#define R367CAB_RS_COUNTER_5 0xf4b3
3484#define F367CAB_UNCORR_CT_H 0xf4b300ff
3485
3486/* BERT_0 */
3487#define R367CAB_BERT_0 0xf4b4
3488#define F367CAB_RS_NOCORR 0xf4b40004
3489#define F367CAB_CT_HOLD 0xf4b40002
3490#define F367CAB_CT_CLEAR 0xf4b40001
3491
3492/* BERT_1 */
3493#define R367CAB_BERT_1 0xf4b5
3494#define F367CAB_BERT_ON 0xf4b50020
3495#define F367CAB_BERT_ERR_SRC 0xf4b50010
3496#define F367CAB_BERT_ERR_MODE 0xf4b50008
3497#define F367CAB_BERT_NBYTE 0xf4b50007
3498
3499/* BERT_2 */
3500#define R367CAB_BERT_2 0xf4b6
3501#define F367CAB_BERT_ERRCOUNT_L 0xf4b600ff
3502
3503/* BERT_3 */
3504#define R367CAB_BERT_3 0xf4b7
3505#define F367CAB_BERT_ERRCOUNT_H 0xf4b700ff
3506
3507/* OUTFORMAT_0 */
3508#define R367CAB_OUTFORMAT_0 0xf4b8
3509#define F367CAB_CLK_POLARITY 0xf4b80080
3510#define F367CAB_FEC_TYPE 0xf4b80040
3511#define F367CAB_SYNC_STRIP 0xf4b80008
3512#define F367CAB_TS_SWAP 0xf4b80004
3513#define F367CAB_OUTFORMAT 0xf4b80003
3514
3515/* OUTFORMAT_1 */
3516#define R367CAB_OUTFORMAT_1 0xf4b9
3517#define F367CAB_CI_DIVRANGE 0xf4b900ff
3518
3519/* SMOOTHER_2 */
3520#define R367CAB_SMOOTHER_2 0xf4be
3521#define F367CAB_FIFO_BYPASS 0xf4be0020
3522
3523/* TSMF_CTRL_0 */
3524#define R367CAB_TSMF_CTRL_0 0xf4c0
3525#define F367CAB_TS_NUMBER 0xf4c0001e
3526#define F367CAB_SEL_MODE 0xf4c00001
3527
3528/* TSMF_CTRL_1 */
3529#define R367CAB_TSMF_CTRL_1 0xf4c1
3530#define F367CAB_CHECK_ERROR_BIT 0xf4c10080
3531#define F367CAB_CHCK_F_SYNC 0xf4c10040
3532#define F367CAB_H_MODE 0xf4c10008
3533#define F367CAB_D_V_MODE 0xf4c10004
3534#define F367CAB_MODE 0xf4c10003
3535
3536/* TSMF_CTRL_3 */
3537#define R367CAB_TSMF_CTRL_3 0xf4c3
3538#define F367CAB_SYNC_IN_COUNT 0xf4c300f0
3539#define F367CAB_SYNC_OUT_COUNT 0xf4c3000f
3540
3541/* TS_ON_ID_0 */
3542#define R367CAB_TS_ON_ID_0 0xf4c4
3543#define F367CAB_TS_ID_L 0xf4c400ff
3544
3545/* TS_ON_ID_1 */
3546#define R367CAB_TS_ON_ID_1 0xf4c5
3547#define F367CAB_TS_ID_H 0xf4c500ff
3548
3549/* TS_ON_ID_2 */
3550#define R367CAB_TS_ON_ID_2 0xf4c6
3551#define F367CAB_ON_ID_L 0xf4c600ff
3552
3553/* TS_ON_ID_3 */
3554#define R367CAB_TS_ON_ID_3 0xf4c7
3555#define F367CAB_ON_ID_H 0xf4c700ff
3556
3557/* RE_STATUS_0 */
3558#define R367CAB_RE_STATUS_0 0xf4c8
3559#define F367CAB_RECEIVE_STATUS_L 0xf4c800ff
3560
3561/* RE_STATUS_1 */
3562#define R367CAB_RE_STATUS_1 0xf4c9
3563#define F367CAB_RECEIVE_STATUS_LH 0xf4c900ff
3564
3565/* RE_STATUS_2 */
3566#define R367CAB_RE_STATUS_2 0xf4ca
3567#define F367CAB_RECEIVE_STATUS_HL 0xf4ca00ff
3568
3569/* RE_STATUS_3 */
3570#define R367CAB_RE_STATUS_3 0xf4cb
3571#define F367CAB_RECEIVE_STATUS_HH 0xf4cb003f
3572
3573/* TS_STATUS_0 */
3574#define R367CAB_TS_STATUS_0 0xf4cc
3575#define F367CAB_TS_STATUS_L 0xf4cc00ff
3576
3577/* TS_STATUS_1 */
3578#define R367CAB_TS_STATUS_1 0xf4cd
3579#define F367CAB_TS_STATUS_H 0xf4cd007f
3580
3581/* TS_STATUS_2 */
3582#define R367CAB_TS_STATUS_2 0xf4ce
3583#define F367CAB_ERROR 0xf4ce0080
3584#define F367CAB_EMERGENCY 0xf4ce0040
3585#define F367CAB_CRE_TS 0xf4ce0030
3586#define F367CAB_VER 0xf4ce000e
3587#define F367CAB_M_LOCK 0xf4ce0001
3588
3589/* TS_STATUS_3 */
3590#define R367CAB_TS_STATUS_3 0xf4cf
3591#define F367CAB_UPDATE_READY 0xf4cf0080
3592#define F367CAB_END_FRAME_HEADER 0xf4cf0040
3593#define F367CAB_CONTCNT 0xf4cf0020
3594#define F367CAB_TS_IDENTIFIER_SEL 0xf4cf000f
3595
3596/* T_O_ID_0 */
3597#define R367CAB_T_O_ID_0 0xf4d0
3598#define F367CAB_ON_ID_I_L 0xf4d000ff
3599
3600/* T_O_ID_1 */
3601#define R367CAB_T_O_ID_1 0xf4d1
3602#define F367CAB_ON_ID_I_H 0xf4d100ff
3603
3604/* T_O_ID_2 */
3605#define R367CAB_T_O_ID_2 0xf4d2
3606#define F367CAB_TS_ID_I_L 0xf4d200ff
3607
3608/* T_O_ID_3 */
3609#define R367CAB_T_O_ID_3 0xf4d3
3610#define F367CAB_TS_ID_I_H 0xf4d300ff
3611
3612#define STV0367CAB_NBREGS 187
3613
3614#endif
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
index e3e35d1ce838..91c7ee8b2313 100644
--- a/drivers/media/dvb/frontends/stv0900.h
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -53,6 +53,8 @@ struct stv0900_config {
53 u8 tun2_type; 53 u8 tun2_type;
54 /* Set device param to start dma */ 54 /* Set device param to start dma */
55 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); 55 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
56 /* Hook for Lock LED */
57 void (*set_lock_led)(struct dvb_frontend *fe, int offon);
56}; 58};
57 59
58#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ 60#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 4f5e7d3a0e61..0ca316d6fffa 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -1604,6 +1604,9 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
1604 p_search.standard = STV0900_AUTO_SEARCH; 1604 p_search.standard = STV0900_AUTO_SEARCH;
1605 p_search.iq_inversion = STV0900_IQ_AUTO; 1605 p_search.iq_inversion = STV0900_IQ_AUTO;
1606 p_search.search_algo = STV0900_BLIND_SEARCH; 1606 p_search.search_algo = STV0900_BLIND_SEARCH;
1607 /* Speeds up DVB-S searching */
1608 if (c->delivery_system == SYS_DVBS)
1609 p_search.standard = STV0900_SEARCH_DVBS1;
1607 1610
1608 intp->srch_standard[demod] = p_search.standard; 1611 intp->srch_standard[demod] = p_search.standard;
1609 intp->symbol_rate[demod] = p_search.symbol_rate; 1612 intp->symbol_rate[demod] = p_search.symbol_rate;
@@ -1660,8 +1663,14 @@ static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
1660 | FE_HAS_VITERBI 1663 | FE_HAS_VITERBI
1661 | FE_HAS_SYNC 1664 | FE_HAS_SYNC
1662 | FE_HAS_LOCK; 1665 | FE_HAS_LOCK;
1663 } else 1666 if (state->config->set_lock_led)
1667 state->config->set_lock_led(fe, 1);
1668 } else {
1669 *status = 0;
1670 if (state->config->set_lock_led)
1671 state->config->set_lock_led(fe, 0);
1664 dprintk("DEMOD LOCK FAIL\n"); 1672 dprintk("DEMOD LOCK FAIL\n");
1673 }
1665 1674
1666 return 0; 1675 return 0;
1667} 1676}
@@ -1831,6 +1840,9 @@ static void stv0900_release(struct dvb_frontend *fe)
1831 1840
1832 dprintk("%s\n", __func__); 1841 dprintk("%s\n", __func__);
1833 1842
1843 if (state->config->set_lock_led)
1844 state->config->set_lock_led(fe, 0);
1845
1834 if ((--(state->internal->dmds_used)) <= 0) { 1846 if ((--(state->internal->dmds_used)) <= 0) {
1835 1847
1836 dprintk("%s: Actually removing\n", __func__); 1848 dprintk("%s: Actually removing\n", __func__);
@@ -1842,6 +1854,18 @@ static void stv0900_release(struct dvb_frontend *fe)
1842 kfree(state); 1854 kfree(state);
1843} 1855}
1844 1856
1857static int stv0900_sleep(struct dvb_frontend *fe)
1858{
1859 struct stv0900_state *state = fe->demodulator_priv;
1860
1861 dprintk("%s\n", __func__);
1862
1863 if (state->config->set_lock_led)
1864 state->config->set_lock_led(fe, 0);
1865
1866 return 0;
1867}
1868
1845static int stv0900_get_frontend(struct dvb_frontend *fe, 1869static int stv0900_get_frontend(struct dvb_frontend *fe,
1846 struct dvb_frontend_parameters *p) 1870 struct dvb_frontend_parameters *p)
1847{ 1871{
@@ -1876,6 +1900,7 @@ static struct dvb_frontend_ops stv0900_ops = {
1876 .release = stv0900_release, 1900 .release = stv0900_release,
1877 .init = stv0900_init, 1901 .init = stv0900_init,
1878 .get_frontend = stv0900_get_frontend, 1902 .get_frontend = stv0900_get_frontend,
1903 .sleep = stv0900_sleep,
1879 .get_frontend_algo = stv0900_frontend_algo, 1904 .get_frontend_algo = stv0900_frontend_algo,
1880 .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, 1905 .i2c_gate_ctrl = stv0900_i2c_gate_ctrl,
1881 .diseqc_send_master_cmd = stv0900_send_master_cmd, 1906 .diseqc_send_master_cmd = stv0900_send_master_cmd,
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 4e0fc2c8a41c..41d0f0a6655d 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -767,8 +767,12 @@ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
767 * In case of any error, the lock is unlocked and exit within the 767 * In case of any error, the lock is unlocked and exit within the
768 * relevant operations themselves. 768 * relevant operations themselves.
769 */ 769 */
770 if (enable) 770 if (enable) {
771 mutex_lock(&state->internal->tuner_lock); 771 if (state->config->tuner_i2c_lock)
772 state->config->tuner_i2c_lock(&state->frontend, 1);
773 else
774 mutex_lock(&state->internal->tuner_lock);
775 }
772 776
773 reg = STV090x_READ_DEMOD(state, I2CRPT); 777 reg = STV090x_READ_DEMOD(state, I2CRPT);
774 if (enable) { 778 if (enable) {
@@ -784,13 +788,20 @@ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
784 goto err; 788 goto err;
785 } 789 }
786 790
787 if (!enable) 791 if (!enable) {
788 mutex_unlock(&state->internal->tuner_lock); 792 if (state->config->tuner_i2c_lock)
793 state->config->tuner_i2c_lock(&state->frontend, 0);
794 else
795 mutex_unlock(&state->internal->tuner_lock);
796 }
789 797
790 return 0; 798 return 0;
791err: 799err:
792 dprintk(FE_ERROR, 1, "I/O error"); 800 dprintk(FE_ERROR, 1, "I/O error");
793 mutex_unlock(&state->internal->tuner_lock); 801 if (state->config->tuner_i2c_lock)
802 state->config->tuner_i2c_lock(&state->frontend, 0);
803 else
804 mutex_unlock(&state->internal->tuner_lock);
794 return -1; 805 return -1;
795} 806}
796 807
@@ -2883,10 +2894,12 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2883 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); 2894 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2884 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 2895 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2885 goto err; 2896 goto err;
2886 if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0) 2897 if (state->internal->dev_ver >= 0x30) {
2887 goto err; 2898 if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)
2888 if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0) 2899 goto err;
2889 goto err; 2900 if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)
2901 goto err;
2902 }
2890 if (state->frame_len == STV090x_LONG_FRAME) { 2903 if (state->frame_len == STV090x_LONG_FRAME) {
2891 reg = STV090x_READ_DEMOD(state, DMDMODCOD); 2904 reg = STV090x_READ_DEMOD(state, DMDMODCOD);
2892 modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); 2905 modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
@@ -3846,6 +3859,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3846{ 3859{
3847 struct stv090x_state *state = fe->demodulator_priv; 3860 struct stv090x_state *state = fe->demodulator_priv;
3848 u32 reg; 3861 u32 reg;
3862 u8 full_standby = 0;
3849 3863
3850 if (stv090x_i2c_gate_ctrl(state, 1) < 0) 3864 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3851 goto err; 3865 goto err;
@@ -3858,24 +3872,119 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3858 if (stv090x_i2c_gate_ctrl(state, 0) < 0) 3872 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3859 goto err; 3873 goto err;
3860 3874
3861 dprintk(FE_DEBUG, 1, "Set %s to sleep", 3875 dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep",
3862 state->device == STV0900 ? "STV0900" : "STV0903"); 3876 state->device == STV0900 ? "STV0900" : "STV0903",
3877 state->demod);
3863 3878
3864 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3879 mutex_lock(&state->internal->demod_lock);
3865 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3866 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3867 goto err;
3868 3880
3869 reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3881 switch (state->demod) {
3870 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); 3882 case STV090x_DEMODULATOR_0:
3871 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3883 /* power off ADC 1 */
3872 goto err; 3884 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3885 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
3886 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
3887 goto err;
3888 /* power off DiSEqC 1 */
3889 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
3890 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
3891 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
3892 goto err;
3893
3894 /* check whether path 2 is already sleeping, that is when
3895 ADC2 is off */
3896 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3897 if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0)
3898 full_standby = 1;
3899
3900 /* stop clocks */
3901 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3902 /* packet delineator 1 clock */
3903 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1);
3904 /* ADC 1 clock */
3905 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1);
3906 /* FEC clock is shared between the two paths, only stop it
3907 when full standby is possible */
3908 if (full_standby)
3909 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3910 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3911 goto err;
3912 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3913 /* sampling 1 clock */
3914 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
3915 /* viterbi 1 clock */
3916 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1);
3917 /* TS clock is shared between the two paths, only stop it
3918 when full standby is possible */
3919 if (full_standby)
3920 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3921 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3922 goto err;
3923 break;
3924
3925 case STV090x_DEMODULATOR_1:
3926 /* power off ADC 2 */
3927 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3928 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
3929 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
3930 goto err;
3931 /* power off DiSEqC 2 */
3932 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
3933 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
3934 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
3935 goto err;
3936
3937 /* check whether path 1 is already sleeping, that is when
3938 ADC1 is off */
3939 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3940 if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0)
3941 full_standby = 1;
3942
3943 /* stop clocks */
3944 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3945 /* packet delineator 2 clock */
3946 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1);
3947 /* ADC 2 clock */
3948 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1);
3949 /* FEC clock is shared between the two paths, only stop it
3950 when full standby is possible */
3951 if (full_standby)
3952 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3953 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3954 goto err;
3955 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3956 /* sampling 2 clock */
3957 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
3958 /* viterbi 2 clock */
3959 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1);
3960 /* TS clock is shared between the two paths, only stop it
3961 when full standby is possible */
3962 if (full_standby)
3963 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3964 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3965 goto err;
3966 break;
3873 3967
3968 default:
3969 dprintk(FE_ERROR, 1, "Wrong demodulator!");
3970 break;
3971 }
3972
3973 if (full_standby) {
3974 /* general power off */
3975 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3976 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3977 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3978 goto err;
3979 }
3980
3981 mutex_unlock(&state->internal->demod_lock);
3874 return 0; 3982 return 0;
3875 3983
3876err_gateoff: 3984err_gateoff:
3877 stv090x_i2c_gate_ctrl(state, 0); 3985 stv090x_i2c_gate_ctrl(state, 0);
3878err: 3986err:
3987 mutex_unlock(&state->internal->demod_lock);
3879 dprintk(FE_ERROR, 1, "I/O error"); 3988 dprintk(FE_ERROR, 1, "I/O error");
3880 return -1; 3989 return -1;
3881} 3990}
@@ -3885,21 +3994,94 @@ static int stv090x_wakeup(struct dvb_frontend *fe)
3885 struct stv090x_state *state = fe->demodulator_priv; 3994 struct stv090x_state *state = fe->demodulator_priv;
3886 u32 reg; 3995 u32 reg;
3887 3996
3888 dprintk(FE_DEBUG, 1, "Wake %s from standby", 3997 dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby",
3889 state->device == STV0900 ? "STV0900" : "STV0903"); 3998 state->device == STV0900 ? "STV0900" : "STV0903",
3999 state->demod);
4000
4001 mutex_lock(&state->internal->demod_lock);
3890 4002
4003 /* general power on */
3891 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 4004 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3892 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00); 4005 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
3893 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 4006 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3894 goto err; 4007 goto err;
3895 4008
3896 reg = stv090x_read_reg(state, STV090x_TSTTNR1); 4009 switch (state->demod) {
3897 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); 4010 case STV090x_DEMODULATOR_0:
3898 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 4011 /* power on ADC 1 */
3899 goto err; 4012 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
4013 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
4014 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
4015 goto err;
4016 /* power on DiSEqC 1 */
4017 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
4018 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1);
4019 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
4020 goto err;
4021
4022 /* activate clocks */
4023 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4024 /* packet delineator 1 clock */
4025 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0);
4026 /* ADC 1 clock */
4027 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0);
4028 /* FEC clock */
4029 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4030 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4031 goto err;
4032 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4033 /* sampling 1 clock */
4034 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0);
4035 /* viterbi 1 clock */
4036 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0);
4037 /* TS clock */
4038 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4039 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4040 goto err;
4041 break;
3900 4042
4043 case STV090x_DEMODULATOR_1:
4044 /* power on ADC 2 */
4045 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
4046 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1);
4047 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
4048 goto err;
4049 /* power on DiSEqC 2 */
4050 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
4051 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1);
4052 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
4053 goto err;
4054
4055 /* activate clocks */
4056 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4057 /* packet delineator 2 clock */
4058 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0);
4059 /* ADC 2 clock */
4060 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0);
4061 /* FEC clock */
4062 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4063 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4064 goto err;
4065 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4066 /* sampling 2 clock */
4067 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0);
4068 /* viterbi 2 clock */
4069 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0);
4070 /* TS clock */
4071 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4072 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4073 goto err;
4074 break;
4075
4076 default:
4077 dprintk(FE_ERROR, 1, "Wrong demodulator!");
4078 break;
4079 }
4080
4081 mutex_unlock(&state->internal->demod_lock);
3901 return 0; 4082 return 0;
3902err: 4083err:
4084 mutex_unlock(&state->internal->demod_lock);
3903 dprintk(FE_ERROR, 1, "I/O error"); 4085 dprintk(FE_ERROR, 1, "I/O error");
3904 return -1; 4086 return -1;
3905} 4087}
@@ -4169,6 +4351,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4169 switch (state->config->ts1_mode) { 4351 switch (state->config->ts1_mode) {
4170 case STV090x_TSMODE_PARALLEL_PUNCTURED: 4352 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4171 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4353 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4354 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4172 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4355 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4173 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4356 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4174 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4357 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4177,6 +4360,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4177 4360
4178 case STV090x_TSMODE_DVBCI: 4361 case STV090x_TSMODE_DVBCI:
4179 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4362 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4363 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4180 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4364 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4181 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4365 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4182 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4366 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4185,6 +4369,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4185 4369
4186 case STV090x_TSMODE_SERIAL_PUNCTURED: 4370 case STV090x_TSMODE_SERIAL_PUNCTURED:
4187 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4371 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4372 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4188 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4373 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4189 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4374 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4190 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4375 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4193,6 +4378,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4193 4378
4194 case STV090x_TSMODE_SERIAL_CONTINUOUS: 4379 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4195 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4380 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4381 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4196 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4382 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4197 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4383 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4198 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4384 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4206,6 +4392,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4206 switch (state->config->ts2_mode) { 4392 switch (state->config->ts2_mode) {
4207 case STV090x_TSMODE_PARALLEL_PUNCTURED: 4393 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4208 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4394 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4395 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4209 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4396 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4210 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4397 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4211 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4398 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4214,6 +4401,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4214 4401
4215 case STV090x_TSMODE_DVBCI: 4402 case STV090x_TSMODE_DVBCI:
4216 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4403 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4404 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4217 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4405 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4218 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4406 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4219 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4407 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4222,6 +4410,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4222 4410
4223 case STV090x_TSMODE_SERIAL_PUNCTURED: 4411 case STV090x_TSMODE_SERIAL_PUNCTURED:
4224 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4412 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4413 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4225 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4414 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4226 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4415 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4227 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4416 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4230,6 +4419,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4230 4419
4231 case STV090x_TSMODE_SERIAL_CONTINUOUS: 4420 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4232 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4421 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4422 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4233 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4423 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4234 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4424 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4235 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4425 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4506,16 +4696,26 @@ static int stv090x_setup(struct dvb_frontend *fe)
4506 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) 4696 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
4507 goto err; 4697 goto err;
4508 4698
4509 /* workaround for stuck DiSEqC output */
4510 if (config->diseqc_envelope_mode)
4511 stv090x_send_diseqc_burst(fe, SEC_MINI_A);
4512
4513 return 0; 4699 return 0;
4514err: 4700err:
4515 dprintk(FE_ERROR, 1, "I/O error"); 4701 dprintk(FE_ERROR, 1, "I/O error");
4516 return -1; 4702 return -1;
4517} 4703}
4518 4704
4705int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
4706 u8 xor_value)
4707{
4708 struct stv090x_state *state = fe->demodulator_priv;
4709 u8 reg = 0;
4710
4711 STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir);
4712 STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value);
4713 STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value);
4714
4715 return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
4716}
4717EXPORT_SYMBOL(stv090x_set_gpio);
4718
4519static struct dvb_frontend_ops stv090x_ops = { 4719static struct dvb_frontend_ops stv090x_ops = {
4520 4720
4521 .info = { 4721 .info = {
@@ -4580,39 +4780,35 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4580 state->internal = temp_int->internal; 4780 state->internal = temp_int->internal;
4581 state->internal->num_used++; 4781 state->internal->num_used++;
4582 dprintk(FE_INFO, 1, "Found Internal Structure!"); 4782 dprintk(FE_INFO, 1, "Found Internal Structure!");
4583 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4584 state->device == STV0900 ? "STV0900" : "STV0903",
4585 demod,
4586 state->internal->dev_ver);
4587 return &state->frontend;
4588 } else { 4783 } else {
4589 state->internal = kmalloc(sizeof(struct stv090x_internal), 4784 state->internal = kmalloc(sizeof(struct stv090x_internal),
4590 GFP_KERNEL); 4785 GFP_KERNEL);
4786 if (!state->internal)
4787 goto error;
4591 temp_int = append_internal(state->internal); 4788 temp_int = append_internal(state->internal);
4789 if (!temp_int) {
4790 kfree(state->internal);
4791 goto error;
4792 }
4592 state->internal->num_used = 1; 4793 state->internal->num_used = 1;
4593 state->internal->mclk = 0; 4794 state->internal->mclk = 0;
4594 state->internal->dev_ver = 0; 4795 state->internal->dev_ver = 0;
4595 state->internal->i2c_adap = state->i2c; 4796 state->internal->i2c_adap = state->i2c;
4596 state->internal->i2c_addr = state->config->address; 4797 state->internal->i2c_addr = state->config->address;
4597 dprintk(FE_INFO, 1, "Create New Internal Structure!"); 4798 dprintk(FE_INFO, 1, "Create New Internal Structure!");
4598 }
4599 4799
4600 mutex_init(&state->internal->demod_lock); 4800 mutex_init(&state->internal->demod_lock);
4601 mutex_init(&state->internal->tuner_lock); 4801 mutex_init(&state->internal->tuner_lock);
4602 4802
4603 if (stv090x_sleep(&state->frontend) < 0) { 4803 if (stv090x_setup(&state->frontend) < 0) {
4604 dprintk(FE_ERROR, 1, "Error putting device to sleep"); 4804 dprintk(FE_ERROR, 1, "Error setting up device");
4605 goto error; 4805 goto err_remove;
4806 }
4606 } 4807 }
4607 4808
4608 if (stv090x_setup(&state->frontend) < 0) { 4809 /* workaround for stuck DiSEqC output */
4609 dprintk(FE_ERROR, 1, "Error setting up device"); 4810 if (config->diseqc_envelope_mode)
4610 goto error; 4811 stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
4611 }
4612 if (stv090x_wakeup(&state->frontend) < 0) {
4613 dprintk(FE_ERROR, 1, "Error waking device");
4614 goto error;
4615 }
4616 4812
4617 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", 4813 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4618 state->device == STV0900 ? "STV0900" : "STV0903", 4814 state->device == STV0900 ? "STV0900" : "STV0903",
@@ -4621,6 +4817,9 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4621 4817
4622 return &state->frontend; 4818 return &state->frontend;
4623 4819
4820err_remove:
4821 remove_dev(state->internal);
4822 kfree(state->internal);
4624error: 4823error:
4625 kfree(state); 4824 kfree(state);
4626 return NULL; 4825 return NULL;
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
index dd1b93ae4e9d..29cdc2b71314 100644
--- a/drivers/media/dvb/frontends/stv090x.h
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -78,6 +78,9 @@ struct stv090x_config {
78 u32 ts1_clk; 78 u32 ts1_clk;
79 u32 ts2_clk; 79 u32 ts2_clk;
80 80
81 u8 ts1_tei : 1;
82 u8 ts2_tei : 1;
83
81 enum stv090x_i2crpt repeater_level; 84 enum stv090x_i2crpt repeater_level;
82 85
83 u8 tuner_bbgain; /* default: 10db */ 86 u8 tuner_bbgain; /* default: 10db */
@@ -97,6 +100,7 @@ struct stv090x_config {
97 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); 100 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
98 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); 101 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
99 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); 102 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
103 void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
100}; 104};
101 105
102#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE)) 106#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
@@ -104,6 +108,11 @@ struct stv090x_config {
104extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, 108extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
105 struct i2c_adapter *i2c, 109 struct i2c_adapter *i2c,
106 enum stv090x_demodulator demod); 110 enum stv090x_demodulator demod);
111
112/* dir = 0 -> output, dir = 1 -> input/open-drain */
113extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
114 u8 dir, u8 value, u8 xor_value);
115
107#else 116#else
108 117
109static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, 118static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
@@ -113,6 +122,13 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c
113 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 122 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
114 return NULL; 123 return NULL;
115} 124}
125
126static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
127 u8 opd, u8 value, u8 xor_value)
128{
129 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
130 return -ENODEV;
131}
116#endif /* CONFIG_DVB_STV090x */ 132#endif /* CONFIG_DVB_STV090x */
117 133
118#endif /* __STV090x_H */ 134#endif /* __STV090x_H */
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
index 2502855dd784..93741ee14297 100644
--- a/drivers/media/dvb/frontends/stv090x_reg.h
+++ b/drivers/media/dvb/frontends/stv090x_reg.h
@@ -1327,10 +1327,10 @@
1327#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8 1327#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8
1328 1328
1329#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1) 1329#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1)
1330#define STv090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0) 1330#define STV090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0)
1331#define STv090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1) 1331#define STV090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1)
1332#define STv090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0) 1332#define STV090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0)
1333#define STv090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1) 1333#define STV090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1)
1334#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0 1334#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0
1335#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8 1335#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8
1336 1336
@@ -1406,7 +1406,7 @@
1406 1406
1407#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200) 1407#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200)
1408#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1) 1408#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1)
1409#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(1) 1409#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(2)
1410#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4 1410#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4
1411#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2 1411#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2
1412#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0 1412#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
@@ -1414,7 +1414,7 @@
1414 1414
1415#define STV090x_Px_BCLC2S216A(__x) (0xf49e - (__x - 1) * 0x200) 1415#define STV090x_Px_BCLC2S216A(__x) (0xf49e - (__x - 1) * 0x200)
1416#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1) 1416#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1)
1417#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1) 1417#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(2)
1418#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4 1418#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4
1419#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2 1419#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2
1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0 1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0
@@ -1422,7 +1422,7 @@
1422 1422
1423#define STV090x_Px_BCLC2S232A(__x) (0xf49f - (__x - 1) * 0x200) 1423#define STV090x_Px_BCLC2S232A(__x) (0xf49f - (__x - 1) * 0x200)
1424#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1) 1424#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1)
1425#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1) 1425#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(2)
1426#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4 1426#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4
1427#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2 1427#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2
1428#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0 1428#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0
@@ -1602,7 +1602,7 @@
1602 1602
1603#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200) 1603#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200)
1604#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1) 1604#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1)
1605#define STV090x_P2_CCIACC STV090x_Px_CCIACC(1) 1605#define STV090x_P2_CCIACC STV090x_Px_CCIACC(2)
1606#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0 1606#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0
1607#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8 1607#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8
1608 1608
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
index 4627f491656b..81aa984c551f 100644
--- a/drivers/media/dvb/frontends/zl10036.c
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -463,16 +463,16 @@ struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
463 const struct zl10036_config *config, 463 const struct zl10036_config *config,
464 struct i2c_adapter *i2c) 464 struct i2c_adapter *i2c)
465{ 465{
466 struct zl10036_state *state = NULL; 466 struct zl10036_state *state;
467 int ret; 467 int ret;
468 468
469 if (NULL == config) { 469 if (!config) {
470 printk(KERN_ERR "%s: no config specified", __func__); 470 printk(KERN_ERR "%s: no config specified", __func__);
471 goto error; 471 return NULL;
472 } 472 }
473 473
474 state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL); 474 state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
475 if (NULL == state) 475 if (!state)
476 return NULL; 476 return NULL;
477 477
478 state->config = config; 478 state->config = config;
@@ -507,7 +507,7 @@ struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
507 return fe; 507 return fe;
508 508
509error: 509error:
510 zl10036_release(fe); 510 kfree(state);
511 return NULL; 511 return NULL;
512} 512}
513EXPORT_SYMBOL(zl10036_attach); 513EXPORT_SYMBOL(zl10036_attach);
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile
index 0608aabb14ee..2bc96874d044 100644
--- a/drivers/media/dvb/ngene/Makefile
+++ b/drivers/media/dvb/ngene/Makefile
@@ -9,3 +9,6 @@ obj-$(CONFIG_DVB_NGENE) += ngene.o
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ 9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ 10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/
11EXTRA_CFLAGS += -Idrivers/media/common/tuners/ 11EXTRA_CFLAGS += -Idrivers/media/common/tuners/
12
13# For the staging CI driver cxd2099
14EXTRA_CFLAGS += -Idrivers/staging/cxd2099/
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 4692a41ad95b..fcf4be901ec8 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -48,20 +48,27 @@
48 48
49static int tuner_attach_stv6110(struct ngene_channel *chan) 49static int tuner_attach_stv6110(struct ngene_channel *chan)
50{ 50{
51 struct i2c_adapter *i2c;
51 struct stv090x_config *feconf = (struct stv090x_config *) 52 struct stv090x_config *feconf = (struct stv090x_config *)
52 chan->dev->card_info->fe_config[chan->number]; 53 chan->dev->card_info->fe_config[chan->number];
53 struct stv6110x_config *tunerconf = (struct stv6110x_config *) 54 struct stv6110x_config *tunerconf = (struct stv6110x_config *)
54 chan->dev->card_info->tuner_config[chan->number]; 55 chan->dev->card_info->tuner_config[chan->number];
55 struct stv6110x_devctl *ctl; 56 struct stv6110x_devctl *ctl;
56 57
57 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, 58 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
58 &chan->i2c_adapter); 59 if (chan->number < 2)
60 i2c = &chan->dev->channel[0].i2c_adapter;
61 else
62 i2c = &chan->dev->channel[1].i2c_adapter;
63
64 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c);
59 if (ctl == NULL) { 65 if (ctl == NULL) {
60 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n"); 66 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
61 return -ENODEV; 67 return -ENODEV;
62 } 68 }
63 69
64 feconf->tuner_init = ctl->tuner_init; 70 feconf->tuner_init = ctl->tuner_init;
71 feconf->tuner_sleep = ctl->tuner_sleep;
65 feconf->tuner_set_mode = ctl->tuner_set_mode; 72 feconf->tuner_set_mode = ctl->tuner_set_mode;
66 feconf->tuner_set_frequency = ctl->tuner_set_frequency; 73 feconf->tuner_set_frequency = ctl->tuner_set_frequency;
67 feconf->tuner_get_frequency = ctl->tuner_get_frequency; 74 feconf->tuner_get_frequency = ctl->tuner_get_frequency;
@@ -78,29 +85,106 @@ static int tuner_attach_stv6110(struct ngene_channel *chan)
78 85
79static int demod_attach_stv0900(struct ngene_channel *chan) 86static int demod_attach_stv0900(struct ngene_channel *chan)
80{ 87{
88 struct i2c_adapter *i2c;
81 struct stv090x_config *feconf = (struct stv090x_config *) 89 struct stv090x_config *feconf = (struct stv090x_config *)
82 chan->dev->card_info->fe_config[chan->number]; 90 chan->dev->card_info->fe_config[chan->number];
83 91
84 chan->fe = dvb_attach(stv090x_attach, 92 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
85 feconf, 93 /* Note: Both adapters share the same i2c bus, but the demod */
86 &chan->i2c_adapter, 94 /* driver requires that each demod has its own i2c adapter */
87 chan->number == 0 ? STV090x_DEMODULATOR_0 : 95 if (chan->number < 2)
88 STV090x_DEMODULATOR_1); 96 i2c = &chan->dev->channel[0].i2c_adapter;
97 else
98 i2c = &chan->dev->channel[1].i2c_adapter;
99
100 chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
101 (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
102 : STV090x_DEMODULATOR_1);
89 if (chan->fe == NULL) { 103 if (chan->fe == NULL) {
90 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n"); 104 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
91 return -ENODEV; 105 return -ENODEV;
92 } 106 }
93 107
94 if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0, 108 /* store channel info */
109 if (feconf->tuner_i2c_lock)
110 chan->fe->analog_demod_priv = chan;
111
112 if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
95 0, chan->dev->card_info->lnb[chan->number])) { 113 0, chan->dev->card_info->lnb[chan->number])) {
96 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n"); 114 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
97 dvb_frontend_detach(chan->fe); 115 dvb_frontend_detach(chan->fe);
116 chan->fe = NULL;
117 return -ENODEV;
118 }
119
120 return 0;
121}
122
123static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock)
124{
125 struct ngene_channel *chan = fe->analog_demod_priv;
126
127 if (lock)
128 down(&chan->dev->pll_mutex);
129 else
130 up(&chan->dev->pll_mutex);
131}
132
133static int cineS2_probe(struct ngene_channel *chan)
134{
135 struct i2c_adapter *i2c;
136 struct stv090x_config *fe_conf;
137 u8 buf[3];
138 struct i2c_msg i2c_msg = { .flags = 0, .buf = buf };
139 int rc;
140
141 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
142 if (chan->number < 2)
143 i2c = &chan->dev->channel[0].i2c_adapter;
144 else
145 i2c = &chan->dev->channel[1].i2c_adapter;
146
147 fe_conf = chan->dev->card_info->fe_config[chan->number];
148 i2c_msg.addr = fe_conf->address;
149
150 /* probe demod */
151 i2c_msg.len = 2;
152 buf[0] = 0xf1;
153 buf[1] = 0x00;
154 rc = i2c_transfer(i2c, &i2c_msg, 1);
155 if (rc != 1)
156 return -ENODEV;
157
158 /* demod found, attach it */
159 rc = demod_attach_stv0900(chan);
160 if (rc < 0 || chan->number < 2)
161 return rc;
162
163 /* demod #2: reprogram outputs DPN1 & DPN2 */
164 i2c_msg.len = 3;
165 buf[0] = 0xf1;
166 switch (chan->number) {
167 case 2:
168 buf[1] = 0x5c;
169 buf[2] = 0xc2;
170 break;
171 case 3:
172 buf[1] = 0x61;
173 buf[2] = 0xcc;
174 break;
175 default:
98 return -ENODEV; 176 return -ENODEV;
99 } 177 }
178 rc = i2c_transfer(i2c, &i2c_msg, 1);
179 if (rc != 1) {
180 printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n");
181 return -EIO;
182 }
100 183
101 return 0; 184 return 0;
102} 185}
103 186
187
104static struct lgdt330x_config aver_m780 = { 188static struct lgdt330x_config aver_m780 = {
105 .demod_address = 0xb2 >> 1, 189 .demod_address = 0xb2 >> 1,
106 .demod_chip = LGDT3303, 190 .demod_chip = LGDT3303,
@@ -151,6 +235,29 @@ static struct stv090x_config fe_cineS2 = {
151 .adc2_range = STV090x_ADC_1Vpp, 235 .adc2_range = STV090x_ADC_1Vpp,
152 236
153 .diseqc_envelope_mode = true, 237 .diseqc_envelope_mode = true,
238
239 .tuner_i2c_lock = cineS2_tuner_i2c_lock,
240};
241
242static struct stv090x_config fe_cineS2_2 = {
243 .device = STV0900,
244 .demod_mode = STV090x_DUAL,
245 .clk_mode = STV090x_CLK_EXT,
246
247 .xtal = 27000000,
248 .address = 0x69,
249
250 .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
251 .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
252
253 .repeater_level = STV090x_RPTLEVEL_16,
254
255 .adc1_range = STV090x_ADC_1Vpp,
256 .adc2_range = STV090x_ADC_1Vpp,
257
258 .diseqc_envelope_mode = true,
259
260 .tuner_i2c_lock = cineS2_tuner_i2c_lock,
154}; 261};
155 262
156static struct stv6110x_config tuner_cineS2_0 = { 263static struct stv6110x_config tuner_cineS2_0 = {
@@ -175,7 +282,8 @@ static struct ngene_info ngene_info_cineS2 = {
175 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 282 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
176 .lnb = {0x0b, 0x08}, 283 .lnb = {0x0b, 0x08},
177 .tsf = {3, 3}, 284 .tsf = {3, 3},
178 .fw_version = 15, 285 .fw_version = 18,
286 .msi_supported = true,
179}; 287};
180 288
181static struct ngene_info ngene_info_satixS2 = { 289static struct ngene_info ngene_info_satixS2 = {
@@ -188,46 +296,54 @@ static struct ngene_info ngene_info_satixS2 = {
188 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 296 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
189 .lnb = {0x0b, 0x08}, 297 .lnb = {0x0b, 0x08},
190 .tsf = {3, 3}, 298 .tsf = {3, 3},
191 .fw_version = 15, 299 .fw_version = 18,
300 .msi_supported = true,
192}; 301};
193 302
194static struct ngene_info ngene_info_satixS2v2 = { 303static struct ngene_info ngene_info_satixS2v2 = {
195 .type = NGENE_SIDEWINDER, 304 .type = NGENE_SIDEWINDER,
196 .name = "Mystique SaTiX-S2 Dual (v2)", 305 .name = "Mystique SaTiX-S2 Dual (v2)",
197 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 306 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
198 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 307 NGENE_IO_TSOUT},
199 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 308 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
200 .fe_config = {&fe_cineS2, &fe_cineS2}, 309 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
201 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 310 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
202 .lnb = {0x0a, 0x08}, 311 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
312 .lnb = {0x0a, 0x08, 0x0b, 0x09},
203 .tsf = {3, 3}, 313 .tsf = {3, 3},
204 .fw_version = 15, 314 .fw_version = 18,
315 .msi_supported = true,
205}; 316};
206 317
207static struct ngene_info ngene_info_cineS2v5 = { 318static struct ngene_info ngene_info_cineS2v5 = {
208 .type = NGENE_SIDEWINDER, 319 .type = NGENE_SIDEWINDER,
209 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)", 320 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
210 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 321 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
211 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 322 NGENE_IO_TSOUT},
212 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 323 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
213 .fe_config = {&fe_cineS2, &fe_cineS2}, 324 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
214 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 325 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
215 .lnb = {0x0a, 0x08}, 326 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
327 .lnb = {0x0a, 0x08, 0x0b, 0x09},
216 .tsf = {3, 3}, 328 .tsf = {3, 3},
217 .fw_version = 15, 329 .fw_version = 18,
330 .msi_supported = true,
218}; 331};
219 332
333
220static struct ngene_info ngene_info_duoFlexS2 = { 334static struct ngene_info ngene_info_duoFlexS2 = {
221 .type = NGENE_SIDEWINDER, 335 .type = NGENE_SIDEWINDER,
222 .name = "Digital Devices DuoFlex S2 miniPCIe", 336 .name = "Digital Devices DuoFlex S2 miniPCIe",
223 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 337 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
224 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 338 NGENE_IO_TSOUT},
225 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 339 .demod_attach = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe},
226 .fe_config = {&fe_cineS2, &fe_cineS2}, 340 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
227 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 341 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
228 .lnb = {0x0a, 0x08}, 342 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
343 .lnb = {0x0a, 0x08, 0x0b, 0x09},
229 .tsf = {3, 3}, 344 .tsf = {3, 3},
230 .fw_version = 15, 345 .fw_version = 18,
346 .msi_supported = true,
231}; 347};
232 348
233static struct ngene_info ngene_info_m780 = { 349static struct ngene_info ngene_info_m780 = {
@@ -321,6 +437,7 @@ static struct pci_driver ngene_pci_driver = {
321 .probe = ngene_probe, 437 .probe = ngene_probe,
322 .remove = __devexit_p(ngene_remove), 438 .remove = __devexit_p(ngene_remove),
323 .err_handler = &ngene_errors, 439 .err_handler = &ngene_errors,
440 .shutdown = ngene_shutdown,
324}; 441};
325 442
326static __init int module_init_ngene(void) 443static __init int module_init_ngene(void)
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index dc073bdc623a..175a0f6c2a4c 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -45,6 +45,9 @@ static int one_adapter = 1;
45module_param(one_adapter, int, 0444); 45module_param(one_adapter, int, 0444);
46MODULE_PARM_DESC(one_adapter, "Use only one adapter."); 46MODULE_PARM_DESC(one_adapter, "Use only one adapter.");
47 47
48static int shutdown_workaround;
49module_param(shutdown_workaround, int, 0644);
50MODULE_PARM_DESC(shutdown_workaround, "Activate workaround for shutdown problem with some chipsets.");
48 51
49static int debug; 52static int debug;
50module_param(debug, int, 0444); 53module_param(debug, int, 0444);
@@ -143,7 +146,7 @@ static void demux_tasklet(unsigned long data)
143 } 146 }
144 } else { 147 } else {
145 if (chan->HWState == HWSTATE_RUN) { 148 if (chan->HWState == HWSTATE_RUN) {
146 u32 Flags = 0; 149 u32 Flags = chan->DataFormatFlags;
147 IBufferExchange *exch1 = chan->pBufferExchange; 150 IBufferExchange *exch1 = chan->pBufferExchange;
148 IBufferExchange *exch2 = chan->pBufferExchange2; 151 IBufferExchange *exch2 = chan->pBufferExchange2;
149 if (Cur->ngeneBuffer.SR.Flags & 0x01) 152 if (Cur->ngeneBuffer.SR.Flags & 0x01)
@@ -474,9 +477,9 @@ static u8 SPDIFConfiguration[10] = {
474 477
475/* Set NGENE I2S Config to transport stream compatible mode */ 478/* Set NGENE I2S Config to transport stream compatible mode */
476 479
477static u8 TS_I2SConfiguration[4] = { 0x3E, 0x1A, 0x00, 0x00 }; /*3e 18 00 00 ?*/ 480static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 };
478 481
479static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x20, 0x00, 0x00 }; 482static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x04, 0x00, 0x00 };
480 483
481static u8 ITUDecoderSetup[4][16] = { 484static u8 ITUDecoderSetup[4][16] = {
482 {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ 485 {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */
@@ -749,13 +752,11 @@ void set_transfer(struct ngene_channel *chan, int state)
749 if (chan->mode & NGENE_IO_TSOUT) { 752 if (chan->mode & NGENE_IO_TSOUT) {
750 chan->pBufferExchange = tsout_exchange; 753 chan->pBufferExchange = tsout_exchange;
751 /* 0x66666666 = 50MHz *2^33 /250MHz */ 754 /* 0x66666666 = 50MHz *2^33 /250MHz */
752 chan->AudioDTOValue = 0x66666666; 755 chan->AudioDTOValue = 0x80000000;
753 /* set_dto(chan, 38810700+1000); */ 756 chan->AudioDTOUpdated = 1;
754 /* set_dto(chan, 19392658); */
755 } 757 }
756 if (chan->mode & NGENE_IO_TSIN) 758 if (chan->mode & NGENE_IO_TSIN)
757 chan->pBufferExchange = tsin_exchange; 759 chan->pBufferExchange = tsin_exchange;
758 /* ngwritel(0, 0x9310); */
759 spin_unlock_irq(&chan->state_lock); 760 spin_unlock_irq(&chan->state_lock);
760 } else 761 } else
761 ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", 762 ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
@@ -1168,6 +1169,7 @@ static void ngene_release_buffers(struct ngene *dev)
1168 iounmap(dev->iomem); 1169 iounmap(dev->iomem);
1169 free_common_buffers(dev); 1170 free_common_buffers(dev);
1170 vfree(dev->tsout_buf); 1171 vfree(dev->tsout_buf);
1172 vfree(dev->tsin_buf);
1171 vfree(dev->ain_buf); 1173 vfree(dev->ain_buf);
1172 vfree(dev->vin_buf); 1174 vfree(dev->vin_buf);
1173 vfree(dev); 1175 vfree(dev);
@@ -1184,6 +1186,13 @@ static int ngene_get_buffers(struct ngene *dev)
1184 dvb_ringbuffer_init(&dev->tsout_rbuf, 1186 dvb_ringbuffer_init(&dev->tsout_rbuf,
1185 dev->tsout_buf, TSOUT_BUF_SIZE); 1187 dev->tsout_buf, TSOUT_BUF_SIZE);
1186 } 1188 }
1189 if (dev->card_info->io_type[2]&NGENE_IO_TSIN) {
1190 dev->tsin_buf = vmalloc(TSIN_BUF_SIZE);
1191 if (!dev->tsin_buf)
1192 return -ENOMEM;
1193 dvb_ringbuffer_init(&dev->tsin_rbuf,
1194 dev->tsin_buf, TSIN_BUF_SIZE);
1195 }
1187 if (dev->card_info->io_type[2] & NGENE_IO_AIN) { 1196 if (dev->card_info->io_type[2] & NGENE_IO_AIN) {
1188 dev->ain_buf = vmalloc(AIN_BUF_SIZE); 1197 dev->ain_buf = vmalloc(AIN_BUF_SIZE);
1189 if (!dev->ain_buf) 1198 if (!dev->ain_buf)
@@ -1257,6 +1266,10 @@ static int ngene_load_firm(struct ngene *dev)
1257 fw_name = "ngene_17.fw"; 1266 fw_name = "ngene_17.fw";
1258 dev->cmd_timeout_workaround = true; 1267 dev->cmd_timeout_workaround = true;
1259 break; 1268 break;
1269 case 18:
1270 size = 0;
1271 fw_name = "ngene_18.fw";
1272 break;
1260 } 1273 }
1261 1274
1262 if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { 1275 if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) {
@@ -1266,6 +1279,8 @@ static int ngene_load_firm(struct ngene *dev)
1266 ": Copy %s to your hotplug directory!\n", fw_name); 1279 ": Copy %s to your hotplug directory!\n", fw_name);
1267 return -1; 1280 return -1;
1268 } 1281 }
1282 if (size == 0)
1283 size = fw->size;
1269 if (size != fw->size) { 1284 if (size != fw->size) {
1270 printk(KERN_ERR DEVICE_NAME 1285 printk(KERN_ERR DEVICE_NAME
1271 ": Firmware %s has invalid size!", fw_name); 1286 ": Firmware %s has invalid size!", fw_name);
@@ -1301,6 +1316,35 @@ static void ngene_stop(struct ngene *dev)
1301#endif 1316#endif
1302} 1317}
1303 1318
1319static int ngene_buffer_config(struct ngene *dev)
1320{
1321 int stat;
1322
1323 if (dev->card_info->fw_version >= 17) {
1324 u8 tsin12_config[6] = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 };
1325 u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 };
1326 u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 };
1327 u8 *bconf = tsin12_config;
1328
1329 if (dev->card_info->io_type[2]&NGENE_IO_TSIN &&
1330 dev->card_info->io_type[3]&NGENE_IO_TSIN) {
1331 bconf = tsin1234_config;
1332 if (dev->card_info->io_type[4]&NGENE_IO_TSOUT &&
1333 dev->ci.en)
1334 bconf = tsio1235_config;
1335 }
1336 stat = ngene_command_config_free_buf(dev, bconf);
1337 } else {
1338 int bconf = BUFFER_CONFIG_4422;
1339
1340 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1341 bconf = BUFFER_CONFIG_3333;
1342 stat = ngene_command_config_buf(dev, bconf);
1343 }
1344 return stat;
1345}
1346
1347
1304static int ngene_start(struct ngene *dev) 1348static int ngene_start(struct ngene *dev)
1305{ 1349{
1306 int stat; 1350 int stat;
@@ -1365,23 +1409,6 @@ static int ngene_start(struct ngene *dev)
1365 if (stat < 0) 1409 if (stat < 0)
1366 goto fail; 1410 goto fail;
1367 1411
1368 if (dev->card_info->fw_version == 17) {
1369 u8 tsin4_config[6] = {
1370 3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0};
1371 u8 default_config[6] = {
1372 4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0};
1373 u8 *bconf = default_config;
1374
1375 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1376 bconf = tsin4_config;
1377 dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n");
1378 stat = ngene_command_config_free_buf(dev, bconf);
1379 } else {
1380 int bconf = BUFFER_CONFIG_4422;
1381 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1382 bconf = BUFFER_CONFIG_3333;
1383 stat = ngene_command_config_buf(dev, bconf);
1384 }
1385 if (!stat) 1412 if (!stat)
1386 return stat; 1413 return stat;
1387 1414
@@ -1397,9 +1424,6 @@ fail2:
1397 return stat; 1424 return stat;
1398} 1425}
1399 1426
1400
1401
1402
1403/****************************************************************************/ 1427/****************************************************************************/
1404/****************************************************************************/ 1428/****************************************************************************/
1405/****************************************************************************/ 1429/****************************************************************************/
@@ -1408,20 +1432,25 @@ static void release_channel(struct ngene_channel *chan)
1408{ 1432{
1409 struct dvb_demux *dvbdemux = &chan->demux; 1433 struct dvb_demux *dvbdemux = &chan->demux;
1410 struct ngene *dev = chan->dev; 1434 struct ngene *dev = chan->dev;
1411 struct ngene_info *ni = dev->card_info;
1412 int io = ni->io_type[chan->number];
1413 1435
1414 if (chan->dev->cmd_timeout_workaround && chan->running) 1436 if (chan->running)
1415 set_transfer(chan, 0); 1437 set_transfer(chan, 0);
1416 1438
1417 tasklet_kill(&chan->demux_tasklet); 1439 tasklet_kill(&chan->demux_tasklet);
1418 1440
1419 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { 1441 if (chan->ci_dev) {
1420 if (chan->fe) { 1442 dvb_unregister_device(chan->ci_dev);
1421 dvb_unregister_frontend(chan->fe); 1443 chan->ci_dev = NULL;
1422 dvb_frontend_detach(chan->fe); 1444 }
1423 chan->fe = NULL; 1445
1424 } 1446 if (chan->fe) {
1447 dvb_unregister_frontend(chan->fe);
1448 dvb_frontend_detach(chan->fe);
1449 chan->fe = NULL;
1450 }
1451
1452 if (chan->has_demux) {
1453 dvb_net_release(&chan->dvbnet);
1425 dvbdemux->dmx.close(&dvbdemux->dmx); 1454 dvbdemux->dmx.close(&dvbdemux->dmx);
1426 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, 1455 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
1427 &chan->hw_frontend); 1456 &chan->hw_frontend);
@@ -1429,9 +1458,12 @@ static void release_channel(struct ngene_channel *chan)
1429 &chan->mem_frontend); 1458 &chan->mem_frontend);
1430 dvb_dmxdev_release(&chan->dmxdev); 1459 dvb_dmxdev_release(&chan->dmxdev);
1431 dvb_dmx_release(&chan->demux); 1460 dvb_dmx_release(&chan->demux);
1461 chan->has_demux = false;
1462 }
1432 1463
1433 if (chan->number == 0 || !one_adapter) 1464 if (chan->has_adapter) {
1434 dvb_unregister_adapter(&dev->adapter[chan->number]); 1465 dvb_unregister_adapter(&dev->adapter[chan->number]);
1466 chan->has_adapter = false;
1435 } 1467 }
1436} 1468}
1437 1469
@@ -1449,9 +1481,27 @@ static int init_channel(struct ngene_channel *chan)
1449 chan->type = io; 1481 chan->type = io;
1450 chan->mode = chan->type; /* for now only one mode */ 1482 chan->mode = chan->type; /* for now only one mode */
1451 1483
1484 if (io & NGENE_IO_TSIN) {
1485 chan->fe = NULL;
1486 if (ni->demod_attach[nr]) {
1487 ret = ni->demod_attach[nr](chan);
1488 if (ret < 0)
1489 goto err;
1490 }
1491 if (chan->fe && ni->tuner_attach[nr]) {
1492 ret = ni->tuner_attach[nr](chan);
1493 if (ret < 0)
1494 goto err;
1495 }
1496 }
1497
1498 if (!dev->ci.en && (io & NGENE_IO_TSOUT))
1499 return 0;
1500
1452 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { 1501 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
1453 if (nr >= STREAM_AUDIOIN1) 1502 if (nr >= STREAM_AUDIOIN1)
1454 chan->DataFormatFlags = DF_SWAP32; 1503 chan->DataFormatFlags = DF_SWAP32;
1504
1455 if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { 1505 if (nr == 0 || !one_adapter || dev->first_adapter == NULL) {
1456 adapter = &dev->adapter[nr]; 1506 adapter = &dev->adapter[nr];
1457 ret = dvb_register_adapter(adapter, "nGene", 1507 ret = dvb_register_adapter(adapter, "nGene",
@@ -1459,40 +1509,50 @@ static int init_channel(struct ngene_channel *chan)
1459 &chan->dev->pci_dev->dev, 1509 &chan->dev->pci_dev->dev,
1460 adapter_nr); 1510 adapter_nr);
1461 if (ret < 0) 1511 if (ret < 0)
1462 return ret; 1512 goto err;
1463 if (dev->first_adapter == NULL) 1513 if (dev->first_adapter == NULL)
1464 dev->first_adapter = adapter; 1514 dev->first_adapter = adapter;
1465 } else { 1515 chan->has_adapter = true;
1516 } else
1466 adapter = dev->first_adapter; 1517 adapter = dev->first_adapter;
1467 } 1518 }
1468 1519
1520 if (dev->ci.en && (io & NGENE_IO_TSOUT)) {
1521 dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1);
1522 set_transfer(chan, 1);
1523 set_transfer(&chan->dev->channel[2], 1);
1524 dvb_register_device(adapter, &chan->ci_dev,
1525 &ngene_dvbdev_ci, (void *) chan,
1526 DVB_DEVICE_SEC);
1527 if (!chan->ci_dev)
1528 goto err;
1529 }
1530
1531 if (chan->fe) {
1532 if (dvb_register_frontend(adapter, chan->fe) < 0)
1533 goto err;
1534 chan->has_demux = true;
1535 }
1536
1537 if (chan->has_demux) {
1469 ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", 1538 ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
1470 ngene_start_feed, 1539 ngene_start_feed,
1471 ngene_stop_feed, chan); 1540 ngene_stop_feed, chan);
1472 ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, 1541 ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux,
1473 &chan->hw_frontend, 1542 &chan->hw_frontend,
1474 &chan->mem_frontend, adapter); 1543 &chan->mem_frontend, adapter);
1544 ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx);
1475 } 1545 }
1476 1546
1477 if (io & NGENE_IO_TSIN) { 1547 return ret;
1548
1549err:
1550 if (chan->fe) {
1551 dvb_frontend_detach(chan->fe);
1478 chan->fe = NULL; 1552 chan->fe = NULL;
1479 if (ni->demod_attach[nr])
1480 ni->demod_attach[nr](chan);
1481 if (chan->fe) {
1482 if (dvb_register_frontend(adapter, chan->fe) < 0) {
1483 if (chan->fe->ops.release)
1484 chan->fe->ops.release(chan->fe);
1485 chan->fe = NULL;
1486 }
1487 }
1488 if (chan->fe && ni->tuner_attach[nr])
1489 if (ni->tuner_attach[nr] (chan) < 0) {
1490 printk(KERN_ERR DEVICE_NAME
1491 ": Tuner attach failed on channel %d!\n",
1492 nr);
1493 }
1494 } 1553 }
1495 return ret; 1554 release_channel(chan);
1555 return 0;
1496} 1556}
1497 1557
1498static int init_channels(struct ngene *dev) 1558static int init_channels(struct ngene *dev)
@@ -1510,6 +1570,57 @@ static int init_channels(struct ngene *dev)
1510 return 0; 1570 return 0;
1511} 1571}
1512 1572
1573static void cxd_attach(struct ngene *dev)
1574{
1575 struct ngene_ci *ci = &dev->ci;
1576
1577 ci->en = cxd2099_attach(0x40, dev, &dev->channel[0].i2c_adapter);
1578 ci->dev = dev;
1579 return;
1580}
1581
1582static void cxd_detach(struct ngene *dev)
1583{
1584 struct ngene_ci *ci = &dev->ci;
1585
1586 dvb_ca_en50221_release(ci->en);
1587 kfree(ci->en);
1588 ci->en = 0;
1589}
1590
1591/***********************************/
1592/* workaround for shutdown failure */
1593/***********************************/
1594
1595static void ngene_unlink(struct ngene *dev)
1596{
1597 struct ngene_command com;
1598
1599 com.cmd.hdr.Opcode = CMD_MEM_WRITE;
1600 com.cmd.hdr.Length = 3;
1601 com.cmd.MemoryWrite.address = 0x910c;
1602 com.cmd.MemoryWrite.data = 0xff;
1603 com.in_len = 3;
1604 com.out_len = 1;
1605
1606 down(&dev->cmd_mutex);
1607 ngwritel(0, NGENE_INT_ENABLE);
1608 ngene_command_mutex(dev, &com);
1609 up(&dev->cmd_mutex);
1610}
1611
1612void ngene_shutdown(struct pci_dev *pdev)
1613{
1614 struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
1615
1616 if (!dev || !shutdown_workaround)
1617 return;
1618
1619 printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n");
1620 ngene_unlink(dev);
1621 pci_disable_device(pdev);
1622}
1623
1513/****************************************************************************/ 1624/****************************************************************************/
1514/* device probe/remove calls ************************************************/ 1625/* device probe/remove calls ************************************************/
1515/****************************************************************************/ 1626/****************************************************************************/
@@ -1522,6 +1633,8 @@ void __devexit ngene_remove(struct pci_dev *pdev)
1522 tasklet_kill(&dev->event_tasklet); 1633 tasklet_kill(&dev->event_tasklet);
1523 for (i = MAX_STREAM - 1; i >= 0; i--) 1634 for (i = MAX_STREAM - 1; i >= 0; i--)
1524 release_channel(&dev->channel[i]); 1635 release_channel(&dev->channel[i]);
1636 if (dev->ci.en)
1637 cxd_detach(dev);
1525 ngene_stop(dev); 1638 ngene_stop(dev);
1526 ngene_release_buffers(dev); 1639 ngene_release_buffers(dev);
1527 pci_set_drvdata(pdev, NULL); 1640 pci_set_drvdata(pdev, NULL);
@@ -1557,6 +1670,13 @@ int __devinit ngene_probe(struct pci_dev *pci_dev,
1557 if (stat < 0) 1670 if (stat < 0)
1558 goto fail1; 1671 goto fail1;
1559 1672
1673 cxd_attach(dev);
1674
1675 stat = ngene_buffer_config(dev);
1676 if (stat < 0)
1677 goto fail1;
1678
1679
1560 dev->i2c_current_bus = -1; 1680 dev->i2c_current_bus = -1;
1561 1681
1562 /* Register DVB adapters and devices for both channels */ 1682 /* Register DVB adapters and devices for both channels */
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c
index 3832e5983c19..0b4943233166 100644
--- a/drivers/media/dvb/ngene/ngene-dvb.c
+++ b/drivers/media/dvb/ngene/ngene-dvb.c
@@ -47,6 +47,64 @@
47/* COMMAND API interface ****************************************************/ 47/* COMMAND API interface ****************************************************/
48/****************************************************************************/ 48/****************************************************************************/
49 49
50static ssize_t ts_write(struct file *file, const char *buf,
51 size_t count, loff_t *ppos)
52{
53 struct dvb_device *dvbdev = file->private_data;
54 struct ngene_channel *chan = dvbdev->priv;
55 struct ngene *dev = chan->dev;
56
57 if (wait_event_interruptible(dev->tsout_rbuf.queue,
58 dvb_ringbuffer_free
59 (&dev->tsout_rbuf) >= count) < 0)
60 return 0;
61
62 dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count);
63
64 return count;
65}
66
67static ssize_t ts_read(struct file *file, char *buf,
68 size_t count, loff_t *ppos)
69{
70 struct dvb_device *dvbdev = file->private_data;
71 struct ngene_channel *chan = dvbdev->priv;
72 struct ngene *dev = chan->dev;
73 int left, avail;
74
75 left = count;
76 while (left) {
77 if (wait_event_interruptible(
78 dev->tsin_rbuf.queue,
79 dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0)
80 return -EAGAIN;
81 avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
82 if (avail > left)
83 avail = left;
84 dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail);
85 left -= avail;
86 buf += avail;
87 }
88 return count;
89}
90
91static const struct file_operations ci_fops = {
92 .owner = THIS_MODULE,
93 .read = ts_read,
94 .write = ts_write,
95 .open = dvb_generic_open,
96 .release = dvb_generic_release,
97};
98
99struct dvb_device ngene_dvbdev_ci = {
100 .priv = 0,
101 .readers = -1,
102 .writers = -1,
103 .users = -1,
104 .fops = &ci_fops,
105};
106
107
50/****************************************************************************/ 108/****************************************************************************/
51/* DVB functions and API interface ******************************************/ 109/* DVB functions and API interface ******************************************/
52/****************************************************************************/ 110/****************************************************************************/
@@ -63,10 +121,21 @@ static void swap_buffer(u32 *p, u32 len)
63void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) 121void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
64{ 122{
65 struct ngene_channel *chan = priv; 123 struct ngene_channel *chan = priv;
124 struct ngene *dev = chan->dev;
66 125
67 126
68 if (chan->users > 0) 127 if (flags & DF_SWAP32)
128 swap_buffer(buf, len);
129 if (dev->ci.en && chan->number == 2) {
130 if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
131 dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len);
132 wake_up_interruptible(&dev->tsin_rbuf.queue);
133 }
134 return 0;
135 }
136 if (chan->users > 0) {
69 dvb_dmx_swfilter(&chan->demux, buf, len); 137 dvb_dmx_swfilter(&chan->demux, buf, len);
138 }
70 return NULL; 139 return NULL;
71} 140}
72 141
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h
index 8fb4200f83f8..40fce9e3ae66 100644
--- a/drivers/media/dvb/ngene/ngene.h
+++ b/drivers/media/dvb/ngene/ngene.h
@@ -36,8 +36,11 @@
36#include "dmxdev.h" 36#include "dmxdev.h"
37#include "dvbdev.h" 37#include "dvbdev.h"
38#include "dvb_demux.h" 38#include "dvb_demux.h"
39#include "dvb_ca_en50221.h"
39#include "dvb_frontend.h" 40#include "dvb_frontend.h"
40#include "dvb_ringbuffer.h" 41#include "dvb_ringbuffer.h"
42#include "dvb_net.h"
43#include "cxd2099.h"
41 44
42#define DEVICE_NAME "ngene" 45#define DEVICE_NAME "ngene"
43 46
@@ -636,14 +639,18 @@ struct ngene_channel {
636 int number; 639 int number;
637 int type; 640 int type;
638 int mode; 641 int mode;
642 bool has_adapter;
643 bool has_demux;
639 644
640 struct dvb_frontend *fe; 645 struct dvb_frontend *fe;
641 struct dmxdev dmxdev; 646 struct dmxdev dmxdev;
642 struct dvb_demux demux; 647 struct dvb_demux demux;
648 struct dvb_net dvbnet;
643 struct dmx_frontend hw_frontend; 649 struct dmx_frontend hw_frontend;
644 struct dmx_frontend mem_frontend; 650 struct dmx_frontend mem_frontend;
645 int users; 651 int users;
646 struct video_device *v4l_dev; 652 struct video_device *v4l_dev;
653 struct dvb_device *ci_dev;
647 struct tasklet_struct demux_tasklet; 654 struct tasklet_struct demux_tasklet;
648 655
649 struct SBufferHeader *nextBuffer; 656 struct SBufferHeader *nextBuffer;
@@ -710,6 +717,15 @@ struct ngene_channel {
710 int running; 717 int running;
711}; 718};
712 719
720
721struct ngene_ci {
722 struct device device;
723 struct i2c_adapter i2c_adapter;
724
725 struct ngene *dev;
726 struct dvb_ca_en50221 *en;
727};
728
713struct ngene; 729struct ngene;
714 730
715typedef void (rx_cb_t)(struct ngene *, u32, u8); 731typedef void (rx_cb_t)(struct ngene *, u32, u8);
@@ -774,6 +790,10 @@ struct ngene {
774#define TSOUT_BUF_SIZE (512*188*8) 790#define TSOUT_BUF_SIZE (512*188*8)
775 struct dvb_ringbuffer tsout_rbuf; 791 struct dvb_ringbuffer tsout_rbuf;
776 792
793 u8 *tsin_buf;
794#define TSIN_BUF_SIZE (512*188*8)
795 struct dvb_ringbuffer tsin_rbuf;
796
777 u8 *ain_buf; 797 u8 *ain_buf;
778#define AIN_BUF_SIZE (128*1024) 798#define AIN_BUF_SIZE (128*1024)
779 struct dvb_ringbuffer ain_rbuf; 799 struct dvb_ringbuffer ain_rbuf;
@@ -785,6 +805,8 @@ struct ngene {
785 805
786 unsigned long exp_val; 806 unsigned long exp_val;
787 int prev_cmd; 807 int prev_cmd;
808
809 struct ngene_ci ci;
788}; 810};
789 811
790struct ngene_info { 812struct ngene_info {
@@ -863,6 +885,7 @@ struct ngene_buffer {
863int __devinit ngene_probe(struct pci_dev *pci_dev, 885int __devinit ngene_probe(struct pci_dev *pci_dev,
864 const struct pci_device_id *id); 886 const struct pci_device_id *id);
865void __devexit ngene_remove(struct pci_dev *pdev); 887void __devexit ngene_remove(struct pci_dev *pdev);
888void ngene_shutdown(struct pci_dev *pdev);
866int ngene_command(struct ngene *dev, struct ngene_command *com); 889int ngene_command(struct ngene *dev, struct ngene_command *com);
867int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level); 890int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level);
868void set_transfer(struct ngene_channel *chan, int state); 891void set_transfer(struct ngene_channel *chan, int state);
@@ -872,6 +895,7 @@ void FillTSBuffer(void *Buffer, int Length, u32 Flags);
872int ngene_i2c_init(struct ngene *dev, int dev_nr); 895int ngene_i2c_init(struct ngene *dev, int dev_nr);
873 896
874/* Provided by ngene-dvb.c */ 897/* Provided by ngene-dvb.c */
898extern struct dvb_device ngene_dvbdev_ci;
875void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); 899void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
876void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); 900void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
877int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed); 901int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed);
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 25b43e587fa6..af121db88ea0 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -64,7 +64,7 @@ static struct sms_board sms_boards[] = {
64 .type = SMS_NOVA_B0, 64 .type = SMS_NOVA_B0,
65 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", 65 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
66 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 66 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
67 .rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW, 67 .rc_codes = RC_MAP_HAUPPAUGE,
68 .board_cfg.leds_power = 26, 68 .board_cfg.leds_power = 26,
69 .board_cfg.led0 = 27, 69 .board_cfg.led0 = 27,
70 .board_cfg.led1 = 28, 70 .board_cfg.led1 = 28,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index b82756db5bd1..1d79ada864d6 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -26,7 +26,7 @@
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 * 27 *
28 * 28 *
29 * the project's page is at http://www.linuxtv.org/ 29 * the project's page is at http://www.linuxtv.org/
30 */ 30 */
31 31
32#include <linux/module.h> 32#include <linux/module.h>
@@ -102,6 +102,7 @@ struct budget_ci_ir {
102 int rc5_device; 102 int rc5_device;
103 u32 ir_key; 103 u32 ir_key;
104 bool have_command; 104 bool have_command;
105 bool full_rc5; /* Outputs a full RC5 code */
105}; 106};
106 107
107struct budget_ci { 108struct budget_ci {
@@ -154,11 +155,18 @@ static void msp430_ir_interrupt(unsigned long data)
154 return; 155 return;
155 budget_ci->ir.have_command = false; 156 budget_ci->ir.have_command = false;
156 157
157 /* FIXME: We should generate complete scancodes with device info */
158 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && 158 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
159 budget_ci->ir.rc5_device != (command & 0x1f)) 159 budget_ci->ir.rc5_device != (command & 0x1f))
160 return; 160 return;
161 161
162 if (budget_ci->ir.full_rc5) {
163 rc_keydown(dev,
164 budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key,
165 (command & 0x20) ? 1 : 0);
166 return;
167 }
168
169 /* FIXME: We should generate complete scancodes for all devices */
162 rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0); 170 rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
163} 171}
164 172
@@ -206,7 +214,8 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
206 case 0x1011: 214 case 0x1011:
207 case 0x1012: 215 case 0x1012:
208 /* The hauppauge keymap is a superset of these remotes */ 216 /* The hauppauge keymap is a superset of these remotes */
209 dev->map_name = RC_MAP_HAUPPAUGE_NEW; 217 dev->map_name = RC_MAP_HAUPPAUGE;
218 budget_ci->ir.full_rc5 = true;
210 219
211 if (rc5_device < 0) 220 if (rc5_device < 0)
212 budget_ci->ir.rc5_device = 0x1f; 221 budget_ci->ir.rc5_device = 0x1f;
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 40625b26ac10..cbe2f0de1442 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -334,6 +334,7 @@ static int ttusb_boot_dsp(struct ttusb *ttusb)
334 err = ttusb_cmd(ttusb, b, 4, 0); 334 err = ttusb_cmd(ttusb, b, 4, 0);
335 335
336 done: 336 done:
337 release_firmware(fw);
337 if (err) { 338 if (err) {
338 dprintk("%s: usb_bulk_msg() failed, return value %i!\n", 339 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
339 __func__, err); 340 __func__, err);
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
new file mode 100644
index 000000000000..16b70b4412f7
--- /dev/null
+++ b/drivers/media/media-device.c
@@ -0,0 +1,382 @@
1/*
2 * Media device
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/types.h>
24#include <linux/ioctl.h>
25#include <linux/media.h>
26
27#include <media/media-device.h>
28#include <media/media-devnode.h>
29#include <media/media-entity.h>
30
31/* -----------------------------------------------------------------------------
32 * Userspace API
33 */
34
35static int media_device_open(struct file *filp)
36{
37 return 0;
38}
39
40static int media_device_close(struct file *filp)
41{
42 return 0;
43}
44
45static int media_device_get_info(struct media_device *dev,
46 struct media_device_info __user *__info)
47{
48 struct media_device_info info;
49
50 memset(&info, 0, sizeof(info));
51
52 strlcpy(info.driver, dev->dev->driver->name, sizeof(info.driver));
53 strlcpy(info.model, dev->model, sizeof(info.model));
54 strlcpy(info.serial, dev->serial, sizeof(info.serial));
55 strlcpy(info.bus_info, dev->bus_info, sizeof(info.bus_info));
56
57 info.media_version = MEDIA_API_VERSION;
58 info.hw_revision = dev->hw_revision;
59 info.driver_version = dev->driver_version;
60
61 return copy_to_user(__info, &info, sizeof(*__info));
62}
63
64static struct media_entity *find_entity(struct media_device *mdev, u32 id)
65{
66 struct media_entity *entity;
67 int next = id & MEDIA_ENT_ID_FLAG_NEXT;
68
69 id &= ~MEDIA_ENT_ID_FLAG_NEXT;
70
71 spin_lock(&mdev->lock);
72
73 media_device_for_each_entity(entity, mdev) {
74 if ((entity->id == id && !next) ||
75 (entity->id > id && next)) {
76 spin_unlock(&mdev->lock);
77 return entity;
78 }
79 }
80
81 spin_unlock(&mdev->lock);
82
83 return NULL;
84}
85
86static long media_device_enum_entities(struct media_device *mdev,
87 struct media_entity_desc __user *uent)
88{
89 struct media_entity *ent;
90 struct media_entity_desc u_ent;
91
92 if (copy_from_user(&u_ent.id, &uent->id, sizeof(u_ent.id)))
93 return -EFAULT;
94
95 ent = find_entity(mdev, u_ent.id);
96
97 if (ent == NULL)
98 return -EINVAL;
99
100 u_ent.id = ent->id;
101 u_ent.name[0] = '\0';
102 if (ent->name)
103 strlcpy(u_ent.name, ent->name, sizeof(u_ent.name));
104 u_ent.type = ent->type;
105 u_ent.revision = ent->revision;
106 u_ent.flags = ent->flags;
107 u_ent.group_id = ent->group_id;
108 u_ent.pads = ent->num_pads;
109 u_ent.links = ent->num_links - ent->num_backlinks;
110 u_ent.v4l.major = ent->v4l.major;
111 u_ent.v4l.minor = ent->v4l.minor;
112 if (copy_to_user(uent, &u_ent, sizeof(u_ent)))
113 return -EFAULT;
114 return 0;
115}
116
117static void media_device_kpad_to_upad(const struct media_pad *kpad,
118 struct media_pad_desc *upad)
119{
120 upad->entity = kpad->entity->id;
121 upad->index = kpad->index;
122 upad->flags = kpad->flags;
123}
124
125static long media_device_enum_links(struct media_device *mdev,
126 struct media_links_enum __user *ulinks)
127{
128 struct media_entity *entity;
129 struct media_links_enum links;
130
131 if (copy_from_user(&links, ulinks, sizeof(links)))
132 return -EFAULT;
133
134 entity = find_entity(mdev, links.entity);
135 if (entity == NULL)
136 return -EINVAL;
137
138 if (links.pads) {
139 unsigned int p;
140
141 for (p = 0; p < entity->num_pads; p++) {
142 struct media_pad_desc pad;
143 media_device_kpad_to_upad(&entity->pads[p], &pad);
144 if (copy_to_user(&links.pads[p], &pad, sizeof(pad)))
145 return -EFAULT;
146 }
147 }
148
149 if (links.links) {
150 struct media_link_desc __user *ulink;
151 unsigned int l;
152
153 for (l = 0, ulink = links.links; l < entity->num_links; l++) {
154 struct media_link_desc link;
155
156 /* Ignore backlinks. */
157 if (entity->links[l].source->entity != entity)
158 continue;
159
160 media_device_kpad_to_upad(entity->links[l].source,
161 &link.source);
162 media_device_kpad_to_upad(entity->links[l].sink,
163 &link.sink);
164 link.flags = entity->links[l].flags;
165 if (copy_to_user(ulink, &link, sizeof(*ulink)))
166 return -EFAULT;
167 ulink++;
168 }
169 }
170 if (copy_to_user(ulinks, &links, sizeof(*ulinks)))
171 return -EFAULT;
172 return 0;
173}
174
175static long media_device_setup_link(struct media_device *mdev,
176 struct media_link_desc __user *_ulink)
177{
178 struct media_link *link = NULL;
179 struct media_link_desc ulink;
180 struct media_entity *source;
181 struct media_entity *sink;
182 int ret;
183
184 if (copy_from_user(&ulink, _ulink, sizeof(ulink)))
185 return -EFAULT;
186
187 /* Find the source and sink entities and link.
188 */
189 source = find_entity(mdev, ulink.source.entity);
190 sink = find_entity(mdev, ulink.sink.entity);
191
192 if (source == NULL || sink == NULL)
193 return -EINVAL;
194
195 if (ulink.source.index >= source->num_pads ||
196 ulink.sink.index >= sink->num_pads)
197 return -EINVAL;
198
199 link = media_entity_find_link(&source->pads[ulink.source.index],
200 &sink->pads[ulink.sink.index]);
201 if (link == NULL)
202 return -EINVAL;
203
204 /* Setup the link on both entities. */
205 ret = __media_entity_setup_link(link, ulink.flags);
206
207 if (copy_to_user(_ulink, &ulink, sizeof(ulink)))
208 return -EFAULT;
209
210 return ret;
211}
212
213static long media_device_ioctl(struct file *filp, unsigned int cmd,
214 unsigned long arg)
215{
216 struct media_devnode *devnode = media_devnode_data(filp);
217 struct media_device *dev = to_media_device(devnode);
218 long ret;
219
220 switch (cmd) {
221 case MEDIA_IOC_DEVICE_INFO:
222 ret = media_device_get_info(dev,
223 (struct media_device_info __user *)arg);
224 break;
225
226 case MEDIA_IOC_ENUM_ENTITIES:
227 ret = media_device_enum_entities(dev,
228 (struct media_entity_desc __user *)arg);
229 break;
230
231 case MEDIA_IOC_ENUM_LINKS:
232 mutex_lock(&dev->graph_mutex);
233 ret = media_device_enum_links(dev,
234 (struct media_links_enum __user *)arg);
235 mutex_unlock(&dev->graph_mutex);
236 break;
237
238 case MEDIA_IOC_SETUP_LINK:
239 mutex_lock(&dev->graph_mutex);
240 ret = media_device_setup_link(dev,
241 (struct media_link_desc __user *)arg);
242 mutex_unlock(&dev->graph_mutex);
243 break;
244
245 default:
246 ret = -ENOIOCTLCMD;
247 }
248
249 return ret;
250}
251
252static const struct media_file_operations media_device_fops = {
253 .owner = THIS_MODULE,
254 .open = media_device_open,
255 .ioctl = media_device_ioctl,
256 .release = media_device_close,
257};
258
259/* -----------------------------------------------------------------------------
260 * sysfs
261 */
262
263static ssize_t show_model(struct device *cd,
264 struct device_attribute *attr, char *buf)
265{
266 struct media_device *mdev = to_media_device(to_media_devnode(cd));
267
268 return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model);
269}
270
271static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
272
273/* -----------------------------------------------------------------------------
274 * Registration/unregistration
275 */
276
277static void media_device_release(struct media_devnode *mdev)
278{
279}
280
281/**
282 * media_device_register - register a media device
283 * @mdev: The media device
284 *
285 * The caller is responsible for initializing the media device before
286 * registration. The following fields must be set:
287 *
288 * - dev must point to the parent device
289 * - model must be filled with the device model name
290 */
291int __must_check media_device_register(struct media_device *mdev)
292{
293 int ret;
294
295 if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0))
296 return -EINVAL;
297
298 mdev->entity_id = 1;
299 INIT_LIST_HEAD(&mdev->entities);
300 spin_lock_init(&mdev->lock);
301 mutex_init(&mdev->graph_mutex);
302
303 /* Register the device node. */
304 mdev->devnode.fops = &media_device_fops;
305 mdev->devnode.parent = mdev->dev;
306 mdev->devnode.release = media_device_release;
307 ret = media_devnode_register(&mdev->devnode);
308 if (ret < 0)
309 return ret;
310
311 ret = device_create_file(&mdev->devnode.dev, &dev_attr_model);
312 if (ret < 0) {
313 media_devnode_unregister(&mdev->devnode);
314 return ret;
315 }
316
317 return 0;
318}
319EXPORT_SYMBOL_GPL(media_device_register);
320
321/**
322 * media_device_unregister - unregister a media device
323 * @mdev: The media device
324 *
325 */
326void media_device_unregister(struct media_device *mdev)
327{
328 struct media_entity *entity;
329 struct media_entity *next;
330
331 list_for_each_entry_safe(entity, next, &mdev->entities, list)
332 media_device_unregister_entity(entity);
333
334 device_remove_file(&mdev->devnode.dev, &dev_attr_model);
335 media_devnode_unregister(&mdev->devnode);
336}
337EXPORT_SYMBOL_GPL(media_device_unregister);
338
339/**
340 * media_device_register_entity - Register an entity with a media device
341 * @mdev: The media device
342 * @entity: The entity
343 */
344int __must_check media_device_register_entity(struct media_device *mdev,
345 struct media_entity *entity)
346{
347 /* Warn if we apparently re-register an entity */
348 WARN_ON(entity->parent != NULL);
349 entity->parent = mdev;
350
351 spin_lock(&mdev->lock);
352 if (entity->id == 0)
353 entity->id = mdev->entity_id++;
354 else
355 mdev->entity_id = max(entity->id + 1, mdev->entity_id);
356 list_add_tail(&entity->list, &mdev->entities);
357 spin_unlock(&mdev->lock);
358
359 return 0;
360}
361EXPORT_SYMBOL_GPL(media_device_register_entity);
362
363/**
364 * media_device_unregister_entity - Unregister an entity
365 * @entity: The entity
366 *
367 * If the entity has never been registered this function will return
368 * immediately.
369 */
370void media_device_unregister_entity(struct media_entity *entity)
371{
372 struct media_device *mdev = entity->parent;
373
374 if (mdev == NULL)
375 return;
376
377 spin_lock(&mdev->lock);
378 list_del(&entity->list);
379 spin_unlock(&mdev->lock);
380 entity->parent = NULL;
381}
382EXPORT_SYMBOL_GPL(media_device_unregister_entity);
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
new file mode 100644
index 000000000000..af5263c6625a
--- /dev/null
+++ b/drivers/media/media-devnode.c
@@ -0,0 +1,320 @@
1/*
2 * Media device node
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Based on drivers/media/video/v4l2_dev.c code authored by
7 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
8 * Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
9 *
10 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * --
27 *
28 * Generic media device node infrastructure to register and unregister
29 * character devices using a dynamic major number and proper reference
30 * counting.
31 */
32
33#include <linux/errno.h>
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/kmod.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/string.h>
41#include <linux/types.h>
42#include <linux/uaccess.h>
43#include <asm/system.h>
44
45#include <media/media-devnode.h>
46
47#define MEDIA_NUM_DEVICES 256
48#define MEDIA_NAME "media"
49
50static dev_t media_dev_t;
51
52/*
53 * Active devices
54 */
55static DEFINE_MUTEX(media_devnode_lock);
56static DECLARE_BITMAP(media_devnode_nums, MEDIA_NUM_DEVICES);
57
58/* Called when the last user of the media device exits. */
59static void media_devnode_release(struct device *cd)
60{
61 struct media_devnode *mdev = to_media_devnode(cd);
62
63 mutex_lock(&media_devnode_lock);
64
65 /* Delete the cdev on this minor as well */
66 cdev_del(&mdev->cdev);
67
68 /* Mark device node number as free */
69 clear_bit(mdev->minor, media_devnode_nums);
70
71 mutex_unlock(&media_devnode_lock);
72
73 /* Release media_devnode and perform other cleanups as needed. */
74 if (mdev->release)
75 mdev->release(mdev);
76}
77
78static struct bus_type media_bus_type = {
79 .name = MEDIA_NAME,
80};
81
82static ssize_t media_read(struct file *filp, char __user *buf,
83 size_t sz, loff_t *off)
84{
85 struct media_devnode *mdev = media_devnode_data(filp);
86
87 if (!mdev->fops->read)
88 return -EINVAL;
89 if (!media_devnode_is_registered(mdev))
90 return -EIO;
91 return mdev->fops->read(filp, buf, sz, off);
92}
93
94static ssize_t media_write(struct file *filp, const char __user *buf,
95 size_t sz, loff_t *off)
96{
97 struct media_devnode *mdev = media_devnode_data(filp);
98
99 if (!mdev->fops->write)
100 return -EINVAL;
101 if (!media_devnode_is_registered(mdev))
102 return -EIO;
103 return mdev->fops->write(filp, buf, sz, off);
104}
105
106static unsigned int media_poll(struct file *filp,
107 struct poll_table_struct *poll)
108{
109 struct media_devnode *mdev = media_devnode_data(filp);
110
111 if (!media_devnode_is_registered(mdev))
112 return POLLERR | POLLHUP;
113 if (!mdev->fops->poll)
114 return DEFAULT_POLLMASK;
115 return mdev->fops->poll(filp, poll);
116}
117
118static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
119{
120 struct media_devnode *mdev = media_devnode_data(filp);
121
122 if (!mdev->fops->ioctl)
123 return -ENOTTY;
124
125 if (!media_devnode_is_registered(mdev))
126 return -EIO;
127
128 return mdev->fops->ioctl(filp, cmd, arg);
129}
130
131/* Override for the open function */
132static int media_open(struct inode *inode, struct file *filp)
133{
134 struct media_devnode *mdev;
135 int ret;
136
137 /* Check if the media device is available. This needs to be done with
138 * the media_devnode_lock held to prevent an open/unregister race:
139 * without the lock, the device could be unregistered and freed between
140 * the media_devnode_is_registered() and get_device() calls, leading to
141 * a crash.
142 */
143 mutex_lock(&media_devnode_lock);
144 mdev = container_of(inode->i_cdev, struct media_devnode, cdev);
145 /* return ENXIO if the media device has been removed
146 already or if it is not registered anymore. */
147 if (!media_devnode_is_registered(mdev)) {
148 mutex_unlock(&media_devnode_lock);
149 return -ENXIO;
150 }
151 /* and increase the device refcount */
152 get_device(&mdev->dev);
153 mutex_unlock(&media_devnode_lock);
154
155 filp->private_data = mdev;
156
157 if (mdev->fops->open) {
158 ret = mdev->fops->open(filp);
159 if (ret) {
160 put_device(&mdev->dev);
161 return ret;
162 }
163 }
164
165 return 0;
166}
167
168/* Override for the release function */
169static int media_release(struct inode *inode, struct file *filp)
170{
171 struct media_devnode *mdev = media_devnode_data(filp);
172 int ret = 0;
173
174 if (mdev->fops->release)
175 mdev->fops->release(filp);
176
177 /* decrease the refcount unconditionally since the release()
178 return value is ignored. */
179 put_device(&mdev->dev);
180 filp->private_data = NULL;
181 return ret;
182}
183
184static const struct file_operations media_devnode_fops = {
185 .owner = THIS_MODULE,
186 .read = media_read,
187 .write = media_write,
188 .open = media_open,
189 .unlocked_ioctl = media_ioctl,
190 .release = media_release,
191 .poll = media_poll,
192 .llseek = no_llseek,
193};
194
195/**
196 * media_devnode_register - register a media device node
197 * @mdev: media device node structure we want to register
198 *
199 * The registration code assigns minor numbers and registers the new device node
200 * with the kernel. An error is returned if no free minor number can be found,
201 * or if the registration of the device node fails.
202 *
203 * Zero is returned on success.
204 *
205 * Note that if the media_devnode_register call fails, the release() callback of
206 * the media_devnode structure is *not* called, so the caller is responsible for
207 * freeing any data.
208 */
209int __must_check media_devnode_register(struct media_devnode *mdev)
210{
211 int minor;
212 int ret;
213
214 /* Part 1: Find a free minor number */
215 mutex_lock(&media_devnode_lock);
216 minor = find_next_zero_bit(media_devnode_nums, 0, MEDIA_NUM_DEVICES);
217 if (minor == MEDIA_NUM_DEVICES) {
218 mutex_unlock(&media_devnode_lock);
219 printk(KERN_ERR "could not get a free minor\n");
220 return -ENFILE;
221 }
222
223 set_bit(mdev->minor, media_devnode_nums);
224 mutex_unlock(&media_devnode_lock);
225
226 mdev->minor = minor;
227
228 /* Part 2: Initialize and register the character device */
229 cdev_init(&mdev->cdev, &media_devnode_fops);
230 mdev->cdev.owner = mdev->fops->owner;
231
232 ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1);
233 if (ret < 0) {
234 printk(KERN_ERR "%s: cdev_add failed\n", __func__);
235 goto error;
236 }
237
238 /* Part 3: Register the media device */
239 mdev->dev.bus = &media_bus_type;
240 mdev->dev.devt = MKDEV(MAJOR(media_dev_t), mdev->minor);
241 mdev->dev.release = media_devnode_release;
242 if (mdev->parent)
243 mdev->dev.parent = mdev->parent;
244 dev_set_name(&mdev->dev, "media%d", mdev->minor);
245 ret = device_register(&mdev->dev);
246 if (ret < 0) {
247 printk(KERN_ERR "%s: device_register failed\n", __func__);
248 goto error;
249 }
250
251 /* Part 4: Activate this minor. The char device can now be used. */
252 set_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
253
254 return 0;
255
256error:
257 cdev_del(&mdev->cdev);
258 clear_bit(mdev->minor, media_devnode_nums);
259 return ret;
260}
261
262/**
263 * media_devnode_unregister - unregister a media device node
264 * @mdev: the device node to unregister
265 *
266 * This unregisters the passed device. Future open calls will be met with
267 * errors.
268 *
269 * This function can safely be called if the device node has never been
270 * registered or has already been unregistered.
271 */
272void media_devnode_unregister(struct media_devnode *mdev)
273{
274 /* Check if mdev was ever registered at all */
275 if (!media_devnode_is_registered(mdev))
276 return;
277
278 mutex_lock(&media_devnode_lock);
279 clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
280 mutex_unlock(&media_devnode_lock);
281 device_unregister(&mdev->dev);
282}
283
284/*
285 * Initialise media for linux
286 */
287static int __init media_devnode_init(void)
288{
289 int ret;
290
291 printk(KERN_INFO "Linux media interface: v0.10\n");
292 ret = alloc_chrdev_region(&media_dev_t, 0, MEDIA_NUM_DEVICES,
293 MEDIA_NAME);
294 if (ret < 0) {
295 printk(KERN_WARNING "media: unable to allocate major\n");
296 return ret;
297 }
298
299 ret = bus_register(&media_bus_type);
300 if (ret < 0) {
301 unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
302 printk(KERN_WARNING "media: bus_register failed\n");
303 return -EIO;
304 }
305
306 return 0;
307}
308
309static void __exit media_devnode_exit(void)
310{
311 bus_unregister(&media_bus_type);
312 unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
313}
314
315module_init(media_devnode_init)
316module_exit(media_devnode_exit)
317
318MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
319MODULE_DESCRIPTION("Device node registration for media drivers");
320MODULE_LICENSE("GPL");
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
new file mode 100644
index 000000000000..23640ed44d85
--- /dev/null
+++ b/drivers/media/media-entity.c
@@ -0,0 +1,536 @@
1/*
2 * Media entity
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <media/media-entity.h>
26#include <media/media-device.h>
27
28/**
29 * media_entity_init - Initialize a media entity
30 *
31 * @num_pads: Total number of sink and source pads.
32 * @extra_links: Initial estimate of the number of extra links.
33 * @pads: Array of 'num_pads' pads.
34 *
35 * The total number of pads is an intrinsic property of entities known by the
36 * entity driver, while the total number of links depends on hardware design
37 * and is an extrinsic property unknown to the entity driver. However, in most
38 * use cases the entity driver can guess the number of links which can safely
39 * be assumed to be equal to or larger than the number of pads.
40 *
41 * For those reasons the links array can be preallocated based on the entity
42 * driver guess and will be reallocated later if extra links need to be
43 * created.
44 *
45 * This function allocates a links array with enough space to hold at least
46 * 'num_pads' + 'extra_links' elements. The media_entity::max_links field will
47 * be set to the number of allocated elements.
48 *
49 * The pads array is managed by the entity driver and passed to
50 * media_entity_init() where its pointer will be stored in the entity structure.
51 */
52int
53media_entity_init(struct media_entity *entity, u16 num_pads,
54 struct media_pad *pads, u16 extra_links)
55{
56 struct media_link *links;
57 unsigned int max_links = num_pads + extra_links;
58 unsigned int i;
59
60 links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
61 if (links == NULL)
62 return -ENOMEM;
63
64 entity->group_id = 0;
65 entity->max_links = max_links;
66 entity->num_links = 0;
67 entity->num_backlinks = 0;
68 entity->num_pads = num_pads;
69 entity->pads = pads;
70 entity->links = links;
71
72 for (i = 0; i < num_pads; i++) {
73 pads[i].entity = entity;
74 pads[i].index = i;
75 }
76
77 return 0;
78}
79EXPORT_SYMBOL_GPL(media_entity_init);
80
81void
82media_entity_cleanup(struct media_entity *entity)
83{
84 kfree(entity->links);
85}
86EXPORT_SYMBOL_GPL(media_entity_cleanup);
87
88/* -----------------------------------------------------------------------------
89 * Graph traversal
90 */
91
92static struct media_entity *
93media_entity_other(struct media_entity *entity, struct media_link *link)
94{
95 if (link->source->entity == entity)
96 return link->sink->entity;
97 else
98 return link->source->entity;
99}
100
101/* push an entity to traversal stack */
102static void stack_push(struct media_entity_graph *graph,
103 struct media_entity *entity)
104{
105 if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) {
106 WARN_ON(1);
107 return;
108 }
109 graph->top++;
110 graph->stack[graph->top].link = 0;
111 graph->stack[graph->top].entity = entity;
112}
113
114static struct media_entity *stack_pop(struct media_entity_graph *graph)
115{
116 struct media_entity *entity;
117
118 entity = graph->stack[graph->top].entity;
119 graph->top--;
120
121 return entity;
122}
123
124#define stack_peek(en) ((en)->stack[(en)->top - 1].entity)
125#define link_top(en) ((en)->stack[(en)->top].link)
126#define stack_top(en) ((en)->stack[(en)->top].entity)
127
128/**
129 * media_entity_graph_walk_start - Start walking the media graph at a given entity
130 * @graph: Media graph structure that will be used to walk the graph
131 * @entity: Starting entity
132 *
133 * This function initializes the graph traversal structure to walk the entities
134 * graph starting at the given entity. The traversal structure must not be
135 * modified by the caller during graph traversal. When done the structure can
136 * safely be freed.
137 */
138void media_entity_graph_walk_start(struct media_entity_graph *graph,
139 struct media_entity *entity)
140{
141 graph->top = 0;
142 graph->stack[graph->top].entity = NULL;
143 stack_push(graph, entity);
144}
145EXPORT_SYMBOL_GPL(media_entity_graph_walk_start);
146
147/**
148 * media_entity_graph_walk_next - Get the next entity in the graph
149 * @graph: Media graph structure
150 *
151 * Perform a depth-first traversal of the given media entities graph.
152 *
153 * The graph structure must have been previously initialized with a call to
154 * media_entity_graph_walk_start().
155 *
156 * Return the next entity in the graph or NULL if the whole graph have been
157 * traversed.
158 */
159struct media_entity *
160media_entity_graph_walk_next(struct media_entity_graph *graph)
161{
162 if (stack_top(graph) == NULL)
163 return NULL;
164
165 /*
166 * Depth first search. Push entity to stack and continue from
167 * top of the stack until no more entities on the level can be
168 * found.
169 */
170 while (link_top(graph) < stack_top(graph)->num_links) {
171 struct media_entity *entity = stack_top(graph);
172 struct media_link *link = &entity->links[link_top(graph)];
173 struct media_entity *next;
174
175 /* The link is not enabled so we do not follow. */
176 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
177 link_top(graph)++;
178 continue;
179 }
180
181 /* Get the entity in the other end of the link . */
182 next = media_entity_other(entity, link);
183
184 /* Was it the entity we came here from? */
185 if (next == stack_peek(graph)) {
186 link_top(graph)++;
187 continue;
188 }
189
190 /* Push the new entity to stack and start over. */
191 link_top(graph)++;
192 stack_push(graph, next);
193 }
194
195 return stack_pop(graph);
196}
197EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
198
199/* -----------------------------------------------------------------------------
200 * Pipeline management
201 */
202
203/**
204 * media_entity_pipeline_start - Mark a pipeline as streaming
205 * @entity: Starting entity
206 * @pipe: Media pipeline to be assigned to all entities in the pipeline.
207 *
208 * Mark all entities connected to a given entity through enabled links, either
209 * directly or indirectly, as streaming. The given pipeline object is assigned to
210 * every entity in the pipeline and stored in the media_entity pipe field.
211 *
212 * Calls to this function can be nested, in which case the same number of
213 * media_entity_pipeline_stop() calls will be required to stop streaming. The
214 * pipeline pointer must be identical for all nested calls to
215 * media_entity_pipeline_start().
216 */
217void media_entity_pipeline_start(struct media_entity *entity,
218 struct media_pipeline *pipe)
219{
220 struct media_device *mdev = entity->parent;
221 struct media_entity_graph graph;
222
223 mutex_lock(&mdev->graph_mutex);
224
225 media_entity_graph_walk_start(&graph, entity);
226
227 while ((entity = media_entity_graph_walk_next(&graph))) {
228 entity->stream_count++;
229 WARN_ON(entity->pipe && entity->pipe != pipe);
230 entity->pipe = pipe;
231 }
232
233 mutex_unlock(&mdev->graph_mutex);
234}
235EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
236
237/**
238 * media_entity_pipeline_stop - Mark a pipeline as not streaming
239 * @entity: Starting entity
240 *
241 * Mark all entities connected to a given entity through enabled links, either
242 * directly or indirectly, as not streaming. The media_entity pipe field is
243 * reset to NULL.
244 *
245 * If multiple calls to media_entity_pipeline_start() have been made, the same
246 * number of calls to this function are required to mark the pipeline as not
247 * streaming.
248 */
249void media_entity_pipeline_stop(struct media_entity *entity)
250{
251 struct media_device *mdev = entity->parent;
252 struct media_entity_graph graph;
253
254 mutex_lock(&mdev->graph_mutex);
255
256 media_entity_graph_walk_start(&graph, entity);
257
258 while ((entity = media_entity_graph_walk_next(&graph))) {
259 entity->stream_count--;
260 if (entity->stream_count == 0)
261 entity->pipe = NULL;
262 }
263
264 mutex_unlock(&mdev->graph_mutex);
265}
266EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
267
268/* -----------------------------------------------------------------------------
269 * Module use count
270 */
271
272/*
273 * media_entity_get - Get a reference to the parent module
274 * @entity: The entity
275 *
276 * Get a reference to the parent media device module.
277 *
278 * The function will return immediately if @entity is NULL.
279 *
280 * Return a pointer to the entity on success or NULL on failure.
281 */
282struct media_entity *media_entity_get(struct media_entity *entity)
283{
284 if (entity == NULL)
285 return NULL;
286
287 if (entity->parent->dev &&
288 !try_module_get(entity->parent->dev->driver->owner))
289 return NULL;
290
291 return entity;
292}
293EXPORT_SYMBOL_GPL(media_entity_get);
294
295/*
296 * media_entity_put - Release the reference to the parent module
297 * @entity: The entity
298 *
299 * Release the reference count acquired by media_entity_get().
300 *
301 * The function will return immediately if @entity is NULL.
302 */
303void media_entity_put(struct media_entity *entity)
304{
305 if (entity == NULL)
306 return;
307
308 if (entity->parent->dev)
309 module_put(entity->parent->dev->driver->owner);
310}
311EXPORT_SYMBOL_GPL(media_entity_put);
312
313/* -----------------------------------------------------------------------------
314 * Links management
315 */
316
317static struct media_link *media_entity_add_link(struct media_entity *entity)
318{
319 if (entity->num_links >= entity->max_links) {
320 struct media_link *links = entity->links;
321 unsigned int max_links = entity->max_links + 2;
322 unsigned int i;
323
324 links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL);
325 if (links == NULL)
326 return NULL;
327
328 for (i = 0; i < entity->num_links; i++)
329 links[i].reverse->reverse = &links[i];
330
331 entity->max_links = max_links;
332 entity->links = links;
333 }
334
335 return &entity->links[entity->num_links++];
336}
337
338int
339media_entity_create_link(struct media_entity *source, u16 source_pad,
340 struct media_entity *sink, u16 sink_pad, u32 flags)
341{
342 struct media_link *link;
343 struct media_link *backlink;
344
345 BUG_ON(source == NULL || sink == NULL);
346 BUG_ON(source_pad >= source->num_pads);
347 BUG_ON(sink_pad >= sink->num_pads);
348
349 link = media_entity_add_link(source);
350 if (link == NULL)
351 return -ENOMEM;
352
353 link->source = &source->pads[source_pad];
354 link->sink = &sink->pads[sink_pad];
355 link->flags = flags;
356
357 /* Create the backlink. Backlinks are used to help graph traversal and
358 * are not reported to userspace.
359 */
360 backlink = media_entity_add_link(sink);
361 if (backlink == NULL) {
362 source->num_links--;
363 return -ENOMEM;
364 }
365
366 backlink->source = &source->pads[source_pad];
367 backlink->sink = &sink->pads[sink_pad];
368 backlink->flags = flags;
369
370 link->reverse = backlink;
371 backlink->reverse = link;
372
373 sink->num_backlinks++;
374
375 return 0;
376}
377EXPORT_SYMBOL_GPL(media_entity_create_link);
378
379static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
380{
381 const u32 mask = MEDIA_LNK_FL_ENABLED;
382 int ret;
383
384 /* Notify both entities. */
385 ret = media_entity_call(link->source->entity, link_setup,
386 link->source, link->sink, flags);
387 if (ret < 0 && ret != -ENOIOCTLCMD)
388 return ret;
389
390 ret = media_entity_call(link->sink->entity, link_setup,
391 link->sink, link->source, flags);
392 if (ret < 0 && ret != -ENOIOCTLCMD) {
393 media_entity_call(link->source->entity, link_setup,
394 link->source, link->sink, link->flags);
395 return ret;
396 }
397
398 link->flags = (link->flags & ~mask) | (flags & mask);
399 link->reverse->flags = link->flags;
400
401 return 0;
402}
403
404/**
405 * __media_entity_setup_link - Configure a media link
406 * @link: The link being configured
407 * @flags: Link configuration flags
408 *
409 * The bulk of link setup is handled by the two entities connected through the
410 * link. This function notifies both entities of the link configuration change.
411 *
412 * If the link is immutable or if the current and new configuration are
413 * identical, return immediately.
414 *
415 * The user is expected to hold link->source->parent->mutex. If not,
416 * media_entity_setup_link() should be used instead.
417 */
418int __media_entity_setup_link(struct media_link *link, u32 flags)
419{
420 struct media_device *mdev;
421 struct media_entity *source, *sink;
422 int ret = -EBUSY;
423
424 if (link == NULL)
425 return -EINVAL;
426
427 if (link->flags & MEDIA_LNK_FL_IMMUTABLE)
428 return link->flags == flags ? 0 : -EINVAL;
429
430 if (link->flags == flags)
431 return 0;
432
433 source = link->source->entity;
434 sink = link->sink->entity;
435
436 if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
437 (source->stream_count || sink->stream_count))
438 return -EBUSY;
439
440 mdev = source->parent;
441
442 if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
443 ret = mdev->link_notify(link->source, link->sink,
444 MEDIA_LNK_FL_ENABLED);
445 if (ret < 0)
446 return ret;
447 }
448
449 ret = __media_entity_setup_link_notify(link, flags);
450 if (ret < 0)
451 goto err;
452
453 if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
454 mdev->link_notify(link->source, link->sink, 0);
455
456 return 0;
457
458err:
459 if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
460 mdev->link_notify(link->source, link->sink, 0);
461
462 return ret;
463}
464
465int media_entity_setup_link(struct media_link *link, u32 flags)
466{
467 int ret;
468
469 mutex_lock(&link->source->entity->parent->graph_mutex);
470 ret = __media_entity_setup_link(link, flags);
471 mutex_unlock(&link->source->entity->parent->graph_mutex);
472
473 return ret;
474}
475EXPORT_SYMBOL_GPL(media_entity_setup_link);
476
477/**
478 * media_entity_find_link - Find a link between two pads
479 * @source: Source pad
480 * @sink: Sink pad
481 *
482 * Return a pointer to the link between the two entities. If no such link
483 * exists, return NULL.
484 */
485struct media_link *
486media_entity_find_link(struct media_pad *source, struct media_pad *sink)
487{
488 struct media_link *link;
489 unsigned int i;
490
491 for (i = 0; i < source->entity->num_links; ++i) {
492 link = &source->entity->links[i];
493
494 if (link->source->entity == source->entity &&
495 link->source->index == source->index &&
496 link->sink->entity == sink->entity &&
497 link->sink->index == sink->index)
498 return link;
499 }
500
501 return NULL;
502}
503EXPORT_SYMBOL_GPL(media_entity_find_link);
504
505/**
506 * media_entity_remote_source - Find the source pad at the remote end of a link
507 * @pad: Sink pad at the local end of the link
508 *
509 * Search for a remote source pad connected to the given sink pad by iterating
510 * over all links originating or terminating at that pad until an enabled link
511 * is found.
512 *
513 * Return a pointer to the pad at the remote end of the first found enabled
514 * link, or NULL if no enabled link has been found.
515 */
516struct media_pad *media_entity_remote_source(struct media_pad *pad)
517{
518 unsigned int i;
519
520 for (i = 0; i < pad->entity->num_links; i++) {
521 struct media_link *link = &pad->entity->links[i];
522
523 if (!(link->flags & MEDIA_LNK_FL_ENABLED))
524 continue;
525
526 if (link->source == pad)
527 return link->sink;
528
529 if (link->sink == pad)
530 return link->source;
531 }
532
533 return NULL;
534
535}
536EXPORT_SYMBOL_GPL(media_entity_remote_source);
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index ecdffa6aac66..299994c3aa74 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -441,6 +441,7 @@ config RADIO_TIMBERDALE
441config RADIO_WL1273 441config RADIO_WL1273
442 tristate "Texas Instruments WL1273 I2C FM Radio" 442 tristate "Texas Instruments WL1273 I2C FM Radio"
443 depends on I2C && VIDEO_V4L2 443 depends on I2C && VIDEO_V4L2
444 select MFD_CORE
444 select MFD_WL1273_CORE 445 select MFD_WL1273_CORE
445 select FW_LOADER 446 select FW_LOADER
446 ---help--- 447 ---help---
@@ -454,4 +455,7 @@ config RADIO_WL1273
454 To compile this driver as a module, choose M here: the 455 To compile this driver as a module, choose M here: the
455 module will be called radio-wl1273. 456 module will be called radio-wl1273.
456 457
458# TI's ST based wl128x FM radio
459source "drivers/media/radio/wl128x/Kconfig"
460
457endif # RADIO_ADAPTERS 461endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 717656d2f749..2faa33371986 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
26obj-$(CONFIG_RADIO_TEF6862) += tef6862.o 26obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
27obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o 27obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
28obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o 28obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
29obj-$(CONFIG_RADIO_WL128X) += wl128x/
29 30
30EXTRA_CFLAGS += -Isound 31EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index ed9cd7ad0604..3d8cc425fa6b 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -129,7 +129,7 @@ devices, that would be 76 and 91. */
129#define STARTED 0 129#define STARTED 0
130#define STOPPED 1 130#define STOPPED 1
131 131
132#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) 132#define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev)
133 133
134static int usb_dsbr100_probe(struct usb_interface *intf, 134static int usb_dsbr100_probe(struct usb_interface *intf,
135 const struct usb_device_id *id); 135 const struct usb_device_id *id);
@@ -148,10 +148,9 @@ struct dsbr100_device {
148 struct v4l2_device v4l2_dev; 148 struct v4l2_device v4l2_dev;
149 149
150 u8 *transfer_buffer; 150 u8 *transfer_buffer;
151 struct mutex lock; /* buffer locking */ 151 struct mutex v4l2_lock;
152 int curfreq; 152 int curfreq;
153 int stereo; 153 int stereo;
154 int removed;
155 int status; 154 int status;
156}; 155};
157 156
@@ -182,8 +181,6 @@ static int dsbr100_start(struct dsbr100_device *radio)
182 int retval; 181 int retval;
183 int request; 182 int request;
184 183
185 mutex_lock(&radio->lock);
186
187 retval = usb_control_msg(radio->usbdev, 184 retval = usb_control_msg(radio->usbdev,
188 usb_rcvctrlpipe(radio->usbdev, 0), 185 usb_rcvctrlpipe(radio->usbdev, 0),
189 USB_REQ_GET_STATUS, 186 USB_REQ_GET_STATUS,
@@ -207,11 +204,9 @@ static int dsbr100_start(struct dsbr100_device *radio)
207 } 204 }
208 205
209 radio->status = STARTED; 206 radio->status = STARTED;
210 mutex_unlock(&radio->lock);
211 return (radio->transfer_buffer)[0]; 207 return (radio->transfer_buffer)[0];
212 208
213usb_control_msg_failed: 209usb_control_msg_failed:
214 mutex_unlock(&radio->lock);
215 dev_err(&radio->usbdev->dev, 210 dev_err(&radio->usbdev->dev,
216 "%s - usb_control_msg returned %i, request %i\n", 211 "%s - usb_control_msg returned %i, request %i\n",
217 __func__, retval, request); 212 __func__, retval, request);
@@ -225,8 +220,6 @@ static int dsbr100_stop(struct dsbr100_device *radio)
225 int retval; 220 int retval;
226 int request; 221 int request;
227 222
228 mutex_lock(&radio->lock);
229
230 retval = usb_control_msg(radio->usbdev, 223 retval = usb_control_msg(radio->usbdev,
231 usb_rcvctrlpipe(radio->usbdev, 0), 224 usb_rcvctrlpipe(radio->usbdev, 0),
232 USB_REQ_GET_STATUS, 225 USB_REQ_GET_STATUS,
@@ -250,11 +243,9 @@ static int dsbr100_stop(struct dsbr100_device *radio)
250 } 243 }
251 244
252 radio->status = STOPPED; 245 radio->status = STOPPED;
253 mutex_unlock(&radio->lock);
254 return (radio->transfer_buffer)[0]; 246 return (radio->transfer_buffer)[0];
255 247
256usb_control_msg_failed: 248usb_control_msg_failed:
257 mutex_unlock(&radio->lock);
258 dev_err(&radio->usbdev->dev, 249 dev_err(&radio->usbdev->dev,
259 "%s - usb_control_msg returned %i, request %i\n", 250 "%s - usb_control_msg returned %i, request %i\n",
260 __func__, retval, request); 251 __func__, retval, request);
@@ -269,8 +260,6 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
269 int request; 260 int request;
270 int freq = (radio->curfreq / 16 * 80) / 1000 + 856; 261 int freq = (radio->curfreq / 16 * 80) / 1000 + 856;
271 262
272 mutex_lock(&radio->lock);
273
274 retval = usb_control_msg(radio->usbdev, 263 retval = usb_control_msg(radio->usbdev,
275 usb_rcvctrlpipe(radio->usbdev, 0), 264 usb_rcvctrlpipe(radio->usbdev, 0),
276 DSB100_TUNE, 265 DSB100_TUNE,
@@ -306,12 +295,10 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
306 } 295 }
307 296
308 radio->stereo = !((radio->transfer_buffer)[0] & 0x01); 297 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
309 mutex_unlock(&radio->lock);
310 return (radio->transfer_buffer)[0]; 298 return (radio->transfer_buffer)[0];
311 299
312usb_control_msg_failed: 300usb_control_msg_failed:
313 radio->stereo = -1; 301 radio->stereo = -1;
314 mutex_unlock(&radio->lock);
315 dev_err(&radio->usbdev->dev, 302 dev_err(&radio->usbdev->dev,
316 "%s - usb_control_msg returned %i, request %i\n", 303 "%s - usb_control_msg returned %i, request %i\n",
317 __func__, retval, request); 304 __func__, retval, request);
@@ -324,8 +311,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
324{ 311{
325 int retval; 312 int retval;
326 313
327 mutex_lock(&radio->lock);
328
329 retval = usb_control_msg(radio->usbdev, 314 retval = usb_control_msg(radio->usbdev,
330 usb_rcvctrlpipe(radio->usbdev, 0), 315 usb_rcvctrlpipe(radio->usbdev, 0),
331 USB_REQ_GET_STATUS, 316 USB_REQ_GET_STATUS,
@@ -340,33 +325,8 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
340 } else { 325 } else {
341 radio->stereo = !(radio->transfer_buffer[0] & 0x01); 326 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
342 } 327 }
343
344 mutex_unlock(&radio->lock);
345} 328}
346 329
347/* USB subsystem interface begins here */
348
349/*
350 * Handle unplugging of the device.
351 * We call video_unregister_device in any case.
352 * The last function called in this procedure is
353 * usb_dsbr100_video_device_release
354 */
355static void usb_dsbr100_disconnect(struct usb_interface *intf)
356{
357 struct dsbr100_device *radio = usb_get_intfdata(intf);
358
359 usb_set_intfdata (intf, NULL);
360
361 mutex_lock(&radio->lock);
362 radio->removed = 1;
363 mutex_unlock(&radio->lock);
364
365 video_unregister_device(&radio->videodev);
366 v4l2_device_disconnect(&radio->v4l2_dev);
367}
368
369
370static int vidioc_querycap(struct file *file, void *priv, 330static int vidioc_querycap(struct file *file, void *priv,
371 struct v4l2_capability *v) 331 struct v4l2_capability *v)
372{ 332{
@@ -385,10 +345,6 @@ static int vidioc_g_tuner(struct file *file, void *priv,
385{ 345{
386 struct dsbr100_device *radio = video_drvdata(file); 346 struct dsbr100_device *radio = video_drvdata(file);
387 347
388 /* safety check */
389 if (radio->removed)
390 return -EIO;
391
392 if (v->index > 0) 348 if (v->index > 0)
393 return -EINVAL; 349 return -EINVAL;
394 350
@@ -410,16 +366,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
410static int vidioc_s_tuner(struct file *file, void *priv, 366static int vidioc_s_tuner(struct file *file, void *priv,
411 struct v4l2_tuner *v) 367 struct v4l2_tuner *v)
412{ 368{
413 struct dsbr100_device *radio = video_drvdata(file); 369 return v->index ? -EINVAL : 0;
414
415 /* safety check */
416 if (radio->removed)
417 return -EIO;
418
419 if (v->index > 0)
420 return -EINVAL;
421
422 return 0;
423} 370}
424 371
425static int vidioc_s_frequency(struct file *file, void *priv, 372static int vidioc_s_frequency(struct file *file, void *priv,
@@ -428,13 +375,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
428 struct dsbr100_device *radio = video_drvdata(file); 375 struct dsbr100_device *radio = video_drvdata(file);
429 int retval; 376 int retval;
430 377
431 /* safety check */
432 if (radio->removed)
433 return -EIO;
434
435 mutex_lock(&radio->lock);
436 radio->curfreq = f->frequency; 378 radio->curfreq = f->frequency;
437 mutex_unlock(&radio->lock);
438 379
439 retval = dsbr100_setfreq(radio); 380 retval = dsbr100_setfreq(radio);
440 if (retval < 0) 381 if (retval < 0)
@@ -447,10 +388,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
447{ 388{
448 struct dsbr100_device *radio = video_drvdata(file); 389 struct dsbr100_device *radio = video_drvdata(file);
449 390
450 /* safety check */
451 if (radio->removed)
452 return -EIO;
453
454 f->type = V4L2_TUNER_RADIO; 391 f->type = V4L2_TUNER_RADIO;
455 f->frequency = radio->curfreq; 392 f->frequency = radio->curfreq;
456 return 0; 393 return 0;
@@ -472,10 +409,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
472{ 409{
473 struct dsbr100_device *radio = video_drvdata(file); 410 struct dsbr100_device *radio = video_drvdata(file);
474 411
475 /* safety check */
476 if (radio->removed)
477 return -EIO;
478
479 switch (ctrl->id) { 412 switch (ctrl->id) {
480 case V4L2_CID_AUDIO_MUTE: 413 case V4L2_CID_AUDIO_MUTE:
481 ctrl->value = radio->status; 414 ctrl->value = radio->status;
@@ -490,10 +423,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
490 struct dsbr100_device *radio = video_drvdata(file); 423 struct dsbr100_device *radio = video_drvdata(file);
491 int retval; 424 int retval;
492 425
493 /* safety check */
494 if (radio->removed)
495 return -EIO;
496
497 switch (ctrl->id) { 426 switch (ctrl->id) {
498 case V4L2_CID_AUDIO_MUTE: 427 case V4L2_CID_AUDIO_MUTE:
499 if (ctrl->value) { 428 if (ctrl->value) {
@@ -535,25 +464,44 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
535 464
536static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 465static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
537{ 466{
538 if (i != 0) 467 return i ? -EINVAL : 0;
539 return -EINVAL;
540 return 0;
541} 468}
542 469
543static int vidioc_s_audio(struct file *file, void *priv, 470static int vidioc_s_audio(struct file *file, void *priv,
544 struct v4l2_audio *a) 471 struct v4l2_audio *a)
545{ 472{
546 if (a->index != 0) 473 return a->index ? -EINVAL : 0;
547 return -EINVAL; 474}
548 return 0; 475
476/* USB subsystem interface begins here */
477
478/*
479 * Handle unplugging of the device.
480 * We call video_unregister_device in any case.
481 * The last function called in this procedure is
482 * usb_dsbr100_video_device_release
483 */
484static void usb_dsbr100_disconnect(struct usb_interface *intf)
485{
486 struct dsbr100_device *radio = usb_get_intfdata(intf);
487
488 v4l2_device_get(&radio->v4l2_dev);
489 mutex_lock(&radio->v4l2_lock);
490 usb_set_intfdata(intf, NULL);
491 video_unregister_device(&radio->videodev);
492 v4l2_device_disconnect(&radio->v4l2_dev);
493 mutex_unlock(&radio->v4l2_lock);
494 v4l2_device_put(&radio->v4l2_dev);
549} 495}
550 496
497
551/* Suspend device - stop device. */ 498/* Suspend device - stop device. */
552static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) 499static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
553{ 500{
554 struct dsbr100_device *radio = usb_get_intfdata(intf); 501 struct dsbr100_device *radio = usb_get_intfdata(intf);
555 int retval; 502 int retval;
556 503
504 mutex_lock(&radio->v4l2_lock);
557 if (radio->status == STARTED) { 505 if (radio->status == STARTED) {
558 retval = dsbr100_stop(radio); 506 retval = dsbr100_stop(radio);
559 if (retval < 0) 507 if (retval < 0)
@@ -564,11 +512,9 @@ static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
564 * we set status equal to STARTED. 512 * we set status equal to STARTED.
565 * On resume we will check status and run radio if needed. 513 * On resume we will check status and run radio if needed.
566 */ 514 */
567
568 mutex_lock(&radio->lock);
569 radio->status = STARTED; 515 radio->status = STARTED;
570 mutex_unlock(&radio->lock);
571 } 516 }
517 mutex_unlock(&radio->v4l2_lock);
572 518
573 dev_info(&intf->dev, "going into suspend..\n"); 519 dev_info(&intf->dev, "going into suspend..\n");
574 520
@@ -581,11 +527,13 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
581 struct dsbr100_device *radio = usb_get_intfdata(intf); 527 struct dsbr100_device *radio = usb_get_intfdata(intf);
582 int retval; 528 int retval;
583 529
530 mutex_lock(&radio->v4l2_lock);
584 if (radio->status == STARTED) { 531 if (radio->status == STARTED) {
585 retval = dsbr100_start(radio); 532 retval = dsbr100_start(radio);
586 if (retval < 0) 533 if (retval < 0)
587 dev_warn(&intf->dev, "dsbr100_start failed\n"); 534 dev_warn(&intf->dev, "dsbr100_start failed\n");
588 } 535 }
536 mutex_unlock(&radio->v4l2_lock);
589 537
590 dev_info(&intf->dev, "coming out of suspend..\n"); 538 dev_info(&intf->dev, "coming out of suspend..\n");
591 539
@@ -593,9 +541,9 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
593} 541}
594 542
595/* free data structures */ 543/* free data structures */
596static void usb_dsbr100_video_device_release(struct video_device *videodev) 544static void usb_dsbr100_release(struct v4l2_device *v4l2_dev)
597{ 545{
598 struct dsbr100_device *radio = videodev_to_radio(videodev); 546 struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev);
599 547
600 v4l2_device_unregister(&radio->v4l2_dev); 548 v4l2_device_unregister(&radio->v4l2_dev);
601 kfree(radio->transfer_buffer); 549 kfree(radio->transfer_buffer);
@@ -605,7 +553,7 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev)
605/* File system interface */ 553/* File system interface */
606static const struct v4l2_file_operations usb_dsbr100_fops = { 554static const struct v4l2_file_operations usb_dsbr100_fops = {
607 .owner = THIS_MODULE, 555 .owner = THIS_MODULE,
608 .ioctl = video_ioctl2, 556 .unlocked_ioctl = video_ioctl2,
609}; 557};
610 558
611static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { 559static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
@@ -644,6 +592,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
644 } 592 }
645 593
646 v4l2_dev = &radio->v4l2_dev; 594 v4l2_dev = &radio->v4l2_dev;
595 v4l2_dev->release = usb_dsbr100_release;
647 596
648 retval = v4l2_device_register(&intf->dev, v4l2_dev); 597 retval = v4l2_device_register(&intf->dev, v4l2_dev);
649 if (retval < 0) { 598 if (retval < 0) {
@@ -653,15 +602,14 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
653 return retval; 602 return retval;
654 } 603 }
655 604
605 mutex_init(&radio->v4l2_lock);
656 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name)); 606 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
657 radio->videodev.v4l2_dev = v4l2_dev; 607 radio->videodev.v4l2_dev = v4l2_dev;
658 radio->videodev.fops = &usb_dsbr100_fops; 608 radio->videodev.fops = &usb_dsbr100_fops;
659 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops; 609 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
660 radio->videodev.release = usb_dsbr100_video_device_release; 610 radio->videodev.release = video_device_release_empty;
661 611 radio->videodev.lock = &radio->v4l2_lock;
662 mutex_init(&radio->lock);
663 612
664 radio->removed = 0;
665 radio->usbdev = interface_to_usbdev(intf); 613 radio->usbdev = interface_to_usbdev(intf);
666 radio->curfreq = FREQ_MIN * FREQ_MUL; 614 radio->curfreq = FREQ_MIN * FREQ_MUL;
667 radio->status = STOPPED; 615 radio->status = STOPPED;
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 726d367ad8d0..444b4cf7e65c 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -224,7 +224,8 @@ static int radio_si4713_s_frequency(struct file *file, void *p,
224 s_frequency, vf); 224 s_frequency, vf);
225} 225}
226 226
227static long radio_si4713_default(struct file *file, void *p, int cmd, void *arg) 227static long radio_si4713_default(struct file *file, void *p,
228 bool valid_prio, int cmd, void *arg)
228{ 229{
229 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core, 230 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
230 ioctl, cmd, arg); 231 ioctl, cmd, arg);
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index a185610b376b..1e3a8dd820a4 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -21,6 +21,7 @@
21#include <media/v4l2-ioctl.h> 21#include <media/v4l2-ioctl.h>
22#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/mfd/core.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/i2c.h> 27#include <linux/i2c.h>
@@ -148,7 +149,7 @@ static const struct v4l2_file_operations timbradio_fops = {
148 149
149static int __devinit timbradio_probe(struct platform_device *pdev) 150static int __devinit timbradio_probe(struct platform_device *pdev)
150{ 151{
151 struct timb_radio_platform_data *pdata = pdev->dev.platform_data; 152 struct timb_radio_platform_data *pdata = mfd_get_data(pdev);
152 struct timbradio *tr; 153 struct timbradio *tr;
153 int err; 154 int err;
154 155
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index 7ecc8e657663..e2550dc2944f 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Texas Instruments WL1273 FM radio. 2 * Driver for the Texas Instruments WL1273 FM radio.
3 * 3 *
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2011 Nokia Corporation
5 * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com> 5 * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
@@ -67,7 +67,6 @@ struct wl1273_device {
67 67
68 /* RDS */ 68 /* RDS */
69 unsigned int rds_on; 69 unsigned int rds_on;
70 struct delayed_work work;
71 70
72 wait_queue_head_t read_queue; 71 wait_queue_head_t read_queue;
73 struct mutex lock; /* for serializing fm radio operations */ 72 struct mutex lock; /* for serializing fm radio operations */
@@ -104,58 +103,6 @@ static unsigned int rds_buf = 100;
104module_param(rds_buf, uint, 0); 103module_param(rds_buf, uint, 0);
105MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100"); 104MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100");
106 105
107static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
108{
109 struct i2c_client *client = core->client;
110 u8 b[2];
111 int r;
112
113 r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
114 if (r != 2) {
115 dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
116 return -EREMOTEIO;
117 }
118
119 *value = (u16)b[0] << 8 | b[1];
120
121 return 0;
122}
123
124static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
125{
126 struct i2c_client *client = core->client;
127 u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
128 int r;
129
130 r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
131 if (r) {
132 dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
133 return r;
134 }
135
136 return 0;
137}
138
139static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
140{
141 struct i2c_client *client = core->client;
142 struct i2c_msg msg;
143 int r;
144
145 msg.addr = client->addr;
146 msg.flags = 0;
147 msg.buf = data;
148 msg.len = len;
149
150 r = i2c_transfer(client->adapter, &msg, 1);
151 if (r != 1) {
152 dev_err(&client->dev, "%s: write error.\n", __func__);
153 return -EREMOTEIO;
154 }
155
156 return 0;
157}
158
159static int wl1273_fm_write_fw(struct wl1273_core *core, 106static int wl1273_fm_write_fw(struct wl1273_core *core,
160 __u8 *fw, int len) 107 __u8 *fw, int len)
161{ 108{
@@ -188,94 +135,6 @@ static int wl1273_fm_write_fw(struct wl1273_core *core,
188 return r; 135 return r;
189} 136}
190 137
191/**
192 * wl1273_fm_set_audio() - Set audio mode.
193 * @core: A pointer to the device struct.
194 * @new_mode: The new audio mode.
195 *
196 * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
197 */
198static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
199{
200 int r = 0;
201
202 if (core->mode == WL1273_MODE_OFF ||
203 core->mode == WL1273_MODE_SUSPENDED)
204 return -EPERM;
205
206 if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
207 r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
208 WL1273_PCM_DEF_MODE);
209 if (r)
210 goto out;
211
212 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
213 core->i2s_mode);
214 if (r)
215 goto out;
216
217 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
218 WL1273_AUDIO_ENABLE_I2S);
219 if (r)
220 goto out;
221
222 } else if (core->mode == WL1273_MODE_RX &&
223 new_mode == WL1273_AUDIO_ANALOG) {
224 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
225 WL1273_AUDIO_ENABLE_ANALOG);
226 if (r)
227 goto out;
228
229 } else if (core->mode == WL1273_MODE_TX &&
230 new_mode == WL1273_AUDIO_DIGITAL) {
231 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
232 core->i2s_mode);
233 if (r)
234 goto out;
235
236 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
237 WL1273_AUDIO_IO_SET_I2S);
238 if (r)
239 goto out;
240
241 } else if (core->mode == WL1273_MODE_TX &&
242 new_mode == WL1273_AUDIO_ANALOG) {
243 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
244 WL1273_AUDIO_IO_SET_ANALOG);
245 if (r)
246 goto out;
247 }
248
249 core->audio_mode = new_mode;
250out:
251 return r;
252}
253
254/**
255 * wl1273_fm_set_volume() - Set volume.
256 * @core: A pointer to the device struct.
257 * @volume: The new volume value.
258 */
259static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
260{
261 u16 val;
262 int r;
263
264 if (volume > WL1273_MAX_VOLUME)
265 return -EINVAL;
266
267 if (core->volume == volume)
268 return 0;
269
270 val = volume;
271 r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val);
272 if (r)
273 return r;
274
275 core->volume = volume;
276 return 0;
277}
278
279#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status) 138#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status)
280#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3) 139#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3)
281#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4) 140#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4)
@@ -306,7 +165,7 @@ static int wl1273_fm_rds(struct wl1273_device *radio)
306 if (core->mode != WL1273_MODE_RX) 165 if (core->mode != WL1273_MODE_RX)
307 return 0; 166 return 0;
308 167
309 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 168 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
310 if (r) 169 if (r)
311 return r; 170 return r;
312 171
@@ -374,7 +233,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
374 u16 flags; 233 u16 flags;
375 int r; 234 int r;
376 235
377 r = wl1273_fm_read_reg(core, WL1273_FLAG_GET, &flags); 236 r = core->read(core, WL1273_FLAG_GET, &flags);
378 if (r) 237 if (r)
379 goto out; 238 goto out;
380 239
@@ -398,7 +257,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
398 if (flags & WL1273_LEV_EVENT) { 257 if (flags & WL1273_LEV_EVENT) {
399 u16 level; 258 u16 level;
400 259
401 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &level); 260 r = core->read(core, WL1273_RSSI_LVL_GET, &level);
402 if (r) 261 if (r)
403 goto out; 262 goto out;
404 263
@@ -439,8 +298,8 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
439 dev_dbg(radio->dev, "IRQ: FR:\n"); 298 dev_dbg(radio->dev, "IRQ: FR:\n");
440 299
441 if (core->mode == WL1273_MODE_RX) { 300 if (core->mode == WL1273_MODE_RX) {
442 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 301 r = core->write(core, WL1273_TUNER_MODE_SET,
443 TUNER_MODE_STOP_SEARCH); 302 TUNER_MODE_STOP_SEARCH);
444 if (r) { 303 if (r) {
445 dev_err(radio->dev, 304 dev_err(radio->dev,
446 "%s: TUNER_MODE_SET fails: %d\n", 305 "%s: TUNER_MODE_SET fails: %d\n",
@@ -448,7 +307,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
448 goto out; 307 goto out;
449 } 308 }
450 309
451 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &freq); 310 r = core->read(core, WL1273_FREQ_SET, &freq);
452 if (r) 311 if (r)
453 goto out; 312 goto out;
454 313
@@ -467,7 +326,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
467 dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency); 326 dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency);
468 327
469 } else { 328 } else {
470 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &freq); 329 r = core->read(core, WL1273_CHANL_SET, &freq);
471 if (r) 330 if (r)
472 goto out; 331 goto out;
473 332
@@ -477,8 +336,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
477 } 336 }
478 337
479out: 338out:
480 wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 339 core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
481 radio->irq_flags);
482 complete(&radio->busy); 340 complete(&radio->busy);
483 341
484 return IRQ_HANDLED; 342 return IRQ_HANDLED;
@@ -512,7 +370,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
512 dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq); 370 dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq);
513 371
514 /* Set the current tx channel */ 372 /* Set the current tx channel */
515 r = wl1273_fm_write_cmd(core, WL1273_CHANL_SET, freq / 10); 373 r = core->write(core, WL1273_CHANL_SET, freq / 10);
516 if (r) 374 if (r)
517 return r; 375 return r;
518 376
@@ -526,7 +384,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
526 dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r); 384 dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r);
527 385
528 /* Enable the output power */ 386 /* Enable the output power */
529 r = wl1273_fm_write_cmd(core, WL1273_POWER_ENB_SET, 1); 387 r = core->write(core, WL1273_POWER_ENB_SET, 1);
530 if (r) 388 if (r)
531 return r; 389 return r;
532 390
@@ -566,20 +424,20 @@ static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq)
566 424
567 dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq); 425 dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq);
568 426
569 wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 427 core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
570 428
571 if (radio->band == WL1273_BAND_JAPAN) 429 if (radio->band == WL1273_BAND_JAPAN)
572 f = (freq - WL1273_BAND_JAPAN_LOW) / 50; 430 f = (freq - WL1273_BAND_JAPAN_LOW) / 50;
573 else 431 else
574 f = (freq - WL1273_BAND_OTHER_LOW) / 50; 432 f = (freq - WL1273_BAND_OTHER_LOW) / 50;
575 433
576 r = wl1273_fm_write_cmd(core, WL1273_FREQ_SET, f); 434 r = core->write(core, WL1273_FREQ_SET, f);
577 if (r) { 435 if (r) {
578 dev_err(radio->dev, "FREQ_SET fails\n"); 436 dev_err(radio->dev, "FREQ_SET fails\n");
579 goto err; 437 goto err;
580 } 438 }
581 439
582 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET); 440 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);
583 if (r) { 441 if (r) {
584 dev_err(radio->dev, "TUNER_MODE_SET fails\n"); 442 dev_err(radio->dev, "TUNER_MODE_SET fails\n");
585 goto err; 443 goto err;
@@ -609,7 +467,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
609 int r; 467 int r;
610 468
611 if (core->mode == WL1273_MODE_RX) { 469 if (core->mode == WL1273_MODE_RX) {
612 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &f); 470 r = core->read(core, WL1273_FREQ_SET, &f);
613 if (r) 471 if (r)
614 return r; 472 return r;
615 473
@@ -619,7 +477,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
619 else 477 else
620 freq = WL1273_BAND_OTHER_LOW + 50 * f; 478 freq = WL1273_BAND_OTHER_LOW + 50 * f;
621 } else { 479 } else {
622 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &f); 480 r = core->read(core, WL1273_CHANL_SET, &f);
623 if (r) 481 if (r)
624 return r; 482 return r;
625 483
@@ -670,7 +528,7 @@ static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio)
670 } 528 }
671 529
672 /* ignore possible error here */ 530 /* ignore possible error here */
673 wl1273_fm_write_cmd(core, WL1273_RESET, 0); 531 core->write(core, WL1273_RESET, 0);
674 532
675 dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r); 533 dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r);
676out: 534out:
@@ -683,14 +541,14 @@ static int wl1273_fm_stop(struct wl1273_device *radio)
683 struct wl1273_core *core = radio->core; 541 struct wl1273_core *core = radio->core;
684 542
685 if (core->mode == WL1273_MODE_RX) { 543 if (core->mode == WL1273_MODE_RX) {
686 int r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 544 int r = core->write(core, WL1273_POWER_SET,
687 WL1273_POWER_SET_OFF); 545 WL1273_POWER_SET_OFF);
688 if (r) 546 if (r)
689 dev_err(radio->dev, "%s: POWER_SET fails: %d\n", 547 dev_err(radio->dev, "%s: POWER_SET fails: %d\n",
690 __func__, r); 548 __func__, r);
691 } else if (core->mode == WL1273_MODE_TX) { 549 } else if (core->mode == WL1273_MODE_TX) {
692 int r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 550 int r = core->write(core, WL1273_PUPD_SET,
693 WL1273_PUPD_SET_OFF); 551 WL1273_PUPD_SET_OFF);
694 if (r) 552 if (r)
695 dev_err(radio->dev, 553 dev_err(radio->dev,
696 "%s: PUPD_SET fails: %d\n", __func__, r); 554 "%s: PUPD_SET fails: %d\n", __func__, r);
@@ -725,11 +583,11 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
725 val |= WL1273_POWER_SET_RDS; 583 val |= WL1273_POWER_SET_RDS;
726 584
727 /* If this fails try again */ 585 /* If this fails try again */
728 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 586 r = core->write(core, WL1273_POWER_SET, val);
729 if (r) { 587 if (r) {
730 msleep(100); 588 msleep(100);
731 589
732 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 590 r = core->write(core, WL1273_POWER_SET, val);
733 if (r) { 591 if (r) {
734 dev_err(dev, "%s: POWER_SET fails\n", __func__); 592 dev_err(dev, "%s: POWER_SET fails\n", __func__);
735 goto fail; 593 goto fail;
@@ -742,11 +600,10 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
742 600
743 } else if (new_mode == WL1273_MODE_TX) { 601 } else if (new_mode == WL1273_MODE_TX) {
744 /* If this fails try again once */ 602 /* If this fails try again once */
745 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 603 r = core->write(core, WL1273_PUPD_SET, WL1273_PUPD_SET_ON);
746 WL1273_PUPD_SET_ON);
747 if (r) { 604 if (r) {
748 msleep(100); 605 msleep(100);
749 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 606 r = core->write(core, WL1273_PUPD_SET,
750 WL1273_PUPD_SET_ON); 607 WL1273_PUPD_SET_ON);
751 if (r) { 608 if (r) {
752 dev_err(dev, "%s: PUPD_SET fails\n", __func__); 609 dev_err(dev, "%s: PUPD_SET fails\n", __func__);
@@ -755,9 +612,9 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
755 } 612 }
756 613
757 if (radio->rds_on) 614 if (radio->rds_on)
758 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1); 615 r = core->write(core, WL1273_RDS_DATA_ENB, 1);
759 else 616 else
760 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0); 617 r = core->write(core, WL1273_RDS_DATA_ENB, 0);
761 } else { 618 } else {
762 dev_warn(dev, "%s: Illegal mode.\n", __func__); 619 dev_warn(dev, "%s: Illegal mode.\n", __func__);
763 } 620 }
@@ -777,14 +634,14 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
777 if (radio->rds_on) 634 if (radio->rds_on)
778 val |= WL1273_POWER_SET_RDS; 635 val |= WL1273_POWER_SET_RDS;
779 636
780 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 637 r = core->write(core, WL1273_POWER_SET, val);
781 if (r) { 638 if (r) {
782 dev_err(dev, "%s: POWER_SET fails\n", __func__); 639 dev_err(dev, "%s: POWER_SET fails\n", __func__);
783 goto fail; 640 goto fail;
784 } 641 }
785 } else if (new_mode == WL1273_MODE_TX) { 642 } else if (new_mode == WL1273_MODE_TX) {
786 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 643 r = core->write(core, WL1273_PUPD_SET,
787 WL1273_PUPD_SET_ON); 644 WL1273_PUPD_SET_ON);
788 if (r) { 645 if (r) {
789 dev_err(dev, "%s: PUPD_SET fails\n", __func__); 646 dev_err(dev, "%s: PUPD_SET fails\n", __func__);
790 goto fail; 647 goto fail;
@@ -808,10 +665,10 @@ static int wl1273_fm_suspend(struct wl1273_device *radio)
808 665
809 /* Cannot go from OFF to SUSPENDED */ 666 /* Cannot go from OFF to SUSPENDED */
810 if (core->mode == WL1273_MODE_RX) 667 if (core->mode == WL1273_MODE_RX)
811 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 668 r = core->write(core, WL1273_POWER_SET,
812 WL1273_POWER_SET_RETENTION); 669 WL1273_POWER_SET_RETENTION);
813 else if (core->mode == WL1273_MODE_TX) 670 else if (core->mode == WL1273_MODE_TX)
814 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 671 r = core->write(core, WL1273_PUPD_SET,
815 WL1273_PUPD_SET_RETENTION); 672 WL1273_PUPD_SET_RETENTION);
816 else 673 else
817 r = -EINVAL; 674 r = -EINVAL;
@@ -852,8 +709,7 @@ static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode)
852 } 709 }
853 710
854 core->mode = mode; 711 core->mode = mode;
855 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 712 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
856 radio->irq_flags);
857 if (r) { 713 if (r) {
858 dev_err(dev, "INT_MASK_SET fails.\n"); 714 dev_err(dev, "INT_MASK_SET fails.\n");
859 goto out; 715 goto out;
@@ -951,22 +807,21 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
951 INIT_COMPLETION(radio->busy); 807 INIT_COMPLETION(radio->busy);
952 dev_dbg(radio->dev, "%s: BUSY\n", __func__); 808 dev_dbg(radio->dev, "%s: BUSY\n", __func__);
953 809
954 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 810 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
955 if (r) 811 if (r)
956 goto out; 812 goto out;
957 813
958 dev_dbg(radio->dev, "%s\n", __func__); 814 dev_dbg(radio->dev, "%s\n", __func__);
959 815
960 r = wl1273_fm_write_cmd(core, WL1273_SEARCH_LVL_SET, level); 816 r = core->write(core, WL1273_SEARCH_LVL_SET, level);
961 if (r) 817 if (r)
962 goto out; 818 goto out;
963 819
964 r = wl1273_fm_write_cmd(core, WL1273_SEARCH_DIR_SET, dir); 820 r = core->write(core, WL1273_SEARCH_DIR_SET, dir);
965 if (r) 821 if (r)
966 goto out; 822 goto out;
967 823
968 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 824 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
969 TUNER_MODE_AUTO_SEEK);
970 if (r) 825 if (r)
971 goto out; 826 goto out;
972 827
@@ -994,8 +849,7 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
994 INIT_COMPLETION(radio->busy); 849 INIT_COMPLETION(radio->busy);
995 dev_dbg(radio->dev, "%s: BUSY\n", __func__); 850 dev_dbg(radio->dev, "%s: BUSY\n", __func__);
996 851
997 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 852 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
998 TUNER_MODE_AUTO_SEEK);
999 if (r) 853 if (r)
1000 goto out; 854 goto out;
1001 855
@@ -1020,7 +874,7 @@ static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio)
1020 core->mode == WL1273_MODE_SUSPENDED) 874 core->mode == WL1273_MODE_SUSPENDED)
1021 return -EPERM; 875 return -EPERM;
1022 876
1023 r = wl1273_fm_read_reg(core, WL1273_READ_FMANT_TUNE_VALUE, &val); 877 r = core->read(core, WL1273_READ_FMANT_TUNE_VALUE, &val);
1024 if (r) { 878 if (r) {
1025 dev_err(dev, "%s: read error: %d\n", __func__, r); 879 dev_err(dev, "%s: read error: %d\n", __func__, r);
1026 goto out; 880 goto out;
@@ -1066,7 +920,7 @@ static int wl1273_fm_set_preemphasis(struct wl1273_device *radio,
1066 goto out; 920 goto out;
1067 } 921 }
1068 922
1069 r = wl1273_fm_write_cmd(core, WL1273_PREMPH_SET, em); 923 r = core->write(core, WL1273_PREMPH_SET, em);
1070 if (r) 924 if (r)
1071 goto out; 925 goto out;
1072 926
@@ -1086,7 +940,7 @@ static int wl1273_fm_rds_on(struct wl1273_device *radio)
1086 if (radio->rds_on) 940 if (radio->rds_on)
1087 return 0; 941 return 0;
1088 942
1089 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 943 r = core->write(core, WL1273_POWER_SET,
1090 WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS); 944 WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS);
1091 if (r) 945 if (r)
1092 goto out; 946 goto out;
@@ -1108,19 +962,16 @@ static int wl1273_fm_rds_off(struct wl1273_device *radio)
1108 962
1109 radio->irq_flags &= ~WL1273_RDS_EVENT; 963 radio->irq_flags &= ~WL1273_RDS_EVENT;
1110 964
1111 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 965 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
1112 if (r) 966 if (r)
1113 goto out; 967 goto out;
1114 968
1115 /* stop rds reception */
1116 cancel_delayed_work(&radio->work);
1117
1118 /* Service pending read */ 969 /* Service pending read */
1119 wake_up_interruptible(&radio->read_queue); 970 wake_up_interruptible(&radio->read_queue);
1120 971
1121 dev_dbg(radio->dev, "%s\n", __func__); 972 dev_dbg(radio->dev, "%s\n", __func__);
1122 973
1123 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, WL1273_POWER_SET_FM); 974 r = core->write(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);
1124 if (r) 975 if (r)
1125 goto out; 976 goto out;
1126 977
@@ -1143,14 +994,14 @@ static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new_mode)
1143 return -EPERM; 994 return -EPERM;
1144 995
1145 if (new_mode == WL1273_RDS_RESET) { 996 if (new_mode == WL1273_RDS_RESET) {
1146 r = wl1273_fm_write_cmd(core, WL1273_RDS_CNTRL_SET, 1); 997 r = core->write(core, WL1273_RDS_CNTRL_SET, 1);
1147 return r; 998 return r;
1148 } 999 }
1149 1000
1150 if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) { 1001 if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) {
1151 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0); 1002 r = core->write(core, WL1273_RDS_DATA_ENB, 0);
1152 } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) { 1003 } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) {
1153 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1); 1004 r = core->write(core, WL1273_RDS_DATA_ENB, 1);
1154 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) { 1005 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) {
1155 r = wl1273_fm_rds_off(radio); 1006 r = wl1273_fm_rds_off(radio);
1156 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) { 1007 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) {
@@ -1171,12 +1022,13 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1171 size_t count, loff_t *ppos) 1022 size_t count, loff_t *ppos)
1172{ 1023{
1173 struct wl1273_device *radio = video_get_drvdata(video_devdata(file)); 1024 struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
1025 struct wl1273_core *core = radio->core;
1174 u16 val; 1026 u16 val;
1175 int r; 1027 int r;
1176 1028
1177 dev_dbg(radio->dev, "%s\n", __func__); 1029 dev_dbg(radio->dev, "%s\n", __func__);
1178 1030
1179 if (radio->core->mode != WL1273_MODE_TX) 1031 if (core->mode != WL1273_MODE_TX)
1180 return count; 1032 return count;
1181 1033
1182 if (radio->rds_users == 0) { 1034 if (radio->rds_users == 0) {
@@ -1184,7 +1036,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1184 return 0; 1036 return 0;
1185 } 1037 }
1186 1038
1187 if (mutex_lock_interruptible(&radio->core->lock)) 1039 if (mutex_lock_interruptible(&core->lock))
1188 return -EINTR; 1040 return -EINTR;
1189 /* 1041 /*
1190 * Multiple processes can open the device, but only 1042 * Multiple processes can open the device, but only
@@ -1202,7 +1054,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1202 else 1054 else
1203 val = count; 1055 val = count;
1204 1056
1205 wl1273_fm_write_cmd(radio->core, WL1273_RDS_CONFIG_DATA_SET, val); 1057 core->write(core, WL1273_RDS_CONFIG_DATA_SET, val);
1206 1058
1207 if (copy_from_user(radio->write_buf + 1, buf, val)) { 1059 if (copy_from_user(radio->write_buf + 1, buf, val)) {
1208 r = -EFAULT; 1060 r = -EFAULT;
@@ -1213,11 +1065,11 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1213 dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf); 1065 dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf);
1214 1066
1215 radio->write_buf[0] = WL1273_RDS_DATA_SET; 1067 radio->write_buf[0] = WL1273_RDS_DATA_SET;
1216 wl1273_fm_write_data(radio->core, radio->write_buf, val + 1); 1068 core->write_data(core, radio->write_buf, val + 1);
1217 1069
1218 r = val; 1070 r = val;
1219out: 1071out:
1220 mutex_unlock(&radio->core->lock); 1072 mutex_unlock(&core->lock);
1221 1073
1222 return r; 1074 return r;
1223} 1075}
@@ -1263,8 +1115,8 @@ static int wl1273_fm_fops_open(struct file *file)
1263 1115
1264 radio->irq_flags |= WL1273_RDS_EVENT; 1116 radio->irq_flags |= WL1273_RDS_EVENT;
1265 1117
1266 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 1118 r = core->write(core, WL1273_INT_MASK_SET,
1267 radio->irq_flags); 1119 radio->irq_flags);
1268 if (r) { 1120 if (r) {
1269 mutex_unlock(&core->lock); 1121 mutex_unlock(&core->lock);
1270 goto out; 1122 goto out;
@@ -1295,9 +1147,9 @@ static int wl1273_fm_fops_release(struct file *file)
1295 radio->irq_flags &= ~WL1273_RDS_EVENT; 1147 radio->irq_flags &= ~WL1273_RDS_EVENT;
1296 1148
1297 if (core->mode == WL1273_MODE_RX) { 1149 if (core->mode == WL1273_MODE_RX) {
1298 r = wl1273_fm_write_cmd(core, 1150 r = core->write(core,
1299 WL1273_INT_MASK_SET, 1151 WL1273_INT_MASK_SET,
1300 radio->irq_flags); 1152 radio->irq_flags);
1301 if (r) { 1153 if (r) {
1302 mutex_unlock(&core->lock); 1154 mutex_unlock(&core->lock);
1303 goto out; 1155 goto out;
@@ -1324,7 +1176,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
1324 1176
1325 dev_dbg(radio->dev, "%s\n", __func__); 1177 dev_dbg(radio->dev, "%s\n", __func__);
1326 1178
1327 if (radio->core->mode != WL1273_MODE_RX) 1179 if (core->mode != WL1273_MODE_RX)
1328 return 0; 1180 return 0;
1329 1181
1330 if (radio->rds_users == 0) { 1182 if (radio->rds_users == 0) {
@@ -1345,7 +1197,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
1345 } 1197 }
1346 radio->owner = file; 1198 radio->owner = file;
1347 1199
1348 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1200 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
1349 if (r) { 1201 if (r) {
1350 dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__); 1202 dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__);
1351 goto out; 1203 goto out;
@@ -1466,23 +1318,24 @@ static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,
1466 */ 1318 */
1467static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power) 1319static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)
1468{ 1320{
1321 struct wl1273_core *core = radio->core;
1469 int r; 1322 int r;
1470 1323
1471 if (radio->core->mode == WL1273_MODE_OFF || 1324 if (core->mode == WL1273_MODE_OFF ||
1472 radio->core->mode == WL1273_MODE_SUSPENDED) 1325 core->mode == WL1273_MODE_SUSPENDED)
1473 return -EPERM; 1326 return -EPERM;
1474 1327
1475 mutex_lock(&radio->core->lock); 1328 mutex_lock(&core->lock);
1476 1329
1477 /* Convert the dBuV value to chip presentation */ 1330 /* Convert the dBuV value to chip presentation */
1478 r = wl1273_fm_write_cmd(radio->core, WL1273_POWER_LEV_SET, 122 - power); 1331 r = core->write(core, WL1273_POWER_LEV_SET, 122 - power);
1479 if (r) 1332 if (r)
1480 goto out; 1333 goto out;
1481 1334
1482 radio->tx_power = power; 1335 radio->tx_power = power;
1483 1336
1484out: 1337out:
1485 mutex_unlock(&radio->core->lock); 1338 mutex_unlock(&core->lock);
1486 return r; 1339 return r;
1487} 1340}
1488 1341
@@ -1493,23 +1346,24 @@ out:
1493static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio, 1346static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio,
1494 unsigned int spacing) 1347 unsigned int spacing)
1495{ 1348{
1349 struct wl1273_core *core = radio->core;
1496 int r; 1350 int r;
1497 1351
1498 if (spacing == 0) { 1352 if (spacing == 0) {
1499 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1353 r = core->write(core, WL1273_SCAN_SPACING_SET,
1500 WL1273_SPACING_100kHz); 1354 WL1273_SPACING_100kHz);
1501 radio->spacing = 100; 1355 radio->spacing = 100;
1502 } else if (spacing - 50000 < 25000) { 1356 } else if (spacing - 50000 < 25000) {
1503 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1357 r = core->write(core, WL1273_SCAN_SPACING_SET,
1504 WL1273_SPACING_50kHz); 1358 WL1273_SPACING_50kHz);
1505 radio->spacing = 50; 1359 radio->spacing = 50;
1506 } else if (spacing - 100000 < 50000) { 1360 } else if (spacing - 100000 < 50000) {
1507 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1361 r = core->write(core, WL1273_SCAN_SPACING_SET,
1508 WL1273_SPACING_100kHz); 1362 WL1273_SPACING_100kHz);
1509 radio->spacing = 100; 1363 radio->spacing = 100;
1510 } else { 1364 } else {
1511 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1365 r = core->write(core, WL1273_SCAN_SPACING_SET,
1512 WL1273_SPACING_200kHz); 1366 WL1273_SPACING_200kHz);
1513 radio->spacing = 200; 1367 radio->spacing = 200;
1514 } 1368 }
1515 1369
@@ -1567,17 +1421,17 @@ static int wl1273_fm_vidioc_s_ctrl(struct v4l2_ctrl *ctrl)
1567 return -EINTR; 1421 return -EINTR;
1568 1422
1569 if (core->mode == WL1273_MODE_RX && ctrl->val) 1423 if (core->mode == WL1273_MODE_RX && ctrl->val)
1570 r = wl1273_fm_write_cmd(core, 1424 r = core->write(core,
1571 WL1273_MUTE_STATUS_SET, 1425 WL1273_MUTE_STATUS_SET,
1572 WL1273_MUTE_HARD_LEFT | 1426 WL1273_MUTE_HARD_LEFT |
1573 WL1273_MUTE_HARD_RIGHT); 1427 WL1273_MUTE_HARD_RIGHT);
1574 else if (core->mode == WL1273_MODE_RX) 1428 else if (core->mode == WL1273_MODE_RX)
1575 r = wl1273_fm_write_cmd(core, 1429 r = core->write(core,
1576 WL1273_MUTE_STATUS_SET, 0x0); 1430 WL1273_MUTE_STATUS_SET, 0x0);
1577 else if (core->mode == WL1273_MODE_TX && ctrl->val) 1431 else if (core->mode == WL1273_MODE_TX && ctrl->val)
1578 r = wl1273_fm_write_cmd(core, WL1273_MUTE, 1); 1432 r = core->write(core, WL1273_MUTE, 1);
1579 else if (core->mode == WL1273_MODE_TX) 1433 else if (core->mode == WL1273_MODE_TX)
1580 r = wl1273_fm_write_cmd(core, WL1273_MUTE, 0); 1434 r = core->write(core, WL1273_MUTE, 0);
1581 1435
1582 mutex_unlock(&core->lock); 1436 mutex_unlock(&core->lock);
1583 break; 1437 break;
@@ -1672,7 +1526,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1672 if (mutex_lock_interruptible(&core->lock)) 1526 if (mutex_lock_interruptible(&core->lock))
1673 return -EINTR; 1527 return -EINTR;
1674 1528
1675 r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val); 1529 r = core->read(core, WL1273_STEREO_GET, &val);
1676 if (r) 1530 if (r)
1677 goto out; 1531 goto out;
1678 1532
@@ -1681,7 +1535,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1681 else 1535 else
1682 tuner->rxsubchans = V4L2_TUNER_SUB_MONO; 1536 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
1683 1537
1684 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val); 1538 r = core->read(core, WL1273_RSSI_LVL_GET, &val);
1685 if (r) 1539 if (r)
1686 goto out; 1540 goto out;
1687 1541
@@ -1690,7 +1544,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1690 1544
1691 tuner->afc = 0; 1545 tuner->afc = 0;
1692 1546
1693 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1547 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
1694 if (r) 1548 if (r)
1695 goto out; 1549 goto out;
1696 1550
@@ -1736,8 +1590,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
1736 dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r); 1590 dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r);
1737 1591
1738 if (tuner->audmode == V4L2_TUNER_MODE_MONO) { 1592 if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
1739 r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, 1593 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
1740 WL1273_RX_MONO);
1741 if (r < 0) { 1594 if (r < 0) {
1742 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", 1595 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
1743 __func__, r); 1596 __func__, r);
@@ -1745,8 +1598,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
1745 } 1598 }
1746 radio->stereo = false; 1599 radio->stereo = false;
1747 } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) { 1600 } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) {
1748 r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, 1601 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
1749 WL1273_RX_STEREO);
1750 if (r < 0) { 1602 if (r < 0) {
1751 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", 1603 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
1752 __func__, r); 1604 __func__, r);
@@ -1885,10 +1737,10 @@ static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,
1885 r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF); 1737 r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
1886 1738
1887 if (modulator->txsubchans & V4L2_TUNER_SUB_MONO) 1739 if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
1888 r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, WL1273_TX_MONO); 1740 r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
1889 else 1741 else
1890 r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, 1742 r = core->write(core, WL1273_MONO_SET,
1891 WL1273_RX_STEREO); 1743 WL1273_RX_STEREO);
1892 if (r < 0) 1744 if (r < 0)
1893 dev_warn(radio->dev, WL1273_FM_DRIVER_NAME 1745 dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
1894 "MONO_SET fails: %d\n", r); 1746 "MONO_SET fails: %d\n", r);
@@ -1923,7 +1775,7 @@ static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,
1923 if (mutex_lock_interruptible(&core->lock)) 1775 if (mutex_lock_interruptible(&core->lock))
1924 return -EINTR; 1776 return -EINTR;
1925 1777
1926 r = wl1273_fm_read_reg(core, WL1273_MONO_SET, &val); 1778 r = core->read(core, WL1273_MONO_SET, &val);
1927 if (r) 1779 if (r)
1928 goto out; 1780 goto out;
1929 1781
@@ -1960,38 +1812,38 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
1960 return 0; 1812 return 0;
1961 } 1813 }
1962 1814
1963 r = wl1273_fm_read_reg(core, WL1273_ASIC_ID_GET, &val); 1815 r = core->read(core, WL1273_ASIC_ID_GET, &val);
1964 if (r) 1816 if (r)
1965 dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__); 1817 dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__);
1966 else 1818 else
1967 dev_info(dev, "ASIC_ID: 0x%04x\n", val); 1819 dev_info(dev, "ASIC_ID: 0x%04x\n", val);
1968 1820
1969 r = wl1273_fm_read_reg(core, WL1273_ASIC_VER_GET, &val); 1821 r = core->read(core, WL1273_ASIC_VER_GET, &val);
1970 if (r) 1822 if (r)
1971 dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__); 1823 dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__);
1972 else 1824 else
1973 dev_info(dev, "ASIC Version: 0x%04x\n", val); 1825 dev_info(dev, "ASIC Version: 0x%04x\n", val);
1974 1826
1975 r = wl1273_fm_read_reg(core, WL1273_FIRM_VER_GET, &val); 1827 r = core->read(core, WL1273_FIRM_VER_GET, &val);
1976 if (r) 1828 if (r)
1977 dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__); 1829 dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__);
1978 else 1830 else
1979 dev_info(dev, "FW version: %d(0x%04x)\n", val, val); 1831 dev_info(dev, "FW version: %d(0x%04x)\n", val, val);
1980 1832
1981 r = wl1273_fm_read_reg(core, WL1273_BAND_SET, &val); 1833 r = core->read(core, WL1273_BAND_SET, &val);
1982 if (r) 1834 if (r)
1983 dev_err(dev, "%s: Get BAND fails.\n", __func__); 1835 dev_err(dev, "%s: Get BAND fails.\n", __func__);
1984 else 1836 else
1985 dev_info(dev, "BAND: %d\n", val); 1837 dev_info(dev, "BAND: %d\n", val);
1986 1838
1987 if (core->mode == WL1273_MODE_TX) { 1839 if (core->mode == WL1273_MODE_TX) {
1988 r = wl1273_fm_read_reg(core, WL1273_PUPD_SET, &val); 1840 r = core->read(core, WL1273_PUPD_SET, &val);
1989 if (r) 1841 if (r)
1990 dev_err(dev, "%s: Get PUPD fails.\n", __func__); 1842 dev_err(dev, "%s: Get PUPD fails.\n", __func__);
1991 else 1843 else
1992 dev_info(dev, "PUPD: 0x%04x\n", val); 1844 dev_info(dev, "PUPD: 0x%04x\n", val);
1993 1845
1994 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &val); 1846 r = core->read(core, WL1273_CHANL_SET, &val);
1995 if (r) 1847 if (r)
1996 dev_err(dev, "%s: Get CHANL fails.\n", __func__); 1848 dev_err(dev, "%s: Get CHANL fails.\n", __func__);
1997 else 1849 else
@@ -1999,13 +1851,13 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
1999 } else if (core->mode == WL1273_MODE_RX) { 1851 } else if (core->mode == WL1273_MODE_RX) {
2000 int bf = radio->rangelow; 1852 int bf = radio->rangelow;
2001 1853
2002 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &val); 1854 r = core->read(core, WL1273_FREQ_SET, &val);
2003 if (r) 1855 if (r)
2004 dev_err(dev, "%s: Get FREQ fails.\n", __func__); 1856 dev_err(dev, "%s: Get FREQ fails.\n", __func__);
2005 else 1857 else
2006 dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50); 1858 dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50);
2007 1859
2008 r = wl1273_fm_read_reg(core, WL1273_MOST_MODE_SET, &val); 1860 r = core->read(core, WL1273_MOST_MODE_SET, &val);
2009 if (r) 1861 if (r)
2010 dev_err(dev, "%s: Get MOST_MODE fails.\n", 1862 dev_err(dev, "%s: Get MOST_MODE fails.\n",
2011 __func__); 1863 __func__);
@@ -2016,7 +1868,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2016 else 1868 else
2017 dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val); 1869 dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val);
2018 1870
2019 r = wl1273_fm_read_reg(core, WL1273_MOST_BLEND_SET, &val); 1871 r = core->read(core, WL1273_MOST_BLEND_SET, &val);
2020 if (r) 1872 if (r)
2021 dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__); 1873 dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__);
2022 else if (val == 0) 1874 else if (val == 0)
@@ -2027,7 +1879,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2027 else 1879 else
2028 dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val); 1880 dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val);
2029 1881
2030 r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val); 1882 r = core->read(core, WL1273_STEREO_GET, &val);
2031 if (r) 1883 if (r)
2032 dev_err(dev, "%s: Get STEREO fails.\n", __func__); 1884 dev_err(dev, "%s: Get STEREO fails.\n", __func__);
2033 else if (val == 0) 1885 else if (val == 0)
@@ -2037,25 +1889,25 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2037 else 1889 else
2038 dev_info(dev, "STEREO: Unexpected value: %d\n", val); 1890 dev_info(dev, "STEREO: Unexpected value: %d\n", val);
2039 1891
2040 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val); 1892 r = core->read(core, WL1273_RSSI_LVL_GET, &val);
2041 if (r) 1893 if (r)
2042 dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__); 1894 dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__);
2043 else 1895 else
2044 dev_info(dev, "RX signal strength: %d\n", (s16) val); 1896 dev_info(dev, "RX signal strength: %d\n", (s16) val);
2045 1897
2046 r = wl1273_fm_read_reg(core, WL1273_POWER_SET, &val); 1898 r = core->read(core, WL1273_POWER_SET, &val);
2047 if (r) 1899 if (r)
2048 dev_err(dev, "%s: Get POWER fails.\n", __func__); 1900 dev_err(dev, "%s: Get POWER fails.\n", __func__);
2049 else 1901 else
2050 dev_info(dev, "POWER: 0x%04x\n", val); 1902 dev_info(dev, "POWER: 0x%04x\n", val);
2051 1903
2052 r = wl1273_fm_read_reg(core, WL1273_INT_MASK_SET, &val); 1904 r = core->read(core, WL1273_INT_MASK_SET, &val);
2053 if (r) 1905 if (r)
2054 dev_err(dev, "%s: Get INT_MASK fails.\n", __func__); 1906 dev_err(dev, "%s: Get INT_MASK fails.\n", __func__);
2055 else 1907 else
2056 dev_info(dev, "INT_MASK: 0x%04x\n", val); 1908 dev_info(dev, "INT_MASK: 0x%04x\n", val);
2057 1909
2058 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1910 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
2059 if (r) 1911 if (r)
2060 dev_err(dev, "%s: Get RDS_SYNC fails.\n", 1912 dev_err(dev, "%s: Get RDS_SYNC fails.\n",
2061 __func__); 1913 __func__);
@@ -2067,14 +1919,14 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2067 else 1919 else
2068 dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val); 1920 dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val);
2069 1921
2070 r = wl1273_fm_read_reg(core, WL1273_I2S_MODE_CONFIG_SET, &val); 1922 r = core->read(core, WL1273_I2S_MODE_CONFIG_SET, &val);
2071 if (r) 1923 if (r)
2072 dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n", 1924 dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n",
2073 __func__); 1925 __func__);
2074 else 1926 else
2075 dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val); 1927 dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val);
2076 1928
2077 r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val); 1929 r = core->read(core, WL1273_VOLUME_SET, &val);
2078 if (r) 1930 if (r)
2079 dev_err(dev, "%s: Get VOLUME fails.\n", __func__); 1931 dev_err(dev, "%s: Get VOLUME fails.\n", __func__);
2080 else 1932 else
@@ -2138,7 +1990,7 @@ static int wl1273_fm_radio_remove(struct platform_device *pdev)
2138 1990
2139static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev) 1991static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
2140{ 1992{
2141 struct wl1273_core **core = pdev->dev.platform_data; 1993 struct wl1273_core **core = mfd_get_data(pdev);
2142 struct wl1273_device *radio; 1994 struct wl1273_device *radio;
2143 struct v4l2_ctrl *ctrl; 1995 struct v4l2_ctrl *ctrl;
2144 int r = 0; 1996 int r = 0;
@@ -2184,10 +2036,6 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
2184 radio->stereo = true; 2036 radio->stereo = true;
2185 radio->bus_type = "I2C"; 2037 radio->bus_type = "I2C";
2186 2038
2187 radio->core->write = wl1273_fm_write_cmd;
2188 radio->core->set_audio = wl1273_fm_set_audio;
2189 radio->core->set_volume = wl1273_fm_set_volume;
2190
2191 if (radio->core->pdata->request_resources) { 2039 if (radio->core->pdata->request_resources) {
2192 r = radio->core->pdata->request_resources(radio->core->client); 2040 r = radio->core->pdata->request_resources(radio->core->client);
2193 if (r) { 2041 if (r) {
@@ -2319,7 +2167,6 @@ module_init(wl1273_fm_module_init);
2319 2167
2320static void __exit wl1273_fm_module_exit(void) 2168static void __exit wl1273_fm_module_exit(void)
2321{ 2169{
2322 flush_scheduled_work();
2323 platform_driver_unregister(&wl1273_fm_radio_driver); 2170 platform_driver_unregister(&wl1273_fm_radio_driver);
2324 pr_info(DRIVER_DESC ", Exiting.\n"); 2171 pr_info(DRIVER_DESC ", Exiting.\n");
2325} 2172}
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 60c176fe328e..38ae6cd65790 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -460,7 +460,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
460 count /= 3; 460 count /= 3;
461 461
462 /* copy RDS block out of internal buffer and to user buffer */ 462 /* copy RDS block out of internal buffer and to user buffer */
463 mutex_lock(&radio->lock);
464 while (block_count < count) { 463 while (block_count < count) {
465 if (radio->rd_index == radio->wr_index) 464 if (radio->rd_index == radio->wr_index)
466 break; 465 break;
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
new file mode 100644
index 000000000000..749f67b192e7
--- /dev/null
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -0,0 +1,17 @@
1#
2# TI's wl128x FM driver based on TI's ST driver.
3#
4menu "Texas Instruments WL128x FM driver (ST based)"
5config RADIO_WL128X
6 tristate "Texas Instruments WL128x FM Radio"
7 depends on VIDEO_V4L2 && RFKILL
8 select TI_ST
9 help
10 Choose Y here if you have this FM radio chip.
11
12 In order to control your radio card, you will need to use programs
13 that are compatible with the Video For Linux 2 API. Information on
14 this API and pointers to "v4l2" programs may be found at
15 <file:Documentation/video4linux/API.html>.
16
17endmenu
diff --git a/drivers/media/radio/wl128x/Makefile b/drivers/media/radio/wl128x/Makefile
new file mode 100644
index 000000000000..32a0ead09845
--- /dev/null
+++ b/drivers/media/radio/wl128x/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for TI's shared transport driver based wl128x
3# FM radio.
4#
5obj-$(CONFIG_RADIO_WL128X) += fm_drv.o
6fm_drv-objs := fmdrv_common.o fmdrv_rx.o fmdrv_tx.o fmdrv_v4l2.o
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h
new file mode 100644
index 000000000000..5db6fd14cf3c
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv.h
@@ -0,0 +1,244 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * Common header for all FM driver sub-modules.
5 *
6 * Copyright (C) 2011 Texas Instruments
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef _FM_DRV_H
24#define _FM_DRV_H
25
26#include <linux/skbuff.h>
27#include <linux/interrupt.h>
28#include <sound/core.h>
29#include <sound/initval.h>
30#include <linux/timer.h>
31#include <linux/version.h>
32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-common.h>
34#include <media/v4l2-ctrls.h>
35
36#define FM_DRV_VERSION "0.10"
37/* Should match with FM_DRV_VERSION */
38#define FM_DRV_RADIO_VERSION KERNEL_VERSION(0, 0, 1)
39#define FM_DRV_NAME "ti_fmdrv"
40#define FM_DRV_CARD_SHORT_NAME "TI FM Radio"
41#define FM_DRV_CARD_LONG_NAME "Texas Instruments FM Radio"
42
43/* Flag info */
44#define FM_INTTASK_RUNNING 0
45#define FM_INTTASK_SCHEDULE_PENDING 1
46#define FM_FW_DW_INPROGRESS 2
47#define FM_CORE_READY 3
48#define FM_CORE_TRANSPORT_READY 4
49#define FM_AF_SWITCH_INPROGRESS 5
50#define FM_CORE_TX_XMITING 6
51
52#define FM_TUNE_COMPLETE 0x1
53#define FM_BAND_LIMIT 0x2
54
55#define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */
56#define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */
57
58#define NO_OF_ENTRIES_IN_ARRAY(array) (sizeof(array) / sizeof(array[0]))
59
60#define fmerr(format, ...) \
61 printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__)
62#define fmwarn(format, ...) \
63 printk(KERN_WARNING "fmdrv: " format, ##__VA_ARGS__)
64#ifdef DEBUG
65#define fmdbg(format, ...) \
66 printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__)
67#else /* DEBUG */
68#define fmdbg(format, ...)
69#endif
70enum {
71 FM_MODE_OFF,
72 FM_MODE_TX,
73 FM_MODE_RX,
74 FM_MODE_ENTRY_MAX
75};
76
77#define FM_RX_RDS_INFO_FIELD_MAX 8 /* 4 Group * 2 Bytes */
78
79/* RX RDS data format */
80struct fm_rdsdata_format {
81 union {
82 struct {
83 u8 buff[FM_RX_RDS_INFO_FIELD_MAX];
84 } groupdatabuff;
85 struct {
86 u16 pidata;
87 u8 blk_b[2];
88 u8 blk_c[2];
89 u8 blk_d[2];
90 } groupgeneral;
91 struct {
92 u16 pidata;
93 u8 blk_b[2];
94 u8 af[2];
95 u8 ps[2];
96 } group0A;
97 struct {
98 u16 pi[2];
99 u8 blk_b[2];
100 u8 ps[2];
101 } group0B;
102 } data;
103};
104
105/* FM region (Europe/US, Japan) info */
106struct region_info {
107 u32 chanl_space;
108 u32 bot_freq;
109 u32 top_freq;
110 u8 fm_band;
111};
112struct fmdev;
113typedef void (*int_handler_prototype) (struct fmdev *);
114
115/* FM Interrupt processing related info */
116struct fm_irq {
117 u8 stage;
118 u16 flag; /* FM interrupt flag */
119 u16 mask; /* FM interrupt mask */
120 /* Interrupt process timeout handler */
121 struct timer_list timer;
122 u8 retry;
123 int_handler_prototype *handlers;
124};
125
126/* RDS info */
127struct fm_rds {
128 u8 flag; /* RX RDS on/off status */
129 u8 last_blk_idx; /* Last received RDS block */
130
131 /* RDS buffer */
132 wait_queue_head_t read_queue;
133 u32 buf_size; /* Size is always multiple of 3 */
134 u32 wr_idx;
135 u32 rd_idx;
136 u8 *buff;
137};
138
139#define FM_RDS_MAX_AF_LIST 25
140
141/*
142 * Current RX channel Alternate Frequency cache.
143 * This info is used to switch to other freq (AF)
144 * when current channel signal strengh is below RSSI threshold.
145 */
146struct tuned_station_info {
147 u16 picode;
148 u32 af_cache[FM_RDS_MAX_AF_LIST];
149 u8 afcache_size;
150 u8 af_list_max;
151};
152
153/* FM RX mode info */
154struct fm_rx {
155 struct region_info region; /* Current selected band */
156 u32 freq; /* Current RX frquency */
157 u8 mute_mode; /* Current mute mode */
158 u8 deemphasis_mode; /* Current deemphasis mode */
159 /* RF dependent soft mute mode */
160 u8 rf_depend_mute;
161 u16 volume; /* Current volume level */
162 u16 rssi_threshold; /* Current RSSI threshold level */
163 /* Holds the index of the current AF jump */
164 u8 afjump_idx;
165 /* Will hold the frequency before the jump */
166 u32 freq_before_jump;
167 u8 rds_mode; /* RDS operation mode (RDS/RDBS) */
168 u8 af_mode; /* Alternate frequency on/off */
169 struct tuned_station_info stat_info;
170 struct fm_rds rds;
171};
172
173#define FMTX_RDS_TXT_STR_SIZE 25
174/*
175 * FM TX RDS data
176 *
177 * @ text_type: is the text following PS or RT
178 * @ text: radio text string which could either be PS or RT
179 * @ af_freq: alternate frequency for Tx
180 * TODO: to be declared in application
181 */
182struct tx_rds {
183 u8 text_type;
184 u8 text[FMTX_RDS_TXT_STR_SIZE];
185 u8 flag;
186 u32 af_freq;
187};
188/*
189 * FM TX global data
190 *
191 * @ pwr_lvl: Power Level of the Transmission from mixer control
192 * @ xmit_state: Transmission state = Updated locally upon Start/Stop
193 * @ audio_io: i2S/Analog
194 * @ tx_frq: Transmission frequency
195 */
196struct fmtx_data {
197 u8 pwr_lvl;
198 u8 xmit_state;
199 u8 audio_io;
200 u8 region;
201 u16 aud_mode;
202 u32 preemph;
203 u32 tx_frq;
204 struct tx_rds rds;
205};
206
207/* FM driver operation structure */
208struct fmdev {
209 struct video_device *radio_dev; /* V4L2 video device pointer */
210 struct snd_card *card; /* Card which holds FM mixer controls */
211 u16 asci_id;
212 spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
213 spinlock_t resp_skb_lock; /* To protect access to received SKB */
214
215 long flag; /* FM driver state machine info */
216 u8 streg_cbdata; /* status of ST registration */
217
218 struct sk_buff_head rx_q; /* RX queue */
219 struct tasklet_struct rx_task; /* RX Tasklet */
220
221 struct sk_buff_head tx_q; /* TX queue */
222 struct tasklet_struct tx_task; /* TX Tasklet */
223 unsigned long last_tx_jiffies; /* Timestamp of last pkt sent */
224 atomic_t tx_cnt; /* Number of packets can send at a time */
225
226 struct sk_buff *resp_skb; /* Response from the chip */
227 /* Main task completion handler */
228 struct completion maintask_comp;
229 /* Opcode of last command sent to the chip */
230 u8 pre_op;
231 /* Handler used for wakeup when response packet is received */
232 struct completion *resp_comp;
233 struct fm_irq irq_info;
234 u8 curr_fmmode; /* Current FM chip mode (TX, RX, OFF) */
235 struct fm_rx rx; /* FM receiver info */
236 struct fmtx_data tx_data;
237
238 /* V4L2 ctrl framwork handler*/
239 struct v4l2_ctrl_handler ctrl_handler;
240
241 /* For core assisted locking */
242 struct mutex mutex;
243};
244#endif
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
new file mode 100644
index 000000000000..64454d39c0ca
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -0,0 +1,1677 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * This sub-module of FM driver is common for FM RX and TX
5 * functionality. This module is responsible for:
6 * 1) Forming group of Channel-8 commands to perform particular
7 * functionality (eg., frequency set require more than
8 * one Channel-8 command to be sent to the chip).
9 * 2) Sending each Channel-8 command to the chip and reading
10 * response back over Shared Transport.
11 * 3) Managing TX and RX Queues and Tasklets.
12 * 4) Handling FM Interrupt packet and taking appropriate action.
13 * 5) Loading FM firmware to the chip (common, FM TX, and FM RX
14 * firmware files based on mode selection)
15 *
16 * Copyright (C) 2011 Texas Instruments
17 * Author: Raja Mani <raja_mani@ti.com>
18 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License version 2 as
22 * published by the Free Software Foundation.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/firmware.h>
37#include <linux/delay.h>
38#include "fmdrv.h"
39#include "fmdrv_v4l2.h"
40#include "fmdrv_common.h"
41#include <linux/ti_wilink_st.h>
42#include "fmdrv_rx.h"
43#include "fmdrv_tx.h"
44
45/* Region info */
46static struct region_info region_configs[] = {
47 /* Europe/US */
48 {
49 .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL,
50 .bot_freq = 87500, /* 87.5 MHz */
51 .top_freq = 108000, /* 108 MHz */
52 .fm_band = 0,
53 },
54 /* Japan */
55 {
56 .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL,
57 .bot_freq = 76000, /* 76 MHz */
58 .top_freq = 90000, /* 90 MHz */
59 .fm_band = 1,
60 },
61};
62
63/* Band selection */
64static u8 default_radio_region; /* Europe/US */
65module_param(default_radio_region, byte, 0);
66MODULE_PARM_DESC(default_radio_region, "Region: 0=Europe/US, 1=Japan");
67
68/* RDS buffer blocks */
69static u32 default_rds_buf = 300;
70module_param(default_rds_buf, uint, 0444);
71MODULE_PARM_DESC(rds_buf, "RDS buffer entries");
72
73/* Radio Nr */
74static u32 radio_nr = -1;
75module_param(radio_nr, int, 0444);
76MODULE_PARM_DESC(radio_nr, "Radio Nr");
77
78/* FM irq handlers forward declaration */
79static void fm_irq_send_flag_getcmd(struct fmdev *);
80static void fm_irq_handle_flag_getcmd_resp(struct fmdev *);
81static void fm_irq_handle_hw_malfunction(struct fmdev *);
82static void fm_irq_handle_rds_start(struct fmdev *);
83static void fm_irq_send_rdsdata_getcmd(struct fmdev *);
84static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *);
85static void fm_irq_handle_rds_finish(struct fmdev *);
86static void fm_irq_handle_tune_op_ended(struct fmdev *);
87static void fm_irq_handle_power_enb(struct fmdev *);
88static void fm_irq_handle_low_rssi_start(struct fmdev *);
89static void fm_irq_afjump_set_pi(struct fmdev *);
90static void fm_irq_handle_set_pi_resp(struct fmdev *);
91static void fm_irq_afjump_set_pimask(struct fmdev *);
92static void fm_irq_handle_set_pimask_resp(struct fmdev *);
93static void fm_irq_afjump_setfreq(struct fmdev *);
94static void fm_irq_handle_setfreq_resp(struct fmdev *);
95static void fm_irq_afjump_enableint(struct fmdev *);
96static void fm_irq_afjump_enableint_resp(struct fmdev *);
97static void fm_irq_start_afjump(struct fmdev *);
98static void fm_irq_handle_start_afjump_resp(struct fmdev *);
99static void fm_irq_afjump_rd_freq(struct fmdev *);
100static void fm_irq_afjump_rd_freq_resp(struct fmdev *);
101static void fm_irq_handle_low_rssi_finish(struct fmdev *);
102static void fm_irq_send_intmsk_cmd(struct fmdev *);
103static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *);
104
105/*
106 * When FM common module receives interrupt packet, following handlers
107 * will be executed one after another to service the interrupt(s)
108 */
109enum fmc_irq_handler_index {
110 FM_SEND_FLAG_GETCMD_IDX,
111 FM_HANDLE_FLAG_GETCMD_RESP_IDX,
112
113 /* HW malfunction irq handler */
114 FM_HW_MAL_FUNC_IDX,
115
116 /* RDS threshold reached irq handler */
117 FM_RDS_START_IDX,
118 FM_RDS_SEND_RDS_GETCMD_IDX,
119 FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX,
120 FM_RDS_FINISH_IDX,
121
122 /* Tune operation ended irq handler */
123 FM_HW_TUNE_OP_ENDED_IDX,
124
125 /* TX power enable irq handler */
126 FM_HW_POWER_ENB_IDX,
127
128 /* Low RSSI irq handler */
129 FM_LOW_RSSI_START_IDX,
130 FM_AF_JUMP_SETPI_IDX,
131 FM_AF_JUMP_HANDLE_SETPI_RESP_IDX,
132 FM_AF_JUMP_SETPI_MASK_IDX,
133 FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX,
134 FM_AF_JUMP_SET_AF_FREQ_IDX,
135 FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX,
136 FM_AF_JUMP_ENABLE_INT_IDX,
137 FM_AF_JUMP_ENABLE_INT_RESP_IDX,
138 FM_AF_JUMP_START_AFJUMP_IDX,
139 FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX,
140 FM_AF_JUMP_RD_FREQ_IDX,
141 FM_AF_JUMP_RD_FREQ_RESP_IDX,
142 FM_LOW_RSSI_FINISH_IDX,
143
144 /* Interrupt process post action */
145 FM_SEND_INTMSK_CMD_IDX,
146 FM_HANDLE_INTMSK_CMD_RESP_IDX,
147};
148
149/* FM interrupt handler table */
150static int_handler_prototype int_handler_table[] = {
151 fm_irq_send_flag_getcmd,
152 fm_irq_handle_flag_getcmd_resp,
153 fm_irq_handle_hw_malfunction,
154 fm_irq_handle_rds_start, /* RDS threshold reached irq handler */
155 fm_irq_send_rdsdata_getcmd,
156 fm_irq_handle_rdsdata_getcmd_resp,
157 fm_irq_handle_rds_finish,
158 fm_irq_handle_tune_op_ended,
159 fm_irq_handle_power_enb, /* TX power enable irq handler */
160 fm_irq_handle_low_rssi_start,
161 fm_irq_afjump_set_pi,
162 fm_irq_handle_set_pi_resp,
163 fm_irq_afjump_set_pimask,
164 fm_irq_handle_set_pimask_resp,
165 fm_irq_afjump_setfreq,
166 fm_irq_handle_setfreq_resp,
167 fm_irq_afjump_enableint,
168 fm_irq_afjump_enableint_resp,
169 fm_irq_start_afjump,
170 fm_irq_handle_start_afjump_resp,
171 fm_irq_afjump_rd_freq,
172 fm_irq_afjump_rd_freq_resp,
173 fm_irq_handle_low_rssi_finish,
174 fm_irq_send_intmsk_cmd, /* Interrupt process post action */
175 fm_irq_handle_intmsk_cmd_resp
176};
177
178long (*g_st_write) (struct sk_buff *skb);
179static struct completion wait_for_fmdrv_reg_comp;
180
181static inline void fm_irq_call(struct fmdev *fmdev)
182{
183 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev);
184}
185
186/* Continue next function in interrupt handler table */
187static inline void fm_irq_call_stage(struct fmdev *fmdev, u8 stage)
188{
189 fmdev->irq_info.stage = stage;
190 fm_irq_call(fmdev);
191}
192
193static inline void fm_irq_timeout_stage(struct fmdev *fmdev, u8 stage)
194{
195 fmdev->irq_info.stage = stage;
196 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT);
197}
198
199#ifdef FM_DUMP_TXRX_PKT
200 /* To dump outgoing FM Channel-8 packets */
201inline void dump_tx_skb_data(struct sk_buff *skb)
202{
203 int len, len_org;
204 u8 index;
205 struct fm_cmd_msg_hdr *cmd_hdr;
206
207 cmd_hdr = (struct fm_cmd_msg_hdr *)skb->data;
208 printk(KERN_INFO "<<%shdr:%02x len:%02x opcode:%02x type:%s dlen:%02x",
209 fm_cb(skb)->completion ? " " : "*", cmd_hdr->hdr,
210 cmd_hdr->len, cmd_hdr->op,
211 cmd_hdr->rd_wr ? "RD" : "WR", cmd_hdr->dlen);
212
213 len_org = skb->len - FM_CMD_MSG_HDR_SIZE;
214 if (len_org > 0) {
215 printk("\n data(%d): ", cmd_hdr->dlen);
216 len = min(len_org, 14);
217 for (index = 0; index < len; index++)
218 printk("%x ",
219 skb->data[FM_CMD_MSG_HDR_SIZE + index]);
220 printk("%s", (len_org > 14) ? ".." : "");
221 }
222 printk("\n");
223}
224
225 /* To dump incoming FM Channel-8 packets */
226inline void dump_rx_skb_data(struct sk_buff *skb)
227{
228 int len, len_org;
229 u8 index;
230 struct fm_event_msg_hdr *evt_hdr;
231
232 evt_hdr = (struct fm_event_msg_hdr *)skb->data;
233 printk(KERN_INFO ">> hdr:%02x len:%02x sts:%02x numhci:%02x "
234 "opcode:%02x type:%s dlen:%02x", evt_hdr->hdr, evt_hdr->len,
235 evt_hdr->status, evt_hdr->num_fm_hci_cmds, evt_hdr->op,
236 (evt_hdr->rd_wr) ? "RD" : "WR", evt_hdr->dlen);
237
238 len_org = skb->len - FM_EVT_MSG_HDR_SIZE;
239 if (len_org > 0) {
240 printk("\n data(%d): ", evt_hdr->dlen);
241 len = min(len_org, 14);
242 for (index = 0; index < len; index++)
243 printk("%x ",
244 skb->data[FM_EVT_MSG_HDR_SIZE + index]);
245 printk("%s", (len_org > 14) ? ".." : "");
246 }
247 printk("\n");
248}
249#endif
250
251void fmc_update_region_info(struct fmdev *fmdev, u8 region_to_set)
252{
253 fmdev->rx.region = region_configs[region_to_set];
254}
255
256/*
257 * FM common sub-module will schedule this tasklet whenever it receives
258 * FM packet from ST driver.
259 */
260static void recv_tasklet(unsigned long arg)
261{
262 struct fmdev *fmdev;
263 struct fm_irq *irq_info;
264 struct fm_event_msg_hdr *evt_hdr;
265 struct sk_buff *skb;
266 u8 num_fm_hci_cmds;
267 unsigned long flags;
268
269 fmdev = (struct fmdev *)arg;
270 irq_info = &fmdev->irq_info;
271 /* Process all packets in the RX queue */
272 while ((skb = skb_dequeue(&fmdev->rx_q))) {
273 if (skb->len < sizeof(struct fm_event_msg_hdr)) {
274 fmerr("skb(%p) has only %d bytes, "
275 "at least need %zu bytes to decode\n", skb,
276 skb->len, sizeof(struct fm_event_msg_hdr));
277 kfree_skb(skb);
278 continue;
279 }
280
281 evt_hdr = (void *)skb->data;
282 num_fm_hci_cmds = evt_hdr->num_fm_hci_cmds;
283
284 /* FM interrupt packet? */
285 if (evt_hdr->op == FM_INTERRUPT) {
286 /* FM interrupt handler started already? */
287 if (!test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) {
288 set_bit(FM_INTTASK_RUNNING, &fmdev->flag);
289 if (irq_info->stage != 0) {
290 fmerr("Inval stage resetting to zero\n");
291 irq_info->stage = 0;
292 }
293
294 /*
295 * Execute first function in interrupt handler
296 * table.
297 */
298 irq_info->handlers[irq_info->stage](fmdev);
299 } else {
300 set_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag);
301 }
302 kfree_skb(skb);
303 }
304 /* Anyone waiting for this with completion handler? */
305 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp != NULL) {
306
307 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
308 fmdev->resp_skb = skb;
309 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
310 complete(fmdev->resp_comp);
311
312 fmdev->resp_comp = NULL;
313 atomic_set(&fmdev->tx_cnt, 1);
314 }
315 /* Is this for interrupt handler? */
316 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp == NULL) {
317 if (fmdev->resp_skb != NULL)
318 fmerr("Response SKB ptr not NULL\n");
319
320 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
321 fmdev->resp_skb = skb;
322 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
323
324 /* Execute interrupt handler where state index points */
325 irq_info->handlers[irq_info->stage](fmdev);
326
327 kfree_skb(skb);
328 atomic_set(&fmdev->tx_cnt, 1);
329 } else {
330 fmerr("Nobody claimed SKB(%p),purging\n", skb);
331 }
332
333 /*
334 * Check flow control field. If Num_FM_HCI_Commands field is
335 * not zero, schedule FM TX tasklet.
336 */
337 if (num_fm_hci_cmds && atomic_read(&fmdev->tx_cnt))
338 if (!skb_queue_empty(&fmdev->tx_q))
339 tasklet_schedule(&fmdev->tx_task);
340 }
341}
342
343/* FM send tasklet: is scheduled when FM packet has to be sent to chip */
344static void send_tasklet(unsigned long arg)
345{
346 struct fmdev *fmdev;
347 struct sk_buff *skb;
348 int len;
349
350 fmdev = (struct fmdev *)arg;
351
352 if (!atomic_read(&fmdev->tx_cnt))
353 return;
354
355 /* Check, is there any timeout happenned to last transmitted packet */
356 if ((jiffies - fmdev->last_tx_jiffies) > FM_DRV_TX_TIMEOUT) {
357 fmerr("TX timeout occurred\n");
358 atomic_set(&fmdev->tx_cnt, 1);
359 }
360
361 /* Send queued FM TX packets */
362 skb = skb_dequeue(&fmdev->tx_q);
363 if (!skb)
364 return;
365
366 atomic_dec(&fmdev->tx_cnt);
367 fmdev->pre_op = fm_cb(skb)->fm_op;
368
369 if (fmdev->resp_comp != NULL)
370 fmerr("Response completion handler is not NULL\n");
371
372 fmdev->resp_comp = fm_cb(skb)->completion;
373
374 /* Write FM packet to ST driver */
375 len = g_st_write(skb);
376 if (len < 0) {
377 kfree_skb(skb);
378 fmdev->resp_comp = NULL;
379 fmerr("TX tasklet failed to send skb(%p)\n", skb);
380 atomic_set(&fmdev->tx_cnt, 1);
381 } else {
382 fmdev->last_tx_jiffies = jiffies;
383 }
384}
385
386/*
387 * Queues FM Channel-8 packet to FM TX queue and schedules FM TX tasklet for
388 * transmission
389 */
390static u32 fm_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
391 int payload_len, struct completion *wait_completion)
392{
393 struct sk_buff *skb;
394 struct fm_cmd_msg_hdr *hdr;
395 int size;
396
397 if (fm_op >= FM_INTERRUPT) {
398 fmerr("Invalid fm opcode - %d\n", fm_op);
399 return -EINVAL;
400 }
401 if (test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) && payload == NULL) {
402 fmerr("Payload data is NULL during fw download\n");
403 return -EINVAL;
404 }
405 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag))
406 size =
407 FM_CMD_MSG_HDR_SIZE + ((payload == NULL) ? 0 : payload_len);
408 else
409 size = payload_len;
410
411 skb = alloc_skb(size, GFP_ATOMIC);
412 if (!skb) {
413 fmerr("No memory to create new SKB\n");
414 return -ENOMEM;
415 }
416 /*
417 * Don't fill FM header info for the commands which come from
418 * FM firmware file.
419 */
420 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) ||
421 test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) {
422 /* Fill command header info */
423 hdr = (struct fm_cmd_msg_hdr *)skb_put(skb, FM_CMD_MSG_HDR_SIZE);
424 hdr->hdr = FM_PKT_LOGICAL_CHAN_NUMBER; /* 0x08 */
425
426 /* 3 (fm_opcode,rd_wr,dlen) + payload len) */
427 hdr->len = ((payload == NULL) ? 0 : payload_len) + 3;
428
429 /* FM opcode */
430 hdr->op = fm_op;
431
432 /* read/write type */
433 hdr->rd_wr = type;
434 hdr->dlen = payload_len;
435 fm_cb(skb)->fm_op = fm_op;
436
437 /*
438 * If firmware download has finished and the command is
439 * not a read command then payload is != NULL - a write
440 * command with u16 payload - convert to be16
441 */
442 if (payload != NULL)
443 *(u16 *)payload = cpu_to_be16(*(u16 *)payload);
444
445 } else if (payload != NULL) {
446 fm_cb(skb)->fm_op = *((u8 *)payload + 2);
447 }
448 if (payload != NULL)
449 memcpy(skb_put(skb, payload_len), payload, payload_len);
450
451 fm_cb(skb)->completion = wait_completion;
452 skb_queue_tail(&fmdev->tx_q, skb);
453 tasklet_schedule(&fmdev->tx_task);
454
455 return 0;
456}
457
458/* Sends FM Channel-8 command to the chip and waits for the response */
459u32 fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
460 unsigned int payload_len, void *response, int *response_len)
461{
462 struct sk_buff *skb;
463 struct fm_event_msg_hdr *evt_hdr;
464 unsigned long flags;
465 u32 ret;
466
467 init_completion(&fmdev->maintask_comp);
468 ret = fm_send_cmd(fmdev, fm_op, type, payload, payload_len,
469 &fmdev->maintask_comp);
470 if (ret)
471 return ret;
472
473 ret = wait_for_completion_timeout(&fmdev->maintask_comp, FM_DRV_TX_TIMEOUT);
474 if (!ret) {
475 fmerr("Timeout(%d sec),didn't get reg"
476 "completion signal from RX tasklet\n",
477 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
478 return -ETIMEDOUT;
479 }
480 if (!fmdev->resp_skb) {
481 fmerr("Reponse SKB is missing\n");
482 return -EFAULT;
483 }
484 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
485 skb = fmdev->resp_skb;
486 fmdev->resp_skb = NULL;
487 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
488
489 evt_hdr = (void *)skb->data;
490 if (evt_hdr->status != 0) {
491 fmerr("Received event pkt status(%d) is not zero\n",
492 evt_hdr->status);
493 kfree_skb(skb);
494 return -EIO;
495 }
496 /* Send response data to caller */
497 if (response != NULL && response_len != NULL && evt_hdr->dlen) {
498 /* Skip header info and copy only response data */
499 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
500 memcpy(response, skb->data, evt_hdr->dlen);
501 *response_len = evt_hdr->dlen;
502 } else if (response_len != NULL && evt_hdr->dlen == 0) {
503 *response_len = 0;
504 }
505 kfree_skb(skb);
506
507 return 0;
508}
509
510/* --- Helper functions used in FM interrupt handlers ---*/
511static inline u32 check_cmdresp_status(struct fmdev *fmdev,
512 struct sk_buff **skb)
513{
514 struct fm_event_msg_hdr *fm_evt_hdr;
515 unsigned long flags;
516
517 del_timer(&fmdev->irq_info.timer);
518
519 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
520 *skb = fmdev->resp_skb;
521 fmdev->resp_skb = NULL;
522 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
523
524 fm_evt_hdr = (void *)(*skb)->data;
525 if (fm_evt_hdr->status != 0) {
526 fmerr("irq: opcode %x response status is not zero "
527 "Initiating irq recovery process\n",
528 fm_evt_hdr->op);
529
530 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT);
531 return -1;
532 }
533
534 return 0;
535}
536
537static inline void fm_irq_common_cmd_resp_helper(struct fmdev *fmdev, u8 stage)
538{
539 struct sk_buff *skb;
540
541 if (!check_cmdresp_status(fmdev, &skb))
542 fm_irq_call_stage(fmdev, stage);
543}
544
545/*
546 * Interrupt process timeout handler.
547 * One of the irq handler did not get proper response from the chip. So take
548 * recovery action here. FM interrupts are disabled in the beginning of
549 * interrupt process. Therefore reset stage index to re-enable default
550 * interrupts. So that next interrupt will be processed as usual.
551 */
552static void int_timeout_handler(unsigned long data)
553{
554 struct fmdev *fmdev;
555 struct fm_irq *fmirq;
556
557 fmdbg("irq: timeout,trying to re-enable fm interrupts\n");
558 fmdev = (struct fmdev *)data;
559 fmirq = &fmdev->irq_info;
560 fmirq->retry++;
561
562 if (fmirq->retry > FM_IRQ_TIMEOUT_RETRY_MAX) {
563 /* Stop recovery action (interrupt reenable process) and
564 * reset stage index & retry count values */
565 fmirq->stage = 0;
566 fmirq->retry = 0;
567 fmerr("Recovery action failed during"
568 "irq processing, max retry reached\n");
569 return;
570 }
571 fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX);
572}
573
574/* --------- FM interrupt handlers ------------*/
575static void fm_irq_send_flag_getcmd(struct fmdev *fmdev)
576{
577 u16 flag;
578
579 /* Send FLAG_GET command , to know the source of interrupt */
580 if (!fm_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, sizeof(flag), NULL))
581 fm_irq_timeout_stage(fmdev, FM_HANDLE_FLAG_GETCMD_RESP_IDX);
582}
583
584static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev)
585{
586 struct sk_buff *skb;
587 struct fm_event_msg_hdr *fm_evt_hdr;
588
589 if (check_cmdresp_status(fmdev, &skb))
590 return;
591
592 fm_evt_hdr = (void *)skb->data;
593
594 /* Skip header info and copy only response data */
595 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
596 memcpy(&fmdev->irq_info.flag, skb->data, fm_evt_hdr->dlen);
597
598 fmdev->irq_info.flag = be16_to_cpu(fmdev->irq_info.flag);
599 fmdbg("irq: flag register(0x%x)\n", fmdev->irq_info.flag);
600
601 /* Continue next function in interrupt handler table */
602 fm_irq_call_stage(fmdev, FM_HW_MAL_FUNC_IDX);
603}
604
605static void fm_irq_handle_hw_malfunction(struct fmdev *fmdev)
606{
607 if (fmdev->irq_info.flag & FM_MAL_EVENT & fmdev->irq_info.mask)
608 fmerr("irq: HW MAL int received - do nothing\n");
609
610 /* Continue next function in interrupt handler table */
611 fm_irq_call_stage(fmdev, FM_RDS_START_IDX);
612}
613
614static void fm_irq_handle_rds_start(struct fmdev *fmdev)
615{
616 if (fmdev->irq_info.flag & FM_RDS_EVENT & fmdev->irq_info.mask) {
617 fmdbg("irq: rds threshold reached\n");
618 fmdev->irq_info.stage = FM_RDS_SEND_RDS_GETCMD_IDX;
619 } else {
620 /* Continue next function in interrupt handler table */
621 fmdev->irq_info.stage = FM_HW_TUNE_OP_ENDED_IDX;
622 }
623
624 fm_irq_call(fmdev);
625}
626
627static void fm_irq_send_rdsdata_getcmd(struct fmdev *fmdev)
628{
629 /* Send the command to read RDS data from the chip */
630 if (!fm_send_cmd(fmdev, RDS_DATA_GET, REG_RD, NULL,
631 (FM_RX_RDS_FIFO_THRESHOLD * 3), NULL))
632 fm_irq_timeout_stage(fmdev, FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX);
633}
634
635/* Keeps track of current RX channel AF (Alternate Frequency) */
636static void fm_rx_update_af_cache(struct fmdev *fmdev, u8 af)
637{
638 struct tuned_station_info *stat_info = &fmdev->rx.stat_info;
639 u8 reg_idx = fmdev->rx.region.fm_band;
640 u8 index;
641 u32 freq;
642
643 /* First AF indicates the number of AF follows. Reset the list */
644 if ((af >= FM_RDS_1_AF_FOLLOWS) && (af <= FM_RDS_25_AF_FOLLOWS)) {
645 fmdev->rx.stat_info.af_list_max = (af - FM_RDS_1_AF_FOLLOWS + 1);
646 fmdev->rx.stat_info.afcache_size = 0;
647 fmdbg("No of expected AF : %d\n", fmdev->rx.stat_info.af_list_max);
648 return;
649 }
650
651 if (af < FM_RDS_MIN_AF)
652 return;
653 if (reg_idx == FM_BAND_EUROPE_US && af > FM_RDS_MAX_AF)
654 return;
655 if (reg_idx == FM_BAND_JAPAN && af > FM_RDS_MAX_AF_JAPAN)
656 return;
657
658 freq = fmdev->rx.region.bot_freq + (af * 100);
659 if (freq == fmdev->rx.freq) {
660 fmdbg("Current freq(%d) is matching with received AF(%d)\n",
661 fmdev->rx.freq, freq);
662 return;
663 }
664 /* Do check in AF cache */
665 for (index = 0; index < stat_info->afcache_size; index++) {
666 if (stat_info->af_cache[index] == freq)
667 break;
668 }
669 /* Reached the limit of the list - ignore the next AF */
670 if (index == stat_info->af_list_max) {
671 fmdbg("AF cache is full\n");
672 return;
673 }
674 /*
675 * If we reached the end of the list then this AF is not
676 * in the list - add it.
677 */
678 if (index == stat_info->afcache_size) {
679 fmdbg("Storing AF %d to cache index %d\n", freq, index);
680 stat_info->af_cache[index] = freq;
681 stat_info->afcache_size++;
682 }
683}
684
685/*
686 * Converts RDS buffer data from big endian format
687 * to little endian format.
688 */
689static void fm_rdsparse_swapbytes(struct fmdev *fmdev,
690 struct fm_rdsdata_format *rds_format)
691{
692 u8 byte1;
693 u8 index = 0;
694 u8 *rds_buff;
695
696 /*
697 * Since in Orca the 2 RDS Data bytes are in little endian and
698 * in Dolphin they are in big endian, the parsing of the RDS data
699 * is chip dependent
700 */
701 if (fmdev->asci_id != 0x6350) {
702 rds_buff = &rds_format->data.groupdatabuff.buff[0];
703 while (index + 1 < FM_RX_RDS_INFO_FIELD_MAX) {
704 byte1 = rds_buff[index];
705 rds_buff[index] = rds_buff[index + 1];
706 rds_buff[index + 1] = byte1;
707 index += 2;
708 }
709 }
710}
711
712static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *fmdev)
713{
714 struct sk_buff *skb;
715 struct fm_rdsdata_format rds_fmt;
716 struct fm_rds *rds = &fmdev->rx.rds;
717 unsigned long group_idx, flags;
718 u8 *rds_data, meta_data, tmpbuf[3];
719 u8 type, blk_idx;
720 u16 cur_picode;
721 u32 rds_len;
722
723 if (check_cmdresp_status(fmdev, &skb))
724 return;
725
726 /* Skip header info */
727 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
728 rds_data = skb->data;
729 rds_len = skb->len;
730
731 /* Parse the RDS data */
732 while (rds_len >= FM_RDS_BLK_SIZE) {
733 meta_data = rds_data[2];
734 /* Get the type: 0=A, 1=B, 2=C, 3=C', 4=D, 5=E */
735 type = (meta_data & 0x07);
736
737 /* Transform the blk type into index sequence (0, 1, 2, 3, 4) */
738 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1));
739 fmdbg("Block index:%d(%s)\n", blk_idx,
740 (meta_data & FM_RDS_STATUS_ERR_MASK) ? "Bad" : "Ok");
741
742 if ((meta_data & FM_RDS_STATUS_ERR_MASK) != 0)
743 break;
744
745 if (blk_idx < FM_RDS_BLK_IDX_A || blk_idx > FM_RDS_BLK_IDX_D) {
746 fmdbg("Block sequence mismatch\n");
747 rds->last_blk_idx = -1;
748 break;
749 }
750
751 /* Skip checkword (control) byte and copy only data byte */
752 memcpy(&rds_fmt.data.groupdatabuff.
753 buff[blk_idx * (FM_RDS_BLK_SIZE - 1)],
754 rds_data, (FM_RDS_BLK_SIZE - 1));
755
756 rds->last_blk_idx = blk_idx;
757
758 /* If completed a whole group then handle it */
759 if (blk_idx == FM_RDS_BLK_IDX_D) {
760 fmdbg("Good block received\n");
761 fm_rdsparse_swapbytes(fmdev, &rds_fmt);
762
763 /*
764 * Extract PI code and store in local cache.
765 * We need this during AF switch processing.
766 */
767 cur_picode = be16_to_cpu(rds_fmt.data.groupgeneral.pidata);
768 if (fmdev->rx.stat_info.picode != cur_picode)
769 fmdev->rx.stat_info.picode = cur_picode;
770
771 fmdbg("picode:%d\n", cur_picode);
772
773 group_idx = (rds_fmt.data.groupgeneral.blk_b[0] >> 3);
774 fmdbg("(fmdrv):Group:%ld%s\n", group_idx/2,
775 (group_idx % 2) ? "B" : "A");
776
777 group_idx = 1 << (rds_fmt.data.groupgeneral.blk_b[0] >> 3);
778 if (group_idx == FM_RDS_GROUP_TYPE_MASK_0A) {
779 fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[0]);
780 fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[1]);
781 }
782 }
783 rds_len -= FM_RDS_BLK_SIZE;
784 rds_data += FM_RDS_BLK_SIZE;
785 }
786
787 /* Copy raw rds data to internal rds buffer */
788 rds_data = skb->data;
789 rds_len = skb->len;
790
791 spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
792 while (rds_len > 0) {
793 /*
794 * Fill RDS buffer as per V4L2 specification.
795 * Store control byte
796 */
797 type = (rds_data[2] & 0x07);
798 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1));
799 tmpbuf[2] = blk_idx; /* Offset name */
800 tmpbuf[2] |= blk_idx << 3; /* Received offset */
801
802 /* Store data byte */
803 tmpbuf[0] = rds_data[0];
804 tmpbuf[1] = rds_data[1];
805
806 memcpy(&rds->buff[rds->wr_idx], &tmpbuf, FM_RDS_BLK_SIZE);
807 rds->wr_idx = (rds->wr_idx + FM_RDS_BLK_SIZE) % rds->buf_size;
808
809 /* Check for overflow & start over */
810 if (rds->wr_idx == rds->rd_idx) {
811 fmdbg("RDS buffer overflow\n");
812 rds->wr_idx = 0;
813 rds->rd_idx = 0;
814 break;
815 }
816 rds_len -= FM_RDS_BLK_SIZE;
817 rds_data += FM_RDS_BLK_SIZE;
818 }
819 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
820
821 /* Wakeup read queue */
822 if (rds->wr_idx != rds->rd_idx)
823 wake_up_interruptible(&rds->read_queue);
824
825 fm_irq_call_stage(fmdev, FM_RDS_FINISH_IDX);
826}
827
828static void fm_irq_handle_rds_finish(struct fmdev *fmdev)
829{
830 fm_irq_call_stage(fmdev, FM_HW_TUNE_OP_ENDED_IDX);
831}
832
833static void fm_irq_handle_tune_op_ended(struct fmdev *fmdev)
834{
835 if (fmdev->irq_info.flag & (FM_FR_EVENT | FM_BL_EVENT) & fmdev->
836 irq_info.mask) {
837 fmdbg("irq: tune ended/bandlimit reached\n");
838 if (test_and_clear_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag)) {
839 fmdev->irq_info.stage = FM_AF_JUMP_RD_FREQ_IDX;
840 } else {
841 complete(&fmdev->maintask_comp);
842 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX;
843 }
844 } else
845 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX;
846
847 fm_irq_call(fmdev);
848}
849
850static void fm_irq_handle_power_enb(struct fmdev *fmdev)
851{
852 if (fmdev->irq_info.flag & FM_POW_ENB_EVENT) {
853 fmdbg("irq: Power Enabled/Disabled\n");
854 complete(&fmdev->maintask_comp);
855 }
856
857 fm_irq_call_stage(fmdev, FM_LOW_RSSI_START_IDX);
858}
859
860static void fm_irq_handle_low_rssi_start(struct fmdev *fmdev)
861{
862 if ((fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) &&
863 (fmdev->irq_info.flag & FM_LEV_EVENT & fmdev->irq_info.mask) &&
864 (fmdev->rx.freq != FM_UNDEFINED_FREQ) &&
865 (fmdev->rx.stat_info.afcache_size != 0)) {
866 fmdbg("irq: rssi level has fallen below threshold level\n");
867
868 /* Disable further low RSSI interrupts */
869 fmdev->irq_info.mask &= ~FM_LEV_EVENT;
870
871 fmdev->rx.afjump_idx = 0;
872 fmdev->rx.freq_before_jump = fmdev->rx.freq;
873 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX;
874 } else {
875 /* Continue next function in interrupt handler table */
876 fmdev->irq_info.stage = FM_SEND_INTMSK_CMD_IDX;
877 }
878
879 fm_irq_call(fmdev);
880}
881
882static void fm_irq_afjump_set_pi(struct fmdev *fmdev)
883{
884 u16 payload;
885
886 /* Set PI code - must be updated if the AF list is not empty */
887 payload = fmdev->rx.stat_info.picode;
888 if (!fm_send_cmd(fmdev, RDS_PI_SET, REG_WR, &payload, sizeof(payload), NULL))
889 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_RESP_IDX);
890}
891
892static void fm_irq_handle_set_pi_resp(struct fmdev *fmdev)
893{
894 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SETPI_MASK_IDX);
895}
896
897/*
898 * Set PI mask.
899 * 0xFFFF = Enable PI code matching
900 * 0x0000 = Disable PI code matching
901 */
902static void fm_irq_afjump_set_pimask(struct fmdev *fmdev)
903{
904 u16 payload;
905
906 payload = 0x0000;
907 if (!fm_send_cmd(fmdev, RDS_PI_MASK_SET, REG_WR, &payload, sizeof(payload), NULL))
908 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX);
909}
910
911static void fm_irq_handle_set_pimask_resp(struct fmdev *fmdev)
912{
913 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SET_AF_FREQ_IDX);
914}
915
916static void fm_irq_afjump_setfreq(struct fmdev *fmdev)
917{
918 u16 frq_index;
919 u16 payload;
920
921 fmdbg("Swtich to %d KHz\n", fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx]);
922 frq_index = (fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx] -
923 fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
924
925 payload = frq_index;
926 if (!fm_send_cmd(fmdev, AF_FREQ_SET, REG_WR, &payload, sizeof(payload), NULL))
927 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX);
928}
929
930static void fm_irq_handle_setfreq_resp(struct fmdev *fmdev)
931{
932 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_ENABLE_INT_IDX);
933}
934
935static void fm_irq_afjump_enableint(struct fmdev *fmdev)
936{
937 u16 payload;
938
939 /* Enable FR (tuning operation ended) interrupt */
940 payload = FM_FR_EVENT;
941 if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, sizeof(payload), NULL))
942 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_ENABLE_INT_RESP_IDX);
943}
944
945static void fm_irq_afjump_enableint_resp(struct fmdev *fmdev)
946{
947 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_START_AFJUMP_IDX);
948}
949
950static void fm_irq_start_afjump(struct fmdev *fmdev)
951{
952 u16 payload;
953
954 payload = FM_TUNER_AF_JUMP_MODE;
955 if (!fm_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
956 sizeof(payload), NULL))
957 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX);
958}
959
960static void fm_irq_handle_start_afjump_resp(struct fmdev *fmdev)
961{
962 struct sk_buff *skb;
963
964 if (check_cmdresp_status(fmdev, &skb))
965 return;
966
967 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX;
968 set_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag);
969 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag);
970}
971
972static void fm_irq_afjump_rd_freq(struct fmdev *fmdev)
973{
974 u16 payload;
975
976 if (!fm_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, sizeof(payload), NULL))
977 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_RD_FREQ_RESP_IDX);
978}
979
980static void fm_irq_afjump_rd_freq_resp(struct fmdev *fmdev)
981{
982 struct sk_buff *skb;
983 u16 read_freq;
984 u32 curr_freq, jumped_freq;
985
986 if (check_cmdresp_status(fmdev, &skb))
987 return;
988
989 /* Skip header info and copy only response data */
990 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
991 memcpy(&read_freq, skb->data, sizeof(read_freq));
992 read_freq = be16_to_cpu(read_freq);
993 curr_freq = fmdev->rx.region.bot_freq + ((u32)read_freq * FM_FREQ_MUL);
994
995 jumped_freq = fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx];
996
997 /* If the frequency was changed the jump succeeded */
998 if ((curr_freq != fmdev->rx.freq_before_jump) && (curr_freq == jumped_freq)) {
999 fmdbg("Successfully switched to alternate freq %d\n", curr_freq);
1000 fmdev->rx.freq = curr_freq;
1001 fm_rx_reset_rds_cache(fmdev);
1002
1003 /* AF feature is on, enable low level RSSI interrupt */
1004 if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
1005 fmdev->irq_info.mask |= FM_LEV_EVENT;
1006
1007 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX;
1008 } else { /* jump to the next freq in the AF list */
1009 fmdev->rx.afjump_idx++;
1010
1011 /* If we reached the end of the list - stop searching */
1012 if (fmdev->rx.afjump_idx >= fmdev->rx.stat_info.afcache_size) {
1013 fmdbg("AF switch processing failed\n");
1014 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX;
1015 } else { /* AF List is not over - try next one */
1016
1017 fmdbg("Trying next freq in AF cache\n");
1018 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX;
1019 }
1020 }
1021 fm_irq_call(fmdev);
1022}
1023
1024static void fm_irq_handle_low_rssi_finish(struct fmdev *fmdev)
1025{
1026 fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX);
1027}
1028
1029static void fm_irq_send_intmsk_cmd(struct fmdev *fmdev)
1030{
1031 u16 payload;
1032
1033 /* Re-enable FM interrupts */
1034 payload = fmdev->irq_info.mask;
1035
1036 if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
1037 sizeof(payload), NULL))
1038 fm_irq_timeout_stage(fmdev, FM_HANDLE_INTMSK_CMD_RESP_IDX);
1039}
1040
1041static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *fmdev)
1042{
1043 struct sk_buff *skb;
1044
1045 if (check_cmdresp_status(fmdev, &skb))
1046 return;
1047 /*
1048 * This is last function in interrupt table to be executed.
1049 * So, reset stage index to 0.
1050 */
1051 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX;
1052
1053 /* Start processing any pending interrupt */
1054 if (test_and_clear_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag))
1055 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev);
1056 else
1057 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag);
1058}
1059
1060/* Returns availability of RDS data in internel buffer */
1061u32 fmc_is_rds_data_available(struct fmdev *fmdev, struct file *file,
1062 struct poll_table_struct *pts)
1063{
1064 poll_wait(file, &fmdev->rx.rds.read_queue, pts);
1065 if (fmdev->rx.rds.rd_idx != fmdev->rx.rds.wr_idx)
1066 return 0;
1067
1068 return -EAGAIN;
1069}
1070
1071/* Copies RDS data from internal buffer to user buffer */
1072u32 fmc_transfer_rds_from_internal_buff(struct fmdev *fmdev, struct file *file,
1073 u8 __user *buf, size_t count)
1074{
1075 u32 block_count;
1076 unsigned long flags;
1077 int ret;
1078
1079 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) {
1080 if (file->f_flags & O_NONBLOCK)
1081 return -EWOULDBLOCK;
1082
1083 ret = wait_event_interruptible(fmdev->rx.rds.read_queue,
1084 (fmdev->rx.rds.wr_idx != fmdev->rx.rds.rd_idx));
1085 if (ret)
1086 return -EINTR;
1087 }
1088
1089 /* Calculate block count from byte count */
1090 count /= 3;
1091 block_count = 0;
1092 ret = 0;
1093
1094 spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
1095
1096 while (block_count < count) {
1097 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx)
1098 break;
1099
1100 if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
1101 FM_RDS_BLK_SIZE))
1102 break;
1103
1104 fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE;
1105 if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size)
1106 fmdev->rx.rds.rd_idx = 0;
1107
1108 block_count++;
1109 buf += FM_RDS_BLK_SIZE;
1110 ret += FM_RDS_BLK_SIZE;
1111 }
1112 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
1113 return ret;
1114}
1115
1116u32 fmc_set_freq(struct fmdev *fmdev, u32 freq_to_set)
1117{
1118 switch (fmdev->curr_fmmode) {
1119 case FM_MODE_RX:
1120 return fm_rx_set_freq(fmdev, freq_to_set);
1121
1122 case FM_MODE_TX:
1123 return fm_tx_set_freq(fmdev, freq_to_set);
1124
1125 default:
1126 return -EINVAL;
1127 }
1128}
1129
1130u32 fmc_get_freq(struct fmdev *fmdev, u32 *cur_tuned_frq)
1131{
1132 if (fmdev->rx.freq == FM_UNDEFINED_FREQ) {
1133 fmerr("RX frequency is not set\n");
1134 return -EPERM;
1135 }
1136 if (cur_tuned_frq == NULL) {
1137 fmerr("Invalid memory\n");
1138 return -ENOMEM;
1139 }
1140
1141 switch (fmdev->curr_fmmode) {
1142 case FM_MODE_RX:
1143 *cur_tuned_frq = fmdev->rx.freq;
1144 return 0;
1145
1146 case FM_MODE_TX:
1147 *cur_tuned_frq = 0; /* TODO : Change this later */
1148 return 0;
1149
1150 default:
1151 return -EINVAL;
1152 }
1153
1154}
1155
1156u32 fmc_set_region(struct fmdev *fmdev, u8 region_to_set)
1157{
1158 switch (fmdev->curr_fmmode) {
1159 case FM_MODE_RX:
1160 return fm_rx_set_region(fmdev, region_to_set);
1161
1162 case FM_MODE_TX:
1163 return fm_tx_set_region(fmdev, region_to_set);
1164
1165 default:
1166 return -EINVAL;
1167 }
1168}
1169
1170u32 fmc_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
1171{
1172 switch (fmdev->curr_fmmode) {
1173 case FM_MODE_RX:
1174 return fm_rx_set_mute_mode(fmdev, mute_mode_toset);
1175
1176 case FM_MODE_TX:
1177 return fm_tx_set_mute_mode(fmdev, mute_mode_toset);
1178
1179 default:
1180 return -EINVAL;
1181 }
1182}
1183
1184u32 fmc_set_stereo_mono(struct fmdev *fmdev, u16 mode)
1185{
1186 switch (fmdev->curr_fmmode) {
1187 case FM_MODE_RX:
1188 return fm_rx_set_stereo_mono(fmdev, mode);
1189
1190 case FM_MODE_TX:
1191 return fm_tx_set_stereo_mono(fmdev, mode);
1192
1193 default:
1194 return -EINVAL;
1195 }
1196}
1197
1198u32 fmc_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
1199{
1200 switch (fmdev->curr_fmmode) {
1201 case FM_MODE_RX:
1202 return fm_rx_set_rds_mode(fmdev, rds_en_dis);
1203
1204 case FM_MODE_TX:
1205 return fm_tx_set_rds_mode(fmdev, rds_en_dis);
1206
1207 default:
1208 return -EINVAL;
1209 }
1210}
1211
1212/* Sends power off command to the chip */
1213static u32 fm_power_down(struct fmdev *fmdev)
1214{
1215 u16 payload;
1216 u32 ret;
1217
1218 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1219 fmerr("FM core is not ready\n");
1220 return -EPERM;
1221 }
1222 if (fmdev->curr_fmmode == FM_MODE_OFF) {
1223 fmdbg("FM chip is already in OFF state\n");
1224 return 0;
1225 }
1226
1227 payload = 0x0;
1228 ret = fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload,
1229 sizeof(payload), NULL, NULL);
1230 if (ret < 0)
1231 return ret;
1232
1233 return fmc_release(fmdev);
1234}
1235
1236/* Reads init command from FM firmware file and loads to the chip */
1237static u32 fm_download_firmware(struct fmdev *fmdev, const u8 *fw_name)
1238{
1239 const struct firmware *fw_entry;
1240 struct bts_header *fw_header;
1241 struct bts_action *action;
1242 struct bts_action_delay *delay;
1243 u8 *fw_data;
1244 int ret, fw_len, cmd_cnt;
1245
1246 cmd_cnt = 0;
1247 set_bit(FM_FW_DW_INPROGRESS, &fmdev->flag);
1248
1249 ret = request_firmware(&fw_entry, fw_name,
1250 &fmdev->radio_dev->dev);
1251 if (ret < 0) {
1252 fmerr("Unable to read firmware(%s) content\n", fw_name);
1253 return ret;
1254 }
1255 fmdbg("Firmware(%s) length : %d bytes\n", fw_name, fw_entry->size);
1256
1257 fw_data = (void *)fw_entry->data;
1258 fw_len = fw_entry->size;
1259
1260 fw_header = (struct bts_header *)fw_data;
1261 if (fw_header->magic != FM_FW_FILE_HEADER_MAGIC) {
1262 fmerr("%s not a legal TI firmware file\n", fw_name);
1263 ret = -EINVAL;
1264 goto rel_fw;
1265 }
1266 fmdbg("FW(%s) magic number : 0x%x\n", fw_name, fw_header->magic);
1267
1268 /* Skip file header info , we already verified it */
1269 fw_data += sizeof(struct bts_header);
1270 fw_len -= sizeof(struct bts_header);
1271
1272 while (fw_data && fw_len > 0) {
1273 action = (struct bts_action *)fw_data;
1274
1275 switch (action->type) {
1276 case ACTION_SEND_COMMAND: /* Send */
1277 if (fmc_send_cmd(fmdev, 0, 0, action->data,
1278 action->size, NULL, NULL))
1279 goto rel_fw;
1280
1281 cmd_cnt++;
1282 break;
1283
1284 case ACTION_DELAY: /* Delay */
1285 delay = (struct bts_action_delay *)action->data;
1286 mdelay(delay->msec);
1287 break;
1288 }
1289
1290 fw_data += (sizeof(struct bts_action) + (action->size));
1291 fw_len -= (sizeof(struct bts_action) + (action->size));
1292 }
1293 fmdbg("Firmware commands(%d) loaded to chip\n", cmd_cnt);
1294rel_fw:
1295 release_firmware(fw_entry);
1296 clear_bit(FM_FW_DW_INPROGRESS, &fmdev->flag);
1297
1298 return ret;
1299}
1300
1301/* Loads default RX configuration to the chip */
1302static u32 load_default_rx_configuration(struct fmdev *fmdev)
1303{
1304 int ret;
1305
1306 ret = fm_rx_set_volume(fmdev, FM_DEFAULT_RX_VOLUME);
1307 if (ret < 0)
1308 return ret;
1309
1310 return fm_rx_set_rssi_threshold(fmdev, FM_DEFAULT_RSSI_THRESHOLD);
1311}
1312
1313/* Does FM power on sequence */
1314static u32 fm_power_up(struct fmdev *fmdev, u8 mode)
1315{
1316 u16 payload, asic_id, asic_ver;
1317 int resp_len, ret;
1318 u8 fw_name[50];
1319
1320 if (mode >= FM_MODE_ENTRY_MAX) {
1321 fmerr("Invalid firmware download option\n");
1322 return -EINVAL;
1323 }
1324
1325 /*
1326 * Initialize FM common module. FM GPIO toggling is
1327 * taken care in Shared Transport driver.
1328 */
1329 ret = fmc_prepare(fmdev);
1330 if (ret < 0) {
1331 fmerr("Unable to prepare FM Common\n");
1332 return ret;
1333 }
1334
1335 payload = FM_ENABLE;
1336 if (fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload,
1337 sizeof(payload), NULL, NULL))
1338 goto rel;
1339
1340 /* Allow the chip to settle down in Channel-8 mode */
1341 msleep(20);
1342
1343 if (fmc_send_cmd(fmdev, ASIC_ID_GET, REG_RD, NULL,
1344 sizeof(asic_id), &asic_id, &resp_len))
1345 goto rel;
1346
1347 if (fmc_send_cmd(fmdev, ASIC_VER_GET, REG_RD, NULL,
1348 sizeof(asic_ver), &asic_ver, &resp_len))
1349 goto rel;
1350
1351 fmdbg("ASIC ID: 0x%x , ASIC Version: %d\n",
1352 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1353
1354 sprintf(fw_name, "%s_%x.%d.bts", FM_FMC_FW_FILE_START,
1355 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1356
1357 ret = fm_download_firmware(fmdev, fw_name);
1358 if (ret < 0) {
1359 fmdbg("Failed to download firmware file %s\n", fw_name);
1360 goto rel;
1361 }
1362 sprintf(fw_name, "%s_%x.%d.bts", (mode == FM_MODE_RX) ?
1363 FM_RX_FW_FILE_START : FM_TX_FW_FILE_START,
1364 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1365
1366 ret = fm_download_firmware(fmdev, fw_name);
1367 if (ret < 0) {
1368 fmdbg("Failed to download firmware file %s\n", fw_name);
1369 goto rel;
1370 } else
1371 return ret;
1372rel:
1373 return fmc_release(fmdev);
1374}
1375
1376/* Set FM Modes(TX, RX, OFF) */
1377u32 fmc_set_mode(struct fmdev *fmdev, u8 fm_mode)
1378{
1379 int ret = 0;
1380
1381 if (fm_mode >= FM_MODE_ENTRY_MAX) {
1382 fmerr("Invalid FM mode\n");
1383 return -EINVAL;
1384 }
1385 if (fmdev->curr_fmmode == fm_mode) {
1386 fmdbg("Already fm is in mode(%d)\n", fm_mode);
1387 return ret;
1388 }
1389
1390 switch (fm_mode) {
1391 case FM_MODE_OFF: /* OFF Mode */
1392 ret = fm_power_down(fmdev);
1393 if (ret < 0) {
1394 fmerr("Failed to set OFF mode\n");
1395 return ret;
1396 }
1397 break;
1398
1399 case FM_MODE_TX: /* TX Mode */
1400 case FM_MODE_RX: /* RX Mode */
1401 /* Power down before switching to TX or RX mode */
1402 if (fmdev->curr_fmmode != FM_MODE_OFF) {
1403 ret = fm_power_down(fmdev);
1404 if (ret < 0) {
1405 fmerr("Failed to set OFF mode\n");
1406 return ret;
1407 }
1408 msleep(30);
1409 }
1410 ret = fm_power_up(fmdev, fm_mode);
1411 if (ret < 0) {
1412 fmerr("Failed to load firmware\n");
1413 return ret;
1414 }
1415 }
1416 fmdev->curr_fmmode = fm_mode;
1417
1418 /* Set default configuration */
1419 if (fmdev->curr_fmmode == FM_MODE_RX) {
1420 fmdbg("Loading default rx configuration..\n");
1421 ret = load_default_rx_configuration(fmdev);
1422 if (ret < 0)
1423 fmerr("Failed to load default values\n");
1424 }
1425
1426 return ret;
1427}
1428
1429/* Returns current FM mode (TX, RX, OFF) */
1430u32 fmc_get_mode(struct fmdev *fmdev, u8 *fmmode)
1431{
1432 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1433 fmerr("FM core is not ready\n");
1434 return -EPERM;
1435 }
1436 if (fmmode == NULL) {
1437 fmerr("Invalid memory\n");
1438 return -ENOMEM;
1439 }
1440
1441 *fmmode = fmdev->curr_fmmode;
1442 return 0;
1443}
1444
1445/* Called by ST layer when FM packet is available */
1446static long fm_st_receive(void *arg, struct sk_buff *skb)
1447{
1448 struct fmdev *fmdev;
1449
1450 fmdev = (struct fmdev *)arg;
1451
1452 if (skb == NULL) {
1453 fmerr("Invalid SKB received from ST\n");
1454 return -EFAULT;
1455 }
1456
1457 if (skb->cb[0] != FM_PKT_LOGICAL_CHAN_NUMBER) {
1458 fmerr("Received SKB (%p) is not FM Channel 8 pkt\n", skb);
1459 return -EINVAL;
1460 }
1461
1462 memcpy(skb_push(skb, 1), &skb->cb[0], 1);
1463 skb_queue_tail(&fmdev->rx_q, skb);
1464 tasklet_schedule(&fmdev->rx_task);
1465
1466 return 0;
1467}
1468
1469/*
1470 * Called by ST layer to indicate protocol registration completion
1471 * status.
1472 */
1473static void fm_st_reg_comp_cb(void *arg, char data)
1474{
1475 struct fmdev *fmdev;
1476
1477 fmdev = (struct fmdev *)arg;
1478 fmdev->streg_cbdata = data;
1479 complete(&wait_for_fmdrv_reg_comp);
1480}
1481
1482/*
1483 * This function will be called from FM V4L2 open function.
1484 * Register with ST driver and initialize driver data.
1485 */
1486u32 fmc_prepare(struct fmdev *fmdev)
1487{
1488 static struct st_proto_s fm_st_proto;
1489 u32 ret;
1490
1491 if (test_bit(FM_CORE_READY, &fmdev->flag)) {
1492 fmdbg("FM Core is already up\n");
1493 return 0;
1494 }
1495
1496 memset(&fm_st_proto, 0, sizeof(fm_st_proto));
1497 fm_st_proto.type = ST_FM;
1498 fm_st_proto.recv = fm_st_receive;
1499 fm_st_proto.match_packet = NULL;
1500 fm_st_proto.reg_complete_cb = fm_st_reg_comp_cb;
1501 fm_st_proto.write = NULL; /* TI ST driver will fill write pointer */
1502 fm_st_proto.priv_data = fmdev;
1503
1504 ret = st_register(&fm_st_proto);
1505 if (ret == -EINPROGRESS) {
1506 init_completion(&wait_for_fmdrv_reg_comp);
1507 fmdev->streg_cbdata = -EINPROGRESS;
1508 fmdbg("%s waiting for ST reg completion signal\n", __func__);
1509
1510 ret = wait_for_completion_timeout(&wait_for_fmdrv_reg_comp,
1511 FM_ST_REG_TIMEOUT);
1512
1513 if (!ret) {
1514 fmerr("Timeout(%d sec), didn't get reg "
1515 "completion signal from ST\n",
1516 jiffies_to_msecs(FM_ST_REG_TIMEOUT) / 1000);
1517 return -ETIMEDOUT;
1518 }
1519 if (fmdev->streg_cbdata != 0) {
1520 fmerr("ST reg comp CB called with error "
1521 "status %d\n", fmdev->streg_cbdata);
1522 return -EAGAIN;
1523 }
1524
1525 ret = 0;
1526 } else if (ret == -1) {
1527 fmerr("st_register failed %d\n", ret);
1528 return -EAGAIN;
1529 }
1530
1531 if (fm_st_proto.write != NULL) {
1532 g_st_write = fm_st_proto.write;
1533 } else {
1534 fmerr("Failed to get ST write func pointer\n");
1535 ret = st_unregister(ST_FM);
1536 if (ret < 0)
1537 fmerr("st_unregister failed %d\n", ret);
1538 return -EAGAIN;
1539 }
1540
1541 spin_lock_init(&fmdev->rds_buff_lock);
1542 spin_lock_init(&fmdev->resp_skb_lock);
1543
1544 /* Initialize TX queue and TX tasklet */
1545 skb_queue_head_init(&fmdev->tx_q);
1546 tasklet_init(&fmdev->tx_task, send_tasklet, (unsigned long)fmdev);
1547
1548 /* Initialize RX Queue and RX tasklet */
1549 skb_queue_head_init(&fmdev->rx_q);
1550 tasklet_init(&fmdev->rx_task, recv_tasklet, (unsigned long)fmdev);
1551
1552 fmdev->irq_info.stage = 0;
1553 atomic_set(&fmdev->tx_cnt, 1);
1554 fmdev->resp_comp = NULL;
1555
1556 init_timer(&fmdev->irq_info.timer);
1557 fmdev->irq_info.timer.function = &int_timeout_handler;
1558 fmdev->irq_info.timer.data = (unsigned long)fmdev;
1559 /*TODO: add FM_STIC_EVENT later */
1560 fmdev->irq_info.mask = FM_MAL_EVENT;
1561
1562 /* Region info */
1563 memcpy(&fmdev->rx.region, &region_configs[default_radio_region],
1564 sizeof(struct region_info));
1565
1566 fmdev->rx.mute_mode = FM_MUTE_OFF;
1567 fmdev->rx.rf_depend_mute = FM_RX_RF_DEPENDENT_MUTE_OFF;
1568 fmdev->rx.rds.flag = FM_RDS_DISABLE;
1569 fmdev->rx.freq = FM_UNDEFINED_FREQ;
1570 fmdev->rx.rds_mode = FM_RDS_SYSTEM_RDS;
1571 fmdev->rx.af_mode = FM_RX_RDS_AF_SWITCH_MODE_OFF;
1572 fmdev->irq_info.retry = 0;
1573
1574 fm_rx_reset_rds_cache(fmdev);
1575 init_waitqueue_head(&fmdev->rx.rds.read_queue);
1576
1577 fm_rx_reset_station_info(fmdev);
1578 set_bit(FM_CORE_READY, &fmdev->flag);
1579
1580 return ret;
1581}
1582
1583/*
1584 * This function will be called from FM V4L2 release function.
1585 * Unregister from ST driver.
1586 */
1587u32 fmc_release(struct fmdev *fmdev)
1588{
1589 u32 ret;
1590
1591 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1592 fmdbg("FM Core is already down\n");
1593 return 0;
1594 }
1595 /* Sevice pending read */
1596 wake_up_interruptible(&fmdev->rx.rds.read_queue);
1597
1598 tasklet_kill(&fmdev->tx_task);
1599 tasklet_kill(&fmdev->rx_task);
1600
1601 skb_queue_purge(&fmdev->tx_q);
1602 skb_queue_purge(&fmdev->rx_q);
1603
1604 fmdev->resp_comp = NULL;
1605 fmdev->rx.freq = 0;
1606
1607 ret = st_unregister(ST_FM);
1608 if (ret < 0)
1609 fmerr("Failed to de-register FM from ST %d\n", ret);
1610 else
1611 fmdbg("Successfully unregistered from ST\n");
1612
1613 clear_bit(FM_CORE_READY, &fmdev->flag);
1614 return ret;
1615}
1616
1617/*
1618 * Module init function. Ask FM V4L module to register video device.
1619 * Allocate memory for FM driver context and RX RDS buffer.
1620 */
1621static int __init fm_drv_init(void)
1622{
1623 struct fmdev *fmdev = NULL;
1624 u32 ret = -ENOMEM;
1625
1626 fmdbg("FM driver version %s\n", FM_DRV_VERSION);
1627
1628 fmdev = kzalloc(sizeof(struct fmdev), GFP_KERNEL);
1629 if (NULL == fmdev) {
1630 fmerr("Can't allocate operation structure memory\n");
1631 return ret;
1632 }
1633 fmdev->rx.rds.buf_size = default_rds_buf * FM_RDS_BLK_SIZE;
1634 fmdev->rx.rds.buff = kzalloc(fmdev->rx.rds.buf_size, GFP_KERNEL);
1635 if (NULL == fmdev->rx.rds.buff) {
1636 fmerr("Can't allocate rds ring buffer\n");
1637 goto rel_dev;
1638 }
1639
1640 ret = fm_v4l2_init_video_device(fmdev, radio_nr);
1641 if (ret < 0)
1642 goto rel_rdsbuf;
1643
1644 fmdev->irq_info.handlers = int_handler_table;
1645 fmdev->curr_fmmode = FM_MODE_OFF;
1646 fmdev->tx_data.pwr_lvl = FM_PWR_LVL_DEF;
1647 fmdev->tx_data.preemph = FM_TX_PREEMPH_50US;
1648 return ret;
1649
1650rel_rdsbuf:
1651 kfree(fmdev->rx.rds.buff);
1652rel_dev:
1653 kfree(fmdev);
1654
1655 return ret;
1656}
1657
1658/* Module exit function. Ask FM V4L module to unregister video device */
1659static void __exit fm_drv_exit(void)
1660{
1661 struct fmdev *fmdev = NULL;
1662
1663 fmdev = fm_v4l2_deinit_video_device();
1664 if (fmdev != NULL) {
1665 kfree(fmdev->rx.rds.buff);
1666 kfree(fmdev);
1667 }
1668}
1669
1670module_init(fm_drv_init);
1671module_exit(fm_drv_exit);
1672
1673/* ------------- Module Info ------------- */
1674MODULE_AUTHOR("Manjunatha Halli <manjunatha_halli@ti.com>");
1675MODULE_DESCRIPTION("FM Driver for TI's Connectivity chip. " FM_DRV_VERSION);
1676MODULE_VERSION(FM_DRV_VERSION);
1677MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/wl128x/fmdrv_common.h b/drivers/media/radio/wl128x/fmdrv_common.h
new file mode 100644
index 000000000000..427c4164cece
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_common.h
@@ -0,0 +1,402 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM Common module header file
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_COMMON_H
23#define _FMDRV_COMMON_H
24
25#define FM_ST_REG_TIMEOUT msecs_to_jiffies(6000) /* 6 sec */
26#define FM_PKT_LOGICAL_CHAN_NUMBER 0x08 /* Logical channel 8 */
27
28#define REG_RD 0x1
29#define REG_WR 0x0
30
31struct fm_reg_table {
32 u8 opcode;
33 u8 type;
34 u8 *name;
35};
36
37#define STEREO_GET 0
38#define RSSI_LVL_GET 1
39#define IF_COUNT_GET 2
40#define FLAG_GET 3
41#define RDS_SYNC_GET 4
42#define RDS_DATA_GET 5
43#define FREQ_SET 10
44#define AF_FREQ_SET 11
45#define MOST_MODE_SET 12
46#define MOST_BLEND_SET 13
47#define DEMPH_MODE_SET 14
48#define SEARCH_LVL_SET 15
49#define BAND_SET 16
50#define MUTE_STATUS_SET 17
51#define RDS_PAUSE_LVL_SET 18
52#define RDS_PAUSE_DUR_SET 19
53#define RDS_MEM_SET 20
54#define RDS_BLK_B_SET 21
55#define RDS_MSK_B_SET 22
56#define RDS_PI_MASK_SET 23
57#define RDS_PI_SET 24
58#define RDS_SYSTEM_SET 25
59#define INT_MASK_SET 26
60#define SEARCH_DIR_SET 27
61#define VOLUME_SET 28
62#define AUDIO_ENABLE_SET 29
63#define PCM_MODE_SET 30
64#define I2S_MODE_CONFIG_SET 31
65#define POWER_SET 32
66#define INTX_CONFIG_SET 33
67#define PULL_EN_SET 34
68#define HILO_SET 35
69#define SWITCH2FREF 36
70#define FREQ_DRIFT_REPORT 37
71
72#define PCE_GET 40
73#define FIRM_VER_GET 41
74#define ASIC_VER_GET 42
75#define ASIC_ID_GET 43
76#define MAN_ID_GET 44
77#define TUNER_MODE_SET 45
78#define STOP_SEARCH 46
79#define RDS_CNTRL_SET 47
80
81#define WRITE_HARDWARE_REG 100
82#define CODE_DOWNLOAD 101
83#define RESET 102
84
85#define FM_POWER_MODE 254
86#define FM_INTERRUPT 255
87
88/* Transmitter API */
89
90#define CHANL_SET 55
91#define CHANL_BW_SET 56
92#define REF_SET 57
93#define POWER_ENB_SET 90
94#define POWER_ATT_SET 58
95#define POWER_LEV_SET 59
96#define AUDIO_DEV_SET 60
97#define PILOT_DEV_SET 61
98#define RDS_DEV_SET 62
99#define TX_BAND_SET 65
100#define PUPD_SET 91
101#define AUDIO_IO_SET 63
102#define PREMPH_SET 64
103#define MONO_SET 66
104#define MUTE 92
105#define MPX_LMT_ENABLE 67
106#define PI_SET 93
107#define ECC_SET 69
108#define PTY 70
109#define AF 71
110#define DISPLAY_MODE 74
111#define RDS_REP_SET 77
112#define RDS_CONFIG_DATA_SET 98
113#define RDS_DATA_SET 99
114#define RDS_DATA_ENB 94
115#define TA_SET 78
116#define TP_SET 79
117#define DI_SET 80
118#define MS_SET 81
119#define PS_SCROLL_SPEED 82
120#define TX_AUDIO_LEVEL_TEST 96
121#define TX_AUDIO_LEVEL_TEST_THRESHOLD 73
122#define TX_AUDIO_INPUT_LEVEL_RANGE_SET 54
123#define RX_ANTENNA_SELECT 87
124#define I2C_DEV_ADDR_SET 86
125#define REF_ERR_CALIB_PARAM_SET 88
126#define REF_ERR_CALIB_PERIODICITY_SET 89
127#define SOC_INT_TRIGGER 52
128#define SOC_AUDIO_PATH_SET 83
129#define SOC_PCMI_OVERRIDE 84
130#define SOC_I2S_OVERRIDE 85
131#define RSSI_BLOCK_SCAN_FREQ_SET 95
132#define RSSI_BLOCK_SCAN_START 97
133#define RSSI_BLOCK_SCAN_DATA_GET 5
134#define READ_FMANT_TUNE_VALUE 104
135
136/* SKB helpers */
137struct fm_skb_cb {
138 __u8 fm_op;
139 struct completion *completion;
140};
141
142#define fm_cb(skb) ((struct fm_skb_cb *)(skb->cb))
143
144/* FM Channel-8 command message format */
145struct fm_cmd_msg_hdr {
146 __u8 hdr; /* Logical Channel-8 */
147 __u8 len; /* Number of bytes follows */
148 __u8 op; /* FM Opcode */
149 __u8 rd_wr; /* Read/Write command */
150 __u8 dlen; /* Length of payload */
151} __attribute__ ((packed));
152
153#define FM_CMD_MSG_HDR_SIZE 5 /* sizeof(struct fm_cmd_msg_hdr) */
154
155/* FM Channel-8 event messgage format */
156struct fm_event_msg_hdr {
157 __u8 header; /* Logical Channel-8 */
158 __u8 len; /* Number of bytes follows */
159 __u8 status; /* Event status */
160 __u8 num_fm_hci_cmds; /* Number of pkts the host allowed to send */
161 __u8 op; /* FM Opcode */
162 __u8 rd_wr; /* Read/Write command */
163 __u8 dlen; /* Length of payload */
164} __attribute__ ((packed));
165
166#define FM_EVT_MSG_HDR_SIZE 7 /* sizeof(struct fm_event_msg_hdr) */
167
168/* TI's magic number in firmware file */
169#define FM_FW_FILE_HEADER_MAGIC 0x42535442
170
171#define FM_ENABLE 1
172#define FM_DISABLE 0
173
174/* FLAG_GET register bits */
175#define FM_FR_EVENT (1 << 0)
176#define FM_BL_EVENT (1 << 1)
177#define FM_RDS_EVENT (1 << 2)
178#define FM_BBLK_EVENT (1 << 3)
179#define FM_LSYNC_EVENT (1 << 4)
180#define FM_LEV_EVENT (1 << 5)
181#define FM_IFFR_EVENT (1 << 6)
182#define FM_PI_EVENT (1 << 7)
183#define FM_PD_EVENT (1 << 8)
184#define FM_STIC_EVENT (1 << 9)
185#define FM_MAL_EVENT (1 << 10)
186#define FM_POW_ENB_EVENT (1 << 11)
187
188/*
189 * Firmware files of FM. ASIC ID and ASIC version will be appened to this,
190 * later.
191 */
192#define FM_FMC_FW_FILE_START ("fmc_ch8")
193#define FM_RX_FW_FILE_START ("fm_rx_ch8")
194#define FM_TX_FW_FILE_START ("fm_tx_ch8")
195
196#define FM_UNDEFINED_FREQ 0xFFFFFFFF
197
198/* Band types */
199#define FM_BAND_EUROPE_US 0
200#define FM_BAND_JAPAN 1
201
202/* Seek directions */
203#define FM_SEARCH_DIRECTION_DOWN 0
204#define FM_SEARCH_DIRECTION_UP 1
205
206/* Tunner modes */
207#define FM_TUNER_STOP_SEARCH_MODE 0
208#define FM_TUNER_PRESET_MODE 1
209#define FM_TUNER_AUTONOMOUS_SEARCH_MODE 2
210#define FM_TUNER_AF_JUMP_MODE 3
211
212/* Min and Max volume */
213#define FM_RX_VOLUME_MIN 0
214#define FM_RX_VOLUME_MAX 70
215
216/* Volume gain step */
217#define FM_RX_VOLUME_GAIN_STEP 0x370
218
219/* Mute modes */
220#define FM_MUTE_ON 0
221#define FM_MUTE_OFF 1
222#define FM_MUTE_ATTENUATE 2
223
224#define FM_RX_UNMUTE_MODE 0x00
225#define FM_RX_RF_DEP_MODE 0x01
226#define FM_RX_AC_MUTE_MODE 0x02
227#define FM_RX_HARD_MUTE_LEFT_MODE 0x04
228#define FM_RX_HARD_MUTE_RIGHT_MODE 0x08
229#define FM_RX_SOFT_MUTE_FORCE_MODE 0x10
230
231/* RF dependent mute mode */
232#define FM_RX_RF_DEPENDENT_MUTE_ON 1
233#define FM_RX_RF_DEPENDENT_MUTE_OFF 0
234
235/* RSSI threshold min and max */
236#define FM_RX_RSSI_THRESHOLD_MIN -128
237#define FM_RX_RSSI_THRESHOLD_MAX 127
238
239/* Stereo/Mono mode */
240#define FM_STEREO_MODE 0
241#define FM_MONO_MODE 1
242#define FM_STEREO_SOFT_BLEND 1
243
244/* FM RX De-emphasis filter modes */
245#define FM_RX_EMPHASIS_FILTER_50_USEC 0
246#define FM_RX_EMPHASIS_FILTER_75_USEC 1
247
248/* FM RDS modes */
249#define FM_RDS_DISABLE 0
250#define FM_RDS_ENABLE 1
251
252#define FM_NO_PI_CODE 0
253
254/* FM and RX RDS block enable/disable */
255#define FM_RX_PWR_SET_FM_ON_RDS_OFF 0x1
256#define FM_RX_PWR_SET_FM_AND_RDS_BLK_ON 0x3
257#define FM_RX_PWR_SET_FM_AND_RDS_BLK_OFF 0x0
258
259/* RX RDS */
260#define FM_RX_RDS_FLUSH_FIFO 0x1
261#define FM_RX_RDS_FIFO_THRESHOLD 64 /* tuples */
262#define FM_RDS_BLK_SIZE 3 /* 3 bytes */
263
264/* RDS block types */
265#define FM_RDS_BLOCK_A 0
266#define FM_RDS_BLOCK_B 1
267#define FM_RDS_BLOCK_C 2
268#define FM_RDS_BLOCK_Ctag 3
269#define FM_RDS_BLOCK_D 4
270#define FM_RDS_BLOCK_E 5
271
272#define FM_RDS_BLK_IDX_A 0
273#define FM_RDS_BLK_IDX_B 1
274#define FM_RDS_BLK_IDX_C 2
275#define FM_RDS_BLK_IDX_D 3
276#define FM_RDS_BLK_IDX_UNKNOWN 0xF0
277
278#define FM_RDS_STATUS_ERR_MASK 0x18
279
280/*
281 * Represents an RDS group type & version.
282 * There are 15 groups, each group has 2 versions: A and B.
283 */
284#define FM_RDS_GROUP_TYPE_MASK_0A ((unsigned long)1<<0)
285#define FM_RDS_GROUP_TYPE_MASK_0B ((unsigned long)1<<1)
286#define FM_RDS_GROUP_TYPE_MASK_1A ((unsigned long)1<<2)
287#define FM_RDS_GROUP_TYPE_MASK_1B ((unsigned long)1<<3)
288#define FM_RDS_GROUP_TYPE_MASK_2A ((unsigned long)1<<4)
289#define FM_RDS_GROUP_TYPE_MASK_2B ((unsigned long)1<<5)
290#define FM_RDS_GROUP_TYPE_MASK_3A ((unsigned long)1<<6)
291#define FM_RDS_GROUP_TYPE_MASK_3B ((unsigned long)1<<7)
292#define FM_RDS_GROUP_TYPE_MASK_4A ((unsigned long)1<<8)
293#define FM_RDS_GROUP_TYPE_MASK_4B ((unsigned long)1<<9)
294#define FM_RDS_GROUP_TYPE_MASK_5A ((unsigned long)1<<10)
295#define FM_RDS_GROUP_TYPE_MASK_5B ((unsigned long)1<<11)
296#define FM_RDS_GROUP_TYPE_MASK_6A ((unsigned long)1<<12)
297#define FM_RDS_GROUP_TYPE_MASK_6B ((unsigned long)1<<13)
298#define FM_RDS_GROUP_TYPE_MASK_7A ((unsigned long)1<<14)
299#define FM_RDS_GROUP_TYPE_MASK_7B ((unsigned long)1<<15)
300#define FM_RDS_GROUP_TYPE_MASK_8A ((unsigned long)1<<16)
301#define FM_RDS_GROUP_TYPE_MASK_8B ((unsigned long)1<<17)
302#define FM_RDS_GROUP_TYPE_MASK_9A ((unsigned long)1<<18)
303#define FM_RDS_GROUP_TYPE_MASK_9B ((unsigned long)1<<19)
304#define FM_RDS_GROUP_TYPE_MASK_10A ((unsigned long)1<<20)
305#define FM_RDS_GROUP_TYPE_MASK_10B ((unsigned long)1<<21)
306#define FM_RDS_GROUP_TYPE_MASK_11A ((unsigned long)1<<22)
307#define FM_RDS_GROUP_TYPE_MASK_11B ((unsigned long)1<<23)
308#define FM_RDS_GROUP_TYPE_MASK_12A ((unsigned long)1<<24)
309#define FM_RDS_GROUP_TYPE_MASK_12B ((unsigned long)1<<25)
310#define FM_RDS_GROUP_TYPE_MASK_13A ((unsigned long)1<<26)
311#define FM_RDS_GROUP_TYPE_MASK_13B ((unsigned long)1<<27)
312#define FM_RDS_GROUP_TYPE_MASK_14A ((unsigned long)1<<28)
313#define FM_RDS_GROUP_TYPE_MASK_14B ((unsigned long)1<<29)
314#define FM_RDS_GROUP_TYPE_MASK_15A ((unsigned long)1<<30)
315#define FM_RDS_GROUP_TYPE_MASK_15B ((unsigned long)1<<31)
316
317/* RX Alternate Frequency info */
318#define FM_RDS_MIN_AF 1
319#define FM_RDS_MAX_AF 204
320#define FM_RDS_MAX_AF_JAPAN 140
321#define FM_RDS_1_AF_FOLLOWS 225
322#define FM_RDS_25_AF_FOLLOWS 249
323
324/* RDS system type (RDS/RBDS) */
325#define FM_RDS_SYSTEM_RDS 0
326#define FM_RDS_SYSTEM_RBDS 1
327
328/* AF on/off */
329#define FM_RX_RDS_AF_SWITCH_MODE_ON 1
330#define FM_RX_RDS_AF_SWITCH_MODE_OFF 0
331
332/* Retry count when interrupt process goes wrong */
333#define FM_IRQ_TIMEOUT_RETRY_MAX 5 /* 5 times */
334
335/* Audio IO set values */
336#define FM_RX_AUDIO_ENABLE_I2S 0x01
337#define FM_RX_AUDIO_ENABLE_ANALOG 0x02
338#define FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG 0x03
339#define FM_RX_AUDIO_ENABLE_DISABLE 0x00
340
341/* HI/LO set values */
342#define FM_RX_IFFREQ_TO_HI_SIDE 0x0
343#define FM_RX_IFFREQ_TO_LO_SIDE 0x1
344#define FM_RX_IFFREQ_HILO_AUTOMATIC 0x2
345
346/*
347 * Default RX mode configuration. Chip will be configured
348 * with this default values after loading RX firmware.
349 */
350#define FM_DEFAULT_RX_VOLUME 10
351#define FM_DEFAULT_RSSI_THRESHOLD 3
352
353/* Range for TX power level in units for dB/uV */
354#define FM_PWR_LVL_LOW 91
355#define FM_PWR_LVL_HIGH 122
356
357/* Chip specific default TX power level value */
358#define FM_PWR_LVL_DEF 4
359
360/* FM TX Pre-emphasis filter values */
361#define FM_TX_PREEMPH_OFF 1
362#define FM_TX_PREEMPH_50US 0
363#define FM_TX_PREEMPH_75US 2
364
365/* FM TX antenna impedence values */
366#define FM_TX_ANT_IMP_50 0
367#define FM_TX_ANT_IMP_200 1
368#define FM_TX_ANT_IMP_500 2
369
370/* Functions exported by FM common sub-module */
371u32 fmc_prepare(struct fmdev *);
372u32 fmc_release(struct fmdev *);
373
374void fmc_update_region_info(struct fmdev *, u8);
375u32 fmc_send_cmd(struct fmdev *, u8, u16,
376 void *, unsigned int, void *, int *);
377u32 fmc_is_rds_data_available(struct fmdev *, struct file *,
378 struct poll_table_struct *);
379u32 fmc_transfer_rds_from_internal_buff(struct fmdev *, struct file *,
380 u8 __user *, size_t);
381
382u32 fmc_set_freq(struct fmdev *, u32);
383u32 fmc_set_mode(struct fmdev *, u8);
384u32 fmc_set_region(struct fmdev *, u8);
385u32 fmc_set_mute_mode(struct fmdev *, u8);
386u32 fmc_set_stereo_mono(struct fmdev *, u16);
387u32 fmc_set_rds_mode(struct fmdev *, u8);
388
389u32 fmc_get_freq(struct fmdev *, u32 *);
390u32 fmc_get_region(struct fmdev *, u8 *);
391u32 fmc_get_mode(struct fmdev *, u8 *);
392
393/*
394 * channel spacing
395 */
396#define FM_CHANNEL_SPACING_50KHZ 1
397#define FM_CHANNEL_SPACING_100KHZ 2
398#define FM_CHANNEL_SPACING_200KHZ 4
399#define FM_FREQ_MUL 50
400
401#endif
402
diff --git a/drivers/media/radio/wl128x/fmdrv_rx.c b/drivers/media/radio/wl128x/fmdrv_rx.c
new file mode 100644
index 000000000000..ec529b55b040
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_rx.c
@@ -0,0 +1,847 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This sub-module of FM driver implements FM RX functionality.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 * Author: Raja Mani <raja_mani@ti.com>
7 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "fmdrv.h"
25#include "fmdrv_common.h"
26#include "fmdrv_rx.h"
27
28void fm_rx_reset_rds_cache(struct fmdev *fmdev)
29{
30 fmdev->rx.rds.flag = FM_RDS_DISABLE;
31 fmdev->rx.rds.last_blk_idx = 0;
32 fmdev->rx.rds.wr_idx = 0;
33 fmdev->rx.rds.rd_idx = 0;
34
35 if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
36 fmdev->irq_info.mask |= FM_LEV_EVENT;
37}
38
39void fm_rx_reset_station_info(struct fmdev *fmdev)
40{
41 fmdev->rx.stat_info.picode = FM_NO_PI_CODE;
42 fmdev->rx.stat_info.afcache_size = 0;
43 fmdev->rx.stat_info.af_list_max = 0;
44}
45
46u32 fm_rx_set_freq(struct fmdev *fmdev, u32 freq)
47{
48 unsigned long timeleft;
49 u16 payload, curr_frq, intr_flag;
50 u32 curr_frq_in_khz;
51 u32 ret, resp_len;
52
53 if (freq < fmdev->rx.region.bot_freq || freq > fmdev->rx.region.top_freq) {
54 fmerr("Invalid frequency %d\n", freq);
55 return -EINVAL;
56 }
57
58 /* Set audio enable */
59 payload = FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG;
60
61 ret = fmc_send_cmd(fmdev, AUDIO_ENABLE_SET, REG_WR, &payload,
62 sizeof(payload), NULL, NULL);
63 if (ret < 0)
64 return ret;
65
66 /* Set hilo to automatic selection */
67 payload = FM_RX_IFFREQ_HILO_AUTOMATIC;
68 ret = fmc_send_cmd(fmdev, HILO_SET, REG_WR, &payload,
69 sizeof(payload), NULL, NULL);
70 if (ret < 0)
71 return ret;
72
73 /* Calculate frequency index and set*/
74 payload = (freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
75
76 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload,
77 sizeof(payload), NULL, NULL);
78 if (ret < 0)
79 return ret;
80
81 /* Read flags - just to clear any pending interrupts if we had */
82 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL);
83 if (ret < 0)
84 return ret;
85
86 /* Enable FR, BL interrupts */
87 intr_flag = fmdev->irq_info.mask;
88 fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT);
89 payload = fmdev->irq_info.mask;
90 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
91 sizeof(payload), NULL, NULL);
92 if (ret < 0)
93 return ret;
94
95 /* Start tune */
96 payload = FM_TUNER_PRESET_MODE;
97 ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
98 sizeof(payload), NULL, NULL);
99 if (ret < 0)
100 goto exit;
101
102 /* Wait for tune ended interrupt */
103 init_completion(&fmdev->maintask_comp);
104 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
105 FM_DRV_TX_TIMEOUT);
106 if (!timeleft) {
107 fmerr("Timeout(%d sec),didn't get tune ended int\n",
108 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
109 ret = -ETIMEDOUT;
110 goto exit;
111 }
112
113 /* Read freq back to confirm */
114 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2, &curr_frq, &resp_len);
115 if (ret < 0)
116 goto exit;
117
118 curr_frq = be16_to_cpu(curr_frq);
119 curr_frq_in_khz = (fmdev->rx.region.bot_freq + ((u32)curr_frq * FM_FREQ_MUL));
120
121 if (curr_frq_in_khz != freq) {
122 pr_info("Frequency is set to (%d) but "
123 "requested freq is (%d)\n", curr_frq_in_khz, freq);
124 }
125
126 /* Update local cache */
127 fmdev->rx.freq = curr_frq_in_khz;
128exit:
129 /* Re-enable default FM interrupts */
130 fmdev->irq_info.mask = intr_flag;
131 payload = fmdev->irq_info.mask;
132 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
133 sizeof(payload), NULL, NULL);
134 if (ret < 0)
135 return ret;
136
137 /* Reset RDS cache and current station pointers */
138 fm_rx_reset_rds_cache(fmdev);
139 fm_rx_reset_station_info(fmdev);
140
141 return ret;
142}
143
144static u32 fm_rx_set_channel_spacing(struct fmdev *fmdev, u32 spacing)
145{
146 u16 payload;
147 u32 ret;
148
149 if (spacing > 0 && spacing <= 50000)
150 spacing = FM_CHANNEL_SPACING_50KHZ;
151 else if (spacing > 50000 && spacing <= 100000)
152 spacing = FM_CHANNEL_SPACING_100KHZ;
153 else
154 spacing = FM_CHANNEL_SPACING_200KHZ;
155
156 /* set channel spacing */
157 payload = spacing;
158 ret = fmc_send_cmd(fmdev, CHANL_BW_SET, REG_WR, &payload,
159 sizeof(payload), NULL, NULL);
160 if (ret < 0)
161 return ret;
162
163 fmdev->rx.region.chanl_space = spacing * FM_FREQ_MUL;
164
165 return ret;
166}
167
168u32 fm_rx_seek(struct fmdev *fmdev, u32 seek_upward,
169 u32 wrap_around, u32 spacing)
170{
171 u32 resp_len;
172 u16 curr_frq, next_frq, last_frq;
173 u16 payload, int_reason, intr_flag;
174 u16 offset, space_idx;
175 unsigned long timeleft;
176 u32 ret;
177
178 /* Set channel spacing */
179 ret = fm_rx_set_channel_spacing(fmdev, spacing);
180 if (ret < 0) {
181 fmerr("Failed to set channel spacing\n");
182 return ret;
183 }
184
185 /* Read the current frequency from chip */
186 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL,
187 sizeof(curr_frq), &curr_frq, &resp_len);
188 if (ret < 0)
189 return ret;
190
191 curr_frq = be16_to_cpu(curr_frq);
192 last_frq = (fmdev->rx.region.top_freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
193
194 /* Check the offset in order to be aligned to the channel spacing*/
195 space_idx = fmdev->rx.region.chanl_space / FM_FREQ_MUL;
196 offset = curr_frq % space_idx;
197
198 next_frq = seek_upward ? curr_frq + space_idx /* Seek Up */ :
199 curr_frq - space_idx /* Seek Down */ ;
200
201 /*
202 * Add or subtract offset in order to stay aligned to the channel
203 * spacing.
204 */
205 if ((short)next_frq < 0)
206 next_frq = last_frq - offset;
207 else if (next_frq > last_frq)
208 next_frq = 0 + offset;
209
210again:
211 /* Set calculated next frequency to perform seek */
212 payload = next_frq;
213 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload,
214 sizeof(payload), NULL, NULL);
215 if (ret < 0)
216 return ret;
217
218 /* Set search direction (0:Seek Down, 1:Seek Up) */
219 payload = (seek_upward ? FM_SEARCH_DIRECTION_UP : FM_SEARCH_DIRECTION_DOWN);
220 ret = fmc_send_cmd(fmdev, SEARCH_DIR_SET, REG_WR, &payload,
221 sizeof(payload), NULL, NULL);
222 if (ret < 0)
223 return ret;
224
225 /* Read flags - just to clear any pending interrupts if we had */
226 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL);
227 if (ret < 0)
228 return ret;
229
230 /* Enable FR, BL interrupts */
231 intr_flag = fmdev->irq_info.mask;
232 fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT);
233 payload = fmdev->irq_info.mask;
234 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
235 sizeof(payload), NULL, NULL);
236 if (ret < 0)
237 return ret;
238
239 /* Start seek */
240 payload = FM_TUNER_AUTONOMOUS_SEARCH_MODE;
241 ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
242 sizeof(payload), NULL, NULL);
243 if (ret < 0)
244 return ret;
245
246 /* Wait for tune ended/band limit reached interrupt */
247 init_completion(&fmdev->maintask_comp);
248 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
249 FM_DRV_RX_SEEK_TIMEOUT);
250 if (!timeleft) {
251 fmerr("Timeout(%d sec),didn't get tune ended int\n",
252 jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000);
253 return -ETIMEDOUT;
254 }
255
256 int_reason = fmdev->irq_info.flag & (FM_TUNE_COMPLETE | FM_BAND_LIMIT);
257
258 /* Re-enable default FM interrupts */
259 fmdev->irq_info.mask = intr_flag;
260 payload = fmdev->irq_info.mask;
261 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
262 sizeof(payload), NULL, NULL);
263 if (ret < 0)
264 return ret;
265
266 if (int_reason & FM_BL_EVENT) {
267 if (wrap_around == 0) {
268 fmdev->rx.freq = seek_upward ?
269 fmdev->rx.region.top_freq :
270 fmdev->rx.region.bot_freq;
271 } else {
272 fmdev->rx.freq = seek_upward ?
273 fmdev->rx.region.bot_freq :
274 fmdev->rx.region.top_freq;
275 /* Calculate frequency index to write */
276 next_frq = (fmdev->rx.freq -
277 fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
278 goto again;
279 }
280 } else {
281 /* Read freq to know where operation tune operation stopped */
282 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2,
283 &curr_frq, &resp_len);
284 if (ret < 0)
285 return ret;
286
287 curr_frq = be16_to_cpu(curr_frq);
288 fmdev->rx.freq = (fmdev->rx.region.bot_freq +
289 ((u32)curr_frq * FM_FREQ_MUL));
290
291 }
292 /* Reset RDS cache and current station pointers */
293 fm_rx_reset_rds_cache(fmdev);
294 fm_rx_reset_station_info(fmdev);
295
296 return ret;
297}
298
299u32 fm_rx_set_volume(struct fmdev *fmdev, u16 vol_to_set)
300{
301 u16 payload;
302 u32 ret;
303
304 if (fmdev->curr_fmmode != FM_MODE_RX)
305 return -EPERM;
306
307 if (vol_to_set < FM_RX_VOLUME_MIN || vol_to_set > FM_RX_VOLUME_MAX) {
308 fmerr("Volume is not within(%d-%d) range\n",
309 FM_RX_VOLUME_MIN, FM_RX_VOLUME_MAX);
310 return -EINVAL;
311 }
312 vol_to_set *= FM_RX_VOLUME_GAIN_STEP;
313
314 payload = vol_to_set;
315 ret = fmc_send_cmd(fmdev, VOLUME_SET, REG_WR, &payload,
316 sizeof(payload), NULL, NULL);
317 if (ret < 0)
318 return ret;
319
320 fmdev->rx.volume = vol_to_set;
321 return ret;
322}
323
324/* Get volume */
325u32 fm_rx_get_volume(struct fmdev *fmdev, u16 *curr_vol)
326{
327 if (fmdev->curr_fmmode != FM_MODE_RX)
328 return -EPERM;
329
330 if (curr_vol == NULL) {
331 fmerr("Invalid memory\n");
332 return -ENOMEM;
333 }
334
335 *curr_vol = fmdev->rx.volume / FM_RX_VOLUME_GAIN_STEP;
336
337 return 0;
338}
339
340/* To get current band's bottom and top frequency */
341u32 fm_rx_get_band_freq_range(struct fmdev *fmdev, u32 *bot_freq, u32 *top_freq)
342{
343 if (bot_freq != NULL)
344 *bot_freq = fmdev->rx.region.bot_freq;
345
346 if (top_freq != NULL)
347 *top_freq = fmdev->rx.region.top_freq;
348
349 return 0;
350}
351
352/* Returns current band index (0-Europe/US; 1-Japan) */
353void fm_rx_get_region(struct fmdev *fmdev, u8 *region)
354{
355 *region = fmdev->rx.region.fm_band;
356}
357
358/* Sets band (0-Europe/US; 1-Japan) */
359u32 fm_rx_set_region(struct fmdev *fmdev, u8 region_to_set)
360{
361 u16 payload;
362 u32 new_frq = 0;
363 u32 ret;
364
365 if (region_to_set != FM_BAND_EUROPE_US &&
366 region_to_set != FM_BAND_JAPAN) {
367 fmerr("Invalid band\n");
368 return -EINVAL;
369 }
370
371 if (fmdev->rx.region.fm_band == region_to_set) {
372 fmerr("Requested band is already configured\n");
373 return 0;
374 }
375
376 /* Send cmd to set the band */
377 payload = (u16)region_to_set;
378 ret = fmc_send_cmd(fmdev, BAND_SET, REG_WR, &payload,
379 sizeof(payload), NULL, NULL);
380 if (ret < 0)
381 return ret;
382
383 fmc_update_region_info(fmdev, region_to_set);
384
385 /* Check whether current RX frequency is within band boundary */
386 if (fmdev->rx.freq < fmdev->rx.region.bot_freq)
387 new_frq = fmdev->rx.region.bot_freq;
388 else if (fmdev->rx.freq > fmdev->rx.region.top_freq)
389 new_frq = fmdev->rx.region.top_freq;
390
391 if (new_frq) {
392 fmdbg("Current freq is not within band limit boundary,"
393 "switching to %d KHz\n", new_frq);
394 /* Current RX frequency is not in range. So, update it */
395 ret = fm_rx_set_freq(fmdev, new_frq);
396 }
397
398 return ret;
399}
400
401/* Reads current mute mode (Mute Off/On/Attenuate)*/
402u32 fm_rx_get_mute_mode(struct fmdev *fmdev, u8 *curr_mute_mode)
403{
404 if (fmdev->curr_fmmode != FM_MODE_RX)
405 return -EPERM;
406
407 if (curr_mute_mode == NULL) {
408 fmerr("Invalid memory\n");
409 return -ENOMEM;
410 }
411
412 *curr_mute_mode = fmdev->rx.mute_mode;
413
414 return 0;
415}
416
417static u32 fm_config_rx_mute_reg(struct fmdev *fmdev)
418{
419 u16 payload, muteval;
420 u32 ret;
421
422 muteval = 0;
423 switch (fmdev->rx.mute_mode) {
424 case FM_MUTE_ON:
425 muteval = FM_RX_AC_MUTE_MODE;
426 break;
427
428 case FM_MUTE_OFF:
429 muteval = FM_RX_UNMUTE_MODE;
430 break;
431
432 case FM_MUTE_ATTENUATE:
433 muteval = FM_RX_SOFT_MUTE_FORCE_MODE;
434 break;
435 }
436 if (fmdev->rx.rf_depend_mute == FM_RX_RF_DEPENDENT_MUTE_ON)
437 muteval |= FM_RX_RF_DEP_MODE;
438 else
439 muteval &= ~FM_RX_RF_DEP_MODE;
440
441 payload = muteval;
442 ret = fmc_send_cmd(fmdev, MUTE_STATUS_SET, REG_WR, &payload,
443 sizeof(payload), NULL, NULL);
444 if (ret < 0)
445 return ret;
446
447 return 0;
448}
449
450/* Configures mute mode (Mute Off/On/Attenuate) */
451u32 fm_rx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
452{
453 u8 org_state;
454 u32 ret;
455
456 if (fmdev->rx.mute_mode == mute_mode_toset)
457 return 0;
458
459 org_state = fmdev->rx.mute_mode;
460 fmdev->rx.mute_mode = mute_mode_toset;
461
462 ret = fm_config_rx_mute_reg(fmdev);
463 if (ret < 0) {
464 fmdev->rx.mute_mode = org_state;
465 return ret;
466 }
467
468 return 0;
469}
470
471/* Gets RF dependent soft mute mode enable/disable status */
472u32 fm_rx_get_rfdepend_softmute(struct fmdev *fmdev, u8 *curr_mute_mode)
473{
474 if (fmdev->curr_fmmode != FM_MODE_RX)
475 return -EPERM;
476
477 if (curr_mute_mode == NULL) {
478 fmerr("Invalid memory\n");
479 return -ENOMEM;
480 }
481
482 *curr_mute_mode = fmdev->rx.rf_depend_mute;
483
484 return 0;
485}
486
487/* Sets RF dependent soft mute mode */
488u32 fm_rx_set_rfdepend_softmute(struct fmdev *fmdev, u8 rfdepend_mute)
489{
490 u8 org_state;
491 u32 ret;
492
493 if (fmdev->curr_fmmode != FM_MODE_RX)
494 return -EPERM;
495
496 if (rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_ON &&
497 rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_OFF) {
498 fmerr("Invalid RF dependent soft mute\n");
499 return -EINVAL;
500 }
501 if (fmdev->rx.rf_depend_mute == rfdepend_mute)
502 return 0;
503
504 org_state = fmdev->rx.rf_depend_mute;
505 fmdev->rx.rf_depend_mute = rfdepend_mute;
506
507 ret = fm_config_rx_mute_reg(fmdev);
508 if (ret < 0) {
509 fmdev->rx.rf_depend_mute = org_state;
510 return ret;
511 }
512
513 return 0;
514}
515
516/* Returns the signal strength level of current channel */
517u32 fm_rx_get_rssi_level(struct fmdev *fmdev, u16 *rssilvl)
518{
519 u16 curr_rssi_lel;
520 u32 resp_len;
521 u32 ret;
522
523 if (rssilvl == NULL) {
524 fmerr("Invalid memory\n");
525 return -ENOMEM;
526 }
527 /* Read current RSSI level */
528 ret = fmc_send_cmd(fmdev, RSSI_LVL_GET, REG_RD, NULL, 2,
529 &curr_rssi_lel, &resp_len);
530 if (ret < 0)
531 return ret;
532
533 *rssilvl = be16_to_cpu(curr_rssi_lel);
534
535 return 0;
536}
537
538/*
539 * Sets the signal strength level that once reached
540 * will stop the auto search process
541 */
542u32 fm_rx_set_rssi_threshold(struct fmdev *fmdev, short rssi_lvl_toset)
543{
544 u16 payload;
545 u32 ret;
546
547 if (rssi_lvl_toset < FM_RX_RSSI_THRESHOLD_MIN ||
548 rssi_lvl_toset > FM_RX_RSSI_THRESHOLD_MAX) {
549 fmerr("Invalid RSSI threshold level\n");
550 return -EINVAL;
551 }
552 payload = (u16)rssi_lvl_toset;
553 ret = fmc_send_cmd(fmdev, SEARCH_LVL_SET, REG_WR, &payload,
554 sizeof(payload), NULL, NULL);
555 if (ret < 0)
556 return ret;
557
558 fmdev->rx.rssi_threshold = rssi_lvl_toset;
559
560 return 0;
561}
562
563/* Returns current RX RSSI threshold value */
564u32 fm_rx_get_rssi_threshold(struct fmdev *fmdev, short *curr_rssi_lvl)
565{
566 if (fmdev->curr_fmmode != FM_MODE_RX)
567 return -EPERM;
568
569 if (curr_rssi_lvl == NULL) {
570 fmerr("Invalid memory\n");
571 return -ENOMEM;
572 }
573
574 *curr_rssi_lvl = fmdev->rx.rssi_threshold;
575
576 return 0;
577}
578
579/* Sets RX stereo/mono modes */
580u32 fm_rx_set_stereo_mono(struct fmdev *fmdev, u16 mode)
581{
582 u16 payload;
583 u32 ret;
584
585 if (mode != FM_STEREO_MODE && mode != FM_MONO_MODE) {
586 fmerr("Invalid mode\n");
587 return -EINVAL;
588 }
589
590 /* Set stereo/mono mode */
591 payload = (u16)mode;
592 ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_WR, &payload,
593 sizeof(payload), NULL, NULL);
594 if (ret < 0)
595 return ret;
596
597 /* Set stereo blending mode */
598 payload = FM_STEREO_SOFT_BLEND;
599 ret = fmc_send_cmd(fmdev, MOST_BLEND_SET, REG_WR, &payload,
600 sizeof(payload), NULL, NULL);
601 if (ret < 0)
602 return ret;
603
604 return 0;
605}
606
607/* Gets current RX stereo/mono mode */
608u32 fm_rx_get_stereo_mono(struct fmdev *fmdev, u16 *mode)
609{
610 u16 curr_mode;
611 u32 ret, resp_len;
612
613 if (mode == NULL) {
614 fmerr("Invalid memory\n");
615 return -ENOMEM;
616 }
617
618 ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_RD, NULL, 2,
619 &curr_mode, &resp_len);
620 if (ret < 0)
621 return ret;
622
623 *mode = be16_to_cpu(curr_mode);
624
625 return 0;
626}
627
628/* Choose RX de-emphasis filter mode (50us/75us) */
629u32 fm_rx_set_deemphasis_mode(struct fmdev *fmdev, u16 mode)
630{
631 u16 payload;
632 u32 ret;
633
634 if (fmdev->curr_fmmode != FM_MODE_RX)
635 return -EPERM;
636
637 if (mode != FM_RX_EMPHASIS_FILTER_50_USEC &&
638 mode != FM_RX_EMPHASIS_FILTER_75_USEC) {
639 fmerr("Invalid rx de-emphasis mode (%d)\n", mode);
640 return -EINVAL;
641 }
642
643 payload = mode;
644 ret = fmc_send_cmd(fmdev, DEMPH_MODE_SET, REG_WR, &payload,
645 sizeof(payload), NULL, NULL);
646 if (ret < 0)
647 return ret;
648
649 fmdev->rx.deemphasis_mode = mode;
650
651 return 0;
652}
653
654/* Gets current RX de-emphasis filter mode */
655u32 fm_rx_get_deemph_mode(struct fmdev *fmdev, u16 *curr_deemphasis_mode)
656{
657 if (fmdev->curr_fmmode != FM_MODE_RX)
658 return -EPERM;
659
660 if (curr_deemphasis_mode == NULL) {
661 fmerr("Invalid memory\n");
662 return -ENOMEM;
663 }
664
665 *curr_deemphasis_mode = fmdev->rx.deemphasis_mode;
666
667 return 0;
668}
669
670/* Enable/Disable RX RDS */
671u32 fm_rx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
672{
673 u16 payload;
674 u32 ret;
675
676 if (rds_en_dis != FM_RDS_ENABLE && rds_en_dis != FM_RDS_DISABLE) {
677 fmerr("Invalid rds option\n");
678 return -EINVAL;
679 }
680
681 if (rds_en_dis == FM_RDS_ENABLE
682 && fmdev->rx.rds.flag == FM_RDS_DISABLE) {
683 /* Turn on RX RDS and RDS circuit */
684 payload = FM_RX_PWR_SET_FM_AND_RDS_BLK_ON;
685 ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload,
686 sizeof(payload), NULL, NULL);
687 if (ret < 0)
688 return ret;
689
690 /* Clear and reset RDS FIFO */
691 payload = FM_RX_RDS_FLUSH_FIFO;
692 ret = fmc_send_cmd(fmdev, RDS_CNTRL_SET, REG_WR, &payload,
693 sizeof(payload), NULL, NULL);
694 if (ret < 0)
695 return ret;
696
697 /* Read flags - just to clear any pending interrupts. */
698 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2,
699 NULL, NULL);
700 if (ret < 0)
701 return ret;
702
703 /* Set RDS FIFO threshold value */
704 payload = FM_RX_RDS_FIFO_THRESHOLD;
705 ret = fmc_send_cmd(fmdev, RDS_MEM_SET, REG_WR, &payload,
706 sizeof(payload), NULL, NULL);
707 if (ret < 0)
708 return ret;
709
710 /* Enable RDS interrupt */
711 fmdev->irq_info.mask |= FM_RDS_EVENT;
712 payload = fmdev->irq_info.mask;
713 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
714 sizeof(payload), NULL, NULL);
715 if (ret < 0) {
716 fmdev->irq_info.mask &= ~FM_RDS_EVENT;
717 return ret;
718 }
719
720 /* Update our local flag */
721 fmdev->rx.rds.flag = FM_RDS_ENABLE;
722 } else if (rds_en_dis == FM_RDS_DISABLE
723 && fmdev->rx.rds.flag == FM_RDS_ENABLE) {
724 /* Turn off RX RDS */
725 payload = FM_RX_PWR_SET_FM_ON_RDS_OFF;
726 ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload,
727 sizeof(payload), NULL, NULL);
728 if (ret < 0)
729 return ret;
730
731 /* Reset RDS pointers */
732 fmdev->rx.rds.last_blk_idx = 0;
733 fmdev->rx.rds.wr_idx = 0;
734 fmdev->rx.rds.rd_idx = 0;
735 fm_rx_reset_station_info(fmdev);
736
737 /* Update RDS local cache */
738 fmdev->irq_info.mask &= ~(FM_RDS_EVENT);
739 fmdev->rx.rds.flag = FM_RDS_DISABLE;
740 }
741
742 return 0;
743}
744
745/* Returns current RX RDS enable/disable status */
746u32 fm_rx_get_rds_mode(struct fmdev *fmdev, u8 *curr_rds_en_dis)
747{
748 if (fmdev->curr_fmmode != FM_MODE_RX)
749 return -EPERM;
750
751 if (curr_rds_en_dis == NULL) {
752 fmerr("Invalid memory\n");
753 return -ENOMEM;
754 }
755
756 *curr_rds_en_dis = fmdev->rx.rds.flag;
757
758 return 0;
759}
760
761/* Sets RDS operation mode (RDS/RDBS) */
762u32 fm_rx_set_rds_system(struct fmdev *fmdev, u8 rds_mode)
763{
764 u16 payload;
765 u32 ret;
766
767 if (fmdev->curr_fmmode != FM_MODE_RX)
768 return -EPERM;
769
770 if (rds_mode != FM_RDS_SYSTEM_RDS && rds_mode != FM_RDS_SYSTEM_RBDS) {
771 fmerr("Invalid rds mode\n");
772 return -EINVAL;
773 }
774 /* Set RDS operation mode */
775 payload = (u16)rds_mode;
776 ret = fmc_send_cmd(fmdev, RDS_SYSTEM_SET, REG_WR, &payload,
777 sizeof(payload), NULL, NULL);
778 if (ret < 0)
779 return ret;
780
781 fmdev->rx.rds_mode = rds_mode;
782
783 return 0;
784}
785
786/* Returns current RDS operation mode */
787u32 fm_rx_get_rds_system(struct fmdev *fmdev, u8 *rds_mode)
788{
789 if (fmdev->curr_fmmode != FM_MODE_RX)
790 return -EPERM;
791
792 if (rds_mode == NULL) {
793 fmerr("Invalid memory\n");
794 return -ENOMEM;
795 }
796
797 *rds_mode = fmdev->rx.rds_mode;
798
799 return 0;
800}
801
802/* Configures Alternate Frequency switch mode */
803u32 fm_rx_set_af_switch(struct fmdev *fmdev, u8 af_mode)
804{
805 u16 payload;
806 u32 ret;
807
808 if (fmdev->curr_fmmode != FM_MODE_RX)
809 return -EPERM;
810
811 if (af_mode != FM_RX_RDS_AF_SWITCH_MODE_ON &&
812 af_mode != FM_RX_RDS_AF_SWITCH_MODE_OFF) {
813 fmerr("Invalid af mode\n");
814 return -EINVAL;
815 }
816 /* Enable/disable low RSSI interrupt based on af_mode */
817 if (af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
818 fmdev->irq_info.mask |= FM_LEV_EVENT;
819 else
820 fmdev->irq_info.mask &= ~FM_LEV_EVENT;
821
822 payload = fmdev->irq_info.mask;
823 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
824 sizeof(payload), NULL, NULL);
825 if (ret < 0)
826 return ret;
827
828 fmdev->rx.af_mode = af_mode;
829
830 return 0;
831}
832
833/* Returns Alternate Frequency switch status */
834u32 fm_rx_get_af_switch(struct fmdev *fmdev, u8 *af_mode)
835{
836 if (fmdev->curr_fmmode != FM_MODE_RX)
837 return -EPERM;
838
839 if (af_mode == NULL) {
840 fmerr("Invalid memory\n");
841 return -ENOMEM;
842 }
843
844 *af_mode = fmdev->rx.af_mode;
845
846 return 0;
847}
diff --git a/drivers/media/radio/wl128x/fmdrv_rx.h b/drivers/media/radio/wl128x/fmdrv_rx.h
new file mode 100644
index 000000000000..329e62f6be76
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_rx.h
@@ -0,0 +1,59 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM RX module header.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_RX_H
23#define _FMDRV_RX_H
24
25u32 fm_rx_set_freq(struct fmdev *, u32);
26u32 fm_rx_set_mute_mode(struct fmdev *, u8);
27u32 fm_rx_set_stereo_mono(struct fmdev *, u16);
28u32 fm_rx_set_rds_mode(struct fmdev *, u8);
29u32 fm_rx_set_rds_system(struct fmdev *, u8);
30u32 fm_rx_set_volume(struct fmdev *, u16);
31u32 fm_rx_set_rssi_threshold(struct fmdev *, short);
32u32 fm_rx_set_region(struct fmdev *, u8);
33u32 fm_rx_set_rfdepend_softmute(struct fmdev *, u8);
34u32 fm_rx_set_deemphasis_mode(struct fmdev *, u16);
35u32 fm_rx_set_af_switch(struct fmdev *, u8);
36
37void fm_rx_reset_rds_cache(struct fmdev *);
38void fm_rx_reset_station_info(struct fmdev *);
39
40u32 fm_rx_seek(struct fmdev *, u32, u32, u32);
41
42u32 fm_rx_get_rds_mode(struct fmdev *, u8 *);
43u32 fm_rx_get_rds_system(struct fmdev *, u8 *);
44u32 fm_rx_get_mute_mode(struct fmdev *, u8 *);
45u32 fm_rx_get_volume(struct fmdev *, u16 *);
46u32 fm_rx_get_band_freq_range(struct fmdev *,
47 u32 *, u32 *);
48u32 fm_rx_get_stereo_mono(struct fmdev *, u16 *);
49u32 fm_rx_get_rssi_level(struct fmdev *, u16 *);
50u32 fm_rx_get_rssi_threshold(struct fmdev *, short *);
51u32 fm_rx_get_rfdepend_softmute(struct fmdev *, u8 *);
52u32 fm_rx_get_deemph_mode(struct fmdev *, u16 *);
53u32 fm_rx_get_af_switch(struct fmdev *, u8 *);
54void fm_rx_get_region(struct fmdev *, u8 *);
55
56u32 fm_rx_set_chanl_spacing(struct fmdev *, u8);
57u32 fm_rx_get_chanl_spacing(struct fmdev *, u8 *);
58#endif
59
diff --git a/drivers/media/radio/wl128x/fmdrv_tx.c b/drivers/media/radio/wl128x/fmdrv_tx.c
new file mode 100644
index 000000000000..be54068b56a8
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_tx.c
@@ -0,0 +1,425 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This sub-module of FM driver implements FM TX functionality.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/delay.h>
23#include "fmdrv.h"
24#include "fmdrv_common.h"
25#include "fmdrv_tx.h"
26
27u32 fm_tx_set_stereo_mono(struct fmdev *fmdev, u16 mode)
28{
29 u16 payload;
30 u32 ret;
31
32 if (fmdev->tx_data.aud_mode == mode)
33 return 0;
34
35 fmdbg("stereo mode: %d\n", mode);
36
37 /* Set Stereo/Mono mode */
38 payload = (1 - mode);
39 ret = fmc_send_cmd(fmdev, MONO_SET, REG_WR, &payload,
40 sizeof(payload), NULL, NULL);
41 if (ret < 0)
42 return ret;
43
44 fmdev->tx_data.aud_mode = mode;
45
46 return ret;
47}
48
49static u32 set_rds_text(struct fmdev *fmdev, u8 *rds_text)
50{
51 u16 payload;
52 u32 ret;
53
54 ret = fmc_send_cmd(fmdev, RDS_DATA_SET, REG_WR, rds_text,
55 strlen(rds_text), NULL, NULL);
56 if (ret < 0)
57 return ret;
58
59 /* Scroll mode */
60 payload = (u16)0x1;
61 ret = fmc_send_cmd(fmdev, DISPLAY_MODE, REG_WR, &payload,
62 sizeof(payload), NULL, NULL);
63 if (ret < 0)
64 return ret;
65
66 return 0;
67}
68
69static u32 set_rds_data_mode(struct fmdev *fmdev, u8 mode)
70{
71 u16 payload;
72 u32 ret;
73
74 /* Setting unique PI TODO: how unique? */
75 payload = (u16)0xcafe;
76 ret = fmc_send_cmd(fmdev, PI_SET, REG_WR, &payload,
77 sizeof(payload), NULL, NULL);
78 if (ret < 0)
79 return ret;
80
81 /* Set decoder id */
82 payload = (u16)0xa;
83 ret = fmc_send_cmd(fmdev, DI_SET, REG_WR, &payload,
84 sizeof(payload), NULL, NULL);
85 if (ret < 0)
86 return ret;
87
88 /* TODO: RDS_MODE_GET? */
89 return 0;
90}
91
92static u32 set_rds_len(struct fmdev *fmdev, u8 type, u16 len)
93{
94 u16 payload;
95 u32 ret;
96
97 len |= type << 8;
98 payload = len;
99 ret = fmc_send_cmd(fmdev, RDS_CONFIG_DATA_SET, REG_WR, &payload,
100 sizeof(payload), NULL, NULL);
101 if (ret < 0)
102 return ret;
103
104 /* TODO: LENGTH_GET? */
105 return 0;
106}
107
108u32 fm_tx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
109{
110 u16 payload;
111 u32 ret;
112 u8 rds_text[] = "Zoom2\n";
113
114 fmdbg("rds_en_dis:%d(E:%d, D:%d)\n", rds_en_dis,
115 FM_RDS_ENABLE, FM_RDS_DISABLE);
116
117 if (rds_en_dis == FM_RDS_ENABLE) {
118 /* Set RDS length */
119 set_rds_len(fmdev, 0, strlen(rds_text));
120
121 /* Set RDS text */
122 set_rds_text(fmdev, rds_text);
123
124 /* Set RDS mode */
125 set_rds_data_mode(fmdev, 0x0);
126 }
127
128 /* Send command to enable RDS */
129 if (rds_en_dis == FM_RDS_ENABLE)
130 payload = 0x01;
131 else
132 payload = 0x00;
133
134 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
135 sizeof(payload), NULL, NULL);
136 if (ret < 0)
137 return ret;
138
139 if (rds_en_dis == FM_RDS_ENABLE) {
140 /* Set RDS length */
141 set_rds_len(fmdev, 0, strlen(rds_text));
142
143 /* Set RDS text */
144 set_rds_text(fmdev, rds_text);
145 }
146 fmdev->tx_data.rds.flag = rds_en_dis;
147
148 return 0;
149}
150
151u32 fm_tx_set_radio_text(struct fmdev *fmdev, u8 *rds_text, u8 rds_type)
152{
153 u16 payload;
154 u32 ret;
155
156 if (fmdev->curr_fmmode != FM_MODE_TX)
157 return -EPERM;
158
159 fm_tx_set_rds_mode(fmdev, 0);
160
161 /* Set RDS length */
162 set_rds_len(fmdev, rds_type, strlen(rds_text));
163
164 /* Set RDS text */
165 set_rds_text(fmdev, rds_text);
166
167 /* Set RDS mode */
168 set_rds_data_mode(fmdev, 0x0);
169
170 payload = 1;
171 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
172 sizeof(payload), NULL, NULL);
173 if (ret < 0)
174 return ret;
175
176 return 0;
177}
178
179u32 fm_tx_set_af(struct fmdev *fmdev, u32 af)
180{
181 u16 payload;
182 u32 ret;
183
184 if (fmdev->curr_fmmode != FM_MODE_TX)
185 return -EPERM;
186
187 fmdbg("AF: %d\n", af);
188
189 af = (af - 87500) / 100;
190 payload = (u16)af;
191 ret = fmc_send_cmd(fmdev, TA_SET, REG_WR, &payload,
192 sizeof(payload), NULL, NULL);
193 if (ret < 0)
194 return ret;
195
196 return 0;
197}
198
199u32 fm_tx_set_region(struct fmdev *fmdev, u8 region)
200{
201 u16 payload;
202 u32 ret;
203
204 if (region != FM_BAND_EUROPE_US && region != FM_BAND_JAPAN) {
205 fmerr("Invalid band\n");
206 return -EINVAL;
207 }
208
209 /* Send command to set the band */
210 payload = (u16)region;
211 ret = fmc_send_cmd(fmdev, TX_BAND_SET, REG_WR, &payload,
212 sizeof(payload), NULL, NULL);
213 if (ret < 0)
214 return ret;
215
216 return 0;
217}
218
219u32 fm_tx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
220{
221 u16 payload;
222 u32 ret;
223
224 fmdbg("tx: mute mode %d\n", mute_mode_toset);
225
226 payload = mute_mode_toset;
227 ret = fmc_send_cmd(fmdev, MUTE, REG_WR, &payload,
228 sizeof(payload), NULL, NULL);
229 if (ret < 0)
230 return ret;
231
232 return 0;
233}
234
235/* Set TX Audio I/O */
236static u32 set_audio_io(struct fmdev *fmdev)
237{
238 struct fmtx_data *tx = &fmdev->tx_data;
239 u16 payload;
240 u32 ret;
241
242 /* Set Audio I/O Enable */
243 payload = tx->audio_io;
244 ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, REG_WR, &payload,
245 sizeof(payload), NULL, NULL);
246 if (ret < 0)
247 return ret;
248
249 /* TODO: is audio set? */
250 return 0;
251}
252
253/* Start TX Transmission */
254static u32 enable_xmit(struct fmdev *fmdev, u8 new_xmit_state)
255{
256 struct fmtx_data *tx = &fmdev->tx_data;
257 unsigned long timeleft;
258 u16 payload;
259 u32 ret;
260
261 /* Enable POWER_ENB interrupts */
262 payload = FM_POW_ENB_EVENT;
263 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
264 sizeof(payload), NULL, NULL);
265 if (ret < 0)
266 return ret;
267
268 /* Set Power Enable */
269 payload = new_xmit_state;
270 ret = fmc_send_cmd(fmdev, POWER_ENB_SET, REG_WR, &payload,
271 sizeof(payload), NULL, NULL);
272 if (ret < 0)
273 return ret;
274
275 /* Wait for Power Enabled */
276 init_completion(&fmdev->maintask_comp);
277 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
278 FM_DRV_TX_TIMEOUT);
279 if (!timeleft) {
280 fmerr("Timeout(%d sec),didn't get tune ended interrupt\n",
281 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
282 return -ETIMEDOUT;
283 }
284
285 set_bit(FM_CORE_TX_XMITING, &fmdev->flag);
286 tx->xmit_state = new_xmit_state;
287
288 return 0;
289}
290
291/* Set TX power level */
292u32 fm_tx_set_pwr_lvl(struct fmdev *fmdev, u8 new_pwr_lvl)
293{
294 u16 payload;
295 struct fmtx_data *tx = &fmdev->tx_data;
296 u32 ret;
297
298 if (fmdev->curr_fmmode != FM_MODE_TX)
299 return -EPERM;
300 fmdbg("tx: pwr_level_to_set %ld\n", (long int)new_pwr_lvl);
301
302 /* If the core isn't ready update global variable */
303 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
304 tx->pwr_lvl = new_pwr_lvl;
305 return 0;
306 }
307
308 /* Set power level: Application will specify power level value in
309 * units of dB/uV, whereas range and step are specific to FM chip.
310 * For TI's WL chips, convert application specified power level value
311 * to chip specific value by subtracting 122 from it. Refer to TI FM
312 * data sheet for details.
313 * */
314
315 payload = (FM_PWR_LVL_HIGH - new_pwr_lvl);
316 ret = fmc_send_cmd(fmdev, POWER_LEV_SET, REG_WR, &payload,
317 sizeof(payload), NULL, NULL);
318 if (ret < 0)
319 return ret;
320
321 /* TODO: is the power level set? */
322 tx->pwr_lvl = new_pwr_lvl;
323
324 return 0;
325}
326
327/*
328 * Sets FM TX pre-emphasis filter value (OFF, 50us, or 75us)
329 * Convert V4L2 specified filter values to chip specific filter values.
330 */
331u32 fm_tx_set_preemph_filter(struct fmdev *fmdev, u32 preemphasis)
332{
333 struct fmtx_data *tx = &fmdev->tx_data;
334 u16 payload;
335 u32 ret;
336
337 if (fmdev->curr_fmmode != FM_MODE_TX)
338 return -EPERM;
339
340 switch (preemphasis) {
341 case V4L2_PREEMPHASIS_DISABLED:
342 payload = FM_TX_PREEMPH_OFF;
343 break;
344 case V4L2_PREEMPHASIS_50_uS:
345 payload = FM_TX_PREEMPH_50US;
346 break;
347 case V4L2_PREEMPHASIS_75_uS:
348 payload = FM_TX_PREEMPH_75US;
349 break;
350 }
351
352 ret = fmc_send_cmd(fmdev, PREMPH_SET, REG_WR, &payload,
353 sizeof(payload), NULL, NULL);
354 if (ret < 0)
355 return ret;
356
357 tx->preemph = payload;
358
359 return ret;
360}
361
362/* Get the TX tuning capacitor value.*/
363u32 fm_tx_get_tune_cap_val(struct fmdev *fmdev)
364{
365 u16 curr_val;
366 u32 ret, resp_len;
367
368 if (fmdev->curr_fmmode != FM_MODE_TX)
369 return -EPERM;
370
371 ret = fmc_send_cmd(fmdev, READ_FMANT_TUNE_VALUE, REG_RD,
372 NULL, sizeof(curr_val), &curr_val, &resp_len);
373 if (ret < 0)
374 return ret;
375
376 curr_val = be16_to_cpu(curr_val);
377
378 return curr_val;
379}
380
381/* Set TX Frequency */
382u32 fm_tx_set_freq(struct fmdev *fmdev, u32 freq_to_set)
383{
384 struct fmtx_data *tx = &fmdev->tx_data;
385 u16 payload, chanl_index;
386 u32 ret;
387
388 if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) {
389 enable_xmit(fmdev, 0);
390 clear_bit(FM_CORE_TX_XMITING, &fmdev->flag);
391 }
392
393 /* Enable FR, BL interrupts */
394 payload = (FM_FR_EVENT | FM_BL_EVENT);
395 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
396 sizeof(payload), NULL, NULL);
397 if (ret < 0)
398 return ret;
399
400 tx->tx_frq = (unsigned long)freq_to_set;
401 fmdbg("tx: freq_to_set %ld\n", (long int)tx->tx_frq);
402
403 chanl_index = freq_to_set / 10;
404
405 /* Set current tuner channel */
406 payload = chanl_index;
407 ret = fmc_send_cmd(fmdev, CHANL_SET, REG_WR, &payload,
408 sizeof(payload), NULL, NULL);
409 if (ret < 0)
410 return ret;
411
412 fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl);
413 fm_tx_set_preemph_filter(fmdev, tx->preemph);
414
415 tx->audio_io = 0x01; /* I2S */
416 set_audio_io(fmdev);
417
418 enable_xmit(fmdev, 0x01); /* Enable transmission */
419
420 tx->aud_mode = FM_STEREO_MODE;
421 tx->rds.flag = FM_RDS_DISABLE;
422
423 return 0;
424}
425
diff --git a/drivers/media/radio/wl128x/fmdrv_tx.h b/drivers/media/radio/wl128x/fmdrv_tx.h
new file mode 100644
index 000000000000..e393a2bdd49e
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_tx.h
@@ -0,0 +1,37 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM TX module header.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_TX_H
23#define _FMDRV_TX_H
24
25u32 fm_tx_set_freq(struct fmdev *, u32);
26u32 fm_tx_set_pwr_lvl(struct fmdev *, u8);
27u32 fm_tx_set_region(struct fmdev *, u8);
28u32 fm_tx_set_mute_mode(struct fmdev *, u8);
29u32 fm_tx_set_stereo_mono(struct fmdev *, u16);
30u32 fm_tx_set_rds_mode(struct fmdev *, u8);
31u32 fm_tx_set_radio_text(struct fmdev *, u8 *, u8);
32u32 fm_tx_set_af(struct fmdev *, u32);
33u32 fm_tx_set_preemph_filter(struct fmdev *, u32);
34u32 fm_tx_get_tune_cap_val(struct fmdev *);
35
36#endif
37
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
new file mode 100644
index 000000000000..d50e5ac75ab6
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -0,0 +1,580 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This file provides interfaces to V4L2 subsystem.
4 *
5 * This module registers with V4L2 subsystem as Radio
6 * data system interface (/dev/radio). During the registration,
7 * it will expose two set of function pointers.
8 *
9 * 1) File operation related API (open, close, read, write, poll...etc).
10 * 2) Set of V4L2 IOCTL complaint API.
11 *
12 * Copyright (C) 2011 Texas Instruments
13 * Author: Raja Mani <raja_mani@ti.com>
14 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include "fmdrv.h"
32#include "fmdrv_v4l2.h"
33#include "fmdrv_common.h"
34#include "fmdrv_rx.h"
35#include "fmdrv_tx.h"
36
37static struct video_device *gradio_dev;
38static u8 radio_disconnected;
39
40/* -- V4L2 RADIO (/dev/radioX) device file operation interfaces --- */
41
42/* Read RX RDS data */
43static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf,
44 size_t count, loff_t *ppos)
45{
46 u8 rds_mode;
47 int ret;
48 struct fmdev *fmdev;
49
50 fmdev = video_drvdata(file);
51
52 if (!radio_disconnected) {
53 fmerr("FM device is already disconnected\n");
54 return -EIO;
55 }
56
57 /* Turn on RDS mode , if it is disabled */
58 ret = fm_rx_get_rds_mode(fmdev, &rds_mode);
59 if (ret < 0) {
60 fmerr("Unable to read current rds mode\n");
61 return ret;
62 }
63
64 if (rds_mode == FM_RDS_DISABLE) {
65 ret = fmc_set_rds_mode(fmdev, FM_RDS_ENABLE);
66 if (ret < 0) {
67 fmerr("Failed to enable rds mode\n");
68 return ret;
69 }
70 }
71
72 /* Copy RDS data from internal buffer to user buffer */
73 return fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count);
74}
75
76/* Write TX RDS data */
77static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
78 size_t count, loff_t *ppos)
79{
80 struct tx_rds rds;
81 int ret;
82 struct fmdev *fmdev;
83
84 ret = copy_from_user(&rds, buf, sizeof(rds));
85 fmdbg("(%d)type: %d, text %s, af %d\n",
86 ret, rds.text_type, rds.text, rds.af_freq);
87
88 fmdev = video_drvdata(file);
89 fm_tx_set_radio_text(fmdev, rds.text, rds.text_type);
90 fm_tx_set_af(fmdev, rds.af_freq);
91
92 return 0;
93}
94
95static u32 fm_v4l2_fops_poll(struct file *file, struct poll_table_struct *pts)
96{
97 int ret;
98 struct fmdev *fmdev;
99
100 fmdev = video_drvdata(file);
101 ret = fmc_is_rds_data_available(fmdev, file, pts);
102 if (ret < 0)
103 return POLLIN | POLLRDNORM;
104
105 return 0;
106}
107
108/*
109 * Handle open request for "/dev/radioX" device.
110 * Start with FM RX mode as default.
111 */
112static int fm_v4l2_fops_open(struct file *file)
113{
114 int ret;
115 struct fmdev *fmdev = NULL;
116
117 /* Don't allow multiple open */
118 if (radio_disconnected) {
119 fmerr("FM device is already opened\n");
120 return -EBUSY;
121 }
122
123 fmdev = video_drvdata(file);
124
125 ret = fmc_prepare(fmdev);
126 if (ret < 0) {
127 fmerr("Unable to prepare FM CORE\n");
128 return ret;
129 }
130
131 fmdbg("Load FM RX firmware..\n");
132
133 ret = fmc_set_mode(fmdev, FM_MODE_RX);
134 if (ret < 0) {
135 fmerr("Unable to load FM RX firmware\n");
136 return ret;
137 }
138 radio_disconnected = 1;
139
140 return ret;
141}
142
143static int fm_v4l2_fops_release(struct file *file)
144{
145 int ret;
146 struct fmdev *fmdev;
147
148 fmdev = video_drvdata(file);
149 if (!radio_disconnected) {
150 fmdbg("FM device is already closed\n");
151 return 0;
152 }
153
154 ret = fmc_set_mode(fmdev, FM_MODE_OFF);
155 if (ret < 0) {
156 fmerr("Unable to turn off the chip\n");
157 return ret;
158 }
159
160 ret = fmc_release(fmdev);
161 if (ret < 0) {
162 fmerr("FM CORE release failed\n");
163 return ret;
164 }
165 radio_disconnected = 0;
166
167 return ret;
168}
169
170/* V4L2 RADIO (/dev/radioX) device IOCTL interfaces */
171static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
172 struct v4l2_capability *capability)
173{
174 strlcpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver));
175 strlcpy(capability->card, FM_DRV_CARD_SHORT_NAME,
176 sizeof(capability->card));
177 sprintf(capability->bus_info, "UART");
178 capability->version = FM_DRV_RADIO_VERSION;
179 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER |
180 V4L2_CAP_RADIO | V4L2_CAP_MODULATOR |
181 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE |
182 V4L2_CAP_RDS_CAPTURE;
183
184 return 0;
185}
186
187static int fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
188{
189 struct fmdev *fmdev = container_of(ctrl->handler,
190 struct fmdev, ctrl_handler);
191
192 switch (ctrl->id) {
193 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
194 ctrl->val = fm_tx_get_tune_cap_val(fmdev);
195 break;
196 default:
197 fmwarn("%s: Unknown IOCTL: %d\n", __func__, ctrl->id);
198 break;
199 }
200
201 return 0;
202}
203
204static int fm_v4l2_s_ctrl(struct v4l2_ctrl *ctrl)
205{
206 struct fmdev *fmdev = container_of(ctrl->handler,
207 struct fmdev, ctrl_handler);
208
209 switch (ctrl->id) {
210 case V4L2_CID_AUDIO_VOLUME: /* set volume */
211 return fm_rx_set_volume(fmdev, (u16)ctrl->val);
212
213 case V4L2_CID_AUDIO_MUTE: /* set mute */
214 return fmc_set_mute_mode(fmdev, (u8)ctrl->val);
215
216 case V4L2_CID_TUNE_POWER_LEVEL:
217 /* set TX power level - ext control */
218 return fm_tx_set_pwr_lvl(fmdev, (u8)ctrl->val);
219
220 case V4L2_CID_TUNE_PREEMPHASIS:
221 return fm_tx_set_preemph_filter(fmdev, (u8) ctrl->val);
222
223 default:
224 return -EINVAL;
225 }
226}
227
228static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
229 struct v4l2_audio *audio)
230{
231 memset(audio, 0, sizeof(*audio));
232 strcpy(audio->name, "Radio");
233 audio->capability = V4L2_AUDCAP_STEREO;
234
235 return 0;
236}
237
238static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
239 struct v4l2_audio *audio)
240{
241 if (audio->index != 0)
242 return -EINVAL;
243
244 return 0;
245}
246
247/* Get tuner attributes. If current mode is NOT RX, return error */
248static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
249 struct v4l2_tuner *tuner)
250{
251 struct fmdev *fmdev = video_drvdata(file);
252 u32 bottom_freq;
253 u32 top_freq;
254 u16 stereo_mono_mode;
255 u16 rssilvl;
256 int ret;
257
258 if (tuner->index != 0)
259 return -EINVAL;
260
261 if (fmdev->curr_fmmode != FM_MODE_RX)
262 return -EPERM;
263
264 ret = fm_rx_get_band_freq_range(fmdev, &bottom_freq, &top_freq);
265 if (ret != 0)
266 return ret;
267
268 ret = fm_rx_get_stereo_mono(fmdev, &stereo_mono_mode);
269 if (ret != 0)
270 return ret;
271
272 ret = fm_rx_get_rssi_level(fmdev, &rssilvl);
273 if (ret != 0)
274 return ret;
275
276 strcpy(tuner->name, "FM");
277 tuner->type = V4L2_TUNER_RADIO;
278 /* Store rangelow and rangehigh freq in unit of 62.5 Hz */
279 tuner->rangelow = bottom_freq * 16;
280 tuner->rangehigh = top_freq * 16;
281 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO |
282 ((fmdev->rx.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0);
283 tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
284 V4L2_TUNER_CAP_LOW;
285 tuner->audmode = (stereo_mono_mode ?
286 V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO);
287
288 /*
289 * Actual rssi value lies in between -128 to +127.
290 * Convert this range from 0 to 255 by adding +128
291 */
292 rssilvl += 128;
293
294 /*
295 * Return signal strength value should be within 0 to 65535.
296 * Find out correct signal radio by multiplying (65535/255) = 257
297 */
298 tuner->signal = rssilvl * 257;
299 tuner->afc = 0;
300
301 return ret;
302}
303
304/*
305 * Set tuner attributes. If current mode is NOT RX, set to RX.
306 * Currently, we set only audio mode (mono/stereo) and RDS state (on/off).
307 * Should we set other tuner attributes, too?
308 */
309static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv,
310 struct v4l2_tuner *tuner)
311{
312 struct fmdev *fmdev = video_drvdata(file);
313 u16 aud_mode;
314 u8 rds_mode;
315 int ret;
316
317 if (tuner->index != 0)
318 return -EINVAL;
319
320 aud_mode = (tuner->audmode == V4L2_TUNER_MODE_STEREO) ?
321 FM_STEREO_MODE : FM_MONO_MODE;
322 rds_mode = (tuner->rxsubchans & V4L2_TUNER_SUB_RDS) ?
323 FM_RDS_ENABLE : FM_RDS_DISABLE;
324
325 if (fmdev->curr_fmmode != FM_MODE_RX) {
326 ret = fmc_set_mode(fmdev, FM_MODE_RX);
327 if (ret < 0) {
328 fmerr("Failed to set RX mode\n");
329 return ret;
330 }
331 }
332
333 ret = fmc_set_stereo_mono(fmdev, aud_mode);
334 if (ret < 0) {
335 fmerr("Failed to set RX stereo/mono mode\n");
336 return ret;
337 }
338
339 ret = fmc_set_rds_mode(fmdev, rds_mode);
340 if (ret < 0)
341 fmerr("Failed to set RX RDS mode\n");
342
343 return ret;
344}
345
346/* Get tuner or modulator radio frequency */
347static int fm_v4l2_vidioc_g_freq(struct file *file, void *priv,
348 struct v4l2_frequency *freq)
349{
350 struct fmdev *fmdev = video_drvdata(file);
351 int ret;
352
353 ret = fmc_get_freq(fmdev, &freq->frequency);
354 if (ret < 0) {
355 fmerr("Failed to get frequency\n");
356 return ret;
357 }
358
359 /* Frequency unit of 62.5 Hz*/
360 freq->frequency = (u32) freq->frequency * 16;
361
362 return 0;
363}
364
365/* Set tuner or modulator radio frequency */
366static int fm_v4l2_vidioc_s_freq(struct file *file, void *priv,
367 struct v4l2_frequency *freq)
368{
369 struct fmdev *fmdev = video_drvdata(file);
370
371 /*
372 * As V4L2_TUNER_CAP_LOW is set 1 user sends the frequency
373 * in units of 62.5 Hz.
374 */
375 freq->frequency = (u32)(freq->frequency / 16);
376
377 return fmc_set_freq(fmdev, freq->frequency);
378}
379
380/* Set hardware frequency seek. If current mode is NOT RX, set it RX. */
381static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *file, void *priv,
382 struct v4l2_hw_freq_seek *seek)
383{
384 struct fmdev *fmdev = video_drvdata(file);
385 int ret;
386
387 if (fmdev->curr_fmmode != FM_MODE_RX) {
388 ret = fmc_set_mode(fmdev, FM_MODE_RX);
389 if (ret != 0) {
390 fmerr("Failed to set RX mode\n");
391 return ret;
392 }
393 }
394
395 ret = fm_rx_seek(fmdev, seek->seek_upward, seek->wrap_around,
396 seek->spacing);
397 if (ret < 0)
398 fmerr("RX seek failed - %d\n", ret);
399
400 return ret;
401}
402/* Get modulator attributes. If mode is not TX, return no attributes. */
403static int fm_v4l2_vidioc_g_modulator(struct file *file, void *priv,
404 struct v4l2_modulator *mod)
405{
406 struct fmdev *fmdev = video_drvdata(file);;
407
408 if (mod->index != 0)
409 return -EINVAL;
410
411 if (fmdev->curr_fmmode != FM_MODE_TX)
412 return -EPERM;
413
414 mod->txsubchans = ((fmdev->tx_data.aud_mode == FM_STEREO_MODE) ?
415 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO) |
416 ((fmdev->tx_data.rds.flag == FM_RDS_ENABLE) ?
417 V4L2_TUNER_SUB_RDS : 0);
418
419 mod->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
420 V4L2_TUNER_CAP_LOW;
421
422 return 0;
423}
424
425/* Set modulator attributes. If mode is not TX, set to TX. */
426static int fm_v4l2_vidioc_s_modulator(struct file *file, void *priv,
427 struct v4l2_modulator *mod)
428{
429 struct fmdev *fmdev = video_drvdata(file);
430 u8 rds_mode;
431 u16 aud_mode;
432 int ret;
433
434 if (mod->index != 0)
435 return -EINVAL;
436
437 if (fmdev->curr_fmmode != FM_MODE_TX) {
438 ret = fmc_set_mode(fmdev, FM_MODE_TX);
439 if (ret != 0) {
440 fmerr("Failed to set TX mode\n");
441 return ret;
442 }
443 }
444
445 aud_mode = (mod->txsubchans & V4L2_TUNER_SUB_STEREO) ?
446 FM_STEREO_MODE : FM_MONO_MODE;
447 rds_mode = (mod->txsubchans & V4L2_TUNER_SUB_RDS) ?
448 FM_RDS_ENABLE : FM_RDS_DISABLE;
449 ret = fm_tx_set_stereo_mono(fmdev, aud_mode);
450 if (ret < 0) {
451 fmerr("Failed to set mono/stereo mode for TX\n");
452 return ret;
453 }
454 ret = fm_tx_set_rds_mode(fmdev, rds_mode);
455 if (ret < 0)
456 fmerr("Failed to set rds mode for TX\n");
457
458 return ret;
459}
460
461static const struct v4l2_file_operations fm_drv_fops = {
462 .owner = THIS_MODULE,
463 .read = fm_v4l2_fops_read,
464 .write = fm_v4l2_fops_write,
465 .poll = fm_v4l2_fops_poll,
466 .unlocked_ioctl = video_ioctl2,
467 .open = fm_v4l2_fops_open,
468 .release = fm_v4l2_fops_release,
469};
470
471static const struct v4l2_ctrl_ops fm_ctrl_ops = {
472 .s_ctrl = fm_v4l2_s_ctrl,
473 .g_volatile_ctrl = fm_g_volatile_ctrl,
474};
475static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = {
476 .vidioc_querycap = fm_v4l2_vidioc_querycap,
477 .vidioc_g_audio = fm_v4l2_vidioc_g_audio,
478 .vidioc_s_audio = fm_v4l2_vidioc_s_audio,
479 .vidioc_g_tuner = fm_v4l2_vidioc_g_tuner,
480 .vidioc_s_tuner = fm_v4l2_vidioc_s_tuner,
481 .vidioc_g_frequency = fm_v4l2_vidioc_g_freq,
482 .vidioc_s_frequency = fm_v4l2_vidioc_s_freq,
483 .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek,
484 .vidioc_g_modulator = fm_v4l2_vidioc_g_modulator,
485 .vidioc_s_modulator = fm_v4l2_vidioc_s_modulator
486};
487
488/* V4L2 RADIO device parent structure */
489static struct video_device fm_viddev_template = {
490 .fops = &fm_drv_fops,
491 .ioctl_ops = &fm_drv_ioctl_ops,
492 .name = FM_DRV_NAME,
493 .release = video_device_release,
494};
495
496int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
497{
498 struct v4l2_ctrl *ctrl;
499 int ret;
500
501 /* Init mutex for core locking */
502 mutex_init(&fmdev->mutex);
503
504 /* Allocate new video device */
505 gradio_dev = video_device_alloc();
506 if (NULL == gradio_dev) {
507 fmerr("Can't allocate video device\n");
508 return -ENOMEM;
509 }
510
511 /* Setup FM driver's V4L2 properties */
512 memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template));
513
514 video_set_drvdata(gradio_dev, fmdev);
515
516 gradio_dev->lock = &fmdev->mutex;
517
518 /* Register with V4L2 subsystem as RADIO device */
519 if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
520 video_device_release(gradio_dev);
521 fmerr("Could not register video device\n");
522 return -ENOMEM;
523 }
524
525 fmdev->radio_dev = gradio_dev;
526
527 /* Register to v4l2 ctrl handler framework */
528 fmdev->radio_dev->ctrl_handler = &fmdev->ctrl_handler;
529
530 ret = v4l2_ctrl_handler_init(&fmdev->ctrl_handler, 5);
531 if (ret < 0) {
532 fmerr("(fmdev): Can't init ctrl handler\n");
533 v4l2_ctrl_handler_free(&fmdev->ctrl_handler);
534 return -EBUSY;
535 }
536
537 /*
538 * Following controls are handled by V4L2 control framework.
539 * Added in ascending ID order.
540 */
541 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
542 V4L2_CID_AUDIO_VOLUME, FM_RX_VOLUME_MIN,
543 FM_RX_VOLUME_MAX, 1, FM_RX_VOLUME_MAX);
544
545 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
546 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
547
548 v4l2_ctrl_new_std_menu(&fmdev->ctrl_handler, &fm_ctrl_ops,
549 V4L2_CID_TUNE_PREEMPHASIS, V4L2_PREEMPHASIS_75_uS,
550 0, V4L2_PREEMPHASIS_75_uS);
551
552 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
553 V4L2_CID_TUNE_POWER_LEVEL, FM_PWR_LVL_LOW,
554 FM_PWR_LVL_HIGH, 1, FM_PWR_LVL_HIGH);
555
556 ctrl = v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
557 V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0,
558 255, 1, 255);
559
560 if (ctrl)
561 ctrl->is_volatile = 1;
562
563 return 0;
564}
565
566void *fm_v4l2_deinit_video_device(void)
567{
568 struct fmdev *fmdev;
569
570
571 fmdev = video_get_drvdata(gradio_dev);
572
573 /* Unregister to v4l2 ctrl handler framework*/
574 v4l2_ctrl_handler_free(&fmdev->ctrl_handler);
575
576 /* Unregister RADIO device from V4L2 subsystem */
577 video_unregister_device(gradio_dev);
578
579 return fmdev;
580}
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.h b/drivers/media/radio/wl128x/fmdrv_v4l2.h
new file mode 100644
index 000000000000..0ba79d745e2f
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.h
@@ -0,0 +1,33 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * FM V4L2 module header.
5 *
6 * Copyright (C) 2011 Texas Instruments
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef _FMDRV_V4L2_H
24#define _FMDRV_V4L2_H
25
26#include <media/v4l2-ioctl.h>
27#include <media/v4l2-common.h>
28#include <media/v4l2-ctrls.h>
29
30int fm_v4l2_init_video_device(struct fmdev *, int);
31void *fm_v4l2_deinit_video_device(void);
32
33#endif
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 3785162f928e..7f03142a329f 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -135,6 +135,19 @@ config IR_MCEUSB
135 To compile this driver as a module, choose M here: the 135 To compile this driver as a module, choose M here: the
136 module will be called mceusb. 136 module will be called mceusb.
137 137
138config IR_ITE_CIR
139 tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver"
140 depends on PNP
141 depends on RC_CORE
142 ---help---
143 Say Y here to enable support for integrated infrared receivers
144 /transceivers made by ITE Tech Inc. These are found in
145 several ASUS devices, like the ASUS Digimatrix or the ASUS
146 EEEBox 1501U.
147
148 To compile this driver as a module, choose M here: the
149 module will be called ite-cir.
150
138config IR_NUVOTON 151config IR_NUVOTON
139 tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" 152 tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
140 depends on PNP 153 depends on PNP
@@ -161,20 +174,20 @@ config IR_STREAMZAP
161 module will be called streamzap. 174 module will be called streamzap.
162 175
163config IR_WINBOND_CIR 176config IR_WINBOND_CIR
164 tristate "Winbond IR remote control" 177 tristate "Winbond IR remote control"
165 depends on X86 && PNP 178 depends on X86 && PNP
166 depends on RC_CORE 179 depends on RC_CORE
167 select NEW_LEDS 180 select NEW_LEDS
168 select LEDS_CLASS 181 select LEDS_CLASS
169 select LEDS_TRIGGERS 182 select LEDS_TRIGGERS
170 select BITREVERSE 183 select BITREVERSE
171 ---help--- 184 ---help---
172 Say Y here if you want to use the IR remote functionality found 185 Say Y here if you want to use the IR remote functionality found
173 in some Winbond SuperI/O chips. Currently only the WPCD376I 186 in some Winbond SuperI/O chips. Currently only the WPCD376I
174 chip is supported (included in some Intel Media series 187 chip is supported (included in some Intel Media series
175 motherboards). 188 motherboards).
176 189
177 To compile this driver as a module, choose M here: the module will 190 To compile this driver as a module, choose M here: the module will
178 be called winbond_cir. 191 be called winbond_cir.
179 192
180config RC_LOOPBACK 193config RC_LOOPBACK
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 67b4f7fe2577..c6cfe70d862f 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
14 14
15# stand-alone IR receivers/transmitters 15# stand-alone IR receivers/transmitters
16obj-$(CONFIG_IR_IMON) += imon.o 16obj-$(CONFIG_IR_IMON) += imon.o
17obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
17obj-$(CONFIG_IR_MCEUSB) += mceusb.o 18obj-$(CONFIG_IR_MCEUSB) += mceusb.o
18obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o 19obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
19obj-$(CONFIG_IR_ENE) += ene_ir.o 20obj-$(CONFIG_IR_ENE) += ene_ir.o
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index e7dc6b46fdfa..f714e1a22c92 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -277,12 +277,21 @@ static const struct {
277 u64 hw_code; 277 u64 hw_code;
278 u32 keycode; 278 u32 keycode;
279} imon_panel_key_table[] = { 279} imon_panel_key_table[] = {
280 { 0x000000000f00ffeell, KEY_PROG1 }, /* Go */ 280 { 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
281 { 0x000000001200ffeell, KEY_UP },
282 { 0x000000001300ffeell, KEY_DOWN },
283 { 0x000000001400ffeell, KEY_LEFT },
284 { 0x000000001500ffeell, KEY_RIGHT },
285 { 0x000000001600ffeell, KEY_ENTER },
286 { 0x000000001700ffeell, KEY_ESC },
281 { 0x000000001f00ffeell, KEY_AUDIO }, 287 { 0x000000001f00ffeell, KEY_AUDIO },
282 { 0x000000002000ffeell, KEY_VIDEO }, 288 { 0x000000002000ffeell, KEY_VIDEO },
283 { 0x000000002100ffeell, KEY_CAMERA }, 289 { 0x000000002100ffeell, KEY_CAMERA },
284 { 0x000000002700ffeell, KEY_DVD }, 290 { 0x000000002700ffeell, KEY_DVD },
285 { 0x000000002300ffeell, KEY_TV }, 291 { 0x000000002300ffeell, KEY_TV },
292 { 0x000000002b00ffeell, KEY_EXIT },
293 { 0x000000002c00ffeell, KEY_SELECT },
294 { 0x000000002d00ffeell, KEY_MENU },
286 { 0x000000000500ffeell, KEY_PREVIOUS }, 295 { 0x000000000500ffeell, KEY_PREVIOUS },
287 { 0x000000000700ffeell, KEY_REWIND }, 296 { 0x000000000700ffeell, KEY_REWIND },
288 { 0x000000000400ffeell, KEY_STOP }, 297 { 0x000000000400ffeell, KEY_STOP },
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 7b58b4a1729b..63ee722dbd02 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -49,6 +49,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
49 struct nec_dec *data = &dev->raw->nec; 49 struct nec_dec *data = &dev->raw->nec;
50 u32 scancode; 50 u32 scancode;
51 u8 address, not_address, command, not_command; 51 u8 address, not_address, command, not_command;
52 bool send_32bits = false;
52 53
53 if (!(dev->raw->enabled_protocols & RC_TYPE_NEC)) 54 if (!(dev->raw->enabled_protocols & RC_TYPE_NEC))
54 return 0; 55 return 0;
@@ -164,10 +165,15 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
164 if ((command ^ not_command) != 0xff) { 165 if ((command ^ not_command) != 0xff) {
165 IR_dprintk(1, "NEC checksum error: received 0x%08x\n", 166 IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
166 data->bits); 167 data->bits);
167 break; 168 send_32bits = true;
168 } 169 }
169 170
170 if ((address ^ not_address) != 0xff) { 171 if (send_32bits) {
172 /* NEC transport, but modified protocol, used by at
173 * least Apple and TiVo remotes */
174 scancode = data->bits;
175 IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode);
176 } else if ((address ^ not_address) != 0xff) {
171 /* Extended NEC */ 177 /* Extended NEC */
172 scancode = address << 16 | 178 scancode = address << 16 |
173 not_address << 8 | 179 not_address << 8 |
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
new file mode 100644
index 000000000000..ac0e42b47b2a
--- /dev/null
+++ b/drivers/media/rc/ite-cir.c
@@ -0,0 +1,1736 @@
1/*
2 * Driver for ITE Tech Inc. IT8712F/IT8512 CIR
3 *
4 * Copyright (C) 2010 Juan Jesús García de Soria <skandalfo@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA.
20 *
21 * Inspired by the original lirc_it87 and lirc_ite8709 drivers, on top of the
22 * skeleton provided by the nuvoton-cir driver.
23 *
24 * The lirc_it87 driver was originally written by Hans-Gunter Lutke Uphues
25 * <hg_lu@web.de> in 2001, with enhancements by Christoph Bartelmus
26 * <lirc@bartelmus.de>, Andrew Calkin <r_tay@hotmail.com> and James Edwards
27 * <jimbo-lirc@edwardsclan.net>.
28 *
29 * The lirc_ite8709 driver was written by Grégory Lardière
30 * <spmf2004-lirc@yahoo.fr> in 2008.
31 */
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/pnp.h>
36#include <linux/io.h>
37#include <linux/interrupt.h>
38#include <linux/sched.h>
39#include <linux/slab.h>
40#include <linux/input.h>
41#include <linux/bitops.h>
42#include <media/rc-core.h>
43#include <linux/pci_ids.h>
44
45#include "ite-cir.h"
46
47/* module parameters */
48
49/* debug level */
50static int debug;
51module_param(debug, int, S_IRUGO | S_IWUSR);
52MODULE_PARM_DESC(debug, "Enable debugging output");
53
54/* low limit for RX carrier freq, Hz, 0 for no RX demodulation */
55static int rx_low_carrier_freq;
56module_param(rx_low_carrier_freq, int, S_IRUGO | S_IWUSR);
57MODULE_PARM_DESC(rx_low_carrier_freq, "Override low RX carrier frequency, Hz, "
58 "0 for no RX demodulation");
59
60/* high limit for RX carrier freq, Hz, 0 for no RX demodulation */
61static int rx_high_carrier_freq;
62module_param(rx_high_carrier_freq, int, S_IRUGO | S_IWUSR);
63MODULE_PARM_DESC(rx_high_carrier_freq, "Override high RX carrier frequency, "
64 "Hz, 0 for no RX demodulation");
65
66/* override tx carrier frequency */
67static int tx_carrier_freq;
68module_param(tx_carrier_freq, int, S_IRUGO | S_IWUSR);
69MODULE_PARM_DESC(tx_carrier_freq, "Override TX carrier frequency, Hz");
70
71/* override tx duty cycle */
72static int tx_duty_cycle;
73module_param(tx_duty_cycle, int, S_IRUGO | S_IWUSR);
74MODULE_PARM_DESC(tx_duty_cycle, "Override TX duty cycle, 1-100");
75
76/* override default sample period */
77static long sample_period;
78module_param(sample_period, long, S_IRUGO | S_IWUSR);
79MODULE_PARM_DESC(sample_period, "Override carrier sample period, us");
80
81/* override detected model id */
82static int model_number = -1;
83module_param(model_number, int, S_IRUGO | S_IWUSR);
84MODULE_PARM_DESC(model_number, "Use this model number, don't autodetect");
85
86
87/* HW-independent code functions */
88
89/* check whether carrier frequency is high frequency */
90static inline bool ite_is_high_carrier_freq(unsigned int freq)
91{
92 return freq >= ITE_HCF_MIN_CARRIER_FREQ;
93}
94
95/* get the bits required to program the carrier frequency in CFQ bits,
96 * unshifted */
97static u8 ite_get_carrier_freq_bits(unsigned int freq)
98{
99 if (ite_is_high_carrier_freq(freq)) {
100 if (freq < 425000)
101 return ITE_CFQ_400;
102
103 else if (freq < 465000)
104 return ITE_CFQ_450;
105
106 else if (freq < 490000)
107 return ITE_CFQ_480;
108
109 else
110 return ITE_CFQ_500;
111 } else {
112 /* trim to limits */
113 if (freq < ITE_LCF_MIN_CARRIER_FREQ)
114 freq = ITE_LCF_MIN_CARRIER_FREQ;
115 if (freq > ITE_LCF_MAX_CARRIER_FREQ)
116 freq = ITE_LCF_MAX_CARRIER_FREQ;
117
118 /* convert to kHz and subtract the base freq */
119 freq =
120 DIV_ROUND_CLOSEST(freq - ITE_LCF_MIN_CARRIER_FREQ,
121 1000);
122
123 return (u8) freq;
124 }
125}
126
127/* get the bits required to program the pulse with in TXMPW */
128static u8 ite_get_pulse_width_bits(unsigned int freq, int duty_cycle)
129{
130 unsigned long period_ns, on_ns;
131
132 /* sanitize freq into range */
133 if (freq < ITE_LCF_MIN_CARRIER_FREQ)
134 freq = ITE_LCF_MIN_CARRIER_FREQ;
135 if (freq > ITE_HCF_MAX_CARRIER_FREQ)
136 freq = ITE_HCF_MAX_CARRIER_FREQ;
137
138 period_ns = 1000000000UL / freq;
139 on_ns = period_ns * duty_cycle / 100;
140
141 if (ite_is_high_carrier_freq(freq)) {
142 if (on_ns < 750)
143 return ITE_TXMPW_A;
144
145 else if (on_ns < 850)
146 return ITE_TXMPW_B;
147
148 else if (on_ns < 950)
149 return ITE_TXMPW_C;
150
151 else if (on_ns < 1080)
152 return ITE_TXMPW_D;
153
154 else
155 return ITE_TXMPW_E;
156 } else {
157 if (on_ns < 6500)
158 return ITE_TXMPW_A;
159
160 else if (on_ns < 7850)
161 return ITE_TXMPW_B;
162
163 else if (on_ns < 9650)
164 return ITE_TXMPW_C;
165
166 else if (on_ns < 11950)
167 return ITE_TXMPW_D;
168
169 else
170 return ITE_TXMPW_E;
171 }
172}
173
174/* decode raw bytes as received by the hardware, and push them to the ir-core
175 * layer */
176static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int
177 length)
178{
179 u32 sample_period;
180 unsigned long *ldata;
181 unsigned int next_one, next_zero, size;
182 DEFINE_IR_RAW_EVENT(ev);
183
184 if (length == 0)
185 return;
186
187 sample_period = dev->params.sample_period;
188 ldata = (unsigned long *)data;
189 size = length << 3;
190 next_one = find_next_bit_le(ldata, size, 0);
191 if (next_one > 0) {
192 ev.pulse = true;
193 ev.duration =
194 ITE_BITS_TO_NS(next_one, sample_period);
195 ir_raw_event_store_with_filter(dev->rdev, &ev);
196 }
197
198 while (next_one < size) {
199 next_zero = find_next_zero_bit_le(ldata, size, next_one + 1);
200 ev.pulse = false;
201 ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period);
202 ir_raw_event_store_with_filter(dev->rdev, &ev);
203
204 if (next_zero < size) {
205 next_one =
206 find_next_bit_le(ldata,
207 size,
208 next_zero + 1);
209 ev.pulse = true;
210 ev.duration =
211 ITE_BITS_TO_NS(next_one - next_zero,
212 sample_period);
213 ir_raw_event_store_with_filter
214 (dev->rdev, &ev);
215 } else
216 next_one = size;
217 }
218
219 ir_raw_event_handle(dev->rdev);
220
221 ite_dbg_verbose("decoded %d bytes.", length);
222}
223
224/* set all the rx/tx carrier parameters; this must be called with the device
225 * spinlock held */
226static void ite_set_carrier_params(struct ite_dev *dev)
227{
228 unsigned int freq, low_freq, high_freq;
229 int allowance;
230 bool use_demodulator;
231 bool for_tx = dev->transmitting;
232
233 ite_dbg("%s called", __func__);
234
235 if (for_tx) {
236 /* we don't need no stinking calculations */
237 freq = dev->params.tx_carrier_freq;
238 allowance = ITE_RXDCR_DEFAULT;
239 use_demodulator = false;
240 } else {
241 low_freq = dev->params.rx_low_carrier_freq;
242 high_freq = dev->params.rx_high_carrier_freq;
243
244 if (low_freq == 0) {
245 /* don't demodulate */
246 freq =
247 ITE_DEFAULT_CARRIER_FREQ;
248 allowance = ITE_RXDCR_DEFAULT;
249 use_demodulator = false;
250 } else {
251 /* calculate the middle freq */
252 freq = (low_freq + high_freq) / 2;
253
254 /* calculate the allowance */
255 allowance =
256 DIV_ROUND_CLOSEST(10000 * (high_freq - low_freq),
257 ITE_RXDCR_PER_10000_STEP
258 * (high_freq + low_freq));
259
260 if (allowance < 1)
261 allowance = 1;
262
263 if (allowance > ITE_RXDCR_MAX)
264 allowance = ITE_RXDCR_MAX;
265 }
266 }
267
268 /* set the carrier parameters in a device-dependent way */
269 dev->params.set_carrier_params(dev, ite_is_high_carrier_freq(freq),
270 use_demodulator, ite_get_carrier_freq_bits(freq), allowance,
271 ite_get_pulse_width_bits(freq, dev->params.tx_duty_cycle));
272}
273
274/* interrupt service routine for incoming and outgoing CIR data */
275static irqreturn_t ite_cir_isr(int irq, void *data)
276{
277 struct ite_dev *dev = data;
278 unsigned long flags;
279 irqreturn_t ret = IRQ_RETVAL(IRQ_NONE);
280 u8 rx_buf[ITE_RX_FIFO_LEN];
281 int rx_bytes;
282 int iflags;
283
284 ite_dbg_verbose("%s firing", __func__);
285
286 /* grab the spinlock */
287 spin_lock_irqsave(&dev->lock, flags);
288
289 /* read the interrupt flags */
290 iflags = dev->params.get_irq_causes(dev);
291
292 /* check for the receive interrupt */
293 if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
294 /* read the FIFO bytes */
295 rx_bytes =
296 dev->params.get_rx_bytes(dev, rx_buf,
297 ITE_RX_FIFO_LEN);
298
299 if (rx_bytes > 0) {
300 /* drop the spinlock, since the ir-core layer
301 * may call us back again through
302 * ite_s_idle() */
303 spin_unlock_irqrestore(&dev->
304 lock,
305 flags);
306
307 /* decode the data we've just received */
308 ite_decode_bytes(dev, rx_buf,
309 rx_bytes);
310
311 /* reacquire the spinlock */
312 spin_lock_irqsave(&dev->lock,
313 flags);
314
315 /* mark the interrupt as serviced */
316 ret = IRQ_RETVAL(IRQ_HANDLED);
317 }
318 } else if (iflags & ITE_IRQ_TX_FIFO) {
319 /* FIFO space available interrupt */
320 ite_dbg_verbose("got interrupt for TX FIFO");
321
322 /* wake any sleeping transmitter */
323 wake_up_interruptible(&dev->tx_queue);
324
325 /* mark the interrupt as serviced */
326 ret = IRQ_RETVAL(IRQ_HANDLED);
327 }
328
329 /* drop the spinlock */
330 spin_unlock_irqrestore(&dev->lock, flags);
331
332 ite_dbg_verbose("%s done returning %d", __func__, (int)ret);
333
334 return ret;
335}
336
337/* set the rx carrier freq range, guess it's in Hz... */
338static int ite_set_rx_carrier_range(struct rc_dev *rcdev, u32 carrier_low, u32
339 carrier_high)
340{
341 unsigned long flags;
342 struct ite_dev *dev = rcdev->priv;
343
344 spin_lock_irqsave(&dev->lock, flags);
345 dev->params.rx_low_carrier_freq = carrier_low;
346 dev->params.rx_high_carrier_freq = carrier_high;
347 ite_set_carrier_params(dev);
348 spin_unlock_irqrestore(&dev->lock, flags);
349
350 return 0;
351}
352
353/* set the tx carrier freq, guess it's in Hz... */
354static int ite_set_tx_carrier(struct rc_dev *rcdev, u32 carrier)
355{
356 unsigned long flags;
357 struct ite_dev *dev = rcdev->priv;
358
359 spin_lock_irqsave(&dev->lock, flags);
360 dev->params.tx_carrier_freq = carrier;
361 ite_set_carrier_params(dev);
362 spin_unlock_irqrestore(&dev->lock, flags);
363
364 return 0;
365}
366
367/* set the tx duty cycle by controlling the pulse width */
368static int ite_set_tx_duty_cycle(struct rc_dev *rcdev, u32 duty_cycle)
369{
370 unsigned long flags;
371 struct ite_dev *dev = rcdev->priv;
372
373 spin_lock_irqsave(&dev->lock, flags);
374 dev->params.tx_duty_cycle = duty_cycle;
375 ite_set_carrier_params(dev);
376 spin_unlock_irqrestore(&dev->lock, flags);
377
378 return 0;
379}
380
381/* transmit out IR pulses; what you get here is a batch of alternating
382 * pulse/space/pulse/space lengths that we should write out completely through
383 * the FIFO, blocking on a full FIFO */
384static int ite_tx_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
385{
386 unsigned long flags;
387 struct ite_dev *dev = rcdev->priv;
388 bool is_pulse = false;
389 int remaining_us, fifo_avail, fifo_remaining, last_idx = 0;
390 int max_rle_us, next_rle_us;
391 int ret = n;
392 u8 last_sent[ITE_TX_FIFO_LEN];
393 u8 val;
394
395 ite_dbg("%s called", __func__);
396
397 /* clear the array just in case */
398 memset(last_sent, 0, ARRAY_SIZE(last_sent));
399
400 /* n comes in bytes; convert to ints */
401 n /= sizeof(int);
402
403 spin_lock_irqsave(&dev->lock, flags);
404
405 /* let everybody know we're now transmitting */
406 dev->transmitting = true;
407
408 /* and set the carrier values for transmission */
409 ite_set_carrier_params(dev);
410
411 /* calculate how much time we can send in one byte */
412 max_rle_us =
413 (ITE_BAUDRATE_DIVISOR * dev->params.sample_period *
414 ITE_TX_MAX_RLE) / 1000;
415
416 /* disable the receiver */
417 dev->params.disable_rx(dev);
418
419 /* this is where we'll begin filling in the FIFO, until it's full.
420 * then we'll just activate the interrupt, wait for it to wake us up
421 * again, disable it, continue filling the FIFO... until everything
422 * has been pushed out */
423 fifo_avail =
424 ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);
425
426 while (n > 0 && dev->in_use) {
427 /* transmit the next sample */
428 is_pulse = !is_pulse;
429 remaining_us = *(txbuf++);
430 n--;
431
432 ite_dbg("%s: %ld",
433 ((is_pulse) ? "pulse" : "space"),
434 (long int)
435 remaining_us);
436
437 /* repeat while the pulse is non-zero length */
438 while (remaining_us > 0 && dev->in_use) {
439 if (remaining_us > max_rle_us)
440 next_rle_us = max_rle_us;
441
442 else
443 next_rle_us = remaining_us;
444
445 remaining_us -= next_rle_us;
446
447 /* check what's the length we have to pump out */
448 val = (ITE_TX_MAX_RLE * next_rle_us) / max_rle_us;
449
450 /* put it into the sent buffer */
451 last_sent[last_idx++] = val;
452 last_idx &= (ITE_TX_FIFO_LEN);
453
454 /* encode it for 7 bits */
455 val = (val - 1) & ITE_TX_RLE_MASK;
456
457 /* take into account pulse/space prefix */
458 if (is_pulse)
459 val |= ITE_TX_PULSE;
460
461 else
462 val |= ITE_TX_SPACE;
463
464 /*
465 * if we get to 0 available, read again, just in case
466 * some other slot got freed
467 */
468 if (fifo_avail <= 0)
469 fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);
470
471 /* if it's still full */
472 if (fifo_avail <= 0) {
473 /* enable the tx interrupt */
474 dev->params.
475 enable_tx_interrupt(dev);
476
477 /* drop the spinlock */
478 spin_unlock_irqrestore(&dev->lock, flags);
479
480 /* wait for the FIFO to empty enough */
481 wait_event_interruptible(dev->tx_queue, (fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev)) >= 8);
482
483 /* get the spinlock again */
484 spin_lock_irqsave(&dev->lock, flags);
485
486 /* disable the tx interrupt again. */
487 dev->params.
488 disable_tx_interrupt(dev);
489 }
490
491 /* now send the byte through the FIFO */
492 dev->params.put_tx_byte(dev, val);
493 fifo_avail--;
494 }
495 }
496
497 /* wait and don't return until the whole FIFO has been sent out;
498 * otherwise we could configure the RX carrier params instead of the
499 * TX ones while the transmission is still being performed! */
500 fifo_remaining = dev->params.get_tx_used_slots(dev);
501 remaining_us = 0;
502 while (fifo_remaining > 0) {
503 fifo_remaining--;
504 last_idx--;
505 last_idx &= (ITE_TX_FIFO_LEN - 1);
506 remaining_us += last_sent[last_idx];
507 }
508 remaining_us = (remaining_us * max_rle_us) / (ITE_TX_MAX_RLE);
509
510 /* drop the spinlock while we sleep */
511 spin_unlock_irqrestore(&dev->lock, flags);
512
513 /* sleep remaining_us microseconds */
514 mdelay(DIV_ROUND_UP(remaining_us, 1000));
515
516 /* reacquire the spinlock */
517 spin_lock_irqsave(&dev->lock, flags);
518
519 /* now we're not transmitting anymore */
520 dev->transmitting = false;
521
522 /* and set the carrier values for reception */
523 ite_set_carrier_params(dev);
524
525 /* reenable the receiver */
526 if (dev->in_use)
527 dev->params.enable_rx(dev);
528
529 /* notify transmission end */
530 wake_up_interruptible(&dev->tx_ended);
531
532 spin_unlock_irqrestore(&dev->lock, flags);
533
534 return ret;
535}
536
537/* idle the receiver if needed */
538static void ite_s_idle(struct rc_dev *rcdev, bool enable)
539{
540 unsigned long flags;
541 struct ite_dev *dev = rcdev->priv;
542
543 ite_dbg("%s called", __func__);
544
545 if (enable) {
546 spin_lock_irqsave(&dev->lock, flags);
547 dev->params.idle_rx(dev);
548 spin_unlock_irqrestore(&dev->lock, flags);
549 }
550}
551
552
553/* IT8712F HW-specific functions */
554
555/* retrieve a bitmask of the current causes for a pending interrupt; this may
556 * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
557 * */
558static int it87_get_irq_causes(struct ite_dev *dev)
559{
560 u8 iflags;
561 int ret = 0;
562
563 ite_dbg("%s called", __func__);
564
565 /* read the interrupt flags */
566 iflags = inb(dev->cir_addr + IT87_IIR) & IT87_II;
567
568 switch (iflags) {
569 case IT87_II_RXDS:
570 ret = ITE_IRQ_RX_FIFO;
571 break;
572 case IT87_II_RXFO:
573 ret = ITE_IRQ_RX_FIFO_OVERRUN;
574 break;
575 case IT87_II_TXLDL:
576 ret = ITE_IRQ_TX_FIFO;
577 break;
578 }
579
580 return ret;
581}
582
583/* set the carrier parameters; to be called with the spinlock held */
584static void it87_set_carrier_params(struct ite_dev *dev, bool high_freq,
585 bool use_demodulator,
586 u8 carrier_freq_bits, u8 allowance_bits,
587 u8 pulse_width_bits)
588{
589 u8 val;
590
591 ite_dbg("%s called", __func__);
592
593 /* program the RCR register */
594 val = inb(dev->cir_addr + IT87_RCR)
595 & ~(IT87_HCFS | IT87_RXEND | IT87_RXDCR);
596
597 if (high_freq)
598 val |= IT87_HCFS;
599
600 if (use_demodulator)
601 val |= IT87_RXEND;
602
603 val |= allowance_bits;
604
605 outb(val, dev->cir_addr + IT87_RCR);
606
607 /* program the TCR2 register */
608 outb((carrier_freq_bits << IT87_CFQ_SHIFT) | pulse_width_bits,
609 dev->cir_addr + IT87_TCR2);
610}
611
612/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
613 * held */
614static int it87_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
615{
616 int fifo, read = 0;
617
618 ite_dbg("%s called", __func__);
619
620 /* read how many bytes are still in the FIFO */
621 fifo = inb(dev->cir_addr + IT87_RSR) & IT87_RXFBC;
622
623 while (fifo > 0 && buf_size > 0) {
624 *(buf++) = inb(dev->cir_addr + IT87_DR);
625 fifo--;
626 read++;
627 buf_size--;
628 }
629
630 return read;
631}
632
633/* return how many bytes are still in the FIFO; this will be called
634 * with the device spinlock NOT HELD while waiting for the TX FIFO to get
635 * empty; let's expect this won't be a problem */
636static int it87_get_tx_used_slots(struct ite_dev *dev)
637{
638 ite_dbg("%s called", __func__);
639
640 return inb(dev->cir_addr + IT87_TSR) & IT87_TXFBC;
641}
642
643/* put a byte to the TX fifo; this should be called with the spinlock held */
644static void it87_put_tx_byte(struct ite_dev *dev, u8 value)
645{
646 outb(value, dev->cir_addr + IT87_DR);
647}
648
649/* idle the receiver so that we won't receive samples until another
650 pulse is detected; this must be called with the device spinlock held */
651static void it87_idle_rx(struct ite_dev *dev)
652{
653 ite_dbg("%s called", __func__);
654
655 /* disable streaming by clearing RXACT writing it as 1 */
656 outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXACT,
657 dev->cir_addr + IT87_RCR);
658
659 /* clear the FIFO */
660 outb(inb(dev->cir_addr + IT87_TCR1) | IT87_FIFOCLR,
661 dev->cir_addr + IT87_TCR1);
662}
663
664/* disable the receiver; this must be called with the device spinlock held */
665static void it87_disable_rx(struct ite_dev *dev)
666{
667 ite_dbg("%s called", __func__);
668
669 /* disable the receiver interrupts */
670 outb(inb(dev->cir_addr + IT87_IER) & ~(IT87_RDAIE | IT87_RFOIE),
671 dev->cir_addr + IT87_IER);
672
673 /* disable the receiver */
674 outb(inb(dev->cir_addr + IT87_RCR) & ~IT87_RXEN,
675 dev->cir_addr + IT87_RCR);
676
677 /* clear the FIFO and RXACT (actually RXACT should have been cleared
678 * in the previous outb() call) */
679 it87_idle_rx(dev);
680}
681
682/* enable the receiver; this must be called with the device spinlock held */
683static void it87_enable_rx(struct ite_dev *dev)
684{
685 ite_dbg("%s called", __func__);
686
687 /* enable the receiver by setting RXEN */
688 outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXEN,
689 dev->cir_addr + IT87_RCR);
690
691 /* just prepare it to idle for the next reception */
692 it87_idle_rx(dev);
693
694 /* enable the receiver interrupts and master enable flag */
695 outb(inb(dev->cir_addr + IT87_IER) | IT87_RDAIE | IT87_RFOIE | IT87_IEC,
696 dev->cir_addr + IT87_IER);
697}
698
699/* disable the transmitter interrupt; this must be called with the device
700 * spinlock held */
701static void it87_disable_tx_interrupt(struct ite_dev *dev)
702{
703 ite_dbg("%s called", __func__);
704
705 /* disable the transmitter interrupts */
706 outb(inb(dev->cir_addr + IT87_IER) & ~IT87_TLDLIE,
707 dev->cir_addr + IT87_IER);
708}
709
710/* enable the transmitter interrupt; this must be called with the device
711 * spinlock held */
712static void it87_enable_tx_interrupt(struct ite_dev *dev)
713{
714 ite_dbg("%s called", __func__);
715
716 /* enable the transmitter interrupts and master enable flag */
717 outb(inb(dev->cir_addr + IT87_IER) | IT87_TLDLIE | IT87_IEC,
718 dev->cir_addr + IT87_IER);
719}
720
721/* disable the device; this must be called with the device spinlock held */
722static void it87_disable(struct ite_dev *dev)
723{
724 ite_dbg("%s called", __func__);
725
726 /* clear out all interrupt enable flags */
727 outb(inb(dev->cir_addr + IT87_IER) &
728 ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE),
729 dev->cir_addr + IT87_IER);
730
731 /* disable the receiver */
732 it87_disable_rx(dev);
733
734 /* erase the FIFO */
735 outb(IT87_FIFOCLR | inb(dev->cir_addr + IT87_TCR1),
736 dev->cir_addr + IT87_TCR1);
737}
738
739/* initialize the hardware */
740static void it87_init_hardware(struct ite_dev *dev)
741{
742 ite_dbg("%s called", __func__);
743
744 /* enable just the baud rate divisor register,
745 disabling all the interrupts at the same time */
746 outb((inb(dev->cir_addr + IT87_IER) &
747 ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE)) | IT87_BR,
748 dev->cir_addr + IT87_IER);
749
750 /* write out the baud rate divisor */
751 outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT87_BDLR);
752 outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff, dev->cir_addr + IT87_BDHR);
753
754 /* disable the baud rate divisor register again */
755 outb(inb(dev->cir_addr + IT87_IER) & ~IT87_BR,
756 dev->cir_addr + IT87_IER);
757
758 /* program the RCR register defaults */
759 outb(ITE_RXDCR_DEFAULT, dev->cir_addr + IT87_RCR);
760
761 /* program the TCR1 register */
762 outb(IT87_TXMPM_DEFAULT | IT87_TXENDF | IT87_TXRLE
763 | IT87_FIFOTL_DEFAULT | IT87_FIFOCLR,
764 dev->cir_addr + IT87_TCR1);
765
766 /* program the carrier parameters */
767 ite_set_carrier_params(dev);
768}
769
770/* IT8512F on ITE8708 HW-specific functions */
771
772/* retrieve a bitmask of the current causes for a pending interrupt; this may
773 * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
774 * */
775static int it8708_get_irq_causes(struct ite_dev *dev)
776{
777 u8 iflags;
778 int ret = 0;
779
780 ite_dbg("%s called", __func__);
781
782 /* read the interrupt flags */
783 iflags = inb(dev->cir_addr + IT8708_C0IIR);
784
785 if (iflags & IT85_TLDLI)
786 ret |= ITE_IRQ_TX_FIFO;
787 if (iflags & IT85_RDAI)
788 ret |= ITE_IRQ_RX_FIFO;
789 if (iflags & IT85_RFOI)
790 ret |= ITE_IRQ_RX_FIFO_OVERRUN;
791
792 return ret;
793}
794
795/* set the carrier parameters; to be called with the spinlock held */
796static void it8708_set_carrier_params(struct ite_dev *dev, bool high_freq,
797 bool use_demodulator,
798 u8 carrier_freq_bits, u8 allowance_bits,
799 u8 pulse_width_bits)
800{
801 u8 val;
802
803 ite_dbg("%s called", __func__);
804
805 /* program the C0CFR register, with HRAE=1 */
806 outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
807 dev->cir_addr + IT8708_BANKSEL);
808
809 val = (inb(dev->cir_addr + IT8708_C0CFR)
810 & ~(IT85_HCFS | IT85_CFQ)) | carrier_freq_bits;
811
812 if (high_freq)
813 val |= IT85_HCFS;
814
815 outb(val, dev->cir_addr + IT8708_C0CFR);
816
817 outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE,
818 dev->cir_addr + IT8708_BANKSEL);
819
820 /* program the C0RCR register */
821 val = inb(dev->cir_addr + IT8708_C0RCR)
822 & ~(IT85_RXEND | IT85_RXDCR);
823
824 if (use_demodulator)
825 val |= IT85_RXEND;
826
827 val |= allowance_bits;
828
829 outb(val, dev->cir_addr + IT8708_C0RCR);
830
831 /* program the C0TCR register */
832 val = inb(dev->cir_addr + IT8708_C0TCR) & ~IT85_TXMPW;
833 val |= pulse_width_bits;
834 outb(val, dev->cir_addr + IT8708_C0TCR);
835}
836
837/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
838 * held */
839static int it8708_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
840{
841 int fifo, read = 0;
842
843 ite_dbg("%s called", __func__);
844
845 /* read how many bytes are still in the FIFO */
846 fifo = inb(dev->cir_addr + IT8708_C0RFSR) & IT85_RXFBC;
847
848 while (fifo > 0 && buf_size > 0) {
849 *(buf++) = inb(dev->cir_addr + IT8708_C0DR);
850 fifo--;
851 read++;
852 buf_size--;
853 }
854
855 return read;
856}
857
858/* return how many bytes are still in the FIFO; this will be called
859 * with the device spinlock NOT HELD while waiting for the TX FIFO to get
860 * empty; let's expect this won't be a problem */
861static int it8708_get_tx_used_slots(struct ite_dev *dev)
862{
863 ite_dbg("%s called", __func__);
864
865 return inb(dev->cir_addr + IT8708_C0TFSR) & IT85_TXFBC;
866}
867
868/* put a byte to the TX fifo; this should be called with the spinlock held */
869static void it8708_put_tx_byte(struct ite_dev *dev, u8 value)
870{
871 outb(value, dev->cir_addr + IT8708_C0DR);
872}
873
874/* idle the receiver so that we won't receive samples until another
875 pulse is detected; this must be called with the device spinlock held */
876static void it8708_idle_rx(struct ite_dev *dev)
877{
878 ite_dbg("%s called", __func__);
879
880 /* disable streaming by clearing RXACT writing it as 1 */
881 outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXACT,
882 dev->cir_addr + IT8708_C0RCR);
883
884 /* clear the FIFO */
885 outb(inb(dev->cir_addr + IT8708_C0MSTCR) | IT85_FIFOCLR,
886 dev->cir_addr + IT8708_C0MSTCR);
887}
888
889/* disable the receiver; this must be called with the device spinlock held */
890static void it8708_disable_rx(struct ite_dev *dev)
891{
892 ite_dbg("%s called", __func__);
893
894 /* disable the receiver interrupts */
895 outb(inb(dev->cir_addr + IT8708_C0IER) &
896 ~(IT85_RDAIE | IT85_RFOIE),
897 dev->cir_addr + IT8708_C0IER);
898
899 /* disable the receiver */
900 outb(inb(dev->cir_addr + IT8708_C0RCR) & ~IT85_RXEN,
901 dev->cir_addr + IT8708_C0RCR);
902
903 /* clear the FIFO and RXACT (actually RXACT should have been cleared
904 * in the previous outb() call) */
905 it8708_idle_rx(dev);
906}
907
908/* enable the receiver; this must be called with the device spinlock held */
909static void it8708_enable_rx(struct ite_dev *dev)
910{
911 ite_dbg("%s called", __func__);
912
913 /* enable the receiver by setting RXEN */
914 outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXEN,
915 dev->cir_addr + IT8708_C0RCR);
916
917 /* just prepare it to idle for the next reception */
918 it8708_idle_rx(dev);
919
920 /* enable the receiver interrupts and master enable flag */
921 outb(inb(dev->cir_addr + IT8708_C0IER)
922 |IT85_RDAIE | IT85_RFOIE | IT85_IEC,
923 dev->cir_addr + IT8708_C0IER);
924}
925
926/* disable the transmitter interrupt; this must be called with the device
927 * spinlock held */
928static void it8708_disable_tx_interrupt(struct ite_dev *dev)
929{
930 ite_dbg("%s called", __func__);
931
932 /* disable the transmitter interrupts */
933 outb(inb(dev->cir_addr + IT8708_C0IER) & ~IT85_TLDLIE,
934 dev->cir_addr + IT8708_C0IER);
935}
936
937/* enable the transmitter interrupt; this must be called with the device
938 * spinlock held */
939static void it8708_enable_tx_interrupt(struct ite_dev *dev)
940{
941 ite_dbg("%s called", __func__);
942
943 /* enable the transmitter interrupts and master enable flag */
944 outb(inb(dev->cir_addr + IT8708_C0IER)
945 |IT85_TLDLIE | IT85_IEC,
946 dev->cir_addr + IT8708_C0IER);
947}
948
949/* disable the device; this must be called with the device spinlock held */
950static void it8708_disable(struct ite_dev *dev)
951{
952 ite_dbg("%s called", __func__);
953
954 /* clear out all interrupt enable flags */
955 outb(inb(dev->cir_addr + IT8708_C0IER) &
956 ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
957 dev->cir_addr + IT8708_C0IER);
958
959 /* disable the receiver */
960 it8708_disable_rx(dev);
961
962 /* erase the FIFO */
963 outb(IT85_FIFOCLR | inb(dev->cir_addr + IT8708_C0MSTCR),
964 dev->cir_addr + IT8708_C0MSTCR);
965}
966
967/* initialize the hardware */
968static void it8708_init_hardware(struct ite_dev *dev)
969{
970 ite_dbg("%s called", __func__);
971
972 /* disable all the interrupts */
973 outb(inb(dev->cir_addr + IT8708_C0IER) &
974 ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
975 dev->cir_addr + IT8708_C0IER);
976
977 /* program the baud rate divisor */
978 outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
979 dev->cir_addr + IT8708_BANKSEL);
980
981 outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT8708_C0BDLR);
982 outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
983 dev->cir_addr + IT8708_C0BDHR);
984
985 outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE,
986 dev->cir_addr + IT8708_BANKSEL);
987
988 /* program the C0MSTCR register defaults */
989 outb((inb(dev->cir_addr + IT8708_C0MSTCR) &
990 ~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL |
991 IT85_FIFOCLR | IT85_RESET)) |
992 IT85_FIFOTL_DEFAULT,
993 dev->cir_addr + IT8708_C0MSTCR);
994
995 /* program the C0RCR register defaults */
996 outb((inb(dev->cir_addr + IT8708_C0RCR) &
997 ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND |
998 IT85_RXACT | IT85_RXDCR)) |
999 ITE_RXDCR_DEFAULT,
1000 dev->cir_addr + IT8708_C0RCR);
1001
1002 /* program the C0TCR register defaults */
1003 outb((inb(dev->cir_addr + IT8708_C0TCR) &
1004 ~(IT85_TXMPM | IT85_TXMPW))
1005 |IT85_TXRLE | IT85_TXENDF |
1006 IT85_TXMPM_DEFAULT | IT85_TXMPW_DEFAULT,
1007 dev->cir_addr + IT8708_C0TCR);
1008
1009 /* program the carrier parameters */
1010 ite_set_carrier_params(dev);
1011}
1012
1013/* IT8512F on ITE8709 HW-specific functions */
1014
1015/* read a byte from the SRAM module */
1016static inline u8 it8709_rm(struct ite_dev *dev, int index)
1017{
1018 outb(index, dev->cir_addr + IT8709_RAM_IDX);
1019 return inb(dev->cir_addr + IT8709_RAM_VAL);
1020}
1021
1022/* write a byte to the SRAM module */
1023static inline void it8709_wm(struct ite_dev *dev, u8 val, int index)
1024{
1025 outb(index, dev->cir_addr + IT8709_RAM_IDX);
1026 outb(val, dev->cir_addr + IT8709_RAM_VAL);
1027}
1028
1029static void it8709_wait(struct ite_dev *dev)
1030{
1031 int i = 0;
1032 /*
1033 * loop until device tells it's ready to continue
1034 * iterations count is usually ~750 but can sometimes achieve 13000
1035 */
1036 for (i = 0; i < 15000; i++) {
1037 udelay(2);
1038 if (it8709_rm(dev, IT8709_MODE) == IT8709_IDLE)
1039 break;
1040 }
1041}
1042
1043/* read the value of a CIR register */
1044static u8 it8709_rr(struct ite_dev *dev, int index)
1045{
1046 /* just wait in case the previous access was a write */
1047 it8709_wait(dev);
1048 it8709_wm(dev, index, IT8709_REG_IDX);
1049 it8709_wm(dev, IT8709_READ, IT8709_MODE);
1050
1051 /* wait for the read data to be available */
1052 it8709_wait(dev);
1053
1054 /* return the read value */
1055 return it8709_rm(dev, IT8709_REG_VAL);
1056}
1057
1058/* write the value of a CIR register */
1059static void it8709_wr(struct ite_dev *dev, u8 val, int index)
1060{
1061 /* we wait before writing, and not afterwards, since this allows us to
1062 * pipeline the host CPU with the microcontroller */
1063 it8709_wait(dev);
1064 it8709_wm(dev, val, IT8709_REG_VAL);
1065 it8709_wm(dev, index, IT8709_REG_IDX);
1066 it8709_wm(dev, IT8709_WRITE, IT8709_MODE);
1067}
1068
1069/* retrieve a bitmask of the current causes for a pending interrupt; this may
1070 * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
1071 * */
1072static int it8709_get_irq_causes(struct ite_dev *dev)
1073{
1074 u8 iflags;
1075 int ret = 0;
1076
1077 ite_dbg("%s called", __func__);
1078
1079 /* read the interrupt flags */
1080 iflags = it8709_rm(dev, IT8709_IIR);
1081
1082 if (iflags & IT85_TLDLI)
1083 ret |= ITE_IRQ_TX_FIFO;
1084 if (iflags & IT85_RDAI)
1085 ret |= ITE_IRQ_RX_FIFO;
1086 if (iflags & IT85_RFOI)
1087 ret |= ITE_IRQ_RX_FIFO_OVERRUN;
1088
1089 return ret;
1090}
1091
1092/* set the carrier parameters; to be called with the spinlock held */
1093static void it8709_set_carrier_params(struct ite_dev *dev, bool high_freq,
1094 bool use_demodulator,
1095 u8 carrier_freq_bits, u8 allowance_bits,
1096 u8 pulse_width_bits)
1097{
1098 u8 val;
1099
1100 ite_dbg("%s called", __func__);
1101
1102 val = (it8709_rr(dev, IT85_C0CFR)
1103 &~(IT85_HCFS | IT85_CFQ)) |
1104 carrier_freq_bits;
1105
1106 if (high_freq)
1107 val |= IT85_HCFS;
1108
1109 it8709_wr(dev, val, IT85_C0CFR);
1110
1111 /* program the C0RCR register */
1112 val = it8709_rr(dev, IT85_C0RCR)
1113 & ~(IT85_RXEND | IT85_RXDCR);
1114
1115 if (use_demodulator)
1116 val |= IT85_RXEND;
1117
1118 val |= allowance_bits;
1119
1120 it8709_wr(dev, val, IT85_C0RCR);
1121
1122 /* program the C0TCR register */
1123 val = it8709_rr(dev, IT85_C0TCR) & ~IT85_TXMPW;
1124 val |= pulse_width_bits;
1125 it8709_wr(dev, val, IT85_C0TCR);
1126}
1127
1128/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
1129 * held */
1130static int it8709_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
1131{
1132 int fifo, read = 0;
1133
1134 ite_dbg("%s called", __func__);
1135
1136 /* read how many bytes are still in the FIFO */
1137 fifo = it8709_rm(dev, IT8709_RFSR) & IT85_RXFBC;
1138
1139 while (fifo > 0 && buf_size > 0) {
1140 *(buf++) = it8709_rm(dev, IT8709_FIFO + read);
1141 fifo--;
1142 read++;
1143 buf_size--;
1144 }
1145
1146 /* 'clear' the FIFO by setting the writing index to 0; this is
1147 * completely bound to be racy, but we can't help it, since it's a
1148 * limitation of the protocol */
1149 it8709_wm(dev, 0, IT8709_RFSR);
1150
1151 return read;
1152}
1153
1154/* return how many bytes are still in the FIFO; this will be called
1155 * with the device spinlock NOT HELD while waiting for the TX FIFO to get
1156 * empty; let's expect this won't be a problem */
1157static int it8709_get_tx_used_slots(struct ite_dev *dev)
1158{
1159 ite_dbg("%s called", __func__);
1160
1161 return it8709_rr(dev, IT85_C0TFSR) & IT85_TXFBC;
1162}
1163
1164/* put a byte to the TX fifo; this should be called with the spinlock held */
1165static void it8709_put_tx_byte(struct ite_dev *dev, u8 value)
1166{
1167 it8709_wr(dev, value, IT85_C0DR);
1168}
1169
1170/* idle the receiver so that we won't receive samples until another
1171 pulse is detected; this must be called with the device spinlock held */
1172static void it8709_idle_rx(struct ite_dev *dev)
1173{
1174 ite_dbg("%s called", __func__);
1175
1176 /* disable streaming by clearing RXACT writing it as 1 */
1177 it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXACT,
1178 IT85_C0RCR);
1179
1180 /* clear the FIFO */
1181 it8709_wr(dev, it8709_rr(dev, IT85_C0MSTCR) | IT85_FIFOCLR,
1182 IT85_C0MSTCR);
1183}
1184
1185/* disable the receiver; this must be called with the device spinlock held */
1186static void it8709_disable_rx(struct ite_dev *dev)
1187{
1188 ite_dbg("%s called", __func__);
1189
1190 /* disable the receiver interrupts */
1191 it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
1192 ~(IT85_RDAIE | IT85_RFOIE),
1193 IT85_C0IER);
1194
1195 /* disable the receiver */
1196 it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) & ~IT85_RXEN,
1197 IT85_C0RCR);
1198
1199 /* clear the FIFO and RXACT (actually RXACT should have been cleared
1200 * in the previous it8709_wr(dev, ) call) */
1201 it8709_idle_rx(dev);
1202}
1203
1204/* enable the receiver; this must be called with the device spinlock held */
1205static void it8709_enable_rx(struct ite_dev *dev)
1206{
1207 ite_dbg("%s called", __func__);
1208
1209 /* enable the receiver by setting RXEN */
1210 it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXEN,
1211 IT85_C0RCR);
1212
1213 /* just prepare it to idle for the next reception */
1214 it8709_idle_rx(dev);
1215
1216 /* enable the receiver interrupts and master enable flag */
1217 it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
1218 |IT85_RDAIE | IT85_RFOIE | IT85_IEC,
1219 IT85_C0IER);
1220}
1221
1222/* disable the transmitter interrupt; this must be called with the device
1223 * spinlock held */
1224static void it8709_disable_tx_interrupt(struct ite_dev *dev)
1225{
1226 ite_dbg("%s called", __func__);
1227
1228 /* disable the transmitter interrupts */
1229 it8709_wr(dev, it8709_rr(dev, IT85_C0IER) & ~IT85_TLDLIE,
1230 IT85_C0IER);
1231}
1232
1233/* enable the transmitter interrupt; this must be called with the device
1234 * spinlock held */
1235static void it8709_enable_tx_interrupt(struct ite_dev *dev)
1236{
1237 ite_dbg("%s called", __func__);
1238
1239 /* enable the transmitter interrupts and master enable flag */
1240 it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
1241 |IT85_TLDLIE | IT85_IEC,
1242 IT85_C0IER);
1243}
1244
1245/* disable the device; this must be called with the device spinlock held */
1246static void it8709_disable(struct ite_dev *dev)
1247{
1248 ite_dbg("%s called", __func__);
1249
1250 /* clear out all interrupt enable flags */
1251 it8709_wr(dev,
1252 it8709_rr(dev,
1253 IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
1254 IT85_RDAIE |
1255 IT85_TLDLIE), IT85_C0IER);
1256
1257 /* disable the receiver */
1258 it8709_disable_rx(dev);
1259
1260 /* erase the FIFO */
1261 it8709_wr(dev, IT85_FIFOCLR | it8709_rr(dev, IT85_C0MSTCR),
1262 IT85_C0MSTCR);
1263}
1264
1265/* initialize the hardware */
1266static void it8709_init_hardware(struct ite_dev *dev)
1267{
1268 ite_dbg("%s called", __func__);
1269
1270 /* disable all the interrupts */
1271 it8709_wr(dev,
1272 it8709_rr(dev,
1273 IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
1274 IT85_RDAIE |
1275 IT85_TLDLIE), IT85_C0IER);
1276
1277 /* program the baud rate divisor */
1278 it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR);
1279 it8709_wr(dev, (ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
1280 IT85_C0BDHR);
1281
1282 /* program the C0MSTCR register defaults */
1283 it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) & ~(IT85_ILSEL |
1284 IT85_ILE
1285 | IT85_FIFOTL
1286 |
1287 IT85_FIFOCLR
1288 |
1289 IT85_RESET))
1290 | IT85_FIFOTL_DEFAULT, IT85_C0MSTCR);
1291
1292 /* program the C0RCR register defaults */
1293 it8709_wr(dev,
1294 (it8709_rr(dev, IT85_C0RCR) &
1295 ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND
1296 | IT85_RXACT | IT85_RXDCR)) |
1297 ITE_RXDCR_DEFAULT, IT85_C0RCR);
1298
1299 /* program the C0TCR register defaults */
1300 it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR)
1301 &~(IT85_TXMPM | IT85_TXMPW))
1302 |IT85_TXRLE | IT85_TXENDF |
1303 IT85_TXMPM_DEFAULT |
1304 IT85_TXMPW_DEFAULT, IT85_C0TCR);
1305
1306 /* program the carrier parameters */
1307 ite_set_carrier_params(dev);
1308}
1309
1310
1311/* generic hardware setup/teardown code */
1312
1313/* activate the device for use */
1314static int ite_open(struct rc_dev *rcdev)
1315{
1316 struct ite_dev *dev = rcdev->priv;
1317 unsigned long flags;
1318
1319 ite_dbg("%s called", __func__);
1320
1321 spin_lock_irqsave(&dev->lock, flags);
1322 dev->in_use = true;
1323
1324 /* enable the receiver */
1325 dev->params.enable_rx(dev);
1326
1327 spin_unlock_irqrestore(&dev->lock, flags);
1328
1329 return 0;
1330}
1331
1332/* deactivate the device for use */
1333static void ite_close(struct rc_dev *rcdev)
1334{
1335 struct ite_dev *dev = rcdev->priv;
1336 unsigned long flags;
1337
1338 ite_dbg("%s called", __func__);
1339
1340 spin_lock_irqsave(&dev->lock, flags);
1341 dev->in_use = false;
1342
1343 /* wait for any transmission to end */
1344 spin_unlock_irqrestore(&dev->lock, flags);
1345 wait_event_interruptible(dev->tx_ended, !dev->transmitting);
1346 spin_lock_irqsave(&dev->lock, flags);
1347
1348 dev->params.disable(dev);
1349
1350 spin_unlock_irqrestore(&dev->lock, flags);
1351}
1352
1353/* supported models and their parameters */
1354static const struct ite_dev_params ite_dev_descs[] = {
1355 { /* 0: ITE8704 */
1356 .model = "ITE8704 CIR transceiver",
1357 .io_region_size = IT87_IOREG_LENGTH,
1358 .hw_tx_capable = true,
1359 .sample_period = (u32) (1000000000ULL / 115200),
1360 .tx_carrier_freq = 38000,
1361 .tx_duty_cycle = 33,
1362 .rx_low_carrier_freq = 0,
1363 .rx_high_carrier_freq = 0,
1364
1365 /* operations */
1366 .get_irq_causes = it87_get_irq_causes,
1367 .enable_rx = it87_enable_rx,
1368 .idle_rx = it87_idle_rx,
1369 .disable_rx = it87_idle_rx,
1370 .get_rx_bytes = it87_get_rx_bytes,
1371 .enable_tx_interrupt = it87_enable_tx_interrupt,
1372 .disable_tx_interrupt = it87_disable_tx_interrupt,
1373 .get_tx_used_slots = it87_get_tx_used_slots,
1374 .put_tx_byte = it87_put_tx_byte,
1375 .disable = it87_disable,
1376 .init_hardware = it87_init_hardware,
1377 .set_carrier_params = it87_set_carrier_params,
1378 },
1379 { /* 1: ITE8713 */
1380 .model = "ITE8713 CIR transceiver",
1381 .io_region_size = IT87_IOREG_LENGTH,
1382 .hw_tx_capable = true,
1383 .sample_period = (u32) (1000000000ULL / 115200),
1384 .tx_carrier_freq = 38000,
1385 .tx_duty_cycle = 33,
1386 .rx_low_carrier_freq = 0,
1387 .rx_high_carrier_freq = 0,
1388
1389 /* operations */
1390 .get_irq_causes = it87_get_irq_causes,
1391 .enable_rx = it87_enable_rx,
1392 .idle_rx = it87_idle_rx,
1393 .disable_rx = it87_idle_rx,
1394 .get_rx_bytes = it87_get_rx_bytes,
1395 .enable_tx_interrupt = it87_enable_tx_interrupt,
1396 .disable_tx_interrupt = it87_disable_tx_interrupt,
1397 .get_tx_used_slots = it87_get_tx_used_slots,
1398 .put_tx_byte = it87_put_tx_byte,
1399 .disable = it87_disable,
1400 .init_hardware = it87_init_hardware,
1401 .set_carrier_params = it87_set_carrier_params,
1402 },
1403 { /* 2: ITE8708 */
1404 .model = "ITE8708 CIR transceiver",
1405 .io_region_size = IT8708_IOREG_LENGTH,
1406 .hw_tx_capable = true,
1407 .sample_period = (u32) (1000000000ULL / 115200),
1408 .tx_carrier_freq = 38000,
1409 .tx_duty_cycle = 33,
1410 .rx_low_carrier_freq = 0,
1411 .rx_high_carrier_freq = 0,
1412
1413 /* operations */
1414 .get_irq_causes = it8708_get_irq_causes,
1415 .enable_rx = it8708_enable_rx,
1416 .idle_rx = it8708_idle_rx,
1417 .disable_rx = it8708_idle_rx,
1418 .get_rx_bytes = it8708_get_rx_bytes,
1419 .enable_tx_interrupt = it8708_enable_tx_interrupt,
1420 .disable_tx_interrupt =
1421 it8708_disable_tx_interrupt,
1422 .get_tx_used_slots = it8708_get_tx_used_slots,
1423 .put_tx_byte = it8708_put_tx_byte,
1424 .disable = it8708_disable,
1425 .init_hardware = it8708_init_hardware,
1426 .set_carrier_params = it8708_set_carrier_params,
1427 },
1428 { /* 3: ITE8709 */
1429 .model = "ITE8709 CIR transceiver",
1430 .io_region_size = IT8709_IOREG_LENGTH,
1431 .hw_tx_capable = true,
1432 .sample_period = (u32) (1000000000ULL / 115200),
1433 .tx_carrier_freq = 38000,
1434 .tx_duty_cycle = 33,
1435 .rx_low_carrier_freq = 0,
1436 .rx_high_carrier_freq = 0,
1437
1438 /* operations */
1439 .get_irq_causes = it8709_get_irq_causes,
1440 .enable_rx = it8709_enable_rx,
1441 .idle_rx = it8709_idle_rx,
1442 .disable_rx = it8709_idle_rx,
1443 .get_rx_bytes = it8709_get_rx_bytes,
1444 .enable_tx_interrupt = it8709_enable_tx_interrupt,
1445 .disable_tx_interrupt =
1446 it8709_disable_tx_interrupt,
1447 .get_tx_used_slots = it8709_get_tx_used_slots,
1448 .put_tx_byte = it8709_put_tx_byte,
1449 .disable = it8709_disable,
1450 .init_hardware = it8709_init_hardware,
1451 .set_carrier_params = it8709_set_carrier_params,
1452 },
1453};
1454
1455static const struct pnp_device_id ite_ids[] = {
1456 {"ITE8704", 0}, /* Default model */
1457 {"ITE8713", 1}, /* CIR found in EEEBox 1501U */
1458 {"ITE8708", 2}, /* Bridged IT8512 */
1459 {"ITE8709", 3}, /* SRAM-Bridged IT8512 */
1460 {"", 0},
1461};
1462
1463/* allocate memory, probe hardware, and initialize everything */
1464static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
1465 *dev_id)
1466{
1467 const struct ite_dev_params *dev_desc = NULL;
1468 struct ite_dev *itdev = NULL;
1469 struct rc_dev *rdev = NULL;
1470 int ret = -ENOMEM;
1471 int model_no;
1472
1473 ite_dbg("%s called", __func__);
1474
1475 itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL);
1476 if (!itdev)
1477 return ret;
1478
1479 /* input device for IR remote (and tx) */
1480 rdev = rc_allocate_device();
1481 if (!rdev)
1482 goto failure;
1483
1484 ret = -ENODEV;
1485
1486 /* get the model number */
1487 model_no = (int)dev_id->driver_data;
1488 ite_pr(KERN_NOTICE, "Auto-detected model: %s\n",
1489 ite_dev_descs[model_no].model);
1490
1491 if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) {
1492 model_no = model_number;
1493 ite_pr(KERN_NOTICE, "The model has been fixed by a module "
1494 "parameter.");
1495 }
1496
1497 ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model);
1498
1499 /* get the description for the device */
1500 dev_desc = &ite_dev_descs[model_no];
1501
1502 /* validate pnp resources */
1503 if (!pnp_port_valid(pdev, 0) ||
1504 pnp_port_len(pdev, 0) != dev_desc->io_region_size) {
1505 dev_err(&pdev->dev, "IR PNP Port not valid!\n");
1506 goto failure;
1507 }
1508
1509 if (!pnp_irq_valid(pdev, 0)) {
1510 dev_err(&pdev->dev, "PNP IRQ not valid!\n");
1511 goto failure;
1512 }
1513
1514 /* store resource values */
1515 itdev->cir_addr = pnp_port_start(pdev, 0);
1516 itdev->cir_irq = pnp_irq(pdev, 0);
1517
1518 /* initialize spinlocks */
1519 spin_lock_init(&itdev->lock);
1520
1521 /* initialize raw event */
1522 init_ir_raw_event(&itdev->rawir);
1523
1524 ret = -EBUSY;
1525 /* now claim resources */
1526 if (!request_region(itdev->cir_addr,
1527 dev_desc->io_region_size, ITE_DRIVER_NAME))
1528 goto failure;
1529
1530 if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
1531 ITE_DRIVER_NAME, (void *)itdev))
1532 goto failure;
1533
1534 /* set driver data into the pnp device */
1535 pnp_set_drvdata(pdev, itdev);
1536 itdev->pdev = pdev;
1537
1538 /* initialize waitqueues for transmission */
1539 init_waitqueue_head(&itdev->tx_queue);
1540 init_waitqueue_head(&itdev->tx_ended);
1541
1542 /* copy model-specific parameters */
1543 itdev->params = *dev_desc;
1544
1545 /* apply any overrides */
1546 if (sample_period > 0)
1547 itdev->params.sample_period = sample_period;
1548
1549 if (tx_carrier_freq > 0)
1550 itdev->params.tx_carrier_freq = tx_carrier_freq;
1551
1552 if (tx_duty_cycle > 0 && tx_duty_cycle <= 100)
1553 itdev->params.tx_duty_cycle = tx_duty_cycle;
1554
1555 if (rx_low_carrier_freq > 0)
1556 itdev->params.rx_low_carrier_freq = rx_low_carrier_freq;
1557
1558 if (rx_high_carrier_freq > 0)
1559 itdev->params.rx_high_carrier_freq = rx_high_carrier_freq;
1560
1561 /* print out parameters */
1562 ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int)
1563 itdev->params.hw_tx_capable);
1564 ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long)
1565 itdev->params.sample_period);
1566 ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int)
1567 itdev->params.tx_carrier_freq);
1568 ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int)
1569 itdev->params.tx_duty_cycle);
1570 ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int)
1571 itdev->params.rx_low_carrier_freq);
1572 ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int)
1573 itdev->params.rx_high_carrier_freq);
1574
1575 /* set up hardware initial state */
1576 itdev->params.init_hardware(itdev);
1577
1578 /* set up ir-core props */
1579 rdev->priv = itdev;
1580 rdev->driver_type = RC_DRIVER_IR_RAW;
1581 rdev->allowed_protos = RC_TYPE_ALL;
1582 rdev->open = ite_open;
1583 rdev->close = ite_close;
1584 rdev->s_idle = ite_s_idle;
1585 rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
1586 rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT;
1587 rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT;
1588 rdev->timeout = ITE_IDLE_TIMEOUT;
1589 rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
1590 itdev->params.sample_period;
1591 rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
1592 itdev->params.sample_period;
1593
1594 /* set up transmitter related values if needed */
1595 if (itdev->params.hw_tx_capable) {
1596 rdev->tx_ir = ite_tx_ir;
1597 rdev->s_tx_carrier = ite_set_tx_carrier;
1598 rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle;
1599 }
1600
1601 rdev->input_name = dev_desc->model;
1602 rdev->input_id.bustype = BUS_HOST;
1603 rdev->input_id.vendor = PCI_VENDOR_ID_ITE;
1604 rdev->input_id.product = 0;
1605 rdev->input_id.version = 0;
1606 rdev->driver_name = ITE_DRIVER_NAME;
1607 rdev->map_name = RC_MAP_RC6_MCE;
1608
1609 ret = rc_register_device(rdev);
1610 if (ret)
1611 goto failure;
1612
1613 itdev->rdev = rdev;
1614 ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");
1615
1616 return 0;
1617
1618failure:
1619 if (itdev->cir_irq)
1620 free_irq(itdev->cir_irq, itdev);
1621
1622 if (itdev->cir_addr)
1623 release_region(itdev->cir_addr, itdev->params.io_region_size);
1624
1625 rc_free_device(rdev);
1626 kfree(itdev);
1627
1628 return ret;
1629}
1630
1631static void __devexit ite_remove(struct pnp_dev *pdev)
1632{
1633 struct ite_dev *dev = pnp_get_drvdata(pdev);
1634 unsigned long flags;
1635
1636 ite_dbg("%s called", __func__);
1637
1638 spin_lock_irqsave(&dev->lock, flags);
1639
1640 /* disable hardware */
1641 dev->params.disable(dev);
1642
1643 spin_unlock_irqrestore(&dev->lock, flags);
1644
1645 /* free resources */
1646 free_irq(dev->cir_irq, dev);
1647 release_region(dev->cir_addr, dev->params.io_region_size);
1648
1649 rc_unregister_device(dev->rdev);
1650
1651 kfree(dev);
1652}
1653
1654static int ite_suspend(struct pnp_dev *pdev, pm_message_t state)
1655{
1656 struct ite_dev *dev = pnp_get_drvdata(pdev);
1657 unsigned long flags;
1658
1659 ite_dbg("%s called", __func__);
1660
1661 spin_lock_irqsave(&dev->lock, flags);
1662
1663 /* disable all interrupts */
1664 dev->params.disable(dev);
1665
1666 spin_unlock_irqrestore(&dev->lock, flags);
1667
1668 return 0;
1669}
1670
1671static int ite_resume(struct pnp_dev *pdev)
1672{
1673 int ret = 0;
1674 struct ite_dev *dev = pnp_get_drvdata(pdev);
1675 unsigned long flags;
1676
1677 ite_dbg("%s called", __func__);
1678
1679 spin_lock_irqsave(&dev->lock, flags);
1680
1681 if (dev->transmitting) {
1682 /* wake up the transmitter */
1683 wake_up_interruptible(&dev->tx_queue);
1684 } else {
1685 /* enable the receiver */
1686 dev->params.enable_rx(dev);
1687 }
1688
1689 spin_unlock_irqrestore(&dev->lock, flags);
1690
1691 return ret;
1692}
1693
1694static void ite_shutdown(struct pnp_dev *pdev)
1695{
1696 struct ite_dev *dev = pnp_get_drvdata(pdev);
1697 unsigned long flags;
1698
1699 ite_dbg("%s called", __func__);
1700
1701 spin_lock_irqsave(&dev->lock, flags);
1702
1703 /* disable all interrupts */
1704 dev->params.disable(dev);
1705
1706 spin_unlock_irqrestore(&dev->lock, flags);
1707}
1708
1709static struct pnp_driver ite_driver = {
1710 .name = ITE_DRIVER_NAME,
1711 .id_table = ite_ids,
1712 .probe = ite_probe,
1713 .remove = __devexit_p(ite_remove),
1714 .suspend = ite_suspend,
1715 .resume = ite_resume,
1716 .shutdown = ite_shutdown,
1717};
1718
1719int ite_init(void)
1720{
1721 return pnp_register_driver(&ite_driver);
1722}
1723
1724void ite_exit(void)
1725{
1726 pnp_unregister_driver(&ite_driver);
1727}
1728
1729MODULE_DEVICE_TABLE(pnp, ite_ids);
1730MODULE_DESCRIPTION("ITE Tech Inc. IT8712F/ITE8512F CIR driver");
1731
1732MODULE_AUTHOR("Juan J. Garcia de Soria <skandalfo@gmail.com>");
1733MODULE_LICENSE("GPL");
1734
1735module_init(ite_init);
1736module_exit(ite_exit);
diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h
new file mode 100644
index 000000000000..16a19f5fd718
--- /dev/null
+++ b/drivers/media/rc/ite-cir.h
@@ -0,0 +1,481 @@
1/*
2 * Driver for ITE Tech Inc. IT8712F/IT8512F CIR
3 *
4 * Copyright (C) 2010 Juan Jesús García de Soria <skandalfo@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA.
20 */
21
22/* platform driver name to register */
23#define ITE_DRIVER_NAME "ite-cir"
24
25/* logging macros */
26#define ite_pr(level, text, ...) \
27 printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
28#define ite_dbg(text, ...) do { \
29 if (debug) \
30 printk(KERN_DEBUG \
31 KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
32} while (0)
33
34#define ite_dbg_verbose(text, ...) do {\
35 if (debug > 1) \
36 printk(KERN_DEBUG \
37 KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
38} while (0)
39
40/* FIFO sizes */
41#define ITE_TX_FIFO_LEN 32
42#define ITE_RX_FIFO_LEN 32
43
44/* interrupt types */
45#define ITE_IRQ_TX_FIFO 1
46#define ITE_IRQ_RX_FIFO 2
47#define ITE_IRQ_RX_FIFO_OVERRUN 4
48
49/* forward declaration */
50struct ite_dev;
51
52/* struct for storing the parameters of different recognized devices */
53struct ite_dev_params {
54 /* model of the device */
55 const char *model;
56
57 /* size of the I/O region */
58 int io_region_size;
59
60 /* true if the hardware supports transmission */
61 bool hw_tx_capable;
62
63 /* base sampling period, in ns */
64 u32 sample_period;
65
66 /* rx low carrier frequency, in Hz, 0 means no demodulation */
67 unsigned int rx_low_carrier_freq;
68
69 /* tx high carrier frequency, in Hz, 0 means no demodulation */
70 unsigned int rx_high_carrier_freq;
71
72 /* tx carrier frequency, in Hz */
73 unsigned int tx_carrier_freq;
74
75 /* duty cycle, 0-100 */
76 int tx_duty_cycle;
77
78 /* hw-specific operation function pointers; most of these must be
79 * called while holding the spin lock, except for the TX FIFO length
80 * one */
81 /* get pending interrupt causes */
82 int (*get_irq_causes) (struct ite_dev *dev);
83
84 /* enable rx */
85 void (*enable_rx) (struct ite_dev *dev);
86
87 /* make rx enter the idle state; keep listening for a pulse, but stop
88 * streaming space bytes */
89 void (*idle_rx) (struct ite_dev *dev);
90
91 /* disable rx completely */
92 void (*disable_rx) (struct ite_dev *dev);
93
94 /* read bytes from RX FIFO; return read count */
95 int (*get_rx_bytes) (struct ite_dev *dev, u8 *buf, int buf_size);
96
97 /* enable tx FIFO space available interrupt */
98 void (*enable_tx_interrupt) (struct ite_dev *dev);
99
100 /* disable tx FIFO space available interrupt */
101 void (*disable_tx_interrupt) (struct ite_dev *dev);
102
103 /* get number of full TX FIFO slots */
104 int (*get_tx_used_slots) (struct ite_dev *dev);
105
106 /* put a byte to the TX FIFO */
107 void (*put_tx_byte) (struct ite_dev *dev, u8 value);
108
109 /* disable hardware completely */
110 void (*disable) (struct ite_dev *dev);
111
112 /* initialize the hardware */
113 void (*init_hardware) (struct ite_dev *dev);
114
115 /* set the carrier parameters */
116 void (*set_carrier_params) (struct ite_dev *dev, bool high_freq,
117 bool use_demodulator, u8 carrier_freq_bits,
118 u8 allowance_bits, u8 pulse_width_bits);
119};
120
121/* ITE CIR device structure */
122struct ite_dev {
123 struct pnp_dev *pdev;
124 struct rc_dev *rdev;
125 struct ir_raw_event rawir;
126
127 /* sync data */
128 spinlock_t lock;
129 bool in_use, transmitting;
130
131 /* transmit support */
132 int tx_fifo_allowance;
133 wait_queue_head_t tx_queue, tx_ended;
134
135 /* hardware I/O settings */
136 unsigned long cir_addr;
137 int cir_irq;
138
139 /* overridable copy of model parameters */
140 struct ite_dev_params params;
141};
142
143/* common values for all kinds of hardware */
144
145/* baud rate divisor default */
146#define ITE_BAUDRATE_DIVISOR 1
147
148/* low-speed carrier frequency limits (Hz) */
149#define ITE_LCF_MIN_CARRIER_FREQ 27000
150#define ITE_LCF_MAX_CARRIER_FREQ 58000
151
152/* high-speed carrier frequency limits (Hz) */
153#define ITE_HCF_MIN_CARRIER_FREQ 400000
154#define ITE_HCF_MAX_CARRIER_FREQ 500000
155
156/* default carrier freq for when demodulator is off (Hz) */
157#define ITE_DEFAULT_CARRIER_FREQ 38000
158
159/* default idling timeout in ns (0.2 seconds) */
160#define ITE_IDLE_TIMEOUT 200000000UL
161
162/* limit timeout values */
163#define ITE_MIN_IDLE_TIMEOUT 100000000UL
164#define ITE_MAX_IDLE_TIMEOUT 1000000000UL
165
166/* convert bits to us */
167#define ITE_BITS_TO_NS(bits, sample_period) \
168((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period))
169
170/*
171 * n in RDCR produces a tolerance of +/- n * 6.25% around the center
172 * carrier frequency...
173 *
174 * From two limit frequencies, L (low) and H (high), we can get both the
175 * center frequency F = (L + H) / 2 and the variation from the center
176 * frequency A = (H - L) / (H + L). We can use this in order to honor the
177 * s_rx_carrier_range() call in ir-core. We'll suppose that any request
178 * setting L=0 means we must shut down the demodulator.
179 */
180#define ITE_RXDCR_PER_10000_STEP 625
181
182/* high speed carrier freq values */
183#define ITE_CFQ_400 0x03
184#define ITE_CFQ_450 0x08
185#define ITE_CFQ_480 0x0b
186#define ITE_CFQ_500 0x0d
187
188/* values for pulse widths */
189#define ITE_TXMPW_A 0x02
190#define ITE_TXMPW_B 0x03
191#define ITE_TXMPW_C 0x04
192#define ITE_TXMPW_D 0x05
193#define ITE_TXMPW_E 0x06
194
195/* values for demodulator carrier range allowance */
196#define ITE_RXDCR_DEFAULT 0x01 /* default carrier range */
197#define ITE_RXDCR_MAX 0x07 /* default carrier range */
198
199/* DR TX bits */
200#define ITE_TX_PULSE 0x00
201#define ITE_TX_SPACE 0x80
202#define ITE_TX_MAX_RLE 0x80
203#define ITE_TX_RLE_MASK 0x7f
204
205/*
206 * IT8712F
207 *
208 * hardware data obtained from:
209 *
210 * IT8712F
211 * Environment Control – Low Pin Count Input / Output
212 * (EC - LPC I/O)
213 * Preliminary Specification V0. 81
214 */
215
216/* register offsets */
217#define IT87_DR 0x00 /* data register */
218#define IT87_IER 0x01 /* interrupt enable register */
219#define IT87_RCR 0x02 /* receiver control register */
220#define IT87_TCR1 0x03 /* transmitter control register 1 */
221#define IT87_TCR2 0x04 /* transmitter control register 2 */
222#define IT87_TSR 0x05 /* transmitter status register */
223#define IT87_RSR 0x06 /* receiver status register */
224#define IT87_BDLR 0x05 /* baud rate divisor low byte register */
225#define IT87_BDHR 0x06 /* baud rate divisor high byte register */
226#define IT87_IIR 0x07 /* interrupt identification register */
227
228#define IT87_IOREG_LENGTH 0x08 /* length of register file */
229
230/* IER bits */
231#define IT87_TLDLIE 0x01 /* transmitter low data interrupt enable */
232#define IT87_RDAIE 0x02 /* receiver data available interrupt enable */
233#define IT87_RFOIE 0x04 /* receiver FIFO overrun interrupt enable */
234#define IT87_IEC 0x08 /* interrupt enable control */
235#define IT87_BR 0x10 /* baud rate register enable */
236#define IT87_RESET 0x20 /* reset */
237
238/* RCR bits */
239#define IT87_RXDCR 0x07 /* receiver demodulation carrier range mask */
240#define IT87_RXACT 0x08 /* receiver active */
241#define IT87_RXEND 0x10 /* receiver demodulation enable */
242#define IT87_RXEN 0x20 /* receiver enable */
243#define IT87_HCFS 0x40 /* high-speed carrier frequency select */
244#define IT87_RDWOS 0x80 /* receiver data without sync */
245
246/* TCR1 bits */
247#define IT87_TXMPM 0x03 /* transmitter modulation pulse mode mask */
248#define IT87_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
249#define IT87_TXENDF 0x04 /* transmitter deferral */
250#define IT87_TXRLE 0x08 /* transmitter run length enable */
251#define IT87_FIFOTL 0x30 /* FIFO level threshold mask */
252#define IT87_FIFOTL_DEFAULT 0x20 /* FIFO level threshold default
253 * 0x00 -> 1, 0x10 -> 7, 0x20 -> 17,
254 * 0x30 -> 25 */
255#define IT87_ILE 0x40 /* internal loopback enable */
256#define IT87_FIFOCLR 0x80 /* FIFO clear bit */
257
258/* TCR2 bits */
259#define IT87_TXMPW 0x07 /* transmitter modulation pulse width mask */
260#define IT87_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
261#define IT87_CFQ 0xf8 /* carrier frequency mask */
262#define IT87_CFQ_SHIFT 3 /* carrier frequency bit shift */
263
264/* TSR bits */
265#define IT87_TXFBC 0x3f /* transmitter FIFO byte count mask */
266
267/* RSR bits */
268#define IT87_RXFBC 0x3f /* receiver FIFO byte count mask */
269#define IT87_RXFTO 0x80 /* receiver FIFO time-out */
270
271/* IIR bits */
272#define IT87_IP 0x01 /* interrupt pending */
273#define IT87_II 0x06 /* interrupt identification mask */
274#define IT87_II_NOINT 0x00 /* no interrupt */
275#define IT87_II_TXLDL 0x02 /* transmitter low data level */
276#define IT87_II_RXDS 0x04 /* receiver data stored */
277#define IT87_II_RXFO 0x06 /* receiver FIFO overrun */
278
279/*
280 * IT8512E/F
281 *
282 * Hardware data obtained from:
283 *
284 * IT8512E/F
285 * Embedded Controller
286 * Preliminary Specification V0.4.1
287 *
288 * Note that the CIR registers are not directly available to the host, because
289 * they only are accessible to the integrated microcontroller. Thus, in order
290 * use it, some kind of bridging is required. As the bridging may depend on
291 * the controller firmware in use, we are going to use the PNP ID in order to
292 * determine the strategy and ports available. See after these generic
293 * IT8512E/F register definitions for register definitions for those
294 * strategies.
295 */
296
297/* register offsets */
298#define IT85_C0DR 0x00 /* data register */
299#define IT85_C0MSTCR 0x01 /* master control register */
300#define IT85_C0IER 0x02 /* interrupt enable register */
301#define IT85_C0IIR 0x03 /* interrupt identification register */
302#define IT85_C0CFR 0x04 /* carrier frequency register */
303#define IT85_C0RCR 0x05 /* receiver control register */
304#define IT85_C0TCR 0x06 /* transmitter control register */
305#define IT85_C0SCK 0x07 /* slow clock control register */
306#define IT85_C0BDLR 0x08 /* baud rate divisor low byte register */
307#define IT85_C0BDHR 0x09 /* baud rate divisor high byte register */
308#define IT85_C0TFSR 0x0a /* transmitter FIFO status register */
309#define IT85_C0RFSR 0x0b /* receiver FIFO status register */
310#define IT85_C0WCL 0x0d /* wakeup code length register */
311#define IT85_C0WCR 0x0e /* wakeup code read/write register */
312#define IT85_C0WPS 0x0f /* wakeup power control/status register */
313
314#define IT85_IOREG_LENGTH 0x10 /* length of register file */
315
316/* C0MSTCR bits */
317#define IT85_RESET 0x01 /* reset */
318#define IT85_FIFOCLR 0x02 /* FIFO clear bit */
319#define IT85_FIFOTL 0x0c /* FIFO level threshold mask */
320#define IT85_FIFOTL_DEFAULT 0x08 /* FIFO level threshold default
321 * 0x00 -> 1, 0x04 -> 7, 0x08 -> 17,
322 * 0x0c -> 25 */
323#define IT85_ILE 0x10 /* internal loopback enable */
324#define IT85_ILSEL 0x20 /* internal loopback select */
325
326/* C0IER bits */
327#define IT85_TLDLIE 0x01 /* TX low data level interrupt enable */
328#define IT85_RDAIE 0x02 /* RX data available interrupt enable */
329#define IT85_RFOIE 0x04 /* RX FIFO overrun interrupt enable */
330#define IT85_IEC 0x80 /* interrupt enable function control */
331
332/* C0IIR bits */
333#define IT85_TLDLI 0x01 /* transmitter low data level interrupt */
334#define IT85_RDAI 0x02 /* receiver data available interrupt */
335#define IT85_RFOI 0x04 /* receiver FIFO overrun interrupt */
336#define IT85_NIP 0x80 /* no interrupt pending */
337
338/* C0CFR bits */
339#define IT85_CFQ 0x1f /* carrier frequency mask */
340#define IT85_HCFS 0x20 /* high speed carrier frequency select */
341
342/* C0RCR bits */
343#define IT85_RXDCR 0x07 /* receiver demodulation carrier range mask */
344#define IT85_RXACT 0x08 /* receiver active */
345#define IT85_RXEND 0x10 /* receiver demodulation enable */
346#define IT85_RDWOS 0x20 /* receiver data without sync */
347#define IT85_RXEN 0x80 /* receiver enable */
348
349/* C0TCR bits */
350#define IT85_TXMPW 0x07 /* transmitter modulation pulse width mask */
351#define IT85_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
352#define IT85_TXMPM 0x18 /* transmitter modulation pulse mode mask */
353#define IT85_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
354#define IT85_TXENDF 0x20 /* transmitter deferral */
355#define IT85_TXRLE 0x40 /* transmitter run length enable */
356
357/* C0SCK bits */
358#define IT85_SCKS 0x01 /* slow clock select */
359#define IT85_TXDCKG 0x02 /* TXD clock gating */
360#define IT85_DLL1P8E 0x04 /* DLL 1.8432M enable */
361#define IT85_DLLTE 0x08 /* DLL test enable */
362#define IT85_BRCM 0x70 /* baud rate count mode */
363#define IT85_DLLOCK 0x80 /* DLL lock */
364
365/* C0TFSR bits */
366#define IT85_TXFBC 0x3f /* transmitter FIFO count mask */
367
368/* C0RFSR bits */
369#define IT85_RXFBC 0x3f /* receiver FIFO count mask */
370#define IT85_RXFTO 0x80 /* receiver FIFO time-out */
371
372/* C0WCL bits */
373#define IT85_WCL 0x3f /* wakeup code length mask */
374
375/* C0WPS bits */
376#define IT85_CIRPOSIE 0x01 /* power on/off status interrupt enable */
377#define IT85_CIRPOIS 0x02 /* power on/off interrupt status */
378#define IT85_CIRPOII 0x04 /* power on/off interrupt identification */
379#define IT85_RCRST 0x10 /* wakeup code reading counter reset bit */
380#define IT85_WCRST 0x20 /* wakeup code writing counter reset bit */
381
382/*
383 * ITE8708
384 *
385 * Hardware data obtained from hacked driver for IT8512 in this forum post:
386 *
387 * http://ubuntuforums.org/showthread.php?t=1028640
388 *
389 * Although there's no official documentation for that driver, analysis would
390 * suggest that it maps the 16 registers of IT8512 onto two 8-register banks,
391 * selectable by a single bank-select bit that's mapped onto both banks. The
392 * IT8512 registers are mapped in a different order, so that the first bank
393 * maps the ones that are used more often, and two registers that share a
394 * reserved high-order bit are placed at the same offset in both banks in
395 * order to reuse the reserved bit as the bank select bit.
396 */
397
398/* register offsets */
399
400/* mapped onto both banks */
401#define IT8708_BANKSEL 0x07 /* bank select register */
402#define IT8708_HRAE 0x80 /* high registers access enable */
403
404/* mapped onto the low bank */
405#define IT8708_C0DR 0x00 /* data register */
406#define IT8708_C0MSTCR 0x01 /* master control register */
407#define IT8708_C0IER 0x02 /* interrupt enable register */
408#define IT8708_C0IIR 0x03 /* interrupt identification register */
409#define IT8708_C0RFSR 0x04 /* receiver FIFO status register */
410#define IT8708_C0RCR 0x05 /* receiver control register */
411#define IT8708_C0TFSR 0x06 /* transmitter FIFO status register */
412#define IT8708_C0TCR 0x07 /* transmitter control register */
413
414/* mapped onto the high bank */
415#define IT8708_C0BDLR 0x01 /* baud rate divisor low byte register */
416#define IT8708_C0BDHR 0x02 /* baud rate divisor high byte register */
417#define IT8708_C0CFR 0x04 /* carrier frequency register */
418
419/* registers whose bank mapping we don't know, since they weren't being used
420 * in the hacked driver... most probably they belong to the high bank too,
421 * since they fit in the holes the other registers leave */
422#define IT8708_C0SCK 0x03 /* slow clock control register */
423#define IT8708_C0WCL 0x05 /* wakeup code length register */
424#define IT8708_C0WCR 0x06 /* wakeup code read/write register */
425#define IT8708_C0WPS 0x07 /* wakeup power control/status register */
426
427#define IT8708_IOREG_LENGTH 0x08 /* length of register file */
428
429/* two more registers that are defined in the hacked driver, but can't be
430 * found in the data sheets; no idea what they are or how they are accessed,
431 * since the hacked driver doesn't seem to use them */
432#define IT8708_CSCRR 0x00
433#define IT8708_CGPINTR 0x01
434
435/* CSCRR bits */
436#define IT8708_CSCRR_SCRB 0x3f
437#define IT8708_CSCRR_PM 0x80
438
439/* CGPINTR bits */
440#define IT8708_CGPINT 0x01
441
442/*
443 * ITE8709
444 *
445 * Hardware interfacing data obtained from the original lirc_ite8709 driver.
446 * Verbatim from its sources:
447 *
448 * The ITE8709 device seems to be the combination of IT8512 superIO chip and
449 * a specific firmware running on the IT8512's embedded micro-controller.
450 * In addition of the embedded micro-controller, the IT8512 chip contains a
451 * CIR module and several other modules. A few modules are directly accessible
452 * by the host CPU, but most of them are only accessible by the
453 * micro-controller. The CIR module is only accessible by the
454 * micro-controller.
455 *
456 * The battery-backed SRAM module is accessible by the host CPU and the
457 * micro-controller. So one of the MC's firmware role is to act as a bridge
458 * between the host CPU and the CIR module. The firmware implements a kind of
459 * communication protocol using the SRAM module as a shared memory. The IT8512
460 * specification is publicly available on ITE's web site, but the
461 * communication protocol is not, so it was reverse-engineered.
462 */
463
464/* register offsets */
465#define IT8709_RAM_IDX 0x00 /* index into the SRAM module bytes */
466#define IT8709_RAM_VAL 0x01 /* read/write data to the indexed byte */
467
468#define IT8709_IOREG_LENGTH 0x02 /* length of register file */
469
470/* register offsets inside the SRAM module */
471#define IT8709_MODE 0x1a /* request/ack byte */
472#define IT8709_REG_IDX 0x1b /* index of the CIR register to access */
473#define IT8709_REG_VAL 0x1c /* value read/to be written */
474#define IT8709_IIR 0x1e /* interrupt identification register */
475#define IT8709_RFSR 0x1f /* receiver FIFO status register */
476#define IT8709_FIFO 0x20 /* start of in RAM RX FIFO copy */
477
478/* MODE values */
479#define IT8709_IDLE 0x00
480#define IT8709_WRITE 0x01
481#define IT8709_READ 0x02
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 0659e9f50144..85cac7ddbcec 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -37,7 +37,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
37 rc-gadmei-rm008z.o \ 37 rc-gadmei-rm008z.o \
38 rc-genius-tvgo-a11mce.o \ 38 rc-genius-tvgo-a11mce.o \
39 rc-gotview7135.o \ 39 rc-gotview7135.o \
40 rc-hauppauge-new.o \
41 rc-imon-mce.o \ 40 rc-imon-mce.o \
42 rc-imon-pad.o \ 41 rc-imon-pad.o \
43 rc-iodata-bctv7e.o \ 42 rc-iodata-bctv7e.o \
@@ -68,14 +67,15 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
68 rc-proteus-2309.o \ 67 rc-proteus-2309.o \
69 rc-purpletv.o \ 68 rc-purpletv.o \
70 rc-pv951.o \ 69 rc-pv951.o \
71 rc-rc5-hauppauge-new.o \ 70 rc-hauppauge.o \
72 rc-rc5-tv.o \
73 rc-rc6-mce.o \ 71 rc-rc6-mce.o \
74 rc-real-audio-220-32-keys.o \ 72 rc-real-audio-220-32-keys.o \
75 rc-streamzap.o \ 73 rc-streamzap.o \
76 rc-tbs-nec.o \ 74 rc-tbs-nec.o \
75 rc-technisat-usb2.o \
77 rc-terratec-cinergy-xs.o \ 76 rc-terratec-cinergy-xs.o \
78 rc-terratec-slim.o \ 77 rc-terratec-slim.o \
78 rc-terratec-slim-2.o \
79 rc-tevii-nec.o \ 79 rc-tevii-nec.o \
80 rc-total-media-in-hand.o \ 80 rc-total-media-in-hand.o \
81 rc-trekstor.o \ 81 rc-trekstor.o \
diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
index 136d3952dedc..9a8752fdcca1 100644
--- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
@@ -50,9 +50,9 @@ static struct rc_map_table adstech_dvb_t_pci[] = {
50 { 0x13, KEY_TUNER }, /* Live */ 50 { 0x13, KEY_TUNER }, /* Live */
51 { 0x0a, KEY_A }, 51 { 0x0a, KEY_A },
52 { 0x12, KEY_B }, 52 { 0x12, KEY_B },
53 { 0x03, KEY_PROG1 }, /* 1 */ 53 { 0x03, KEY_RED }, /* 1 */
54 { 0x01, KEY_PROG2 }, /* 2 */ 54 { 0x01, KEY_GREEN }, /* 2 */
55 { 0x00, KEY_PROG3 }, /* 3 */ 55 { 0x00, KEY_YELLOW }, /* 3 */
56 { 0x06, KEY_DVD }, 56 { 0x06, KEY_DVD },
57 { 0x48, KEY_AUX }, /* Photo */ 57 { 0x48, KEY_AUX }, /* Photo */
58 { 0x40, KEY_VIDEO }, 58 { 0x40, KEY_VIDEO },
diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
index 3ddb41bc075e..c25809d4c813 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
@@ -26,12 +26,12 @@ static struct rc_map_table avermedia_dvbt[] = {
26 { 0x16, KEY_8 }, /* '8' / 'down arrow' */ 26 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
27 { 0x36, KEY_9 }, /* '9' */ 27 { 0x36, KEY_9 }, /* '9' */
28 28
29 { 0x20, KEY_LIST }, /* 'source' */ 29 { 0x20, KEY_VIDEO }, /* 'source' */
30 { 0x10, KEY_TEXT }, /* 'teletext' */ 30 { 0x10, KEY_TEXT }, /* 'teletext' */
31 { 0x00, KEY_POWER }, /* 'power' */ 31 { 0x00, KEY_POWER }, /* 'power' */
32 { 0x04, KEY_AUDIO }, /* 'audio' */ 32 { 0x04, KEY_AUDIO }, /* 'audio' */
33 { 0x06, KEY_ZOOM }, /* 'full screen' */ 33 { 0x06, KEY_ZOOM }, /* 'full screen' */
34 { 0x18, KEY_VIDEO }, /* 'display' */ 34 { 0x18, KEY_SWITCHVIDEOMODE }, /* 'display' */
35 { 0x38, KEY_SEARCH }, /* 'loop' */ 35 { 0x38, KEY_SEARCH }, /* 'loop' */
36 { 0x08, KEY_INFO }, /* 'preview' */ 36 { 0x08, KEY_INFO }, /* 'preview' */
37 { 0x2a, KEY_REWIND }, /* 'backward <<' */ 37 { 0x2a, KEY_REWIND }, /* 'backward <<' */
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
index 357fea58a46e..3d2cbe4e5e46 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
@@ -108,7 +108,7 @@ static struct rc_map_table avermedia_m135a[] = {
108 { 0x0414, KEY_TEXT }, 108 { 0x0414, KEY_TEXT },
109 { 0x0415, KEY_EPG }, 109 { 0x0415, KEY_EPG },
110 { 0x041a, KEY_TV2 }, /* PIP */ 110 { 0x041a, KEY_TV2 }, /* PIP */
111 { 0x041b, KEY_MHP }, /* Snapshot */ 111 { 0x041b, KEY_CAMERA }, /* Snapshot */
112 112
113 { 0x0417, KEY_RECORD }, 113 { 0x0417, KEY_RECORD },
114 { 0x0416, KEY_PLAYPAUSE }, 114 { 0x0416, KEY_PLAYPAUSE },
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
index e694e6eac37e..8cd7f28808bd 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
@@ -56,7 +56,7 @@ static struct rc_map_table avermedia_m733a_rm_k6[] = {
56 { 0x0414, KEY_TEXT }, 56 { 0x0414, KEY_TEXT },
57 { 0x0415, KEY_EPG }, 57 { 0x0415, KEY_EPG },
58 { 0x041a, KEY_TV2 }, /* PIP */ 58 { 0x041a, KEY_TV2 }, /* PIP */
59 { 0x041b, KEY_MHP }, /* Snapshot */ 59 { 0x041b, KEY_CAMERA }, /* Snapshot */
60 60
61 { 0x0417, KEY_RECORD }, 61 { 0x0417, KEY_RECORD },
62 { 0x0416, KEY_PLAYPAUSE }, 62 { 0x0416, KEY_PLAYPAUSE },
diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
index f4ca1fff455d..9d68af217d8b 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
@@ -31,7 +31,7 @@ static struct rc_map_table avermedia_rm_ks[] = {
31 { 0x0505, KEY_VOLUMEDOWN }, 31 { 0x0505, KEY_VOLUMEDOWN },
32 { 0x0506, KEY_MUTE }, 32 { 0x0506, KEY_MUTE },
33 { 0x0507, KEY_RIGHT }, 33 { 0x0507, KEY_RIGHT },
34 { 0x0508, KEY_PROG1 }, 34 { 0x0508, KEY_RED },
35 { 0x0509, KEY_1 }, 35 { 0x0509, KEY_1 },
36 { 0x050a, KEY_2 }, 36 { 0x050a, KEY_2 },
37 { 0x050b, KEY_3 }, 37 { 0x050b, KEY_3 },
diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c
index 4b787fa94f08..8bf058f67f0c 100644
--- a/drivers/media/rc/keymaps/rc-behold-columbus.c
+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c
@@ -28,7 +28,7 @@ static struct rc_map_table behold_columbus[] = {
28 * */ 28 * */
29 29
30 { 0x13, KEY_MUTE }, 30 { 0x13, KEY_MUTE },
31 { 0x11, KEY_PROPS }, 31 { 0x11, KEY_VIDEO },
32 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */ 32 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
33 { 0x12, KEY_POWER }, 33 { 0x12, KEY_POWER },
34 34
diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
index 0ee1f149364c..c909a234c776 100644
--- a/drivers/media/rc/keymaps/rc-behold.c
+++ b/drivers/media/rc/keymaps/rc-behold.c
@@ -97,7 +97,7 @@ static struct rc_map_table behold[] = {
97 { 0x6b861a, KEY_STOP }, 97 { 0x6b861a, KEY_STOP },
98 { 0x6b860e, KEY_TEXT }, 98 { 0x6b860e, KEY_TEXT },
99 { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */ 99 { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */
100 { 0x6b861e, KEY_YELLOW }, /*XXX KEY_SOURCE */ 100 { 0x6b861e, KEY_VIDEO },
101 101
102 /* 0x1d 0x13 0x19 * 102 /* 0x1d 0x13 0x19 *
103 * SLEEP PREVIEW DVB * 103 * SLEEP PREVIEW DVB *
diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c
index 97fc3862f608..2f66e4310d20 100644
--- a/drivers/media/rc/keymaps/rc-budget-ci-old.c
+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c
@@ -12,7 +12,8 @@
12 12
13#include <media/rc-map.h> 13#include <media/rc-map.h>
14 14
15/* From reading the following remotes: 15/*
16 * From reading the following remotes:
16 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 17 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
17 * Hauppauge (from NOVA-CI-s box product) 18 * Hauppauge (from NOVA-CI-s box product)
18 * This is a "middle of the road" approach, differences are noted 19 * This is a "middle of the road" approach, differences are noted
diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c
index 99520ff65b61..cf3a6bfb190c 100644
--- a/drivers/media/rc/keymaps/rc-cinergy.c
+++ b/drivers/media/rc/keymaps/rc-cinergy.c
@@ -25,7 +25,7 @@ static struct rc_map_table cinergy[] = {
25 { 0x09, KEY_9 }, 25 { 0x09, KEY_9 },
26 26
27 { 0x0a, KEY_POWER }, 27 { 0x0a, KEY_POWER },
28 { 0x0b, KEY_PROG1 }, /* app */ 28 { 0x0b, KEY_MEDIA }, /* app */
29 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */ 29 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
30 { 0x0d, KEY_CHANNELUP }, /* channel */ 30 { 0x0d, KEY_CHANNELUP }, /* channel */
31 { 0x0e, KEY_CHANNELDOWN }, /* channel- */ 31 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
index 43912bd02a9e..82c0200029af 100644
--- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
@@ -32,7 +32,7 @@ static struct rc_map_table dntv_live_dvb_t[] = {
32 { 0x0c, KEY_SEARCH }, /* scan */ 32 { 0x0c, KEY_SEARCH }, /* scan */
33 { 0x0d, KEY_STOP }, 33 { 0x0d, KEY_STOP },
34 { 0x0e, KEY_PAUSE }, 34 { 0x0e, KEY_PAUSE },
35 { 0x0f, KEY_LIST }, /* source */ 35 { 0x0f, KEY_VIDEO }, /* source */
36 36
37 { 0x10, KEY_MUTE }, 37 { 0x10, KEY_MUTE },
38 { 0x11, KEY_REWIND }, /* backward << */ 38 { 0x11, KEY_REWIND }, /* backward << */
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c
index afa4e92284ef..e56ac6e9670a 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c
@@ -24,7 +24,7 @@ static struct rc_map_table encore_enltv[] = {
24 { 0x1e, KEY_TV }, 24 { 0x1e, KEY_TV },
25 { 0x00, KEY_VIDEO }, 25 { 0x00, KEY_VIDEO },
26 { 0x01, KEY_AUDIO }, /* music */ 26 { 0x01, KEY_AUDIO }, /* music */
27 { 0x02, KEY_MHP }, /* picture */ 27 { 0x02, KEY_CAMERA }, /* picture */
28 28
29 { 0x1f, KEY_1 }, 29 { 0x1f, KEY_1 },
30 { 0x03, KEY_2 }, 30 { 0x03, KEY_2 },
@@ -77,7 +77,7 @@ static struct rc_map_table encore_enltv[] = {
77 { 0x50, KEY_SLEEP }, /* shutdown */ 77 { 0x50, KEY_SLEEP }, /* shutdown */
78 { 0x51, KEY_MODE }, /* stereo > main */ 78 { 0x51, KEY_MODE }, /* stereo > main */
79 { 0x52, KEY_SELECT }, /* stereo > sap */ 79 { 0x52, KEY_SELECT }, /* stereo > sap */
80 { 0x53, KEY_PROG1 }, /* teletext */ 80 { 0x53, KEY_TEXT }, /* teletext */
81 81
82 82
83 { 0x59, KEY_RED }, /* AP1 */ 83 { 0x59, KEY_RED }, /* AP1 */
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c
index 7d5b00ed4ff2..b6264f1bc4c1 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv2.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c
@@ -32,7 +32,7 @@ static struct rc_map_table encore_enltv2[] = {
32 { 0x64, KEY_LAST }, /* +100 */ 32 { 0x64, KEY_LAST }, /* +100 */
33 { 0x4e, KEY_AGAIN }, /* Recall */ 33 { 0x4e, KEY_AGAIN }, /* Recall */
34 34
35 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */ 35 { 0x6c, KEY_VIDEO }, /* Video Source */
36 { 0x5e, KEY_MENU }, 36 { 0x5e, KEY_MENU },
37 { 0x56, KEY_SCREEN }, 37 { 0x56, KEY_SCREEN },
38 { 0x7a, KEY_SETUP }, 38 { 0x7a, KEY_SETUP },
diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c
index aea2f4acf7d8..a8b0f66edaa9 100644
--- a/drivers/media/rc/keymaps/rc-flydvb.c
+++ b/drivers/media/rc/keymaps/rc-flydvb.c
@@ -37,8 +37,8 @@ static struct rc_map_table flydvb[] = {
37 { 0x13, KEY_CHANNELDOWN }, /* CH- */ 37 { 0x13, KEY_CHANNELDOWN }, /* CH- */
38 { 0x1d, KEY_ENTER }, /* Enter */ 38 { 0x1d, KEY_ENTER }, /* Enter */
39 39
40 { 0x1a, KEY_MODE }, /* PIP */ 40 { 0x1a, KEY_TV2 }, /* PIP */
41 { 0x18, KEY_TUNER }, /* Source */ 41 { 0x18, KEY_VIDEO }, /* Source */
42 42
43 { 0x1e, KEY_RECORD }, /* Record/Pause */ 43 { 0x1e, KEY_RECORD }, /* Record/Pause */
44 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */ 44 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c
deleted file mode 100644
index bd11da46e56a..000000000000
--- a/drivers/media/rc/keymaps/rc-hauppauge-new.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/* hauppauge-new.h - Keytable for hauppauge_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Hauppauge: the newer, gray remotes (seems there are multiple
16 * slightly different versions), shipped with cx88+ivtv cards.
17 * almost rc5 coding, but some non-standard keys */
18
19static struct rc_map_table hauppauge_new[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
33 { 0x0b, KEY_RED }, /* red button */
34 { 0x0c, KEY_RADIO },
35 { 0x0d, KEY_MENU },
36 { 0x0e, KEY_SUBTITLE }, /* also the # key */
37 { 0x0f, KEY_MUTE },
38 { 0x10, KEY_VOLUMEUP },
39 { 0x11, KEY_VOLUMEDOWN },
40 { 0x12, KEY_PREVIOUS }, /* previous channel */
41 { 0x14, KEY_UP },
42 { 0x15, KEY_DOWN },
43 { 0x16, KEY_LEFT },
44 { 0x17, KEY_RIGHT },
45 { 0x18, KEY_VIDEO }, /* Videos */
46 { 0x19, KEY_AUDIO }, /* Music */
47 /* 0x1a: Pictures - presume this means
48 "Multimedia Home Platform" -
49 no "PICTURES" key in input.h
50 */
51 { 0x1a, KEY_MHP },
52
53 { 0x1b, KEY_EPG }, /* Guide */
54 { 0x1c, KEY_TV },
55 { 0x1e, KEY_NEXTSONG }, /* skip >| */
56 { 0x1f, KEY_EXIT }, /* back/exit */
57 { 0x20, KEY_CHANNELUP }, /* channel / program + */
58 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
59 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
60 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
61 { 0x25, KEY_ENTER }, /* OK */
62 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
63 { 0x29, KEY_BLUE }, /* blue key */
64 { 0x2e, KEY_GREEN }, /* green button */
65 { 0x30, KEY_PAUSE }, /* pause */
66 { 0x32, KEY_REWIND }, /* backward << */
67 { 0x34, KEY_FASTFORWARD }, /* forward >> */
68 { 0x35, KEY_PLAY },
69 { 0x36, KEY_STOP },
70 { 0x37, KEY_RECORD }, /* recording */
71 { 0x38, KEY_YELLOW }, /* yellow key */
72 { 0x3b, KEY_SELECT }, /* top right button */
73 { 0x3c, KEY_ZOOM }, /* full */
74 { 0x3d, KEY_POWER }, /* system power (green button) */
75};
76
77static struct rc_map_list hauppauge_new_map = {
78 .map = {
79 .scan = hauppauge_new,
80 .size = ARRAY_SIZE(hauppauge_new),
81 .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
82 .name = RC_MAP_HAUPPAUGE_NEW,
83 }
84};
85
86static int __init init_rc_map_hauppauge_new(void)
87{
88 return rc_map_register(&hauppauge_new_map);
89}
90
91static void __exit exit_rc_map_hauppauge_new(void)
92{
93 rc_map_unregister(&hauppauge_new_map);
94}
95
96module_init(init_rc_map_hauppauge_new)
97module_exit(exit_rc_map_hauppauge_new)
98
99MODULE_LICENSE("GPL");
100MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge.c
index dfc9b15f43a9..cd3db7779772 100644
--- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
+++ b/drivers/media/rc/keymaps/rc-hauppauge.c
@@ -1,8 +1,14 @@
1/* rc5-hauppauge-new.h - Keytable for rc5_hauppauge_new Remote Controller 1/* rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
2 * 2 *
3 * keymap imported from ir-keymaps.c 3 * keymap imported from ir-keymaps.c
4 * 4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> 5 * This map currently contains the code for four different RCs:
6 * - New Hauppauge Gray;
7 * - Old Hauppauge Gray (with a golden screen for media keys);
8 * - Hauppauge Black;
9 * - DSR-0112 remote bundled with Haupauge MiniStick.
10 *
11 * Copyright (c) 2010-2011 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 * 12 *
7 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
@@ -20,63 +26,124 @@
20 */ 26 */
21 27
22static struct rc_map_table rc5_hauppauge_new[] = { 28static struct rc_map_table rc5_hauppauge_new[] = {
23 /* Keys 0 to 9 */ 29 /*
24 { 0x1e00, KEY_0 }, 30 * Remote Controller Hauppauge Gray found on modern devices
31 * Keycodes start with address = 0x1e
32 */
33
34 { 0x1e3b, KEY_SELECT }, /* GO / house symbol */
35 { 0x1e3d, KEY_POWER2 }, /* system power (green button) */
36
37 { 0x1e1c, KEY_TV },
38 { 0x1e18, KEY_VIDEO }, /* Videos */
39 { 0x1e19, KEY_AUDIO }, /* Music */
40 { 0x1e1a, KEY_CAMERA }, /* Pictures */
41
42 { 0x1e1b, KEY_EPG }, /* Guide */
43 { 0x1e0c, KEY_RADIO },
44
45 { 0x1e14, KEY_UP },
46 { 0x1e15, KEY_DOWN },
47 { 0x1e16, KEY_LEFT },
48 { 0x1e17, KEY_RIGHT },
49 { 0x1e25, KEY_OK }, /* OK */
50
51 { 0x1e1f, KEY_EXIT }, /* back/exit */
52 { 0x1e0d, KEY_MENU },
53
54 { 0x1e10, KEY_VOLUMEUP },
55 { 0x1e11, KEY_VOLUMEDOWN },
56
57 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
58 { 0x1e0f, KEY_MUTE },
59
60 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
61 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
62
63 { 0x1e37, KEY_RECORD }, /* recording */
64 { 0x1e36, KEY_STOP },
65
66 { 0x1e32, KEY_REWIND }, /* backward << */
67 { 0x1e35, KEY_PLAY },
68 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
69
70 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
71 { 0x1e30, KEY_PAUSE }, /* pause */
72 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
73
25 { 0x1e01, KEY_1 }, 74 { 0x1e01, KEY_1 },
26 { 0x1e02, KEY_2 }, 75 { 0x1e02, KEY_2 },
27 { 0x1e03, KEY_3 }, 76 { 0x1e03, KEY_3 },
77
28 { 0x1e04, KEY_4 }, 78 { 0x1e04, KEY_4 },
29 { 0x1e05, KEY_5 }, 79 { 0x1e05, KEY_5 },
30 { 0x1e06, KEY_6 }, 80 { 0x1e06, KEY_6 },
81
31 { 0x1e07, KEY_7 }, 82 { 0x1e07, KEY_7 },
32 { 0x1e08, KEY_8 }, 83 { 0x1e08, KEY_8 },
33 { 0x1e09, KEY_9 }, 84 { 0x1e09, KEY_9 },
34 85
35 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ 86 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
36 { 0x1e0b, KEY_RED }, /* red button */ 87 { 0x1e00, KEY_0 },
37 { 0x1e0c, KEY_RADIO }, 88 { 0x1e0e, KEY_SUBTITLE }, /* also the Pound key (#) */
38 { 0x1e0d, KEY_MENU },
39 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
40 { 0x1e0f, KEY_MUTE },
41 { 0x1e10, KEY_VOLUMEUP },
42 { 0x1e11, KEY_VOLUMEDOWN },
43 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
44 { 0x1e14, KEY_UP },
45 { 0x1e15, KEY_DOWN },
46 { 0x1e16, KEY_LEFT },
47 { 0x1e17, KEY_RIGHT },
48 { 0x1e18, KEY_VIDEO }, /* Videos */
49 { 0x1e19, KEY_AUDIO }, /* Music */
50 /* 0x1e1a: Pictures - presume this means
51 "Multimedia Home Platform" -
52 no "PICTURES" key in input.h
53 */
54 { 0x1e1a, KEY_MHP },
55 89
56 { 0x1e1b, KEY_EPG }, /* Guide */ 90 { 0x1e0b, KEY_RED }, /* red button */
57 { 0x1e1c, KEY_TV },
58 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
59 { 0x1e1f, KEY_EXIT }, /* back/exit */
60 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
61 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
62 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
63 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
64 { 0x1e25, KEY_ENTER }, /* OK */
65 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
66 { 0x1e29, KEY_BLUE }, /* blue key */
67 { 0x1e2e, KEY_GREEN }, /* green button */ 91 { 0x1e2e, KEY_GREEN }, /* green button */
68 { 0x1e30, KEY_PAUSE }, /* pause */
69 { 0x1e32, KEY_REWIND }, /* backward << */
70 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
71 { 0x1e35, KEY_PLAY },
72 { 0x1e36, KEY_STOP },
73 { 0x1e37, KEY_RECORD }, /* recording */
74 { 0x1e38, KEY_YELLOW }, /* yellow key */ 92 { 0x1e38, KEY_YELLOW }, /* yellow key */
75 { 0x1e3b, KEY_SELECT }, /* top right button */ 93 { 0x1e29, KEY_BLUE }, /* blue key */
76 { 0x1e3c, KEY_ZOOM }, /* full */ 94
77 { 0x1e3d, KEY_POWER }, /* system power (green button) */ 95 /*
96 * Old Remote Controller Hauppauge Gray with a golden screen
97 * Keycodes start with address = 0x1f
98 */
99 { 0x1f3d, KEY_POWER2 }, /* system power (green button) */
100 { 0x1f3b, KEY_SELECT }, /* GO */
101
102 /* Keys 0 to 9 */
103 { 0x1f00, KEY_0 },
104 { 0x1f01, KEY_1 },
105 { 0x1f02, KEY_2 },
106 { 0x1f03, KEY_3 },
107 { 0x1f04, KEY_4 },
108 { 0x1f05, KEY_5 },
109 { 0x1f06, KEY_6 },
110 { 0x1f07, KEY_7 },
111 { 0x1f08, KEY_8 },
112 { 0x1f09, KEY_9 },
113
114 { 0x1f1f, KEY_EXIT }, /* back/exit */
115 { 0x1f0d, KEY_MENU },
116
117 { 0x1f10, KEY_VOLUMEUP },
118 { 0x1f11, KEY_VOLUMEDOWN },
119 { 0x1f20, KEY_CHANNELUP }, /* channel / program + */
120 { 0x1f21, KEY_CHANNELDOWN }, /* channel / program - */
121 { 0x1f25, KEY_ENTER }, /* OK */
122
123 { 0x1f0b, KEY_RED }, /* red button */
124 { 0x1f2e, KEY_GREEN }, /* green button */
125 { 0x1f38, KEY_YELLOW }, /* yellow key */
126 { 0x1f29, KEY_BLUE }, /* blue key */
127
128 { 0x1f0f, KEY_MUTE },
129 { 0x1f0c, KEY_RADIO }, /* There's no indicator on this key */
130 { 0x1f3c, KEY_ZOOM }, /* full */
131
132 { 0x1f32, KEY_REWIND }, /* backward << */
133 { 0x1f35, KEY_PLAY },
134 { 0x1f34, KEY_FASTFORWARD }, /* forward >> */
78 135
79 /* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick */ 136 { 0x1f37, KEY_RECORD }, /* recording */
137 { 0x1f36, KEY_STOP },
138 { 0x1f30, KEY_PAUSE }, /* pause */
139
140 { 0x1f24, KEY_PREVIOUSSONG }, /* replay |< */
141 { 0x1f1e, KEY_NEXTSONG }, /* skip >| */
142
143 /*
144 * Keycodes for DSR-0112 remote bundled with Haupauge MiniStick
145 * Keycodes start with address = 0x1d
146 */
80 { 0x1d00, KEY_0 }, 147 { 0x1d00, KEY_0 },
81 { 0x1d01, KEY_1 }, 148 { 0x1d01, KEY_1 },
82 { 0x1d02, KEY_2 }, 149 { 0x1d02, KEY_2 },
@@ -113,6 +180,39 @@ static struct rc_map_table rc5_hauppauge_new[] = {
113 { 0x1d3b, KEY_GOTO }, 180 { 0x1d3b, KEY_GOTO },
114 { 0x1d3d, KEY_POWER }, 181 { 0x1d3d, KEY_POWER },
115 { 0x1d3f, KEY_HOME }, 182 { 0x1d3f, KEY_HOME },
183
184 /*
185 * Keycodes for the old Black Remote Controller
186 * This one also uses RC-5 protocol
187 * Keycodes start with address = 0x00
188 */
189 { 0x001f, KEY_TV },
190 { 0x0020, KEY_CHANNELUP },
191 { 0x000c, KEY_RADIO },
192
193 { 0x0011, KEY_VOLUMEDOWN },
194 { 0x002e, KEY_ZOOM }, /* full screen */
195 { 0x0010, KEY_VOLUMEUP },
196
197 { 0x000d, KEY_MUTE },
198 { 0x0021, KEY_CHANNELDOWN },
199 { 0x0022, KEY_VIDEO }, /* source */
200
201 { 0x0001, KEY_1 },
202 { 0x0002, KEY_2 },
203 { 0x0003, KEY_3 },
204
205 { 0x0004, KEY_4 },
206 { 0x0005, KEY_5 },
207 { 0x0006, KEY_6 },
208
209 { 0x0007, KEY_7 },
210 { 0x0008, KEY_8 },
211 { 0x0009, KEY_9 },
212
213 { 0x001e, KEY_RED }, /* Reserved */
214 { 0x0000, KEY_0 },
215 { 0x0026, KEY_SLEEP }, /* Minimize */
116}; 216};
117 217
118static struct rc_map_list rc5_hauppauge_new_map = { 218static struct rc_map_list rc5_hauppauge_new_map = {
@@ -120,7 +220,7 @@ static struct rc_map_list rc5_hauppauge_new_map = {
120 .scan = rc5_hauppauge_new, 220 .scan = rc5_hauppauge_new,
121 .size = ARRAY_SIZE(rc5_hauppauge_new), 221 .size = ARRAY_SIZE(rc5_hauppauge_new),
122 .rc_type = RC_TYPE_RC5, 222 .rc_type = RC_TYPE_RC5,
123 .name = RC_MAP_RC5_HAUPPAUGE_NEW, 223 .name = RC_MAP_HAUPPAUGE,
124 } 224 }
125}; 225};
126 226
diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c
index cb67184e015c..937a81989f00 100644
--- a/drivers/media/rc/keymaps/rc-imon-mce.c
+++ b/drivers/media/rc/keymaps/rc-imon-mce.c
@@ -111,7 +111,7 @@ static struct rc_map_table imon_mce[] = {
111 { 0x800ff44d, KEY_TITLE }, 111 { 0x800ff44d, KEY_TITLE },
112 112
113 { 0x800ff40c, KEY_POWER }, 113 { 0x800ff40c, KEY_POWER },
114 { 0x800ff40d, KEY_PROG1 }, /* Windows MCE button */ 114 { 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */
115 115
116}; 116};
117 117
diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c
index eef46b73ca7b..63d42bd24c9e 100644
--- a/drivers/media/rc/keymaps/rc-imon-pad.c
+++ b/drivers/media/rc/keymaps/rc-imon-pad.c
@@ -125,7 +125,7 @@ static struct rc_map_table imon_pad[] = {
125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/ 125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */ 126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */
127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */ 127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
128 { 0x2ab195b7, KEY_PROG1 }, /* Go or MultiMon */ 128 { 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */
129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */ 129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
130}; 130};
131 131
diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c
index 3ce6ef79fc34..7f33edb47244 100644
--- a/drivers/media/rc/keymaps/rc-kworld-315u.c
+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c
@@ -17,7 +17,7 @@
17 17
18static struct rc_map_table kworld_315u[] = { 18static struct rc_map_table kworld_315u[] = {
19 { 0x6143, KEY_POWER }, 19 { 0x6143, KEY_POWER },
20 { 0x6101, KEY_TUNER }, /* source */ 20 { 0x6101, KEY_VIDEO }, /* source */
21 { 0x610b, KEY_ZOOM }, 21 { 0x610b, KEY_ZOOM },
22 { 0x6103, KEY_POWER2 }, /* shutdown */ 22 { 0x6103, KEY_POWER2 }, /* shutdown */
23 23
diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
index e45f0b8759d0..08d183120e41 100644
--- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19static struct rc_map_table kworld_plus_tv_analog[] = { 19static struct rc_map_table kworld_plus_tv_analog[] = {
20 { 0x0c, KEY_PROG1 }, /* Kworld key */ 20 { 0x0c, KEY_LEFTMETA }, /* Kworld key */
21 { 0x16, KEY_CLOSECD }, /* -> ) */ 21 { 0x16, KEY_CLOSECD }, /* -> ) */
22 { 0x1d, KEY_POWER2 }, 22 { 0x1d, KEY_POWER2 },
23 23
diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c
index 875cd81477c7..3c1913926c1a 100644
--- a/drivers/media/rc/keymaps/rc-lme2510.c
+++ b/drivers/media/rc/keymaps/rc-lme2510.c
@@ -13,33 +13,75 @@
13 13
14 14
15static struct rc_map_table lme2510_rc[] = { 15static struct rc_map_table lme2510_rc[] = {
16 { 0xba45, KEY_0 }, 16 /* Type 1 - 26 buttons */
17 { 0xa05f, KEY_1 }, 17 { 0xef12ba45, KEY_0 },
18 { 0xaf50, KEY_2 }, 18 { 0xef12a05f, KEY_1 },
19 { 0xa25d, KEY_3 }, 19 { 0xef12af50, KEY_2 },
20 { 0xbe41, KEY_4 }, 20 { 0xef12a25d, KEY_3 },
21 { 0xf50a, KEY_5 }, 21 { 0xef12be41, KEY_4 },
22 { 0xbd42, KEY_6 }, 22 { 0xef12f50a, KEY_5 },
23 { 0xb847, KEY_7 }, 23 { 0xef12bd42, KEY_6 },
24 { 0xb649, KEY_8 }, 24 { 0xef12b847, KEY_7 },
25 { 0xfa05, KEY_9 }, 25 { 0xef12b649, KEY_8 },
26 { 0xbc43, KEY_POWER }, 26 { 0xef12fa05, KEY_9 },
27 { 0xb946, KEY_SUBTITLE }, 27 { 0xef12bc43, KEY_POWER },
28 { 0xf906, KEY_PAUSE }, 28 { 0xef12b946, KEY_SUBTITLE },
29 { 0xfc03, KEY_MEDIA_REPEAT}, 29 { 0xef12f906, KEY_PAUSE },
30 { 0xfd02, KEY_PAUSE }, 30 { 0xef12fc03, KEY_MEDIA_REPEAT},
31 { 0xa15e, KEY_VOLUMEUP }, 31 { 0xef12fd02, KEY_PAUSE },
32 { 0xa35c, KEY_VOLUMEDOWN }, 32 { 0xef12a15e, KEY_VOLUMEUP },
33 { 0xf609, KEY_CHANNELUP }, 33 { 0xef12a35c, KEY_VOLUMEDOWN },
34 { 0xe51a, KEY_CHANNELDOWN }, 34 { 0xef12f609, KEY_CHANNELUP },
35 { 0xe11e, KEY_PLAY }, 35 { 0xef12e51a, KEY_CHANNELDOWN },
36 { 0xe41b, KEY_ZOOM }, 36 { 0xef12e11e, KEY_PLAY },
37 { 0xa659, KEY_MUTE }, 37 { 0xef12e41b, KEY_ZOOM },
38 { 0xa55a, KEY_TV }, 38 { 0xef12a659, KEY_MUTE },
39 { 0xe718, KEY_RECORD }, 39 { 0xef12a55a, KEY_TV },
40 { 0xf807, KEY_EPG }, 40 { 0xef12e718, KEY_RECORD },
41 { 0xfe01, KEY_STOP }, 41 { 0xef12f807, KEY_EPG },
42 42 { 0xef12fe01, KEY_STOP },
43 /* Type 2 - 20 buttons */
44 { 0xff40ea15, KEY_0 },
45 { 0xff40f708, KEY_1 },
46 { 0xff40f609, KEY_2 },
47 { 0xff40f50a, KEY_3 },
48 { 0xff40f30c, KEY_4 },
49 { 0xff40f20d, KEY_5 },
50 { 0xff40f10e, KEY_6 },
51 { 0xff40ef10, KEY_7 },
52 { 0xff40ee11, KEY_8 },
53 { 0xff40ed12, KEY_9 },
54 { 0xff40ff00, KEY_POWER },
55 { 0xff40fb04, KEY_MEDIA_REPEAT}, /* Recall */
56 { 0xff40e51a, KEY_PAUSE }, /* Timeshift */
57 { 0xff40fd02, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
58 { 0xff40f906, KEY_VOLUMEDOWN }, /* Volumne defined as right hand*/
59 { 0xff40fe01, KEY_CHANNELUP },
60 { 0xff40fa05, KEY_CHANNELDOWN },
61 { 0xff40eb14, KEY_ZOOM },
62 { 0xff40e718, KEY_RECORD },
63 { 0xff40e916, KEY_STOP },
64 /* Type 3 - 20 buttons */
65 { 0xff00e31c, KEY_0 },
66 { 0xff00f807, KEY_1 },
67 { 0xff00ea15, KEY_2 },
68 { 0xff00f609, KEY_3 },
69 { 0xff00e916, KEY_4 },
70 { 0xff00e619, KEY_5 },
71 { 0xff00f20d, KEY_6 },
72 { 0xff00f30c, KEY_7 },
73 { 0xff00e718, KEY_8 },
74 { 0xff00a15e, KEY_9 },
75 { 0xff00ba45, KEY_POWER },
76 { 0xff00bb44, KEY_MEDIA_REPEAT}, /* Recall */
77 { 0xff00b54a, KEY_PAUSE }, /* Timeshift */
78 { 0xff00b847, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
79 { 0xff00bc43, KEY_VOLUMEDOWN }, /* Volumne defined as right hand*/
80 { 0xff00b946, KEY_CHANNELUP },
81 { 0xff00bf40, KEY_CHANNELDOWN },
82 { 0xff00f708, KEY_ZOOM },
83 { 0xff00bd42, KEY_RECORD },
84 { 0xff00a55a, KEY_STOP },
43}; 85};
44 86
45static struct rc_map_list lme2510_map = { 87static struct rc_map_list lme2510_map = {
diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
index fa8fd0ab94c7..8e9969d1239b 100644
--- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
@@ -62,7 +62,7 @@ static struct rc_map_table msi_tvanywhere_plus[] = {
62 { 0x13, KEY_AGAIN }, /* Recall */ 62 { 0x13, KEY_AGAIN }, /* Recall */
63 63
64 { 0x1e, KEY_POWER }, /* Power */ 64 { 0x1e, KEY_POWER }, /* Power */
65 { 0x07, KEY_TUNER }, /* Source */ 65 { 0x07, KEY_VIDEO }, /* Source */
66 { 0x1c, KEY_SEARCH }, /* Scan */ 66 { 0x1c, KEY_SEARCH }, /* Scan */
67 { 0x18, KEY_MUTE }, /* Mute */ 67 { 0x18, KEY_MUTE }, /* Mute */
68 68
diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
index 3e6f077eb700..ddae20e9cd96 100644
--- a/drivers/media/rc/keymaps/rc-nebula.c
+++ b/drivers/media/rc/keymaps/rc-nebula.c
@@ -27,7 +27,7 @@ static struct rc_map_table nebula[] = {
27 { 0x0b, KEY_AUX }, 27 { 0x0b, KEY_AUX },
28 { 0x0c, KEY_DVD }, 28 { 0x0c, KEY_DVD },
29 { 0x0d, KEY_POWER }, 29 { 0x0d, KEY_POWER },
30 { 0x0e, KEY_MHP }, /* labelled 'Picture' */ 30 { 0x0e, KEY_CAMERA }, /* labelled 'Picture' */
31 { 0x0f, KEY_AUDIO }, 31 { 0x0f, KEY_AUDIO },
32 { 0x10, KEY_INFO }, 32 { 0x10, KEY_INFO },
33 { 0x11, KEY_F13 }, /* 16:9 */ 33 { 0x11, KEY_F13 }, /* 16:9 */
diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c
index 629ee9d84537..f1c1281fbc17 100644
--- a/drivers/media/rc/keymaps/rc-norwood.c
+++ b/drivers/media/rc/keymaps/rc-norwood.c
@@ -29,7 +29,7 @@ static struct rc_map_table norwood[] = {
29 { 0x28, KEY_8 }, 29 { 0x28, KEY_8 },
30 { 0x29, KEY_9 }, 30 { 0x29, KEY_9 },
31 31
32 { 0x78, KEY_TUNER }, /* Video Source */ 32 { 0x78, KEY_VIDEO }, /* Video Source */
33 { 0x2c, KEY_EXIT }, /* Open/Close software */ 33 { 0x2c, KEY_EXIT }, /* Open/Close software */
34 { 0x2a, KEY_SELECT }, /* 2 Digit Select */ 34 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
35 { 0x69, KEY_AGAIN }, /* Recall */ 35 { 0x69, KEY_AGAIN }, /* Recall */
diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c
index fa5ae5981eb8..7cdef6e6cc0f 100644
--- a/drivers/media/rc/keymaps/rc-pctv-sedna.c
+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c
@@ -36,7 +36,7 @@ static struct rc_map_table pctv_sedna[] = {
36 { 0x0e, KEY_STOP }, 36 { 0x0e, KEY_STOP },
37 { 0x0f, KEY_PREVIOUSSONG }, 37 { 0x0f, KEY_PREVIOUSSONG },
38 { 0x10, KEY_ZOOM }, 38 { 0x10, KEY_ZOOM },
39 { 0x11, KEY_TUNER }, /* Source */ 39 { 0x11, KEY_VIDEO }, /* Source */
40 { 0x12, KEY_POWER }, 40 { 0x12, KEY_POWER },
41 { 0x13, KEY_MUTE }, 41 { 0x13, KEY_MUTE },
42 { 0x15, KEY_CHANNELDOWN }, 42 { 0x15, KEY_CHANNELDOWN },
diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
index 8d9f664e0a2d..125fc3949c15 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
@@ -34,7 +34,7 @@ static struct rc_map_table pixelview_mk12[] = {
34 { 0x866b13, KEY_AGAIN }, /* loop */ 34 { 0x866b13, KEY_AGAIN }, /* loop */
35 { 0x866b10, KEY_DIGITS }, /* +100 */ 35 { 0x866b10, KEY_DIGITS }, /* +100 */
36 36
37 { 0x866b00, KEY_MEDIA }, /* source */ 37 { 0x866b00, KEY_VIDEO }, /* source */
38 { 0x866b18, KEY_MUTE }, /* mute */ 38 { 0x866b18, KEY_MUTE }, /* mute */
39 { 0x866b19, KEY_CAMERA }, /* snapshot */ 39 { 0x866b19, KEY_CAMERA }, /* snapshot */
40 { 0x866b1a, KEY_SEARCH }, /* scan */ 40 { 0x866b1a, KEY_SEARCH }, /* scan */
diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c
index 777a70076be2..bd78d6ac1e16 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-new.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c
@@ -33,7 +33,7 @@ static struct rc_map_table pixelview_new[] = {
33 { 0x3e, KEY_0 }, 33 { 0x3e, KEY_0 },
34 34
35 { 0x1c, KEY_AGAIN }, /* LOOP */ 35 { 0x1c, KEY_AGAIN }, /* LOOP */
36 { 0x3f, KEY_MEDIA }, /* Source */ 36 { 0x3f, KEY_VIDEO }, /* Source */
37 { 0x1f, KEY_LAST }, /* +100 */ 37 { 0x1f, KEY_LAST }, /* +100 */
38 { 0x1b, KEY_MUTE }, 38 { 0x1b, KEY_MUTE },
39 39
diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c
index 0ec5988916b9..06187e7db446 100644
--- a/drivers/media/rc/keymaps/rc-pixelview.c
+++ b/drivers/media/rc/keymaps/rc-pixelview.c
@@ -15,7 +15,7 @@
15static struct rc_map_table pixelview[] = { 15static struct rc_map_table pixelview[] = {
16 16
17 { 0x1e, KEY_POWER }, /* power */ 17 { 0x1e, KEY_POWER }, /* power */
18 { 0x07, KEY_MEDIA }, /* source */ 18 { 0x07, KEY_VIDEO }, /* source */
19 { 0x1c, KEY_SEARCH }, /* scan */ 19 { 0x1c, KEY_SEARCH }, /* scan */
20 20
21 21
diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c
index 83a418de12c6..5e8beee94de4 100644
--- a/drivers/media/rc/keymaps/rc-pv951.c
+++ b/drivers/media/rc/keymaps/rc-pv951.c
@@ -46,10 +46,10 @@ static struct rc_map_table pv951[] = {
46 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */ 46 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
47 47
48 /* Not sure what to do with these ones! */ 48 /* Not sure what to do with these ones! */
49 { 0x0f, KEY_SELECT }, /* SOURCE */ 49 { 0x0f, KEY_VIDEO }, /* SOURCE */
50 { 0x0a, KEY_KPPLUS }, /* +100 */ 50 { 0x0a, KEY_KPPLUS }, /* +100 */
51 { 0x14, KEY_EQUAL }, /* SYNC */ 51 { 0x14, KEY_EQUAL }, /* SYNC */
52 { 0x1c, KEY_MEDIA }, /* PC/TV */ 52 { 0x1c, KEY_TV }, /* PC/TV */
53}; 53};
54 54
55static struct rc_map_list pv951_map = { 55static struct rc_map_list pv951_map = {
diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c
deleted file mode 100644
index 4fcef9f1f721..000000000000
--- a/drivers/media/rc/keymaps/rc-rc5-tv.c
+++ /dev/null
@@ -1,81 +0,0 @@
1/* rc5-tv.h - Keytable for rc5_tv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* generic RC5 keytable */
16/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
17/* used by old (black) Hauppauge remotes */
18
19static struct rc_map_table rc5_tv[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
33 { 0x0c, KEY_POWER }, /* standby */
34 { 0x0d, KEY_MUTE }, /* mute / demute */
35 { 0x0f, KEY_TV }, /* display */
36 { 0x10, KEY_VOLUMEUP },
37 { 0x11, KEY_VOLUMEDOWN },
38 { 0x12, KEY_BRIGHTNESSUP },
39 { 0x13, KEY_BRIGHTNESSDOWN },
40 { 0x1e, KEY_SEARCH }, /* search + */
41 { 0x20, KEY_CHANNELUP }, /* channel / program + */
42 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
43 { 0x22, KEY_CHANNEL }, /* alt / channel */
44 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
45 { 0x26, KEY_SLEEP }, /* sleeptimer */
46 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
47 { 0x30, KEY_PAUSE },
48 { 0x32, KEY_REWIND },
49 { 0x33, KEY_GOTO },
50 { 0x35, KEY_PLAY },
51 { 0x36, KEY_STOP },
52 { 0x37, KEY_RECORD }, /* recording */
53 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
54 { 0x3d, KEY_SUSPEND }, /* system standby */
55
56};
57
58static struct rc_map_list rc5_tv_map = {
59 .map = {
60 .scan = rc5_tv,
61 .size = ARRAY_SIZE(rc5_tv),
62 .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_RC5_TV,
64 }
65};
66
67static int __init init_rc_map_rc5_tv(void)
68{
69 return rc_map_register(&rc5_tv_map);
70}
71
72static void __exit exit_rc_map_rc5_tv(void)
73{
74 rc_map_unregister(&rc5_tv_map);
75}
76
77module_init(init_rc_map_rc5_tv)
78module_exit(exit_rc_map_rc5_tv)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c
index 2f5dc0622b94..8dd519ecc58e 100644
--- a/drivers/media/rc/keymaps/rc-rc6-mce.c
+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
@@ -30,7 +30,7 @@ static struct rc_map_table rc6_mce[] = {
30 { 0x800f040a, KEY_DELETE }, 30 { 0x800f040a, KEY_DELETE },
31 { 0x800f040b, KEY_ENTER }, 31 { 0x800f040b, KEY_ENTER },
32 { 0x800f040c, KEY_POWER }, /* PC Power */ 32 { 0x800f040c, KEY_POWER }, /* PC Power */
33 { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ 33 { 0x800f040d, KEY_LEFTMETA }, /* Windows MCE button */
34 { 0x800f040e, KEY_MUTE }, 34 { 0x800f040e, KEY_MUTE },
35 { 0x800f040f, KEY_INFO }, 35 { 0x800f040f, KEY_INFO },
36 36
diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
index 2d14598592d8..6813d1102118 100644
--- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
@@ -35,7 +35,7 @@ static struct rc_map_table real_audio_220_32_keys[] = {
35 { 0x15, KEY_CHANNELDOWN}, 35 { 0x15, KEY_CHANNELDOWN},
36 { 0x16, KEY_ENTER}, 36 { 0x16, KEY_ENTER},
37 37
38 { 0x11, KEY_LIST}, /* Source */ 38 { 0x11, KEY_VIDEO}, /* Source */
39 { 0x0d, KEY_AUDIO}, /* stereo */ 39 { 0x0d, KEY_AUDIO}, /* stereo */
40 40
41 { 0x0f, KEY_PREVIOUS}, /* Prev */ 41 { 0x0f, KEY_PREVIOUS}, /* Prev */
diff --git a/drivers/media/rc/keymaps/rc-technisat-usb2.c b/drivers/media/rc/keymaps/rc-technisat-usb2.c
new file mode 100644
index 000000000000..4afe5774f192
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-technisat-usb2.c
@@ -0,0 +1,93 @@
1/* rc-technisat-usb2.c - Keytable for SkyStar HD USB
2 *
3 * Copyright (C) 2010 Patrick Boettcher,
4 * Kernel Labs Inc. PO Box 745, St James, NY 11780
5 *
6 * Development was sponsored by Technisat Digital UK Limited, whose
7 * registered office is Witan Gate House 500 - 600 Witan Gate West,
8 * Milton Keynes, MK9 1SH
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
21 * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
22 * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
23 * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
24 * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
25 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
26 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
27 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
28 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
29 * GNU General Public License for more details.
30 */
31
32#include <media/rc-map.h>
33
34static struct rc_map_table technisat_usb2[] = {
35 {0x0a0c, KEY_POWER},
36 {0x0a01, KEY_1},
37 {0x0a02, KEY_2},
38 {0x0a03, KEY_3},
39 {0x0a0d, KEY_MUTE},
40 {0x0a04, KEY_4},
41 {0x0a05, KEY_5},
42 {0x0a06, KEY_6},
43 {0x0a38, KEY_VIDEO}, /* EXT */
44 {0x0a07, KEY_7},
45 {0x0a08, KEY_8},
46 {0x0a09, KEY_9},
47 {0x0a00, KEY_0},
48 {0x0a4f, KEY_INFO},
49 {0x0a20, KEY_CHANNELUP},
50 {0x0a52, KEY_MENU},
51 {0x0a11, KEY_VOLUMEUP},
52 {0x0a57, KEY_OK},
53 {0x0a10, KEY_VOLUMEDOWN},
54 {0x0a2f, KEY_EPG},
55 {0x0a21, KEY_CHANNELDOWN},
56 {0x0a22, KEY_REFRESH},
57 {0x0a3c, KEY_TEXT},
58 {0x0a76, KEY_ENTER}, /* HOOK */
59 {0x0a0f, KEY_HELP},
60 {0x0a6b, KEY_RED},
61 {0x0a6c, KEY_GREEN},
62 {0x0a6d, KEY_YELLOW},
63 {0x0a6e, KEY_BLUE},
64 {0x0a29, KEY_STOP},
65 {0x0a23, KEY_LANGUAGE},
66 {0x0a53, KEY_TV},
67 {0x0a0a, KEY_PROGRAM},
68};
69
70static struct rc_map_list technisat_usb2_map = {
71 .map = {
72 .scan = technisat_usb2,
73 .size = ARRAY_SIZE(technisat_usb2),
74 .rc_type = RC_TYPE_RC5,
75 .name = RC_MAP_TECHNISAT_USB2,
76 }
77};
78
79static int __init init_rc_map(void)
80{
81 return rc_map_register(&technisat_usb2_map);
82}
83
84static void __exit exit_rc_map(void)
85{
86 rc_map_unregister(&technisat_usb2_map);
87}
88
89module_init(init_rc_map)
90module_exit(exit_rc_map)
91
92MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
93MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/keymaps/rc-terratec-slim-2.c b/drivers/media/rc/keymaps/rc-terratec-slim-2.c
new file mode 100644
index 000000000000..44093918cf03
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-terratec-slim-2.c
@@ -0,0 +1,72 @@
1/*
2 * TerraTec remote controller keytable
3 *
4 * Copyright (C) 2011 Martin Groszhauser <mgroszhauser@gmail.com>
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include <media/rc-map.h>
23
24/*
25 * TerraTec slim remote, 6 rows, 3 columns.
26 * Keytable from Martin Groszhauser <mgroszhauser@gmail.com>
27 */
28static struct rc_map_table terratec_slim_2[] = {
29 { 0x8001, KEY_MUTE }, /* MUTE */
30 { 0x8002, KEY_VOLUMEDOWN },
31 { 0x8003, KEY_CHANNELDOWN },
32 { 0x8004, KEY_1 },
33 { 0x8005, KEY_2 },
34 { 0x8006, KEY_3 },
35 { 0x8007, KEY_4 },
36 { 0x8008, KEY_5 },
37 { 0x8009, KEY_6 },
38 { 0x800a, KEY_7 },
39 { 0x800c, KEY_ZOOM }, /* [fullscreen] */
40 { 0x800d, KEY_0 },
41 { 0x800e, KEY_AGAIN }, /* [two arrows forming a circle] */
42 { 0x8012, KEY_POWER2 }, /* [red power button] */
43 { 0x801a, KEY_VOLUMEUP },
44 { 0x801b, KEY_8 },
45 { 0x801e, KEY_CHANNELUP },
46 { 0x801f, KEY_9 },
47};
48
49static struct rc_map_list terratec_slim_2_map = {
50 .map = {
51 .scan = terratec_slim_2,
52 .size = ARRAY_SIZE(terratec_slim_2),
53 .rc_type = RC_TYPE_NEC,
54 .name = RC_MAP_TERRATEC_SLIM_2,
55 }
56};
57
58static int __init init_rc_map_terratec_slim_2(void)
59{
60 return rc_map_register(&terratec_slim_2_map);
61}
62
63static void __exit exit_rc_map_terratec_slim_2(void)
64{
65 rc_map_unregister(&terratec_slim_2_map);
66}
67
68module_init(init_rc_map_terratec_slim_2)
69module_exit(exit_rc_map_terratec_slim_2)
70
71MODULE_LICENSE("GPL");
72MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c
index 2747db43b70c..0062ca291959 100644
--- a/drivers/media/rc/keymaps/rc-winfast.c
+++ b/drivers/media/rc/keymaps/rc-winfast.c
@@ -27,15 +27,15 @@ static struct rc_map_table winfast[] = {
27 { 0x0e, KEY_8 }, 27 { 0x0e, KEY_8 },
28 { 0x0f, KEY_9 }, 28 { 0x0f, KEY_9 },
29 29
30 { 0x00, KEY_POWER }, 30 { 0x00, KEY_POWER2 },
31 { 0x1b, KEY_AUDIO }, /* Audio Source */ 31 { 0x1b, KEY_AUDIO }, /* Audio Source */
32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */ 32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
33 { 0x1e, KEY_VIDEO }, /* Video Source */ 33 { 0x1e, KEY_VIDEO }, /* Video Source */
34 { 0x16, KEY_INFO }, /* Display information */ 34 { 0x16, KEY_INFO }, /* Display information */
35 { 0x04, KEY_VOLUMEUP }, 35 { 0x04, KEY_LEFT },
36 { 0x08, KEY_VOLUMEDOWN }, 36 { 0x08, KEY_RIGHT },
37 { 0x0c, KEY_CHANNELUP }, 37 { 0x0c, KEY_UP },
38 { 0x10, KEY_CHANNELDOWN }, 38 { 0x10, KEY_DOWN },
39 { 0x03, KEY_ZOOM }, /* fullscreen */ 39 { 0x03, KEY_ZOOM }, /* fullscreen */
40 { 0x1f, KEY_TEXT }, /* closed caption/teletext */ 40 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
41 { 0x20, KEY_SLEEP }, 41 { 0x20, KEY_SLEEP },
@@ -47,7 +47,7 @@ static struct rc_map_table winfast[] = {
47 { 0x2e, KEY_BLUE }, 47 { 0x2e, KEY_BLUE },
48 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */ 48 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
49 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */ 49 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
50 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */ 50 { 0x2a, KEY_TV2 }, /* PIP (Picture in picture */
51 { 0x21, KEY_DOT }, 51 { 0x21, KEY_DOT },
52 { 0x13, KEY_ENTER }, 52 { 0x13, KEY_ENTER },
53 { 0x11, KEY_LAST }, /* Recall (last channel */ 53 { 0x11, KEY_LAST }, /* Recall (last channel */
@@ -57,7 +57,7 @@ static struct rc_map_table winfast[] = {
57 { 0x25, KEY_TIME }, /* Time Shifting */ 57 { 0x25, KEY_TIME }, /* Time Shifting */
58 { 0x26, KEY_STOP }, 58 { 0x26, KEY_STOP },
59 { 0x27, KEY_RECORD }, 59 { 0x27, KEY_RECORD },
60 { 0x28, KEY_SAVE }, /* Screenshot */ 60 { 0x28, KEY_CAMERA }, /* Screenshot */
61 { 0x2f, KEY_MENU }, 61 { 0x2f, KEY_MENU },
62 { 0x30, KEY_CANCEL }, 62 { 0x30, KEY_CANCEL },
63 { 0x31, KEY_CHANNEL }, /* Channel Surf */ 63 { 0x31, KEY_CHANNEL }, /* Channel Surf */
@@ -70,10 +70,10 @@ static struct rc_map_table winfast[] = {
70 { 0x38, KEY_DVD }, 70 { 0x38, KEY_DVD },
71 71
72 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */ 72 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
73 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ 73 { 0x3e, KEY_VOLUMEUP }, /* MCE +VOL, on Y04G0033 */
74 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ 74 { 0x3a, KEY_VOLUMEDOWN }, /* MCE -VOL, on Y04G0033 */
75 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ 75 { 0x3b, KEY_CHANNELUP }, /* MCE +CH, on Y04G0033 */
76 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */ 76 { 0x3f, KEY_CHANNELDOWN } /* MCE -CH, on Y04G0033 */
77}; 77};
78 78
79static struct rc_map_list winfast_map = { 79static struct rc_map_list winfast_map = {
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index e4f8eac7f717..044fb7a382d6 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -186,7 +186,7 @@ static const struct mceusb_model mceusb_model[] = {
186 * remotes, but we should have something handy, 186 * remotes, but we should have something handy,
187 * to allow testing it 187 * to allow testing it
188 */ 188 */
189 .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, 189 .rc_map = RC_MAP_HAUPPAUGE,
190 .name = "Conexant Hybrid TV (cx231xx) MCE IR", 190 .name = "Conexant Hybrid TV (cx231xx) MCE IR",
191 }, 191 },
192 [CX_HYBRID_TV] = { 192 [CX_HYBRID_TV] = {
@@ -261,7 +261,7 @@ static struct usb_device_id mceusb_dev_table[] = {
261 .driver_info = MCE_GEN2_TX_INV }, 261 .driver_info = MCE_GEN2_TX_INV },
262 /* Topseed eHome Infrared Transceiver */ 262 /* Topseed eHome Infrared Transceiver */
263 { USB_DEVICE(VENDOR_TOPSEED, 0x0011), 263 { USB_DEVICE(VENDOR_TOPSEED, 0x0011),
264 .driver_info = MCE_GEN2_TX_INV }, 264 .driver_info = MCE_GEN3 },
265 /* Ricavision internal Infrared Transceiver */ 265 /* Ricavision internal Infrared Transceiver */
266 { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, 266 { USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
267 /* Itron ione Libra Q-11 */ 267 /* Itron ione Libra Q-11 */
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index aa021600e9df..4498b944dec8 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -42,8 +42,30 @@ config VIDEO_TUNER
42 42
43config V4L2_MEM2MEM_DEV 43config V4L2_MEM2MEM_DEV
44 tristate 44 tristate
45 depends on VIDEOBUF_GEN 45 depends on VIDEOBUF2_CORE
46 46
47config VIDEOBUF2_CORE
48 tristate
49
50config VIDEOBUF2_MEMOPS
51 tristate
52
53config VIDEOBUF2_DMA_CONTIG
54 select VIDEOBUF2_CORE
55 select VIDEOBUF2_MEMOPS
56 tristate
57
58config VIDEOBUF2_VMALLOC
59 select VIDEOBUF2_CORE
60 select VIDEOBUF2_MEMOPS
61 tristate
62
63
64config VIDEOBUF2_DMA_SG
65 #depends on HAS_DMA
66 select VIDEOBUF2_CORE
67 select VIDEOBUF2_MEMOPS
68 tristate
47# 69#
48# Multimedia Video device configuration 70# Multimedia Video device configuration
49# 71#
@@ -527,7 +549,7 @@ config VIDEO_VIVI
527 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 549 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
528 depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE 550 depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
529 select FONT_8x16 551 select FONT_8x16
530 select VIDEOBUF_VMALLOC 552 select VIDEOBUF2_VMALLOC
531 default n 553 default n
532 ---help--- 554 ---help---
533 Enables a virtual video driver. This device shows a color bar 555 Enables a virtual video driver. This device shows a color bar
@@ -718,10 +740,30 @@ config VIDEO_VIA_CAMERA
718 Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems 740 Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems
719 with ov7670 sensors. 741 with ov7670 sensors.
720 742
743config VIDEO_NOON010PC30
744 tristate "NOON010PC30 CIF camera sensor support"
745 depends on I2C && VIDEO_V4L2
746 ---help---
747 This driver supports NOON010PC30 CIF camera from Siliconfile
748
749config VIDEO_OMAP3
750 tristate "OMAP 3 Camera support (EXPERIMENTAL)"
751 select OMAP_IOMMU
752 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL
753 ---help---
754 Driver for an OMAP 3 camera controller.
755
756config VIDEO_OMAP3_DEBUG
757 bool "OMAP 3 Camera debug messages"
758 depends on VIDEO_OMAP3
759 ---help---
760 Enable debug messages on OMAP 3 camera controller driver.
761
721config SOC_CAMERA 762config SOC_CAMERA
722 tristate "SoC camera support" 763 tristate "SoC camera support"
723 depends on VIDEO_V4L2 && HAS_DMA && I2C 764 depends on VIDEO_V4L2 && HAS_DMA && I2C
724 select VIDEOBUF_GEN 765 select VIDEOBUF_GEN
766 select VIDEOBUF2_CORE
725 help 767 help
726 SoC Camera is a common API to several cameras, not connecting 768 SoC Camera is a common API to several cameras, not connecting
727 over a bus like PCI or USB. For example some i2c camera connected 769 over a bus like PCI or USB. For example some i2c camera connected
@@ -809,6 +851,12 @@ config SOC_CAMERA_OV9640
809 help 851 help
810 This is a ov9640 camera driver 852 This is a ov9640 camera driver
811 853
854config SOC_CAMERA_OV9740
855 tristate "ov9740 camera support"
856 depends on SOC_CAMERA && I2C
857 help
858 This is a ov9740 camera driver
859
812config MX1_VIDEO 860config MX1_VIDEO
813 bool 861 bool
814 862
@@ -848,7 +896,7 @@ config VIDEO_SH_MOBILE_CSI2
848config VIDEO_SH_MOBILE_CEU 896config VIDEO_SH_MOBILE_CEU
849 tristate "SuperH Mobile CEU Interface driver" 897 tristate "SuperH Mobile CEU Interface driver"
850 depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK 898 depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
851 select VIDEOBUF_DMA_CONTIG 899 select VIDEOBUF2_DMA_CONTIG
852 ---help--- 900 ---help---
853 This is a v4l2 driver for the SuperH Mobile CEU Interface 901 This is a v4l2 driver for the SuperH Mobile CEU Interface
854 902
@@ -967,7 +1015,7 @@ if V4L_MEM2MEM_DRIVERS
967config VIDEO_MEM2MEM_TESTDEV 1015config VIDEO_MEM2MEM_TESTDEV
968 tristate "Virtual test device for mem2mem framework" 1016 tristate "Virtual test device for mem2mem framework"
969 depends on VIDEO_DEV && VIDEO_V4L2 1017 depends on VIDEO_DEV && VIDEO_V4L2
970 select VIDEOBUF_VMALLOC 1018 select VIDEOBUF2_VMALLOC
971 select V4L2_MEM2MEM_DEV 1019 select V4L2_MEM2MEM_DEV
972 default n 1020 default n
973 ---help--- 1021 ---help---
@@ -977,7 +1025,7 @@ config VIDEO_MEM2MEM_TESTDEV
977config VIDEO_SAMSUNG_S5P_FIMC 1025config VIDEO_SAMSUNG_S5P_FIMC
978 tristate "Samsung S5P FIMC (video postprocessor) driver" 1026 tristate "Samsung S5P FIMC (video postprocessor) driver"
979 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P 1027 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
980 select VIDEOBUF_DMA_CONTIG 1028 select VIDEOBUF2_DMA_CONTIG
981 select V4L2_MEM2MEM_DEV 1029 select V4L2_MEM2MEM_DEV
982 help 1030 help
983 This is a v4l2 driver for the S5P camera interface 1031 This is a v4l2 driver for the S5P camera interface
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index a509d317e258..ace5d8b57221 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -11,7 +11,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o
11omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o 11omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
12 12
13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ 13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
14 v4l2-event.o v4l2-ctrls.o 14 v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
15 15
16# V4L2 core modules 16# V4L2 core modules
17 17
@@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o 68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
69obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 69obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
70obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
70 71
71obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o 72obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
72obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o 73obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
@@ -78,6 +79,7 @@ obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
78obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o 79obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
79obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o 80obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
80obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o 81obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
82obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
81obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o 83obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
82obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o 84obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
83 85
@@ -111,6 +113,12 @@ obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
111obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o 113obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
112obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o 114obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
113 115
116obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
117obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
118obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
119obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
120obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
121
114obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o 122obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
115 123
116obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o 124obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
@@ -121,6 +129,8 @@ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
121 129
122obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o 130obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
123 131
132obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/
133
124obj-$(CONFIG_USB_ZR364XX) += zr364xx.o 134obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
125obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o 135obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
126 136
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 41b2930d0ce4..021fab23070d 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -29,6 +29,7 @@
29#include <media/adv7343.h> 29#include <media/adv7343.h>
30#include <media/v4l2-device.h> 30#include <media/v4l2-device.h>
31#include <media/v4l2-chip-ident.h> 31#include <media/v4l2-chip-ident.h>
32#include <media/v4l2-ctrls.h>
32 33
33#include "adv7343_regs.h" 34#include "adv7343_regs.h"
34 35
@@ -41,15 +42,13 @@ MODULE_PARM_DESC(debug, "Debug level 0-1");
41 42
42struct adv7343_state { 43struct adv7343_state {
43 struct v4l2_subdev sd; 44 struct v4l2_subdev sd;
45 struct v4l2_ctrl_handler hdl;
44 u8 reg00; 46 u8 reg00;
45 u8 reg01; 47 u8 reg01;
46 u8 reg02; 48 u8 reg02;
47 u8 reg35; 49 u8 reg35;
48 u8 reg80; 50 u8 reg80;
49 u8 reg82; 51 u8 reg82;
50 int bright;
51 int hue;
52 int gain;
53 u32 output; 52 u32 output;
54 v4l2_std_id std; 53 v4l2_std_id std;
55}; 54};
@@ -59,6 +58,11 @@ static inline struct adv7343_state *to_state(struct v4l2_subdev *sd)
59 return container_of(sd, struct adv7343_state, sd); 58 return container_of(sd, struct adv7343_state, sd);
60} 59}
61 60
61static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
62{
63 return &container_of(ctrl->handler, struct adv7343_state, hdl)->sd;
64}
65
62static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value) 66static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
63{ 67{
64 struct i2c_client *client = v4l2_get_subdevdata(sd); 68 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -268,111 +272,22 @@ static int adv7343_log_status(struct v4l2_subdev *sd)
268 return 0; 272 return 0;
269} 273}
270 274
271static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 275static int adv7343_s_ctrl(struct v4l2_ctrl *ctrl)
272{
273 switch (qc->id) {
274 case V4L2_CID_BRIGHTNESS:
275 return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN,
276 ADV7343_BRIGHTNESS_MAX, 1,
277 ADV7343_BRIGHTNESS_DEF);
278 case V4L2_CID_HUE:
279 return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN,
280 ADV7343_HUE_MAX, 1 ,
281 ADV7343_HUE_DEF);
282 case V4L2_CID_GAIN:
283 return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN,
284 ADV7343_GAIN_MAX, 1,
285 ADV7343_GAIN_DEF);
286 default:
287 break;
288 }
289
290 return 0;
291}
292
293static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
294{
295 struct adv7343_state *state = to_state(sd);
296 int err = 0;
297
298 switch (ctrl->id) {
299 case V4L2_CID_BRIGHTNESS:
300 if (ctrl->value < ADV7343_BRIGHTNESS_MIN ||
301 ctrl->value > ADV7343_BRIGHTNESS_MAX) {
302 v4l2_dbg(1, debug, sd,
303 "invalid brightness settings %d\n",
304 ctrl->value);
305 return -ERANGE;
306 }
307
308 state->bright = ctrl->value;
309 err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
310 state->bright);
311 break;
312
313 case V4L2_CID_HUE:
314 if (ctrl->value < ADV7343_HUE_MIN ||
315 ctrl->value > ADV7343_HUE_MAX) {
316 v4l2_dbg(1, debug, sd, "invalid hue settings %d\n",
317 ctrl->value);
318 return -ERANGE;
319 }
320
321 state->hue = ctrl->value;
322 err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue);
323 break;
324
325 case V4L2_CID_GAIN:
326 if (ctrl->value < ADV7343_GAIN_MIN ||
327 ctrl->value > ADV7343_GAIN_MAX) {
328 v4l2_dbg(1, debug, sd, "invalid gain settings %d\n",
329 ctrl->value);
330 return -ERANGE;
331 }
332
333 if ((ctrl->value > POSITIVE_GAIN_MAX) &&
334 (ctrl->value < NEGATIVE_GAIN_MIN)) {
335 v4l2_dbg(1, debug, sd,
336 "gain settings not within the specified range\n");
337 return -ERANGE;
338 }
339
340 state->gain = ctrl->value;
341 err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain);
342 break;
343
344 default:
345 return -EINVAL;
346 }
347
348 if (err < 0)
349 v4l2_err(sd, "Failed to set the encoder controls\n");
350
351 return err;
352}
353
354static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
355{ 276{
356 struct adv7343_state *state = to_state(sd); 277 struct v4l2_subdev *sd = to_sd(ctrl);
357 278
358 switch (ctrl->id) { 279 switch (ctrl->id) {
359 case V4L2_CID_BRIGHTNESS: 280 case V4L2_CID_BRIGHTNESS:
360 ctrl->value = state->bright; 281 return adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
361 break; 282 ctrl->val);
362 283
363 case V4L2_CID_HUE: 284 case V4L2_CID_HUE:
364 ctrl->value = state->hue; 285 return adv7343_write(sd, ADV7343_SD_HUE_REG, ctrl->val);
365 break;
366 286
367 case V4L2_CID_GAIN: 287 case V4L2_CID_GAIN:
368 ctrl->value = state->gain; 288 return adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, ctrl->val);
369 break;
370
371 default:
372 return -EINVAL;
373 } 289 }
374 290 return -EINVAL;
375 return 0;
376} 291}
377 292
378static int adv7343_g_chip_ident(struct v4l2_subdev *sd, 293static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
@@ -383,12 +298,20 @@ static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
383 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0); 298 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
384} 299}
385 300
301static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
302 .s_ctrl = adv7343_s_ctrl,
303};
304
386static const struct v4l2_subdev_core_ops adv7343_core_ops = { 305static const struct v4l2_subdev_core_ops adv7343_core_ops = {
387 .log_status = adv7343_log_status, 306 .log_status = adv7343_log_status,
388 .g_chip_ident = adv7343_g_chip_ident, 307 .g_chip_ident = adv7343_g_chip_ident,
389 .g_ctrl = adv7343_g_ctrl, 308 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
390 .s_ctrl = adv7343_s_ctrl, 309 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
391 .queryctrl = adv7343_queryctrl, 310 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
311 .g_ctrl = v4l2_subdev_g_ctrl,
312 .s_ctrl = v4l2_subdev_s_ctrl,
313 .queryctrl = v4l2_subdev_queryctrl,
314 .querymenu = v4l2_subdev_querymenu,
392}; 315};
393 316
394static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) 317static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
@@ -468,6 +391,7 @@ static int adv7343_probe(struct i2c_client *client,
468 const struct i2c_device_id *id) 391 const struct i2c_device_id *id)
469{ 392{
470 struct adv7343_state *state; 393 struct adv7343_state *state;
394 int err;
471 395
472 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 396 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
473 return -ENODEV; 397 return -ENODEV;
@@ -490,15 +414,46 @@ static int adv7343_probe(struct i2c_client *client,
490 state->std = V4L2_STD_NTSC; 414 state->std = V4L2_STD_NTSC;
491 415
492 v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops); 416 v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops);
493 return adv7343_initialize(&state->sd); 417
418 v4l2_ctrl_handler_init(&state->hdl, 2);
419 v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
420 V4L2_CID_BRIGHTNESS, ADV7343_BRIGHTNESS_MIN,
421 ADV7343_BRIGHTNESS_MAX, 1,
422 ADV7343_BRIGHTNESS_DEF);
423 v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
424 V4L2_CID_HUE, ADV7343_HUE_MIN,
425 ADV7343_HUE_MAX, 1,
426 ADV7343_HUE_DEF);
427 v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
428 V4L2_CID_GAIN, ADV7343_GAIN_MIN,
429 ADV7343_GAIN_MAX, 1,
430 ADV7343_GAIN_DEF);
431 state->sd.ctrl_handler = &state->hdl;
432 if (state->hdl.error) {
433 int err = state->hdl.error;
434
435 v4l2_ctrl_handler_free(&state->hdl);
436 kfree(state);
437 return err;
438 }
439 v4l2_ctrl_handler_setup(&state->hdl);
440
441 err = adv7343_initialize(&state->sd);
442 if (err) {
443 v4l2_ctrl_handler_free(&state->hdl);
444 kfree(state);
445 }
446 return err;
494} 447}
495 448
496static int adv7343_remove(struct i2c_client *client) 449static int adv7343_remove(struct i2c_client *client)
497{ 450{
498 struct v4l2_subdev *sd = i2c_get_clientdata(client); 451 struct v4l2_subdev *sd = i2c_get_clientdata(client);
452 struct adv7343_state *state = to_state(sd);
499 453
500 v4l2_device_unregister_subdev(sd); 454 v4l2_device_unregister_subdev(sd);
501 kfree(to_state(sd)); 455 v4l2_ctrl_handler_free(&state->hdl);
456 kfree(state);
502 457
503 return 0; 458 return 0;
504} 459}
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/video/adv7343_regs.h
index 3431045b33da..446606764346 100644
--- a/drivers/media/video/adv7343_regs.h
+++ b/drivers/media/video/adv7343_regs.h
@@ -102,10 +102,6 @@ struct adv7343_std_info {
102 102
103/* Bit masks for DAC output levels */ 103/* Bit masks for DAC output levels */
104#define DAC_OUTPUT_LEVEL_MASK (0xFF) 104#define DAC_OUTPUT_LEVEL_MASK (0xFF)
105#define POSITIVE_GAIN_MAX (0x40)
106#define POSITIVE_GAIN_MIN (0x00)
107#define NEGATIVE_GAIN_MAX (0xFF)
108#define NEGATIVE_GAIN_MIN (0xC0)
109 105
110/* Bit masks for soft reset register */ 106/* Bit masks for soft reset register */
111#define SOFT_RESET (0x02) 107#define SOFT_RESET (0x02)
@@ -178,8 +174,8 @@ struct adv7343_std_info {
178#define ADV7343_HUE_MAX (255) 174#define ADV7343_HUE_MAX (255)
179#define ADV7343_HUE_MIN (0) 175#define ADV7343_HUE_MIN (0)
180#define ADV7343_HUE_DEF (127) 176#define ADV7343_HUE_DEF (127)
181#define ADV7343_GAIN_MAX (255) 177#define ADV7343_GAIN_MAX (64)
182#define ADV7343_GAIN_MIN (0) 178#define ADV7343_GAIN_MIN (-64)
183#define ADV7343_GAIN_DEF (0) 179#define ADV7343_GAIN_DEF (0)
184 180
185#endif 181#endif
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 01be89fa5c78..39fc923fc46b 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -185,8 +185,7 @@ void au0828_card_setup(struct au0828_dev *dev)
185 static u8 eeprom[256]; 185 static u8 eeprom[256];
186 struct tuner_setup tun_setup; 186 struct tuner_setup tun_setup;
187 struct v4l2_subdev *sd; 187 struct v4l2_subdev *sd;
188 unsigned int mode_mask = T_ANALOG_TV | 188 unsigned int mode_mask = T_ANALOG_TV;
189 T_DIGITAL_TV;
190 189
191 dprintk(1, "%s()\n", __func__); 190 dprintk(1, "%s()\n", __func__);
192 191
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index f1edf1d4afe8..518216743c9c 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -96,7 +96,6 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = {
96/*-------------------------------------------------------------------*/ 96/*-------------------------------------------------------------------*/
97static void urb_completion(struct urb *purb) 97static void urb_completion(struct urb *purb)
98{ 98{
99 u8 *ptr;
100 struct au0828_dev *dev = purb->context; 99 struct au0828_dev *dev = purb->context;
101 int ptype = usb_pipetype(purb->pipe); 100 int ptype = usb_pipetype(purb->pipe);
102 101
@@ -114,8 +113,6 @@ static void urb_completion(struct urb *purb)
114 return; 113 return;
115 } 114 }
116 115
117 ptr = (u8 *)purb->transfer_buffer;
118
119 /* Feed the transport payload into the kernel demux */ 116 /* Feed the transport payload into the kernel demux */
120 dvb_dmx_swfilter_packets(&dev->dvb.demux, 117 dvb_dmx_swfilter_packets(&dev->dvb.demux,
121 purb->transfer_buffer, purb->actual_length / 188); 118 purb->transfer_buffer, purb->actual_length / 188);
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 9c475c600fc9..6ad83a15d073 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -1177,10 +1177,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
1177 int ret; 1177 int ret;
1178 int width = format->fmt.pix.width; 1178 int width = format->fmt.pix.width;
1179 int height = format->fmt.pix.height; 1179 int height = format->fmt.pix.height;
1180 unsigned int maxwidth, maxheight;
1181
1182 maxwidth = 720;
1183 maxheight = 480;
1184 1180
1185 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1181 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1186 return -EINVAL; 1182 return -EINVAL;
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index c38300fc0b1d..f87204461cb4 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -37,6 +37,7 @@
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <media/v4l2-device.h> 38#include <media/v4l2-device.h>
39#include <media/v4l2-chip-ident.h> 39#include <media/v4l2-chip-ident.h>
40#include <media/v4l2-ctrls.h>
40#include <media/bt819.h> 41#include <media/bt819.h>
41 42
42MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); 43MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
@@ -52,16 +53,13 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
52 53
53struct bt819 { 54struct bt819 {
54 struct v4l2_subdev sd; 55 struct v4l2_subdev sd;
56 struct v4l2_ctrl_handler hdl;
55 unsigned char reg[32]; 57 unsigned char reg[32];
56 58
57 v4l2_std_id norm; 59 v4l2_std_id norm;
58 int ident; 60 int ident;
59 int input; 61 int input;
60 int enable; 62 int enable;
61 int bright;
62 int contrast;
63 int hue;
64 int sat;
65}; 63};
66 64
67static inline struct bt819 *to_bt819(struct v4l2_subdev *sd) 65static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
@@ -69,6 +67,11 @@ static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
69 return container_of(sd, struct bt819, sd); 67 return container_of(sd, struct bt819, sd);
70} 68}
71 69
70static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
71{
72 return &container_of(ctrl->handler, struct bt819, hdl)->sd;
73}
74
72struct timing { 75struct timing {
73 int hactive; 76 int hactive;
74 int hdelay; 77 int hdelay;
@@ -333,71 +336,35 @@ static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
333 return 0; 336 return 0;
334} 337}
335 338
336static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 339static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
337{
338 switch (qc->id) {
339 case V4L2_CID_BRIGHTNESS:
340 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
341 break;
342
343 case V4L2_CID_CONTRAST:
344 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
345 break;
346
347 case V4L2_CID_SATURATION:
348 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
349 break;
350
351 case V4L2_CID_HUE:
352 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
353 break;
354
355 default:
356 return -EINVAL;
357 }
358 return 0;
359}
360
361static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
362{ 340{
341 struct v4l2_subdev *sd = to_sd(ctrl);
363 struct bt819 *decoder = to_bt819(sd); 342 struct bt819 *decoder = to_bt819(sd);
364 int temp; 343 int temp;
365 344
366 switch (ctrl->id) { 345 switch (ctrl->id) {
367 case V4L2_CID_BRIGHTNESS: 346 case V4L2_CID_BRIGHTNESS:
368 if (decoder->bright == ctrl->value) 347 bt819_write(decoder, 0x0a, ctrl->val);
369 break;
370 decoder->bright = ctrl->value;
371 bt819_write(decoder, 0x0a, decoder->bright);
372 break; 348 break;
373 349
374 case V4L2_CID_CONTRAST: 350 case V4L2_CID_CONTRAST:
375 if (decoder->contrast == ctrl->value) 351 bt819_write(decoder, 0x0c, ctrl->val & 0xff);
376 break; 352 bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
377 decoder->contrast = ctrl->value;
378 bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
379 bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01));
380 break; 353 break;
381 354
382 case V4L2_CID_SATURATION: 355 case V4L2_CID_SATURATION:
383 if (decoder->sat == ctrl->value) 356 bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
384 break; 357 bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
385 decoder->sat = ctrl->value;
386 bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
387 bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
388 358
389 /* Ratio between U gain and V gain must stay the same as 359 /* Ratio between U gain and V gain must stay the same as
390 the ratio between the default U and V gain values. */ 360 the ratio between the default U and V gain values. */
391 temp = (decoder->sat * 180) / 254; 361 temp = (ctrl->val * 180) / 254;
392 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff); 362 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
393 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01); 363 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
394 break; 364 break;
395 365
396 case V4L2_CID_HUE: 366 case V4L2_CID_HUE:
397 if (decoder->hue == ctrl->value) 367 bt819_write(decoder, 0x0f, ctrl->val);
398 break;
399 decoder->hue = ctrl->value;
400 bt819_write(decoder, 0x0f, decoder->hue);
401 break; 368 break;
402 369
403 default: 370 default:
@@ -406,29 +373,6 @@ static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
406 return 0; 373 return 0;
407} 374}
408 375
409static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
410{
411 struct bt819 *decoder = to_bt819(sd);
412
413 switch (ctrl->id) {
414 case V4L2_CID_BRIGHTNESS:
415 ctrl->value = decoder->bright;
416 break;
417 case V4L2_CID_CONTRAST:
418 ctrl->value = decoder->contrast;
419 break;
420 case V4L2_CID_SATURATION:
421 ctrl->value = decoder->sat;
422 break;
423 case V4L2_CID_HUE:
424 ctrl->value = decoder->hue;
425 break;
426 default:
427 return -EINVAL;
428 }
429 return 0;
430}
431
432static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) 376static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
433{ 377{
434 struct bt819 *decoder = to_bt819(sd); 378 struct bt819 *decoder = to_bt819(sd);
@@ -439,11 +383,19 @@ static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident
439 383
440/* ----------------------------------------------------------------------- */ 384/* ----------------------------------------------------------------------- */
441 385
386static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
387 .s_ctrl = bt819_s_ctrl,
388};
389
442static const struct v4l2_subdev_core_ops bt819_core_ops = { 390static const struct v4l2_subdev_core_ops bt819_core_ops = {
443 .g_chip_ident = bt819_g_chip_ident, 391 .g_chip_ident = bt819_g_chip_ident,
444 .g_ctrl = bt819_g_ctrl, 392 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
445 .s_ctrl = bt819_s_ctrl, 393 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
446 .queryctrl = bt819_queryctrl, 394 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
395 .g_ctrl = v4l2_subdev_g_ctrl,
396 .s_ctrl = v4l2_subdev_s_ctrl,
397 .queryctrl = v4l2_subdev_queryctrl,
398 .querymenu = v4l2_subdev_querymenu,
447 .s_std = bt819_s_std, 399 .s_std = bt819_s_std,
448}; 400};
449 401
@@ -505,23 +457,40 @@ static int bt819_probe(struct i2c_client *client,
505 decoder->norm = V4L2_STD_NTSC; 457 decoder->norm = V4L2_STD_NTSC;
506 decoder->input = 0; 458 decoder->input = 0;
507 decoder->enable = 1; 459 decoder->enable = 1;
508 decoder->bright = 0;
509 decoder->contrast = 0xd8; /* 100% of original signal */
510 decoder->hue = 0;
511 decoder->sat = 0xfe; /* 100% of original signal */
512 460
513 i = bt819_init(sd); 461 i = bt819_init(sd);
514 if (i < 0) 462 if (i < 0)
515 v4l2_dbg(1, debug, sd, "init status %d\n", i); 463 v4l2_dbg(1, debug, sd, "init status %d\n", i);
464
465 v4l2_ctrl_handler_init(&decoder->hdl, 4);
466 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
467 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
468 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
469 V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
470 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
471 V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
472 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
473 V4L2_CID_HUE, -128, 127, 1, 0);
474 sd->ctrl_handler = &decoder->hdl;
475 if (decoder->hdl.error) {
476 int err = decoder->hdl.error;
477
478 v4l2_ctrl_handler_free(&decoder->hdl);
479 kfree(decoder);
480 return err;
481 }
482 v4l2_ctrl_handler_setup(&decoder->hdl);
516 return 0; 483 return 0;
517} 484}
518 485
519static int bt819_remove(struct i2c_client *client) 486static int bt819_remove(struct i2c_client *client)
520{ 487{
521 struct v4l2_subdev *sd = i2c_get_clientdata(client); 488 struct v4l2_subdev *sd = i2c_get_clientdata(client);
489 struct bt819 *decoder = to_bt819(sd);
522 490
523 v4l2_device_unregister_subdev(sd); 491 v4l2_device_unregister_subdev(sd);
524 kfree(to_bt819(sd)); 492 v4l2_ctrl_handler_free(&decoder->hdl);
493 kfree(decoder);
525 return 0; 494 return 0;
526} 495}
527 496
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 7f58756d72c8..242f0d512238 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3616,7 +3616,7 @@ void __devinit bttv_init_tuner(struct bttv *btv)
3616 &btv->c.i2c_adap, "tuner", 3616 &btv->c.i2c_adap, "tuner",
3617 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); 3617 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
3618 3618
3619 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 3619 tun_setup.mode_mask = T_ANALOG_TV;
3620 tun_setup.type = btv->tuner_type; 3620 tun_setup.type = btv->tuner_type;
3621 tun_setup.addr = addr; 3621 tun_setup.addr = addr;
3622 3622
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index e8b64bca9db2..677d70c0e1ce 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -193,12 +193,10 @@ static void bttv_rc5_timer_end(unsigned long data)
193{ 193{
194 struct bttv_ir *ir = (struct bttv_ir *)data; 194 struct bttv_ir *ir = (struct bttv_ir *)data;
195 struct timeval tv; 195 struct timeval tv;
196 unsigned long current_jiffies;
197 u32 gap; 196 u32 gap;
198 u32 rc5 = 0; 197 u32 rc5 = 0;
199 198
200 /* get time */ 199 /* get time */
201 current_jiffies = jiffies;
202 do_gettimeofday(&tv); 200 do_gettimeofday(&tv);
203 201
204 /* avoid overflow with gap >1s */ 202 /* avoid overflow with gap >1s */
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
index aaffca8e13fd..ee91e295c90a 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -519,22 +519,16 @@ int cpia2_do_command(struct camera_data *cam,
519 * cpia2_send_command 519 * cpia2_send_command
520 * 520 *
521 *****************************************************************************/ 521 *****************************************************************************/
522
523#define DIR(cmd) ((cmd->direction == TRANSFER_WRITE) ? "Write" : "Read")
524#define BINDEX(cmd) (cmd->req_mode & 0x03)
525
522int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd) 526int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
523{ 527{
524 u8 count; 528 u8 count;
525 u8 start; 529 u8 start;
526 u8 block_index;
527 u8 *buffer; 530 u8 *buffer;
528 int retval; 531 int retval;
529 const char* dir;
530
531 if (cmd->direction == TRANSFER_WRITE) {
532 dir = "Write";
533 } else {
534 dir = "Read";
535 }
536
537 block_index = cmd->req_mode & 0x03;
538 532
539 switch (cmd->req_mode & 0x0c) { 533 switch (cmd->req_mode & 0x0c) {
540 case CAMERAACCESS_TYPE_RANDOM: 534 case CAMERAACCESS_TYPE_RANDOM:
@@ -542,32 +536,32 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
542 start = 0; 536 start = 0;
543 buffer = (u8 *) & cmd->buffer; 537 buffer = (u8 *) & cmd->buffer;
544 if (debugs_on & DEBUG_REG) 538 if (debugs_on & DEBUG_REG)
545 DBG("%s Random: Register block %s\n", dir, 539 DBG("%s Random: Register block %s\n", DIR(cmd),
546 block_name[block_index]); 540 block_name[BINDEX(cmd)]);
547 break; 541 break;
548 case CAMERAACCESS_TYPE_BLOCK: 542 case CAMERAACCESS_TYPE_BLOCK:
549 count = cmd->reg_count; 543 count = cmd->reg_count;
550 start = cmd->start; 544 start = cmd->start;
551 buffer = cmd->buffer.block_data; 545 buffer = cmd->buffer.block_data;
552 if (debugs_on & DEBUG_REG) 546 if (debugs_on & DEBUG_REG)
553 DBG("%s Block: Register block %s\n", dir, 547 DBG("%s Block: Register block %s\n", DIR(cmd),
554 block_name[block_index]); 548 block_name[BINDEX(cmd)]);
555 break; 549 break;
556 case CAMERAACCESS_TYPE_MASK: 550 case CAMERAACCESS_TYPE_MASK:
557 count = cmd->reg_count * sizeof(struct cpia2_reg_mask); 551 count = cmd->reg_count * sizeof(struct cpia2_reg_mask);
558 start = 0; 552 start = 0;
559 buffer = (u8 *) & cmd->buffer; 553 buffer = (u8 *) & cmd->buffer;
560 if (debugs_on & DEBUG_REG) 554 if (debugs_on & DEBUG_REG)
561 DBG("%s Mask: Register block %s\n", dir, 555 DBG("%s Mask: Register block %s\n", DIR(cmd),
562 block_name[block_index]); 556 block_name[BINDEX(cmd)]);
563 break; 557 break;
564 case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */ 558 case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */
565 count = cmd->reg_count; 559 count = cmd->reg_count;
566 start = cmd->start; 560 start = cmd->start;
567 buffer = cmd->buffer.block_data; 561 buffer = cmd->buffer.block_data;
568 if (debugs_on & DEBUG_REG) 562 if (debugs_on & DEBUG_REG)
569 DBG("%s Repeat: Register block %s\n", dir, 563 DBG("%s Repeat: Register block %s\n", DIR(cmd),
570 block_name[block_index]); 564 block_name[BINDEX(cmd)]);
571 break; 565 break;
572 default: 566 default:
573 LOG("%s: invalid request mode\n",__func__); 567 LOG("%s: invalid request mode\n",__func__);
@@ -584,10 +578,10 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
584 for (i = 0; i < cmd->reg_count; i++) { 578 for (i = 0; i < cmd->reg_count; i++) {
585 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK) 579 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK)
586 KINFO("%s Block: [0x%02X] = 0x%02X\n", 580 KINFO("%s Block: [0x%02X] = 0x%02X\n",
587 dir, start + i, buffer[i]); 581 DIR(cmd), start + i, buffer[i]);
588 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM) 582 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM)
589 KINFO("%s Random: [0x%02X] = 0x%02X\n", 583 KINFO("%s Random: [0x%02X] = 0x%02X\n",
590 dir, cmd->buffer.registers[i].index, 584 DIR(cmd), cmd->buffer.registers[i].index,
591 cmd->buffer.registers[i].value); 585 cmd->buffer.registers[i].value);
592 } 586 }
593 } 587 }
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 9bad39842936..5111bbcefad5 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -395,10 +395,15 @@ static int sync(struct camera_data *cam, int frame_nr)
395 * 395 *
396 *****************************************************************************/ 396 *****************************************************************************/
397 397
398static int ioctl_set_gpio(void *arg, struct camera_data *cam) 398static long cpia2_default(struct file *file, void *fh, bool valid_prio,
399 int cmd, void *arg)
399{ 400{
401 struct camera_data *cam = video_drvdata(file);
400 __u32 gpio_val; 402 __u32 gpio_val;
401 403
404 if (cmd != CPIA2_CID_GPIO)
405 return -EINVAL;
406
402 gpio_val = *(__u32*) arg; 407 gpio_val = *(__u32*) arg;
403 408
404 if (gpio_val &~ 0xFFU) 409 if (gpio_val &~ 0xFFU)
@@ -415,11 +420,10 @@ static int ioctl_set_gpio(void *arg, struct camera_data *cam)
415 * 420 *
416 *****************************************************************************/ 421 *****************************************************************************/
417 422
418static int ioctl_querycap(void *arg, struct camera_data *cam) 423static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *vc)
419{ 424{
420 struct v4l2_capability *vc = arg; 425 struct camera_data *cam = video_drvdata(file);
421 426
422 memset(vc, 0, sizeof(*vc));
423 strcpy(vc->driver, "cpia2"); 427 strcpy(vc->driver, "cpia2");
424 428
425 if (cam->params.pnp_id.product == 0x151) 429 if (cam->params.pnp_id.product == 0x151)
@@ -479,22 +483,26 @@ static int ioctl_querycap(void *arg, struct camera_data *cam)
479 * 483 *
480 *****************************************************************************/ 484 *****************************************************************************/
481 485
482static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) 486static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i)
483{ 487{
484 struct v4l2_input *i = arg; 488 if (i->index)
485 489 return -EINVAL;
486 if(ioclt_nr != VIDIOC_G_INPUT) {
487 if (i->index != 0)
488 return -EINVAL;
489 }
490
491 memset(i, 0, sizeof(*i));
492 strcpy(i->name, "Camera"); 490 strcpy(i->name, "Camera");
493 i->type = V4L2_INPUT_TYPE_CAMERA; 491 i->type = V4L2_INPUT_TYPE_CAMERA;
492 return 0;
493}
494 494
495static int cpia2_g_input(struct file *file, void *fh, unsigned int *i)
496{
497 *i = 0;
495 return 0; 498 return 0;
496} 499}
497 500
501static int cpia2_s_input(struct file *file, void *fh, unsigned int i)
502{
503 return i ? -EINVAL : 0;
504}
505
498/****************************************************************************** 506/******************************************************************************
499 * 507 *
500 * ioctl_enum_fmt 508 * ioctl_enum_fmt
@@ -503,9 +511,9 @@ static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam)
503 * 511 *
504 *****************************************************************************/ 512 *****************************************************************************/
505 513
506static int ioctl_enum_fmt(void *arg,struct camera_data *cam) 514static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh,
515 struct v4l2_fmtdesc *f)
507{ 516{
508 struct v4l2_fmtdesc *f = arg;
509 int index = f->index; 517 int index = f->index;
510 518
511 if (index < 0 || index > 1) 519 if (index < 0 || index > 1)
@@ -539,12 +547,10 @@ static int ioctl_enum_fmt(void *arg,struct camera_data *cam)
539 * 547 *
540 *****************************************************************************/ 548 *****************************************************************************/
541 549
542static int ioctl_try_fmt(void *arg,struct camera_data *cam) 550static int cpia2_try_fmt_vid_cap(struct file *file, void *fh,
551 struct v4l2_format *f)
543{ 552{
544 struct v4l2_format *f = arg; 553 struct camera_data *cam = video_drvdata(file);
545
546 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
547 return -EINVAL;
548 554
549 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && 555 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
550 f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) 556 f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
@@ -603,12 +609,17 @@ static int ioctl_try_fmt(void *arg,struct camera_data *cam)
603 * 609 *
604 *****************************************************************************/ 610 *****************************************************************************/
605 611
606static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) 612static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh,
613 struct v4l2_format *f)
607{ 614{
608 struct v4l2_format *f = arg; 615 struct camera_data *cam = video_drvdata(file);
616 struct cpia2_fh *fh = _fh;
609 int err, frame; 617 int err, frame;
610 618
611 err = ioctl_try_fmt(arg, cam); 619 err = v4l2_prio_check(&cam->prio, fh->prio);
620 if (err)
621 return err;
622 err = cpia2_try_fmt_vid_cap(file, _fh, f);
612 if(err != 0) 623 if(err != 0)
613 return err; 624 return err;
614 625
@@ -658,12 +669,10 @@ static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh)
658 * 669 *
659 *****************************************************************************/ 670 *****************************************************************************/
660 671
661static int ioctl_get_fmt(void *arg,struct camera_data *cam) 672static int cpia2_g_fmt_vid_cap(struct file *file, void *fh,
673 struct v4l2_format *f)
662{ 674{
663 struct v4l2_format *f = arg; 675 struct camera_data *cam = video_drvdata(file);
664
665 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
666 return -EINVAL;
667 676
668 f->fmt.pix.width = cam->width; 677 f->fmt.pix.width = cam->width;
669 f->fmt.pix.height = cam->height; 678 f->fmt.pix.height = cam->height;
@@ -686,9 +695,9 @@ static int ioctl_get_fmt(void *arg,struct camera_data *cam)
686 * 695 *
687 *****************************************************************************/ 696 *****************************************************************************/
688 697
689static int ioctl_cropcap(void *arg,struct camera_data *cam) 698static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c)
690{ 699{
691 struct v4l2_cropcap *c = arg; 700 struct camera_data *cam = video_drvdata(file);
692 701
693 if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 702 if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
694 return -EINVAL; 703 return -EINVAL;
@@ -715,9 +724,9 @@ static int ioctl_cropcap(void *arg,struct camera_data *cam)
715 * 724 *
716 *****************************************************************************/ 725 *****************************************************************************/
717 726
718static int ioctl_queryctrl(void *arg,struct camera_data *cam) 727static int cpia2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
719{ 728{
720 struct v4l2_queryctrl *c = arg; 729 struct camera_data *cam = video_drvdata(file);
721 int i; 730 int i;
722 731
723 for(i=0; i<NUM_CONTROLS; ++i) { 732 for(i=0; i<NUM_CONTROLS; ++i) {
@@ -783,12 +792,9 @@ static int ioctl_queryctrl(void *arg,struct camera_data *cam)
783 * 792 *
784 *****************************************************************************/ 793 *****************************************************************************/
785 794
786static int ioctl_querymenu(void *arg,struct camera_data *cam) 795static int cpia2_querymenu(struct file *file, void *fh, struct v4l2_querymenu *m)
787{ 796{
788 struct v4l2_querymenu *m = arg; 797 struct camera_data *cam = video_drvdata(file);
789
790 memset(m->name, 0, sizeof(m->name));
791 m->reserved = 0;
792 798
793 switch(m->id) { 799 switch(m->id) {
794 case CPIA2_CID_FLICKER_MODE: 800 case CPIA2_CID_FLICKER_MODE:
@@ -837,9 +843,9 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
837 * 843 *
838 *****************************************************************************/ 844 *****************************************************************************/
839 845
840static int ioctl_g_ctrl(void *arg,struct camera_data *cam) 846static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
841{ 847{
842 struct v4l2_control *c = arg; 848 struct camera_data *cam = video_drvdata(file);
843 849
844 switch(c->id) { 850 switch(c->id) {
845 case V4L2_CID_BRIGHTNESS: 851 case V4L2_CID_BRIGHTNESS:
@@ -955,9 +961,9 @@ static int ioctl_g_ctrl(void *arg,struct camera_data *cam)
955 * 961 *
956 *****************************************************************************/ 962 *****************************************************************************/
957 963
958static int ioctl_s_ctrl(void *arg,struct camera_data *cam) 964static int cpia2_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
959{ 965{
960 struct v4l2_control *c = arg; 966 struct camera_data *cam = video_drvdata(file);
961 int i; 967 int i;
962 int retval = 0; 968 int retval = 0;
963 969
@@ -1031,9 +1037,9 @@ static int ioctl_s_ctrl(void *arg,struct camera_data *cam)
1031 * 1037 *
1032 *****************************************************************************/ 1038 *****************************************************************************/
1033 1039
1034static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) 1040static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
1035{ 1041{
1036 struct v4l2_jpegcompression *parms = arg; 1042 struct camera_data *cam = video_drvdata(file);
1037 1043
1038 memset(parms, 0, sizeof(*parms)); 1044 memset(parms, 0, sizeof(*parms));
1039 1045
@@ -1072,9 +1078,9 @@ static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam)
1072 * 1078 *
1073 *****************************************************************************/ 1079 *****************************************************************************/
1074 1080
1075static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) 1081static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
1076{ 1082{
1077 struct v4l2_jpegcompression *parms = arg; 1083 struct camera_data *cam = video_drvdata(file);
1078 1084
1079 DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n", 1085 DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
1080 parms->APP_len, parms->COM_len); 1086 parms->APP_len, parms->COM_len);
@@ -1121,9 +1127,9 @@ static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam)
1121 * 1127 *
1122 *****************************************************************************/ 1128 *****************************************************************************/
1123 1129
1124static int ioctl_reqbufs(void *arg,struct camera_data *cam) 1130static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req)
1125{ 1131{
1126 struct v4l2_requestbuffers *req = arg; 1132 struct camera_data *cam = video_drvdata(file);
1127 1133
1128 if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1134 if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1129 req->memory != V4L2_MEMORY_MMAP) 1135 req->memory != V4L2_MEMORY_MMAP)
@@ -1144,9 +1150,9 @@ static int ioctl_reqbufs(void *arg,struct camera_data *cam)
1144 * 1150 *
1145 *****************************************************************************/ 1151 *****************************************************************************/
1146 1152
1147static int ioctl_querybuf(void *arg,struct camera_data *cam) 1153static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1148{ 1154{
1149 struct v4l2_buffer *buf = arg; 1155 struct camera_data *cam = video_drvdata(file);
1150 1156
1151 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1157 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1152 buf->index > cam->num_frames) 1158 buf->index > cam->num_frames)
@@ -1192,9 +1198,9 @@ static int ioctl_querybuf(void *arg,struct camera_data *cam)
1192 * 1198 *
1193 *****************************************************************************/ 1199 *****************************************************************************/
1194 1200
1195static int ioctl_qbuf(void *arg,struct camera_data *cam) 1201static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1196{ 1202{
1197 struct v4l2_buffer *buf = arg; 1203 struct camera_data *cam = video_drvdata(file);
1198 1204
1199 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1205 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1200 buf->memory != V4L2_MEMORY_MMAP || 1206 buf->memory != V4L2_MEMORY_MMAP ||
@@ -1248,9 +1254,9 @@ static int find_earliest_filled_buffer(struct camera_data *cam)
1248 * 1254 *
1249 *****************************************************************************/ 1255 *****************************************************************************/
1250 1256
1251static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) 1257static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1252{ 1258{
1253 struct v4l2_buffer *buf = arg; 1259 struct camera_data *cam = video_drvdata(file);
1254 int frame; 1260 int frame;
1255 1261
1256 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1262 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
@@ -1296,210 +1302,56 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
1296 return 0; 1302 return 0;
1297} 1303}
1298 1304
1299/****************************************************************************** 1305static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p)
1300 *
1301 * cpia2_ioctl
1302 *
1303 *****************************************************************************/
1304static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1305{ 1306{
1306 struct camera_data *cam = video_drvdata(file); 1307 struct cpia2_fh *fh = _fh;
1307 long retval = 0;
1308
1309 if (!cam)
1310 return -ENOTTY;
1311
1312 if (!cam->present)
1313 return -ENODEV;
1314
1315 /* Priority check */
1316 switch (cmd) {
1317 case VIDIOC_S_FMT:
1318 {
1319 struct cpia2_fh *fh = file->private_data;
1320 retval = v4l2_prio_check(&cam->prio, fh->prio);
1321 if (retval)
1322 return retval;
1323 break;
1324 }
1325 default:
1326 break;
1327 }
1328
1329 switch (cmd) {
1330 /* CPIA2 extension to Video4Linux API */
1331 case CPIA2_IOC_SET_GPIO:
1332 retval = ioctl_set_gpio(arg, cam);
1333 break;
1334 case VIDIOC_QUERYCAP:
1335 retval = ioctl_querycap(arg,cam);
1336 break;
1337
1338 case VIDIOC_ENUMINPUT:
1339 case VIDIOC_G_INPUT:
1340 case VIDIOC_S_INPUT:
1341 retval = ioctl_input(cmd, arg, cam);
1342 break;
1343
1344 case VIDIOC_ENUM_FMT:
1345 retval = ioctl_enum_fmt(arg,cam);
1346 break;
1347 case VIDIOC_TRY_FMT:
1348 retval = ioctl_try_fmt(arg,cam);
1349 break;
1350 case VIDIOC_G_FMT:
1351 retval = ioctl_get_fmt(arg,cam);
1352 break;
1353 case VIDIOC_S_FMT:
1354 retval = ioctl_set_fmt(arg,cam,file->private_data);
1355 break;
1356 1308
1357 case VIDIOC_CROPCAP: 1309 *p = fh->prio;
1358 retval = ioctl_cropcap(arg,cam); 1310 return 0;
1359 break; 1311}
1360 case VIDIOC_G_CROP:
1361 case VIDIOC_S_CROP:
1362 // TODO: I think cropping can be implemented - SJB
1363 retval = -EINVAL;
1364 break;
1365
1366 case VIDIOC_QUERYCTRL:
1367 retval = ioctl_queryctrl(arg,cam);
1368 break;
1369 case VIDIOC_QUERYMENU:
1370 retval = ioctl_querymenu(arg,cam);
1371 break;
1372 case VIDIOC_G_CTRL:
1373 retval = ioctl_g_ctrl(arg,cam);
1374 break;
1375 case VIDIOC_S_CTRL:
1376 retval = ioctl_s_ctrl(arg,cam);
1377 break;
1378
1379 case VIDIOC_G_JPEGCOMP:
1380 retval = ioctl_g_jpegcomp(arg,cam);
1381 break;
1382 case VIDIOC_S_JPEGCOMP:
1383 retval = ioctl_s_jpegcomp(arg,cam);
1384 break;
1385
1386 case VIDIOC_G_PRIORITY:
1387 {
1388 struct cpia2_fh *fh = file->private_data;
1389 *(enum v4l2_priority*)arg = fh->prio;
1390 break;
1391 }
1392 case VIDIOC_S_PRIORITY:
1393 {
1394 struct cpia2_fh *fh = file->private_data;
1395 enum v4l2_priority prio;
1396 prio = *(enum v4l2_priority*)arg;
1397 if(cam->streaming &&
1398 prio != fh->prio &&
1399 fh->prio == V4L2_PRIORITY_RECORD) {
1400 /* Can't drop record priority while streaming */
1401 retval = -EBUSY;
1402 } else if(prio == V4L2_PRIORITY_RECORD &&
1403 prio != fh->prio &&
1404 v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) {
1405 /* Only one program can record at a time */
1406 retval = -EBUSY;
1407 } else {
1408 retval = v4l2_prio_change(&cam->prio, &fh->prio, prio);
1409 }
1410 break;
1411 }
1412
1413 case VIDIOC_REQBUFS:
1414 retval = ioctl_reqbufs(arg,cam);
1415 break;
1416 case VIDIOC_QUERYBUF:
1417 retval = ioctl_querybuf(arg,cam);
1418 break;
1419 case VIDIOC_QBUF:
1420 retval = ioctl_qbuf(arg,cam);
1421 break;
1422 case VIDIOC_DQBUF:
1423 retval = ioctl_dqbuf(arg,cam,file);
1424 break;
1425 case VIDIOC_STREAMON:
1426 {
1427 int type;
1428 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1429 type = *(int*)arg;
1430 if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1431 retval = -EINVAL;
1432
1433 if(!cam->streaming) {
1434 retval = cpia2_usb_stream_start(cam,
1435 cam->params.camera_state.stream_mode);
1436 } else {
1437 retval = -EINVAL;
1438 }
1439
1440 break;
1441 }
1442 case VIDIOC_STREAMOFF:
1443 {
1444 int type;
1445 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1446 type = *(int*)arg;
1447 if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1448 retval = -EINVAL;
1449
1450 if(cam->streaming) {
1451 retval = cpia2_usb_stream_stop(cam);
1452 } else {
1453 retval = -EINVAL;
1454 }
1455
1456 break;
1457 }
1458
1459 case VIDIOC_ENUMOUTPUT:
1460 case VIDIOC_G_OUTPUT:
1461 case VIDIOC_S_OUTPUT:
1462 case VIDIOC_G_MODULATOR:
1463 case VIDIOC_S_MODULATOR:
1464
1465 case VIDIOC_ENUMAUDIO:
1466 case VIDIOC_G_AUDIO:
1467 case VIDIOC_S_AUDIO:
1468 1312
1469 case VIDIOC_ENUMAUDOUT: 1313static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio)
1470 case VIDIOC_G_AUDOUT: 1314{
1471 case VIDIOC_S_AUDOUT: 1315 struct camera_data *cam = video_drvdata(file);
1316 struct cpia2_fh *fh = fh;
1472 1317
1473 case VIDIOC_ENUMSTD: 1318 if (cam->streaming && prio != fh->prio &&
1474 case VIDIOC_QUERYSTD: 1319 fh->prio == V4L2_PRIORITY_RECORD)
1475 case VIDIOC_G_STD: 1320 /* Can't drop record priority while streaming */
1476 case VIDIOC_S_STD: 1321 return -EBUSY;
1477 1322
1478 case VIDIOC_G_TUNER: 1323 if (prio == V4L2_PRIORITY_RECORD && prio != fh->prio &&
1479 case VIDIOC_S_TUNER: 1324 v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD)
1480 case VIDIOC_G_FREQUENCY: 1325 /* Only one program can record at a time */
1481 case VIDIOC_S_FREQUENCY: 1326 return -EBUSY;
1327 return v4l2_prio_change(&cam->prio, &fh->prio, prio);
1328}
1482 1329
1483 case VIDIOC_OVERLAY: 1330static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1484 case VIDIOC_G_FBUF: 1331{
1485 case VIDIOC_S_FBUF: 1332 struct camera_data *cam = video_drvdata(file);
1486 1333
1487 case VIDIOC_G_PARM: 1334 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1488 case VIDIOC_S_PARM: 1335 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1489 retval = -EINVAL; 1336 return -EINVAL;
1490 break;
1491 default:
1492 retval = -ENOIOCTLCMD;
1493 break;
1494 }
1495 1337
1496 return retval; 1338 if (!cam->streaming)
1339 return cpia2_usb_stream_start(cam,
1340 cam->params.camera_state.stream_mode);
1341 return -EINVAL;
1497} 1342}
1498 1343
1499static long cpia2_ioctl(struct file *file, 1344static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1500 unsigned int cmd, unsigned long arg)
1501{ 1345{
1502 return video_usercopy(file, cmd, arg, cpia2_do_ioctl); 1346 struct camera_data *cam = video_drvdata(file);
1347
1348 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1349 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1350 return -EINVAL;
1351
1352 if (cam->streaming)
1353 return cpia2_usb_stream_stop(cam);
1354 return -EINVAL;
1503} 1355}
1504 1356
1505/****************************************************************************** 1357/******************************************************************************
@@ -1550,6 +1402,33 @@ static void reset_camera_struct_v4l(struct camera_data *cam)
1550 v4l2_prio_init(&cam->prio); 1402 v4l2_prio_init(&cam->prio);
1551} 1403}
1552 1404
1405static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
1406 .vidioc_querycap = cpia2_querycap,
1407 .vidioc_enum_input = cpia2_enum_input,
1408 .vidioc_g_input = cpia2_g_input,
1409 .vidioc_s_input = cpia2_s_input,
1410 .vidioc_enum_fmt_vid_cap = cpia2_enum_fmt_vid_cap,
1411 .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap,
1412 .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap,
1413 .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap,
1414 .vidioc_queryctrl = cpia2_queryctrl,
1415 .vidioc_querymenu = cpia2_querymenu,
1416 .vidioc_g_ctrl = cpia2_g_ctrl,
1417 .vidioc_s_ctrl = cpia2_s_ctrl,
1418 .vidioc_g_jpegcomp = cpia2_g_jpegcomp,
1419 .vidioc_s_jpegcomp = cpia2_s_jpegcomp,
1420 .vidioc_cropcap = cpia2_cropcap,
1421 .vidioc_reqbufs = cpia2_reqbufs,
1422 .vidioc_querybuf = cpia2_querybuf,
1423 .vidioc_qbuf = cpia2_qbuf,
1424 .vidioc_dqbuf = cpia2_dqbuf,
1425 .vidioc_streamon = cpia2_streamon,
1426 .vidioc_streamoff = cpia2_streamoff,
1427 .vidioc_g_priority = cpia2_g_priority,
1428 .vidioc_s_priority = cpia2_s_priority,
1429 .vidioc_default = cpia2_default,
1430};
1431
1553/*** 1432/***
1554 * The v4l video device structure initialized for this device 1433 * The v4l video device structure initialized for this device
1555 ***/ 1434 ***/
@@ -1559,7 +1438,7 @@ static const struct v4l2_file_operations cpia2_fops = {
1559 .release = cpia2_close, 1438 .release = cpia2_close,
1560 .read = cpia2_v4l_read, 1439 .read = cpia2_v4l_read,
1561 .poll = cpia2_v4l_poll, 1440 .poll = cpia2_v4l_poll,
1562 .unlocked_ioctl = cpia2_ioctl, 1441 .unlocked_ioctl = video_ioctl2,
1563 .mmap = cpia2_mmap, 1442 .mmap = cpia2_mmap,
1564}; 1443};
1565 1444
@@ -1567,6 +1446,7 @@ static struct video_device cpia2_template = {
1567 /* I could not find any place for the old .initialize initializer?? */ 1446 /* I could not find any place for the old .initialize initializer?? */
1568 .name = "CPiA2 Camera", 1447 .name = "CPiA2 Camera",
1569 .fops = &cpia2_fops, 1448 .fops = &cpia2_fops,
1449 .ioctl_ops = &cpia2_ioctl_ops,
1570 .release = video_device_release, 1450 .release = video_device_release,
1571}; 1451};
1572 1452
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 9358fe77e562..5909f2557ab4 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <media/v4l2-device.h> 26#include <media/v4l2-device.h>
27#include <media/v4l2-chip-ident.h> 27#include <media/v4l2-chip-ident.h>
28#include <media/v4l2-ctrls.h>
28 29
29MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC"); 30MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
30MODULE_AUTHOR("Hans Verkuil"); 31MODULE_AUTHOR("Hans Verkuil");
@@ -36,6 +37,20 @@ module_param(debug, bool, 0644);
36 37
37MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On"); 38MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
38 39
40struct cs5345_state {
41 struct v4l2_subdev sd;
42 struct v4l2_ctrl_handler hdl;
43};
44
45static inline struct cs5345_state *to_state(struct v4l2_subdev *sd)
46{
47 return container_of(sd, struct cs5345_state, sd);
48}
49
50static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
51{
52 return &container_of(ctrl->handler, struct cs5345_state, hdl)->sd;
53}
39 54
40/* ----------------------------------------------------------------------- */ 55/* ----------------------------------------------------------------------- */
41 56
@@ -65,33 +80,20 @@ static int cs5345_s_routing(struct v4l2_subdev *sd,
65 return 0; 80 return 0;
66} 81}
67 82
68static int cs5345_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 83static int cs5345_s_ctrl(struct v4l2_ctrl *ctrl)
69{ 84{
70 if (ctrl->id == V4L2_CID_AUDIO_MUTE) { 85 struct v4l2_subdev *sd = to_sd(ctrl);
71 ctrl->value = (cs5345_read(sd, 0x04) & 0x08) != 0;
72 return 0;
73 }
74 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
75 return -EINVAL;
76 ctrl->value = cs5345_read(sd, 0x07) & 0x3f;
77 if (ctrl->value >= 32)
78 ctrl->value = ctrl->value - 64;
79 return 0;
80}
81 86
82static int cs5345_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 87 switch (ctrl->id) {
83{ 88 case V4L2_CID_AUDIO_MUTE:
84 if (ctrl->id == V4L2_CID_AUDIO_MUTE) { 89 cs5345_write(sd, 0x04, ctrl->val ? 0x80 : 0);
85 cs5345_write(sd, 0x04, ctrl->value ? 0x80 : 0); 90 return 0;
91 case V4L2_CID_AUDIO_VOLUME:
92 cs5345_write(sd, 0x07, ((u8)ctrl->val) & 0x3f);
93 cs5345_write(sd, 0x08, ((u8)ctrl->val) & 0x3f);
86 return 0; 94 return 0;
87 } 95 }
88 if (ctrl->id != V4L2_CID_AUDIO_VOLUME) 96 return -EINVAL;
89 return -EINVAL;
90 if (ctrl->value > 24 || ctrl->value < -24)
91 return -EINVAL;
92 cs5345_write(sd, 0x07, ((u8)ctrl->value) & 0x3f);
93 cs5345_write(sd, 0x08, ((u8)ctrl->value) & 0x3f);
94 return 0;
95} 97}
96 98
97#ifdef CONFIG_VIDEO_ADV_DEBUG 99#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -144,11 +146,20 @@ static int cs5345_log_status(struct v4l2_subdev *sd)
144 146
145/* ----------------------------------------------------------------------- */ 147/* ----------------------------------------------------------------------- */
146 148
149static const struct v4l2_ctrl_ops cs5345_ctrl_ops = {
150 .s_ctrl = cs5345_s_ctrl,
151};
152
147static const struct v4l2_subdev_core_ops cs5345_core_ops = { 153static const struct v4l2_subdev_core_ops cs5345_core_ops = {
148 .log_status = cs5345_log_status, 154 .log_status = cs5345_log_status,
149 .g_chip_ident = cs5345_g_chip_ident, 155 .g_chip_ident = cs5345_g_chip_ident,
150 .g_ctrl = cs5345_g_ctrl, 156 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
151 .s_ctrl = cs5345_s_ctrl, 157 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
158 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
159 .g_ctrl = v4l2_subdev_g_ctrl,
160 .s_ctrl = v4l2_subdev_s_ctrl,
161 .queryctrl = v4l2_subdev_queryctrl,
162 .querymenu = v4l2_subdev_querymenu,
152#ifdef CONFIG_VIDEO_ADV_DEBUG 163#ifdef CONFIG_VIDEO_ADV_DEBUG
153 .g_register = cs5345_g_register, 164 .g_register = cs5345_g_register,
154 .s_register = cs5345_s_register, 165 .s_register = cs5345_s_register,
@@ -169,6 +180,7 @@ static const struct v4l2_subdev_ops cs5345_ops = {
169static int cs5345_probe(struct i2c_client *client, 180static int cs5345_probe(struct i2c_client *client,
170 const struct i2c_device_id *id) 181 const struct i2c_device_id *id)
171{ 182{
183 struct cs5345_state *state;
172 struct v4l2_subdev *sd; 184 struct v4l2_subdev *sd;
173 185
174 /* Check if the adapter supports the needed features */ 186 /* Check if the adapter supports the needed features */
@@ -178,11 +190,28 @@ static int cs5345_probe(struct i2c_client *client,
178 v4l_info(client, "chip found @ 0x%x (%s)\n", 190 v4l_info(client, "chip found @ 0x%x (%s)\n",
179 client->addr << 1, client->adapter->name); 191 client->addr << 1, client->adapter->name);
180 192
181 sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); 193 state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
182 if (sd == NULL) 194 if (state == NULL)
183 return -ENOMEM; 195 return -ENOMEM;
196 sd = &state->sd;
184 v4l2_i2c_subdev_init(sd, client, &cs5345_ops); 197 v4l2_i2c_subdev_init(sd, client, &cs5345_ops);
185 198
199 v4l2_ctrl_handler_init(&state->hdl, 2);
200 v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
201 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
202 v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
203 V4L2_CID_AUDIO_VOLUME, -24, 24, 1, 0);
204 sd->ctrl_handler = &state->hdl;
205 if (state->hdl.error) {
206 int err = state->hdl.error;
207
208 v4l2_ctrl_handler_free(&state->hdl);
209 kfree(state);
210 return err;
211 }
212 /* set volume/mute */
213 v4l2_ctrl_handler_setup(&state->hdl);
214
186 cs5345_write(sd, 0x02, 0x00); 215 cs5345_write(sd, 0x02, 0x00);
187 cs5345_write(sd, 0x04, 0x01); 216 cs5345_write(sd, 0x04, 0x01);
188 cs5345_write(sd, 0x09, 0x01); 217 cs5345_write(sd, 0x09, 0x01);
@@ -194,9 +223,11 @@ static int cs5345_probe(struct i2c_client *client,
194static int cs5345_remove(struct i2c_client *client) 223static int cs5345_remove(struct i2c_client *client)
195{ 224{
196 struct v4l2_subdev *sd = i2c_get_clientdata(client); 225 struct v4l2_subdev *sd = i2c_get_clientdata(client);
226 struct cs5345_state *state = to_state(sd);
197 227
198 v4l2_device_unregister_subdev(sd); 228 v4l2_device_unregister_subdev(sd);
199 kfree(sd); 229 v4l2_ctrl_handler_free(&state->hdl);
230 kfree(state);
200 return 0; 231 return 0;
201} 232}
202 233
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index 43d09a24b262..4a24ffb17a7d 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -342,17 +342,6 @@ void cx18_av_audio_set_path(struct cx18 *cx)
342 } 342 }
343} 343}
344 344
345static int get_volume(struct cx18 *cx)
346{
347 /* Volume runs +18dB to -96dB in 1/2dB steps
348 * change to fit the msp3400 -114dB to +12dB range */
349
350 /* check PATH1_VOLUME */
351 int vol = 228 - cx18_av_read(cx, 0x8d4);
352 vol = (vol / 2) + 23;
353 return vol << 9;
354}
355
356static void set_volume(struct cx18 *cx, int volume) 345static void set_volume(struct cx18 *cx, int volume)
357{ 346{
358 /* First convert the volume to msp3400 values (0-127) */ 347 /* First convert the volume to msp3400 values (0-127) */
@@ -369,52 +358,18 @@ static void set_volume(struct cx18 *cx, int volume)
369 cx18_av_write(cx, 0x8d4, 228 - (vol * 2)); 358 cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
370} 359}
371 360
372static int get_bass(struct cx18 *cx)
373{
374 /* bass is 49 steps +12dB to -12dB */
375
376 /* check PATH1_EQ_BASS_VOL */
377 int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
378 bass = (((48 - bass) * 0xffff) + 47) / 48;
379 return bass;
380}
381
382static void set_bass(struct cx18 *cx, int bass) 361static void set_bass(struct cx18 *cx, int bass)
383{ 362{
384 /* PATH1_EQ_BASS_VOL */ 363 /* PATH1_EQ_BASS_VOL */
385 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); 364 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
386} 365}
387 366
388static int get_treble(struct cx18 *cx)
389{
390 /* treble is 49 steps +12dB to -12dB */
391
392 /* check PATH1_EQ_TREBLE_VOL */
393 int treble = cx18_av_read(cx, 0x8db) & 0x3f;
394 treble = (((48 - treble) * 0xffff) + 47) / 48;
395 return treble;
396}
397
398static void set_treble(struct cx18 *cx, int treble) 367static void set_treble(struct cx18 *cx, int treble)
399{ 368{
400 /* PATH1_EQ_TREBLE_VOL */ 369 /* PATH1_EQ_TREBLE_VOL */
401 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); 370 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
402} 371}
403 372
404static int get_balance(struct cx18 *cx)
405{
406 /* balance is 7 bit, 0 to -96dB */
407
408 /* check PATH1_BAL_LEVEL */
409 int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
410 /* check PATH1_BAL_LEFT */
411 if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
412 balance = 0x80 - balance;
413 else
414 balance = 0x80 + balance;
415 return balance << 8;
416}
417
418static void set_balance(struct cx18 *cx, int balance) 373static void set_balance(struct cx18 *cx, int balance)
419{ 374{
420 int bal = balance >> 8; 375 int bal = balance >> 8;
@@ -431,12 +386,6 @@ static void set_balance(struct cx18 *cx, int balance)
431 } 386 }
432} 387}
433 388
434static int get_mute(struct cx18 *cx)
435{
436 /* check SRC1_MUTE_EN */
437 return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
438}
439
440static void set_mute(struct cx18 *cx, int mute) 389static void set_mute(struct cx18 *cx, int mute)
441{ 390{
442 struct cx18_av_state *state = &cx->av_state; 391 struct cx18_av_state *state = &cx->av_state;
@@ -490,50 +439,33 @@ int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
490 return retval; 439 return retval;
491} 440}
492 441
493int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl) 442static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
494{ 443{
495 switch (ctrl->id) { 444 struct v4l2_subdev *sd = to_sd(ctrl);
496 case V4L2_CID_AUDIO_VOLUME: 445 struct cx18 *cx = v4l2_get_subdevdata(sd);
497 ctrl->value = get_volume(cx);
498 break;
499 case V4L2_CID_AUDIO_BASS:
500 ctrl->value = get_bass(cx);
501 break;
502 case V4L2_CID_AUDIO_TREBLE:
503 ctrl->value = get_treble(cx);
504 break;
505 case V4L2_CID_AUDIO_BALANCE:
506 ctrl->value = get_balance(cx);
507 break;
508 case V4L2_CID_AUDIO_MUTE:
509 ctrl->value = get_mute(cx);
510 break;
511 default:
512 return -EINVAL;
513 }
514 return 0;
515}
516 446
517int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
518{
519 switch (ctrl->id) { 447 switch (ctrl->id) {
520 case V4L2_CID_AUDIO_VOLUME: 448 case V4L2_CID_AUDIO_VOLUME:
521 set_volume(cx, ctrl->value); 449 set_volume(cx, ctrl->val);
522 break; 450 break;
523 case V4L2_CID_AUDIO_BASS: 451 case V4L2_CID_AUDIO_BASS:
524 set_bass(cx, ctrl->value); 452 set_bass(cx, ctrl->val);
525 break; 453 break;
526 case V4L2_CID_AUDIO_TREBLE: 454 case V4L2_CID_AUDIO_TREBLE:
527 set_treble(cx, ctrl->value); 455 set_treble(cx, ctrl->val);
528 break; 456 break;
529 case V4L2_CID_AUDIO_BALANCE: 457 case V4L2_CID_AUDIO_BALANCE:
530 set_balance(cx, ctrl->value); 458 set_balance(cx, ctrl->val);
531 break; 459 break;
532 case V4L2_CID_AUDIO_MUTE: 460 case V4L2_CID_AUDIO_MUTE:
533 set_mute(cx, ctrl->value); 461 set_mute(cx, ctrl->val);
534 break; 462 break;
535 default: 463 default:
536 return -EINVAL; 464 return -EINVAL;
537 } 465 }
538 return 0; 466 return 0;
539} 467}
468
469const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
470 .s_ctrl = cx18_av_audio_s_ctrl,
471};
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index a41951cab276..f164b7f610a5 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -129,6 +129,7 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
129{ 129{
130 struct cx18_av_state *state = to_cx18_av_state(sd); 130 struct cx18_av_state *state = to_cx18_av_state(sd);
131 struct cx18 *cx = v4l2_get_subdevdata(sd); 131 struct cx18 *cx = v4l2_get_subdevdata(sd);
132 int default_volume;
132 u32 v; 133 u32 v;
133 134
134 cx18_av_loadfw(cx); 135 cx18_av_loadfw(cx);
@@ -247,8 +248,23 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
247/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */ 248/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
248/* } */ 249/* } */
249 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F); 250 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
250 state->default_volume = 228 - cx18_av_read(cx, 0x8d4); 251 default_volume = cx18_av_read(cx, 0x8d4);
251 state->default_volume = ((state->default_volume / 2) + 23) << 9; 252 /*
253 * Enforce the legacy volume scale mapping limits to avoid
254 * -ERANGE errors when initializing the volume control
255 */
256 if (default_volume > 228) {
257 /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
258 default_volume = 228;
259 cx18_av_write(cx, 0x8d4, 228);
260 } else if (default_volume < 20) {
261 /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
262 default_volume = 20;
263 cx18_av_write(cx, 0x8d4, 20);
264 }
265 default_volume = (((228 - default_volume) >> 1) + 23) << 9;
266 state->volume->cur.val = state->volume->default_value = default_volume;
267 v4l2_ctrl_handler_setup(&state->hdl);
252} 268}
253 269
254static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) 270static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
@@ -901,126 +917,35 @@ static int cx18_av_s_radio(struct v4l2_subdev *sd)
901 return 0; 917 return 0;
902} 918}
903 919
904static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 920static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl)
905{ 921{
922 struct v4l2_subdev *sd = to_sd(ctrl);
906 struct cx18 *cx = v4l2_get_subdevdata(sd); 923 struct cx18 *cx = v4l2_get_subdevdata(sd);
907 924
908 switch (ctrl->id) { 925 switch (ctrl->id) {
909 case V4L2_CID_BRIGHTNESS: 926 case V4L2_CID_BRIGHTNESS:
910 if (ctrl->value < 0 || ctrl->value > 255) { 927 cx18_av_write(cx, 0x414, ctrl->val - 128);
911 CX18_ERR_DEV(sd, "invalid brightness setting %d\n",
912 ctrl->value);
913 return -ERANGE;
914 }
915
916 cx18_av_write(cx, 0x414, ctrl->value - 128);
917 break; 928 break;
918 929
919 case V4L2_CID_CONTRAST: 930 case V4L2_CID_CONTRAST:
920 if (ctrl->value < 0 || ctrl->value > 127) { 931 cx18_av_write(cx, 0x415, ctrl->val << 1);
921 CX18_ERR_DEV(sd, "invalid contrast setting %d\n",
922 ctrl->value);
923 return -ERANGE;
924 }
925
926 cx18_av_write(cx, 0x415, ctrl->value << 1);
927 break; 932 break;
928 933
929 case V4L2_CID_SATURATION: 934 case V4L2_CID_SATURATION:
930 if (ctrl->value < 0 || ctrl->value > 127) { 935 cx18_av_write(cx, 0x420, ctrl->val << 1);
931 CX18_ERR_DEV(sd, "invalid saturation setting %d\n", 936 cx18_av_write(cx, 0x421, ctrl->val << 1);
932 ctrl->value);
933 return -ERANGE;
934 }
935
936 cx18_av_write(cx, 0x420, ctrl->value << 1);
937 cx18_av_write(cx, 0x421, ctrl->value << 1);
938 break; 937 break;
939 938
940 case V4L2_CID_HUE: 939 case V4L2_CID_HUE:
941 if (ctrl->value < -128 || ctrl->value > 127) { 940 cx18_av_write(cx, 0x422, ctrl->val);
942 CX18_ERR_DEV(sd, "invalid hue setting %d\n",
943 ctrl->value);
944 return -ERANGE;
945 }
946
947 cx18_av_write(cx, 0x422, ctrl->value);
948 break; 941 break;
949 942
950 case V4L2_CID_AUDIO_VOLUME:
951 case V4L2_CID_AUDIO_BASS:
952 case V4L2_CID_AUDIO_TREBLE:
953 case V4L2_CID_AUDIO_BALANCE:
954 case V4L2_CID_AUDIO_MUTE:
955 return cx18_av_audio_s_ctrl(cx, ctrl);
956
957 default:
958 return -EINVAL;
959 }
960 return 0;
961}
962
963static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
964{
965 struct cx18 *cx = v4l2_get_subdevdata(sd);
966
967 switch (ctrl->id) {
968 case V4L2_CID_BRIGHTNESS:
969 ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
970 break;
971 case V4L2_CID_CONTRAST:
972 ctrl->value = cx18_av_read(cx, 0x415) >> 1;
973 break;
974 case V4L2_CID_SATURATION:
975 ctrl->value = cx18_av_read(cx, 0x420) >> 1;
976 break;
977 case V4L2_CID_HUE:
978 ctrl->value = (s8)cx18_av_read(cx, 0x422);
979 break;
980 case V4L2_CID_AUDIO_VOLUME:
981 case V4L2_CID_AUDIO_BASS:
982 case V4L2_CID_AUDIO_TREBLE:
983 case V4L2_CID_AUDIO_BALANCE:
984 case V4L2_CID_AUDIO_MUTE:
985 return cx18_av_audio_g_ctrl(cx, ctrl);
986 default: 943 default:
987 return -EINVAL; 944 return -EINVAL;
988 } 945 }
989 return 0; 946 return 0;
990} 947}
991 948
992static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
993{
994 struct cx18_av_state *state = to_cx18_av_state(sd);
995
996 switch (qc->id) {
997 case V4L2_CID_BRIGHTNESS:
998 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
999 case V4L2_CID_CONTRAST:
1000 case V4L2_CID_SATURATION:
1001 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
1002 case V4L2_CID_HUE:
1003 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
1004 default:
1005 break;
1006 }
1007
1008 switch (qc->id) {
1009 case V4L2_CID_AUDIO_VOLUME:
1010 return v4l2_ctrl_query_fill(qc, 0, 65535,
1011 65535 / 100, state->default_volume);
1012 case V4L2_CID_AUDIO_MUTE:
1013 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
1014 case V4L2_CID_AUDIO_BALANCE:
1015 case V4L2_CID_AUDIO_BASS:
1016 case V4L2_CID_AUDIO_TREBLE:
1017 return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
1018 default:
1019 return -EINVAL;
1020 }
1021 return -EINVAL;
1022}
1023
1024static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) 949static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
1025{ 950{
1026 struct cx18_av_state *state = to_cx18_av_state(sd); 951 struct cx18_av_state *state = to_cx18_av_state(sd);
@@ -1356,14 +1281,22 @@ static int cx18_av_s_register(struct v4l2_subdev *sd,
1356} 1281}
1357#endif 1282#endif
1358 1283
1284static const struct v4l2_ctrl_ops cx18_av_ctrl_ops = {
1285 .s_ctrl = cx18_av_s_ctrl,
1286};
1287
1359static const struct v4l2_subdev_core_ops cx18_av_general_ops = { 1288static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
1360 .g_chip_ident = cx18_av_g_chip_ident, 1289 .g_chip_ident = cx18_av_g_chip_ident,
1361 .log_status = cx18_av_log_status, 1290 .log_status = cx18_av_log_status,
1362 .load_fw = cx18_av_load_fw, 1291 .load_fw = cx18_av_load_fw,
1363 .reset = cx18_av_reset, 1292 .reset = cx18_av_reset,
1364 .queryctrl = cx18_av_queryctrl, 1293 .g_ctrl = v4l2_subdev_g_ctrl,
1365 .g_ctrl = cx18_av_g_ctrl, 1294 .s_ctrl = v4l2_subdev_s_ctrl,
1366 .s_ctrl = cx18_av_s_ctrl, 1295 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
1296 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1297 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1298 .queryctrl = v4l2_subdev_queryctrl,
1299 .querymenu = v4l2_subdev_querymenu,
1367 .s_std = cx18_av_s_std, 1300 .s_std = cx18_av_s_std,
1368#ifdef CONFIG_VIDEO_ADV_DEBUG 1301#ifdef CONFIG_VIDEO_ADV_DEBUG
1369 .g_register = cx18_av_g_register, 1302 .g_register = cx18_av_g_register,
@@ -1427,8 +1360,42 @@ int cx18_av_probe(struct cx18 *cx)
1427 snprintf(sd->name, sizeof(sd->name), 1360 snprintf(sd->name, sizeof(sd->name),
1428 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4)); 1361 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
1429 sd->grp_id = CX18_HW_418_AV; 1362 sd->grp_id = CX18_HW_418_AV;
1363 v4l2_ctrl_handler_init(&state->hdl, 9);
1364 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1365 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1366 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1367 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1368 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1369 V4L2_CID_SATURATION, 0, 127, 1, 64);
1370 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1371 V4L2_CID_HUE, -128, 127, 1, 0);
1372
1373 state->volume = v4l2_ctrl_new_std(&state->hdl,
1374 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
1375 0, 65535, 65535 / 100, 0);
1376 v4l2_ctrl_new_std(&state->hdl,
1377 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
1378 0, 1, 1, 0);
1379 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1380 V4L2_CID_AUDIO_BALANCE,
1381 0, 65535, 65535 / 100, 32768);
1382 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1383 V4L2_CID_AUDIO_BASS,
1384 0, 65535, 65535 / 100, 32768);
1385 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1386 V4L2_CID_AUDIO_TREBLE,
1387 0, 65535, 65535 / 100, 32768);
1388 sd->ctrl_handler = &state->hdl;
1389 if (state->hdl.error) {
1390 int err = state->hdl.error;
1391
1392 v4l2_ctrl_handler_free(&state->hdl);
1393 return err;
1394 }
1430 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd); 1395 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
1431 if (!err) 1396 if (err)
1397 v4l2_ctrl_handler_free(&state->hdl);
1398 else
1432 cx18_av_init(cx); 1399 cx18_av_init(cx);
1433 return err; 1400 return err;
1434} 1401}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index 1956991795e3..188c9c3d2db1 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -26,6 +26,7 @@
26#define _CX18_AV_CORE_H_ 26#define _CX18_AV_CORE_H_
27 27
28#include <media/v4l2-device.h> 28#include <media/v4l2-device.h>
29#include <media/v4l2-ctrls.h>
29 30
30struct cx18; 31struct cx18;
31 32
@@ -95,13 +96,14 @@ enum cx18_av_audio_input {
95 96
96struct cx18_av_state { 97struct cx18_av_state {
97 struct v4l2_subdev sd; 98 struct v4l2_subdev sd;
99 struct v4l2_ctrl_handler hdl;
100 struct v4l2_ctrl *volume;
98 int radio; 101 int radio;
99 v4l2_std_id std; 102 v4l2_std_id std;
100 enum cx18_av_video_input vid_input; 103 enum cx18_av_video_input vid_input;
101 enum cx18_av_audio_input aud_input; 104 enum cx18_av_audio_input aud_input;
102 u32 audclk_freq; 105 u32 audclk_freq;
103 int audmode; 106 int audmode;
104 int default_volume;
105 u32 id; 107 u32 id;
106 u32 rev; 108 u32 rev;
107 int is_initialized; 109 int is_initialized;
@@ -347,6 +349,11 @@ static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
347 return container_of(sd, struct cx18_av_state, sd); 349 return container_of(sd, struct cx18_av_state, sd);
348} 350}
349 351
352static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
353{
354 return &container_of(ctrl->handler, struct cx18_av_state, hdl)->sd;
355}
356
350/* ----------------------------------------------------------------------- */ 357/* ----------------------------------------------------------------------- */
351/* cx18_av-core.c */ 358/* cx18_av-core.c */
352int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); 359int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
@@ -369,10 +376,9 @@ int cx18_av_loadfw(struct cx18 *cx);
369 376
370/* ----------------------------------------------------------------------- */ 377/* ----------------------------------------------------------------------- */
371/* cx18_av-audio.c */ 378/* cx18_av-audio.c */
372int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
373int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
374int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq); 379int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
375void cx18_av_audio_set_path(struct cx18 *cx); 380void cx18_av_audio_set_path(struct cx18 *cx);
381extern const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops;
376 382
377/* ----------------------------------------------------------------------- */ 383/* ----------------------------------------------------------------------- */
378/* cx18_av-vbi.c */ 384/* cx18_av-vbi.c */
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 97d7b7e100a3..282a3d29fdaa 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -30,152 +30,11 @@
30#include "cx18-mailbox.h" 30#include "cx18-mailbox.h"
31#include "cx18-controls.h" 31#include "cx18-controls.h"
32 32
33/* Must be sorted from low to high control ID! */ 33static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
34static const u32 user_ctrls[] = {
35 V4L2_CID_USER_CLASS,
36 V4L2_CID_BRIGHTNESS,
37 V4L2_CID_CONTRAST,
38 V4L2_CID_SATURATION,
39 V4L2_CID_HUE,
40 V4L2_CID_AUDIO_VOLUME,
41 V4L2_CID_AUDIO_BALANCE,
42 V4L2_CID_AUDIO_BASS,
43 V4L2_CID_AUDIO_TREBLE,
44 V4L2_CID_AUDIO_MUTE,
45 V4L2_CID_AUDIO_LOUDNESS,
46 0
47};
48
49static const u32 *ctrl_classes[] = {
50 user_ctrls,
51 cx2341x_mpeg_ctrls,
52 NULL
53};
54
55int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
56{
57 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
58 const char *name;
59
60 qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
61 if (qctrl->id == 0)
62 return -EINVAL;
63
64 switch (qctrl->id) {
65 /* Standard V4L2 controls */
66 case V4L2_CID_USER_CLASS:
67 return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
68 case V4L2_CID_BRIGHTNESS:
69 case V4L2_CID_HUE:
70 case V4L2_CID_SATURATION:
71 case V4L2_CID_CONTRAST:
72 if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
73 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
74 return 0;
75
76 case V4L2_CID_AUDIO_VOLUME:
77 case V4L2_CID_AUDIO_MUTE:
78 case V4L2_CID_AUDIO_BALANCE:
79 case V4L2_CID_AUDIO_BASS:
80 case V4L2_CID_AUDIO_TREBLE:
81 case V4L2_CID_AUDIO_LOUDNESS:
82 if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
83 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
84 return 0;
85
86 default:
87 if (cx2341x_ctrl_query(&cx->params, qctrl))
88 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
89 return 0;
90 }
91 strncpy(qctrl->name, name, sizeof(qctrl->name) - 1);
92 qctrl->name[sizeof(qctrl->name) - 1] = 0;
93 return 0;
94}
95
96int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
97{ 34{
98 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 35 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
99 struct v4l2_queryctrl qctrl; 36 int type = cxhdl->stream_type->val;
100
101 qctrl.id = qmenu->id;
102 cx18_queryctrl(file, fh, &qctrl);
103 return v4l2_ctrl_query_menu(qmenu, &qctrl,
104 cx2341x_ctrl_get_menu(&cx->params, qmenu->id));
105}
106
107static int cx18_try_ctrl(struct file *file, void *fh,
108 struct v4l2_ext_control *vctrl)
109{
110 struct v4l2_queryctrl qctrl;
111 const char * const *menu_items = NULL;
112 int err;
113
114 qctrl.id = vctrl->id;
115 err = cx18_queryctrl(file, fh, &qctrl);
116 if (err)
117 return err;
118 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
119 menu_items = v4l2_ctrl_get_menu(qctrl.id);
120 return v4l2_ctrl_check(vctrl, &qctrl, menu_items);
121}
122
123static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
124{
125 switch (vctrl->id) {
126 /* Standard V4L2 controls */
127 case V4L2_CID_BRIGHTNESS:
128 case V4L2_CID_HUE:
129 case V4L2_CID_SATURATION:
130 case V4L2_CID_CONTRAST:
131 return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
132
133 case V4L2_CID_AUDIO_VOLUME:
134 case V4L2_CID_AUDIO_MUTE:
135 case V4L2_CID_AUDIO_BALANCE:
136 case V4L2_CID_AUDIO_BASS:
137 case V4L2_CID_AUDIO_TREBLE:
138 case V4L2_CID_AUDIO_LOUDNESS:
139 return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
140
141 default:
142 CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
143 return -EINVAL;
144 }
145 return 0;
146}
147
148static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
149{
150 switch (vctrl->id) {
151 /* Standard V4L2 controls */
152 case V4L2_CID_BRIGHTNESS:
153 case V4L2_CID_HUE:
154 case V4L2_CID_SATURATION:
155 case V4L2_CID_CONTRAST:
156 return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
157
158 case V4L2_CID_AUDIO_VOLUME:
159 case V4L2_CID_AUDIO_MUTE:
160 case V4L2_CID_AUDIO_BALANCE:
161 case V4L2_CID_AUDIO_BASS:
162 case V4L2_CID_AUDIO_TREBLE:
163 case V4L2_CID_AUDIO_LOUDNESS:
164 return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
165 37
166 default:
167 CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
168 return -EINVAL;
169 }
170 return 0;
171}
172
173static int cx18_setup_vbi_fmt(struct cx18 *cx,
174 enum v4l2_mpeg_stream_vbi_fmt fmt,
175 enum v4l2_mpeg_stream_type type)
176{
177 if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
178 return -EINVAL;
179 if (atomic_read(&cx->ana_capturing) > 0) 38 if (atomic_read(&cx->ana_capturing) > 0)
180 return -EBUSY; 39 return -EBUSY;
181 40
@@ -230,121 +89,43 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx,
230 return 0; 89 return 0;
231} 90}
232 91
233int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) 92static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
234{ 93{
235 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 94 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
236 struct v4l2_control ctrl; 95 int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
237 96 struct v4l2_mbus_framefmt fmt;
238 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { 97
239 int i; 98 /* fix videodecoder resolution */
240 int err = 0; 99 fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
241 100 fmt.height = cxhdl->height;
242 for (i = 0; i < c->count; i++) { 101 fmt.code = V4L2_MBUS_FMT_FIXED;
243 ctrl.id = c->controls[i].id; 102 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
244 ctrl.value = c->controls[i].value; 103 return 0;
245 err = cx18_g_ctrl(cx, &ctrl);
246 c->controls[i].value = ctrl.value;
247 if (err) {
248 c->error_idx = i;
249 break;
250 }
251 }
252 return err;
253 }
254 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
255 return cx2341x_ext_ctrls(&cx->params, 0, c, VIDIOC_G_EXT_CTRLS);
256 return -EINVAL;
257} 104}
258 105
259int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) 106static int cx18_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
260{ 107{
261 struct cx18_open_id *id = fh; 108 static const u32 freqs[3] = { 44100, 48000, 32000 };
262 struct cx18 *cx = id->cx; 109 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
263 int ret;
264 struct v4l2_control ctrl;
265
266 ret = v4l2_prio_check(&cx->prio, id->prio);
267 if (ret)
268 return ret;
269
270 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
271 int i;
272 int err = 0;
273
274 for (i = 0; i < c->count; i++) {
275 ctrl.id = c->controls[i].id;
276 ctrl.value = c->controls[i].value;
277 err = cx18_s_ctrl(cx, &ctrl);
278 c->controls[i].value = ctrl.value;
279 if (err) {
280 c->error_idx = i;
281 break;
282 }
283 }
284 return err;
285 }
286 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
287 static u32 freqs[3] = { 44100, 48000, 32000 };
288 struct cx18_api_func_private priv;
289 struct cx2341x_mpeg_params p = cx->params;
290 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
291 c, VIDIOC_S_EXT_CTRLS);
292 unsigned int idx;
293
294 if (err)
295 return err;
296 110
297 if (p.video_encoding != cx->params.video_encoding) { 111 /* The audio clock of the digitizer must match the codec sample
298 int is_mpeg1 = p.video_encoding == 112 rate otherwise you get some very strange effects. */
299 V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 113 if (idx < ARRAY_SIZE(freqs))
300 struct v4l2_mbus_framefmt fmt; 114 cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
301 115 return 0;
302 /* fix videodecoder resolution */
303 fmt.width = cx->params.width / (is_mpeg1 ? 2 : 1);
304 fmt.height = cx->params.height;
305 fmt.code = V4L2_MBUS_FMT_FIXED;
306 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
307 }
308 priv.cx = cx;
309 priv.s = &cx->streams[id->type];
310 err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p);
311 if (!err &&
312 (cx->params.stream_vbi_fmt != p.stream_vbi_fmt ||
313 cx->params.stream_type != p.stream_type))
314 err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt,
315 p.stream_type);
316 cx->params = p;
317 cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
318 idx = p.audio_properties & 0x03;
319 /* The audio clock of the digitizer must match the codec sample
320 rate otherwise you get some very strange effects. */
321 if (idx < ARRAY_SIZE(freqs))
322 cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
323 return err;
324 }
325 return -EINVAL;
326} 116}
327 117
328int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) 118static int cx18_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
329{ 119{
330 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 120 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
331 121
332 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { 122 cx->dualwatch_stereo_mode = val;
333 int i; 123 return 0;
334 int err = 0;
335
336 for (i = 0; i < c->count; i++) {
337 err = cx18_try_ctrl(file, fh, &c->controls[i]);
338 if (err) {
339 c->error_idx = i;
340 break;
341 }
342 }
343 return err;
344 }
345 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
346 return cx2341x_ext_ctrls(&cx->params,
347 atomic_read(&cx->ana_capturing),
348 c, VIDIOC_TRY_EXT_CTRLS);
349 return -EINVAL;
350} 124}
125
126struct cx2341x_handler_ops cx18_cxhdl_ops = {
127 .s_audio_mode = cx18_s_audio_mode,
128 .s_audio_sampling_freq = cx18_s_audio_sampling_freq,
129 .s_video_encoding = cx18_s_video_encoding,
130 .s_stream_vbi_fmt = cx18_s_stream_vbi_fmt,
131};
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
index e46323700b81..cb5dfc7b2054 100644
--- a/drivers/media/video/cx18/cx18-controls.h
+++ b/drivers/media/video/cx18/cx18-controls.h
@@ -21,9 +21,4 @@
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); 24extern struct cx2341x_handler_ops cx18_cxhdl_ops;
25int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
26int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
27int cx18_try_ext_ctrls(struct file *file, void *fh,
28 struct v4l2_ext_controls *a);
29int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index b1c3cbd92743..321c1b79794c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -36,6 +36,7 @@
36#include "cx18-scb.h" 36#include "cx18-scb.h"
37#include "cx18-mailbox.h" 37#include "cx18-mailbox.h"
38#include "cx18-ioctl.h" 38#include "cx18-ioctl.h"
39#include "cx18-controls.h"
39#include "tuner-xc2028.h" 40#include "tuner-xc2028.h"
40 41
41#include <media/tveeprom.h> 42#include <media/tveeprom.h>
@@ -729,15 +730,22 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
729 cx->open_id = 1; 730 cx->open_id = 1;
730 731
731 /* Initial settings */ 732 /* Initial settings */
732 cx2341x_fill_defaults(&cx->params); 733 cx->cxhdl.port = CX2341X_PORT_MEMORY;
733 cx->temporal_strength = cx->params.video_temporal_filter; 734 cx->cxhdl.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
734 cx->spatial_strength = cx->params.video_spatial_filter; 735 cx->cxhdl.ops = &cx18_cxhdl_ops;
735 cx->filter_mode = cx->params.video_spatial_filter_mode | 736 cx->cxhdl.func = cx18_api_func;
736 (cx->params.video_temporal_filter_mode << 1) | 737 cx->cxhdl.priv = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
737 (cx->params.video_median_filter_type << 2); 738 ret = cx2341x_handler_init(&cx->cxhdl, 50);
738 cx->params.port = CX2341X_PORT_MEMORY; 739 if (ret)
739 cx->params.capabilities = 740 return ret;
740 CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI; 741 cx->v4l2_dev.ctrl_handler = &cx->cxhdl.hdl;
742
743 cx->temporal_strength = cx->cxhdl.video_temporal_filter->cur.val;
744 cx->spatial_strength = cx->cxhdl.video_spatial_filter->cur.val;
745 cx->filter_mode = cx->cxhdl.video_spatial_filter_mode->cur.val |
746 (cx->cxhdl.video_temporal_filter_mode->cur.val << 1) |
747 (cx->cxhdl.video_median_filter_type->cur.val << 2);
748
741 init_waitqueue_head(&cx->cap_w); 749 init_waitqueue_head(&cx->cap_w);
742 init_waitqueue_head(&cx->mb_apu_waitq); 750 init_waitqueue_head(&cx->mb_apu_waitq);
743 init_waitqueue_head(&cx->mb_cpu_waitq); 751 init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -1049,7 +1057,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1049 else 1057 else
1050 cx->is_50hz = 1; 1058 cx->is_50hz = 1;
1051 1059
1052 cx->params.video_gop_size = cx->is_60hz ? 15 : 12; 1060 cx2341x_handler_set_50hz(&cx->cxhdl, !cx->is_60hz);
1053 1061
1054 if (cx->options.radio > 0) 1062 if (cx->options.radio > 0)
1055 cx->v4l2_cap |= V4L2_CAP_RADIO; 1063 cx->v4l2_cap |= V4L2_CAP_RADIO;
@@ -1095,7 +1103,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1095 1103
1096 /* Load cx18 submodules (cx18-alsa) */ 1104 /* Load cx18 submodules (cx18-alsa) */
1097 request_modules(cx); 1105 request_modules(cx);
1098
1099 return 0; 1106 return 0;
1100 1107
1101free_streams: 1108free_streams:
@@ -1278,6 +1285,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
1278 for (i = 0; i < CX18_VBI_FRAMES; i++) 1285 for (i = 0; i < CX18_VBI_FRAMES; i++)
1279 kfree(cx->vbi.sliced_mpeg_data[i]); 1286 kfree(cx->vbi.sliced_mpeg_data[i]);
1280 1287
1288 v4l2_ctrl_handler_free(&cx->av_state.hdl);
1289
1281 CX18_INFO("Removed %s\n", cx->card_name); 1290 CX18_INFO("Removed %s\n", cx->card_name);
1282 1291
1283 v4l2_device_unregister(v4l2_dev); 1292 v4l2_device_unregister(v4l2_dev);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index f736679d2517..b86a740c68df 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -50,6 +50,7 @@
50#include <media/v4l2-common.h> 50#include <media/v4l2-common.h>
51#include <media/v4l2-ioctl.h> 51#include <media/v4l2-ioctl.h>
52#include <media/v4l2-device.h> 52#include <media/v4l2-device.h>
53#include <media/v4l2-fh.h>
53#include <media/tuner.h> 54#include <media/tuner.h>
54#include <media/ir-kbd-i2c.h> 55#include <media/ir-kbd-i2c.h>
55#include "cx18-mailbox.h" 56#include "cx18-mailbox.h"
@@ -405,12 +406,22 @@ struct cx18_stream {
405}; 406};
406 407
407struct cx18_open_id { 408struct cx18_open_id {
409 struct v4l2_fh fh;
408 u32 open_id; 410 u32 open_id;
409 int type; 411 int type;
410 enum v4l2_priority prio;
411 struct cx18 *cx; 412 struct cx18 *cx;
412}; 413};
413 414
415static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
416{
417 return container_of(fh, struct cx18_open_id, fh);
418}
419
420static inline struct cx18_open_id *file2id(struct file *file)
421{
422 return fh2id(file->private_data);
423}
424
414/* forward declaration of struct defined in cx18-cards.h */ 425/* forward declaration of struct defined in cx18-cards.h */
415struct cx18_card; 426struct cx18_card;
416 427
@@ -565,7 +576,7 @@ struct cx18 {
565 struct cx18_av_state av_state; 576 struct cx18_av_state av_state;
566 577
567 /* codec settings */ 578 /* codec settings */
568 struct cx2341x_mpeg_params params; 579 struct cx2341x_handler cxhdl;
569 u32 filter_mode; 580 u32 filter_mode;
570 u32 temporal_strength; 581 u32 temporal_strength;
571 u32 spatial_strength; 582 u32 spatial_strength;
@@ -593,7 +604,6 @@ struct cx18 {
593 uninitialized value in the stream->id. */ 604 uninitialized value in the stream->id. */
594 605
595 u32 base_addr; 606 u32 base_addr;
596 struct v4l2_prio_state prio;
597 607
598 u8 card_rev; 608 u8 card_rev;
599 void __iomem *enc_mem, *reg_mem; 609 void __iomem *enc_mem, *reg_mem;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 9f23b90732f2..e9802d99439b 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -160,13 +160,10 @@ EXPORT_SYMBOL(cx18_release_stream);
160static void cx18_dualwatch(struct cx18 *cx) 160static void cx18_dualwatch(struct cx18 *cx)
161{ 161{
162 struct v4l2_tuner vt; 162 struct v4l2_tuner vt;
163 u32 new_bitmap;
164 u32 new_stereo_mode; 163 u32 new_stereo_mode;
165 const u32 stereo_mask = 0x0300;
166 const u32 dual = 0x0200; 164 const u32 dual = 0x0200;
167 u32 h;
168 165
169 new_stereo_mode = cx->params.audio_properties & stereo_mask; 166 new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
170 memset(&vt, 0, sizeof(vt)); 167 memset(&vt, 0, sizeof(vt));
171 cx18_call_all(cx, tuner, g_tuner, &vt); 168 cx18_call_all(cx, tuner, g_tuner, &vt);
172 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && 169 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
@@ -176,25 +173,10 @@ static void cx18_dualwatch(struct cx18 *cx)
176 if (new_stereo_mode == cx->dualwatch_stereo_mode) 173 if (new_stereo_mode == cx->dualwatch_stereo_mode)
177 return; 174 return;
178 175
179 new_bitmap = new_stereo_mode 176 CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
180 | (cx->params.audio_properties & ~stereo_mask); 177 cx->dualwatch_stereo_mode, new_stereo_mode);
181 178 if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
182 CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. " 179 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
183 "new audio_bitmask=0x%ux\n",
184 cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap);
185
186 h = cx18_find_handle(cx);
187 if (h == CX18_INVALID_TASK_HANDLE) {
188 CX18_DEBUG_INFO("dualwatch: can't find valid task handle\n");
189 return;
190 }
191
192 if (cx18_vapi(cx,
193 CX18_CPU_SET_AUDIO_PARAMETERS, 2, h, new_bitmap) == 0) {
194 cx->dualwatch_stereo_mode = new_stereo_mode;
195 return;
196 }
197 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
198} 180}
199 181
200 182
@@ -603,7 +585,7 @@ start_failed:
603ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, 585ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
604 loff_t *pos) 586 loff_t *pos)
605{ 587{
606 struct cx18_open_id *id = filp->private_data; 588 struct cx18_open_id *id = file2id(filp);
607 struct cx18 *cx = id->cx; 589 struct cx18 *cx = id->cx;
608 struct cx18_stream *s = &cx->streams[id->type]; 590 struct cx18_stream *s = &cx->streams[id->type];
609 int rc; 591 int rc;
@@ -620,7 +602,7 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
620 602
621unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) 603unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
622{ 604{
623 struct cx18_open_id *id = filp->private_data; 605 struct cx18_open_id *id = file2id(filp);
624 struct cx18 *cx = id->cx; 606 struct cx18 *cx = id->cx;
625 struct cx18_stream *s = &cx->streams[id->type]; 607 struct cx18_stream *s = &cx->streams[id->type];
626 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); 608 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
@@ -694,13 +676,15 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
694 676
695int cx18_v4l2_close(struct file *filp) 677int cx18_v4l2_close(struct file *filp)
696{ 678{
697 struct cx18_open_id *id = filp->private_data; 679 struct v4l2_fh *fh = filp->private_data;
680 struct cx18_open_id *id = fh2id(fh);
698 struct cx18 *cx = id->cx; 681 struct cx18 *cx = id->cx;
699 struct cx18_stream *s = &cx->streams[id->type]; 682 struct cx18_stream *s = &cx->streams[id->type];
700 683
701 CX18_DEBUG_IOCTL("close() of %s\n", s->name); 684 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
702 685
703 v4l2_prio_close(&cx->prio, id->prio); 686 v4l2_fh_del(fh);
687 v4l2_fh_exit(fh);
704 688
705 /* Easy case first: this stream was never claimed by us */ 689 /* Easy case first: this stream was never claimed by us */
706 if (s->id != id->open_id) { 690 if (s->id != id->open_id) {
@@ -724,8 +708,8 @@ int cx18_v4l2_close(struct file *filp)
724 if (atomic_read(&cx->ana_capturing) > 0) { 708 if (atomic_read(&cx->ana_capturing) > 0) {
725 /* Undo video mute */ 709 /* Undo video mute */
726 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, 710 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
727 cx->params.video_mute | 711 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
728 (cx->params.video_mute_yuv << 8)); 712 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
729 } 713 }
730 /* Done! Unmute and continue. */ 714 /* Done! Unmute and continue. */
731 cx18_unmute(cx); 715 cx18_unmute(cx);
@@ -746,22 +730,24 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
746 CX18_DEBUG_FILE("open %s\n", s->name); 730 CX18_DEBUG_FILE("open %s\n", s->name);
747 731
748 /* Allocate memory */ 732 /* Allocate memory */
749 item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL); 733 item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
750 if (NULL == item) { 734 if (NULL == item) {
751 CX18_DEBUG_WARN("nomem on v4l2 open\n"); 735 CX18_DEBUG_WARN("nomem on v4l2 open\n");
752 return -ENOMEM; 736 return -ENOMEM;
753 } 737 }
738 v4l2_fh_init(&item->fh, s->video_dev);
739
754 item->cx = cx; 740 item->cx = cx;
755 item->type = s->type; 741 item->type = s->type;
756 v4l2_prio_open(&cx->prio, &item->prio);
757 742
758 item->open_id = cx->open_id++; 743 item->open_id = cx->open_id++;
759 filp->private_data = item; 744 filp->private_data = &item->fh;
760 745
761 if (item->type == CX18_ENC_STREAM_TYPE_RAD) { 746 if (item->type == CX18_ENC_STREAM_TYPE_RAD) {
762 /* Try to claim this stream */ 747 /* Try to claim this stream */
763 if (cx18_claim_stream(item, item->type)) { 748 if (cx18_claim_stream(item, item->type)) {
764 /* No, it's already in use */ 749 /* No, it's already in use */
750 v4l2_fh_exit(&item->fh);
765 kfree(item); 751 kfree(item);
766 return -EBUSY; 752 return -EBUSY;
767 } 753 }
@@ -771,6 +757,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
771 /* switching to radio while capture is 757 /* switching to radio while capture is
772 in progress is not polite */ 758 in progress is not polite */
773 cx18_release_stream(s); 759 cx18_release_stream(s);
760 v4l2_fh_exit(&item->fh);
774 kfree(item); 761 kfree(item);
775 return -EBUSY; 762 return -EBUSY;
776 } 763 }
@@ -787,6 +774,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
787 /* Done! Unmute and continue. */ 774 /* Done! Unmute and continue. */
788 cx18_unmute(cx); 775 cx18_unmute(cx);
789 } 776 }
777 v4l2_fh_add(&item->fh);
790 return 0; 778 return 0;
791} 779}
792 780
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index c330fb917b50..040aaa87579d 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -96,7 +96,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
96 /* Our default information for ir-kbd-i2c.c to use */ 96 /* Our default information for ir-kbd-i2c.c to use */
97 switch (hw) { 97 switch (hw) {
98 case CX18_HW_Z8F0811_IR_RX_HAUP: 98 case CX18_HW_Z8F0811_IR_RX_HAUP:
99 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 99 init_data->ir_codes = RC_MAP_HAUPPAUGE;
100 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 100 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
101 init_data->type = RC_TYPE_RC5; 101 init_data->type = RC_TYPE_RC5;
102 init_data->name = cx->card_name; 102 init_data->name = cx->card_name;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 7150195740dc..86c30b9963e5 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -148,12 +148,12 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
148static int cx18_g_fmt_vid_cap(struct file *file, void *fh, 148static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
149 struct v4l2_format *fmt) 149 struct v4l2_format *fmt)
150{ 150{
151 struct cx18_open_id *id = fh; 151 struct cx18_open_id *id = fh2id(fh);
152 struct cx18 *cx = id->cx; 152 struct cx18 *cx = id->cx;
153 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 153 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
154 154
155 pixfmt->width = cx->params.width; 155 pixfmt->width = cx->cxhdl.width;
156 pixfmt->height = cx->params.height; 156 pixfmt->height = cx->cxhdl.height;
157 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 157 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
158 pixfmt->field = V4L2_FIELD_INTERLACED; 158 pixfmt->field = V4L2_FIELD_INTERLACED;
159 pixfmt->priv = 0; 159 pixfmt->priv = 0;
@@ -173,7 +173,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
173static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, 173static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
174 struct v4l2_format *fmt) 174 struct v4l2_format *fmt)
175{ 175{
176 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 176 struct cx18 *cx = fh2id(fh)->cx;
177 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; 177 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
178 178
179 vbifmt->sampling_rate = 27000000; 179 vbifmt->sampling_rate = 27000000;
@@ -192,7 +192,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
192static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, 192static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
193 struct v4l2_format *fmt) 193 struct v4l2_format *fmt)
194{ 194{
195 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 195 struct cx18 *cx = fh2id(fh)->cx;
196 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 196 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
197 197
198 /* sane, V4L2 spec compliant, defaults */ 198 /* sane, V4L2 spec compliant, defaults */
@@ -221,7 +221,7 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
221static int cx18_try_fmt_vid_cap(struct file *file, void *fh, 221static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
222 struct v4l2_format *fmt) 222 struct v4l2_format *fmt)
223{ 223{
224 struct cx18_open_id *id = fh; 224 struct cx18_open_id *id = fh2id(fh);
225 struct cx18 *cx = id->cx; 225 struct cx18 *cx = id->cx;
226 int w = fmt->fmt.pix.width; 226 int w = fmt->fmt.pix.width;
227 int h = fmt->fmt.pix.height; 227 int h = fmt->fmt.pix.height;
@@ -252,7 +252,7 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
252static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, 252static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
253 struct v4l2_format *fmt) 253 struct v4l2_format *fmt)
254{ 254{
255 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 255 struct cx18 *cx = fh2id(fh)->cx;
256 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 256 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
257 257
258 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; 258 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
@@ -271,30 +271,26 @@ static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
271static int cx18_s_fmt_vid_cap(struct file *file, void *fh, 271static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
272 struct v4l2_format *fmt) 272 struct v4l2_format *fmt)
273{ 273{
274 struct cx18_open_id *id = fh; 274 struct cx18_open_id *id = fh2id(fh);
275 struct cx18 *cx = id->cx; 275 struct cx18 *cx = id->cx;
276 struct v4l2_mbus_framefmt mbus_fmt; 276 struct v4l2_mbus_framefmt mbus_fmt;
277 int ret; 277 int ret;
278 int w, h; 278 int w, h;
279 279
280 ret = v4l2_prio_check(&cx->prio, id->prio);
281 if (ret)
282 return ret;
283
284 ret = cx18_try_fmt_vid_cap(file, fh, fmt); 280 ret = cx18_try_fmt_vid_cap(file, fh, fmt);
285 if (ret) 281 if (ret)
286 return ret; 282 return ret;
287 w = fmt->fmt.pix.width; 283 w = fmt->fmt.pix.width;
288 h = fmt->fmt.pix.height; 284 h = fmt->fmt.pix.height;
289 285
290 if (cx->params.width == w && cx->params.height == h) 286 if (cx->cxhdl.width == w && cx->cxhdl.height == h)
291 return 0; 287 return 0;
292 288
293 if (atomic_read(&cx->ana_capturing) > 0) 289 if (atomic_read(&cx->ana_capturing) > 0)
294 return -EBUSY; 290 return -EBUSY;
295 291
296 mbus_fmt.width = cx->params.width = w; 292 mbus_fmt.width = cx->cxhdl.width = w;
297 mbus_fmt.height = cx->params.height = h; 293 mbus_fmt.height = cx->cxhdl.height = h;
298 mbus_fmt.code = V4L2_MBUS_FMT_FIXED; 294 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
299 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt); 295 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
300 return cx18_g_fmt_vid_cap(file, fh, fmt); 296 return cx18_g_fmt_vid_cap(file, fh, fmt);
@@ -303,14 +299,10 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
303static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, 299static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
304 struct v4l2_format *fmt) 300 struct v4l2_format *fmt)
305{ 301{
306 struct cx18_open_id *id = fh; 302 struct cx18_open_id *id = fh2id(fh);
307 struct cx18 *cx = id->cx; 303 struct cx18 *cx = id->cx;
308 int ret; 304 int ret;
309 305
310 ret = v4l2_prio_check(&cx->prio, id->prio);
311 if (ret)
312 return ret;
313
314 /* 306 /*
315 * Changing the Encoder's Raw VBI parameters won't have any effect 307 * Changing the Encoder's Raw VBI parameters won't have any effect
316 * if any analog capture is ongoing 308 * if any analog capture is ongoing
@@ -337,15 +329,11 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
337static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, 329static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
338 struct v4l2_format *fmt) 330 struct v4l2_format *fmt)
339{ 331{
340 struct cx18_open_id *id = fh; 332 struct cx18_open_id *id = fh2id(fh);
341 struct cx18 *cx = id->cx; 333 struct cx18 *cx = id->cx;
342 int ret; 334 int ret;
343 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 335 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
344 336
345 ret = v4l2_prio_check(&cx->prio, id->prio);
346 if (ret)
347 return ret;
348
349 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt); 337 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
350 338
351 /* 339 /*
@@ -372,7 +360,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
372static int cx18_g_chip_ident(struct file *file, void *fh, 360static int cx18_g_chip_ident(struct file *file, void *fh,
373 struct v4l2_dbg_chip_ident *chip) 361 struct v4l2_dbg_chip_ident *chip)
374{ 362{
375 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 363 struct cx18 *cx = fh2id(fh)->cx;
376 int err = 0; 364 int err = 0;
377 365
378 chip->ident = V4L2_IDENT_NONE; 366 chip->ident = V4L2_IDENT_NONE;
@@ -442,7 +430,7 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
442static int cx18_g_register(struct file *file, void *fh, 430static int cx18_g_register(struct file *file, void *fh,
443 struct v4l2_dbg_register *reg) 431 struct v4l2_dbg_register *reg)
444{ 432{
445 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 433 struct cx18 *cx = fh2id(fh)->cx;
446 434
447 if (v4l2_chip_match_host(&reg->match)) 435 if (v4l2_chip_match_host(&reg->match))
448 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); 436 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
@@ -454,7 +442,7 @@ static int cx18_g_register(struct file *file, void *fh,
454static int cx18_s_register(struct file *file, void *fh, 442static int cx18_s_register(struct file *file, void *fh,
455 struct v4l2_dbg_register *reg) 443 struct v4l2_dbg_register *reg)
456{ 444{
457 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 445 struct cx18 *cx = fh2id(fh)->cx;
458 446
459 if (v4l2_chip_match_host(&reg->match)) 447 if (v4l2_chip_match_host(&reg->match))
460 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); 448 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
@@ -464,26 +452,10 @@ static int cx18_s_register(struct file *file, void *fh,
464} 452}
465#endif 453#endif
466 454
467static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
468{
469 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
470
471 *p = v4l2_prio_max(&cx->prio);
472 return 0;
473}
474
475static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
476{
477 struct cx18_open_id *id = fh;
478 struct cx18 *cx = id->cx;
479
480 return v4l2_prio_change(&cx->prio, &id->prio, prio);
481}
482
483static int cx18_querycap(struct file *file, void *fh, 455static int cx18_querycap(struct file *file, void *fh,
484 struct v4l2_capability *vcap) 456 struct v4l2_capability *vcap)
485{ 457{
486 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 458 struct cx18 *cx = fh2id(fh)->cx;
487 459
488 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); 460 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
489 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); 461 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
@@ -496,14 +468,14 @@ static int cx18_querycap(struct file *file, void *fh,
496 468
497static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) 469static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
498{ 470{
499 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 471 struct cx18 *cx = fh2id(fh)->cx;
500 472
501 return cx18_get_audio_input(cx, vin->index, vin); 473 return cx18_get_audio_input(cx, vin->index, vin);
502} 474}
503 475
504static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) 476static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
505{ 477{
506 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 478 struct cx18 *cx = fh2id(fh)->cx;
507 479
508 vin->index = cx->audio_input; 480 vin->index = cx->audio_input;
509 return cx18_get_audio_input(cx, vin->index, vin); 481 return cx18_get_audio_input(cx, vin->index, vin);
@@ -511,7 +483,7 @@ static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
511 483
512static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) 484static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
513{ 485{
514 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 486 struct cx18 *cx = fh2id(fh)->cx;
515 487
516 if (vout->index >= cx->nof_audio_inputs) 488 if (vout->index >= cx->nof_audio_inputs)
517 return -EINVAL; 489 return -EINVAL;
@@ -522,7 +494,7 @@ static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
522 494
523static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) 495static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
524{ 496{
525 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 497 struct cx18 *cx = fh2id(fh)->cx;
526 498
527 /* set it to defaults from our table */ 499 /* set it to defaults from our table */
528 return cx18_get_input(cx, vin->index, vin); 500 return cx18_get_input(cx, vin->index, vin);
@@ -531,7 +503,7 @@ static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
531static int cx18_cropcap(struct file *file, void *fh, 503static int cx18_cropcap(struct file *file, void *fh,
532 struct v4l2_cropcap *cropcap) 504 struct v4l2_cropcap *cropcap)
533{ 505{
534 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 506 struct cx18 *cx = fh2id(fh)->cx;
535 507
536 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 508 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
537 return -EINVAL; 509 return -EINVAL;
@@ -546,13 +518,8 @@ static int cx18_cropcap(struct file *file, void *fh,
546 518
547static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) 519static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
548{ 520{
549 struct cx18_open_id *id = fh; 521 struct cx18_open_id *id = fh2id(fh);
550 struct cx18 *cx = id->cx; 522 struct cx18 *cx = id->cx;
551 int ret;
552
553 ret = v4l2_prio_check(&cx->prio, id->prio);
554 if (ret)
555 return ret;
556 523
557 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 524 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
558 return -EINVAL; 525 return -EINVAL;
@@ -562,7 +529,7 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
562 529
563static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) 530static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
564{ 531{
565 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 532 struct cx18 *cx = fh2id(fh)->cx;
566 533
567 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 534 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
568 return -EINVAL; 535 return -EINVAL;
@@ -590,7 +557,7 @@ static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
590 557
591static int cx18_g_input(struct file *file, void *fh, unsigned int *i) 558static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
592{ 559{
593 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 560 struct cx18 *cx = fh2id(fh)->cx;
594 561
595 *i = cx->active_input; 562 *i = cx->active_input;
596 return 0; 563 return 0;
@@ -598,13 +565,8 @@ static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
598 565
599int cx18_s_input(struct file *file, void *fh, unsigned int inp) 566int cx18_s_input(struct file *file, void *fh, unsigned int inp)
600{ 567{
601 struct cx18_open_id *id = fh; 568 struct cx18_open_id *id = fh2id(fh);
602 struct cx18 *cx = id->cx; 569 struct cx18 *cx = id->cx;
603 int ret;
604
605 ret = v4l2_prio_check(&cx->prio, id->prio);
606 if (ret)
607 return ret;
608 570
609 if (inp >= cx->nof_inputs) 571 if (inp >= cx->nof_inputs)
610 return -EINVAL; 572 return -EINVAL;
@@ -633,7 +595,7 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
633static int cx18_g_frequency(struct file *file, void *fh, 595static int cx18_g_frequency(struct file *file, void *fh,
634 struct v4l2_frequency *vf) 596 struct v4l2_frequency *vf)
635{ 597{
636 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 598 struct cx18 *cx = fh2id(fh)->cx;
637 599
638 if (vf->tuner != 0) 600 if (vf->tuner != 0)
639 return -EINVAL; 601 return -EINVAL;
@@ -644,13 +606,8 @@ static int cx18_g_frequency(struct file *file, void *fh,
644 606
645int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 607int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
646{ 608{
647 struct cx18_open_id *id = fh; 609 struct cx18_open_id *id = fh2id(fh);
648 struct cx18 *cx = id->cx; 610 struct cx18 *cx = id->cx;
649 int ret;
650
651 ret = v4l2_prio_check(&cx->prio, id->prio);
652 if (ret)
653 return ret;
654 611
655 if (vf->tuner != 0) 612 if (vf->tuner != 0)
656 return -EINVAL; 613 return -EINVAL;
@@ -664,7 +621,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
664 621
665static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) 622static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
666{ 623{
667 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 624 struct cx18 *cx = fh2id(fh)->cx;
668 625
669 *std = cx->std; 626 *std = cx->std;
670 return 0; 627 return 0;
@@ -672,13 +629,8 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
672 629
673int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) 630int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
674{ 631{
675 struct cx18_open_id *id = fh; 632 struct cx18_open_id *id = fh2id(fh);
676 struct cx18 *cx = id->cx; 633 struct cx18 *cx = id->cx;
677 int ret;
678
679 ret = v4l2_prio_check(&cx->prio, id->prio);
680 if (ret)
681 return ret;
682 634
683 if ((*std & V4L2_STD_ALL) == 0) 635 if ((*std & V4L2_STD_ALL) == 0)
684 return -EINVAL; 636 return -EINVAL;
@@ -696,9 +648,10 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
696 648
697 cx->std = *std; 649 cx->std = *std;
698 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; 650 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
699 cx->params.is_50hz = cx->is_50hz = !cx->is_60hz; 651 cx->is_50hz = !cx->is_60hz;
700 cx->params.width = 720; 652 cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
701 cx->params.height = cx->is_50hz ? 576 : 480; 653 cx->cxhdl.width = 720;
654 cx->cxhdl.height = cx->is_50hz ? 576 : 480;
702 cx->vbi.count = cx->is_50hz ? 18 : 12; 655 cx->vbi.count = cx->is_50hz ? 18 : 12;
703 cx->vbi.start[0] = cx->is_50hz ? 6 : 10; 656 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
704 cx->vbi.start[1] = cx->is_50hz ? 318 : 273; 657 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
@@ -712,13 +665,8 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
712 665
713static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 666static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
714{ 667{
715 struct cx18_open_id *id = fh; 668 struct cx18_open_id *id = fh2id(fh);
716 struct cx18 *cx = id->cx; 669 struct cx18 *cx = id->cx;
717 int ret;
718
719 ret = v4l2_prio_check(&cx->prio, id->prio);
720 if (ret)
721 return ret;
722 670
723 if (vt->index != 0) 671 if (vt->index != 0)
724 return -EINVAL; 672 return -EINVAL;
@@ -729,7 +677,7 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
729 677
730static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 678static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
731{ 679{
732 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 680 struct cx18 *cx = fh2id(fh)->cx;
733 681
734 if (vt->index != 0) 682 if (vt->index != 0)
735 return -EINVAL; 683 return -EINVAL;
@@ -750,7 +698,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
750static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, 698static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
751 struct v4l2_sliced_vbi_cap *cap) 699 struct v4l2_sliced_vbi_cap *cap)
752{ 700{
753 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 701 struct cx18 *cx = fh2id(fh)->cx;
754 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; 702 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
755 int f, l; 703 int f, l;
756 704
@@ -871,7 +819,7 @@ static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
871static int cx18_g_enc_index(struct file *file, void *fh, 819static int cx18_g_enc_index(struct file *file, void *fh,
872 struct v4l2_enc_idx *idx) 820 struct v4l2_enc_idx *idx)
873{ 821{
874 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 822 struct cx18 *cx = fh2id(fh)->cx;
875 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX]; 823 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
876 s32 tmp; 824 s32 tmp;
877 struct cx18_mdl *mdl; 825 struct cx18_mdl *mdl;
@@ -918,7 +866,7 @@ static int cx18_g_enc_index(struct file *file, void *fh,
918static int cx18_encoder_cmd(struct file *file, void *fh, 866static int cx18_encoder_cmd(struct file *file, void *fh,
919 struct v4l2_encoder_cmd *enc) 867 struct v4l2_encoder_cmd *enc)
920{ 868{
921 struct cx18_open_id *id = fh; 869 struct cx18_open_id *id = fh2id(fh);
922 struct cx18 *cx = id->cx; 870 struct cx18 *cx = id->cx;
923 u32 h; 871 u32 h;
924 872
@@ -979,7 +927,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh,
979static int cx18_try_encoder_cmd(struct file *file, void *fh, 927static int cx18_try_encoder_cmd(struct file *file, void *fh,
980 struct v4l2_encoder_cmd *enc) 928 struct v4l2_encoder_cmd *enc)
981{ 929{
982 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 930 struct cx18 *cx = fh2id(fh)->cx;
983 931
984 switch (enc->cmd) { 932 switch (enc->cmd) {
985 case V4L2_ENC_CMD_START: 933 case V4L2_ENC_CMD_START:
@@ -1011,7 +959,7 @@ static int cx18_try_encoder_cmd(struct file *file, void *fh,
1011 959
1012static int cx18_log_status(struct file *file, void *fh) 960static int cx18_log_status(struct file *file, void *fh)
1013{ 961{
1014 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 962 struct cx18 *cx = fh2id(fh)->cx;
1015 struct v4l2_input vidin; 963 struct v4l2_input vidin;
1016 struct v4l2_audio audin; 964 struct v4l2_audio audin;
1017 int i; 965 int i;
@@ -1035,7 +983,7 @@ static int cx18_log_status(struct file *file, void *fh)
1035 mutex_unlock(&cx->gpio_lock); 983 mutex_unlock(&cx->gpio_lock);
1036 CX18_INFO("Tuner: %s\n", 984 CX18_INFO("Tuner: %s\n",
1037 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); 985 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
1038 cx2341x_log_status(&cx->params, cx->v4l2_dev.name); 986 v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
1039 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); 987 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
1040 for (i = 0; i < CX18_MAX_STREAMS; i++) { 988 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1041 struct cx18_stream *s = &cx->streams[i]; 989 struct cx18_stream *s = &cx->streams[i];
@@ -1056,9 +1004,10 @@ static int cx18_log_status(struct file *file, void *fh)
1056 return 0; 1004 return 0;
1057} 1005}
1058 1006
1059static long cx18_default(struct file *file, void *fh, int cmd, void *arg) 1007static long cx18_default(struct file *file, void *fh, bool valid_prio,
1008 int cmd, void *arg)
1060{ 1009{
1061 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 1010 struct cx18 *cx = fh2id(fh)->cx;
1062 1011
1063 switch (cmd) { 1012 switch (cmd) {
1064 case VIDIOC_INT_RESET: { 1013 case VIDIOC_INT_RESET: {
@@ -1080,14 +1029,12 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
1080 unsigned long arg) 1029 unsigned long arg)
1081{ 1030{
1082 struct video_device *vfd = video_devdata(filp); 1031 struct video_device *vfd = video_devdata(filp);
1083 struct cx18_open_id *id = filp->private_data; 1032 struct cx18_open_id *id = file2id(filp);
1084 struct cx18 *cx = id->cx; 1033 struct cx18 *cx = id->cx;
1085 long res; 1034 long res;
1086 1035
1087 mutex_lock(&cx->serialize_lock); 1036 mutex_lock(&cx->serialize_lock);
1088 1037
1089 /* FIXME - consolidate v4l2_prio_check()'s here */
1090
1091 if (cx18_debug & CX18_DBGFLG_IOCTL) 1038 if (cx18_debug & CX18_DBGFLG_IOCTL)
1092 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; 1039 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1093 res = video_ioctl2(filp, cmd, arg); 1040 res = video_ioctl2(filp, cmd, arg);
@@ -1098,8 +1045,6 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
1098 1045
1099static const struct v4l2_ioctl_ops cx18_ioctl_ops = { 1046static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1100 .vidioc_querycap = cx18_querycap, 1047 .vidioc_querycap = cx18_querycap,
1101 .vidioc_g_priority = cx18_g_priority,
1102 .vidioc_s_priority = cx18_s_priority,
1103 .vidioc_s_audio = cx18_s_audio, 1048 .vidioc_s_audio = cx18_s_audio,
1104 .vidioc_g_audio = cx18_g_audio, 1049 .vidioc_g_audio = cx18_g_audio,
1105 .vidioc_enumaudio = cx18_enumaudio, 1050 .vidioc_enumaudio = cx18_enumaudio,
@@ -1136,11 +1081,6 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1136 .vidioc_s_register = cx18_s_register, 1081 .vidioc_s_register = cx18_s_register,
1137#endif 1082#endif
1138 .vidioc_default = cx18_default, 1083 .vidioc_default = cx18_default,
1139 .vidioc_queryctrl = cx18_queryctrl,
1140 .vidioc_querymenu = cx18_querymenu,
1141 .vidioc_g_ext_ctrls = cx18_g_ext_ctrls,
1142 .vidioc_s_ext_ctrls = cx18_s_ext_ctrls,
1143 .vidioc_try_ext_ctrls = cx18_try_ext_ctrls,
1144}; 1084};
1145 1085
1146void cx18_set_funcs(struct video_device *vdev) 1086void cx18_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index c545f3beef78..9605d54bd083 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -716,9 +716,8 @@ static int cx18_set_filter_param(struct cx18_stream *s)
716int cx18_api_func(void *priv, u32 cmd, int in, int out, 716int cx18_api_func(void *priv, u32 cmd, int in, int out,
717 u32 data[CX2341X_MBOX_MAX_DATA]) 717 u32 data[CX2341X_MBOX_MAX_DATA])
718{ 718{
719 struct cx18_api_func_private *api_priv = priv; 719 struct cx18_stream *s = priv;
720 struct cx18 *cx = api_priv->cx; 720 struct cx18 *cx = s->cx;
721 struct cx18_stream *s = api_priv->s;
722 721
723 switch (cmd) { 722 switch (cmd) {
724 case CX2341X_ENC_SET_OUTPUT_PORT: 723 case CX2341X_ENC_SET_OUTPUT_PORT:
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index 077952fcbcca..05fe6bdbe062 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -81,11 +81,6 @@ struct cx18_mailbox {
81 81
82struct cx18_stream; 82struct cx18_stream;
83 83
84struct cx18_api_func_private {
85 struct cx18 *cx;
86 struct cx18_stream *s;
87};
88
89int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]); 84int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
90int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd, 85int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
91 int args, ...); 86 int args, ...);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 94f5d7967c5c..c6e2ca3b1149 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -207,6 +207,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
207 s->video_dev->fops = &cx18_v4l2_enc_fops; 207 s->video_dev->fops = &cx18_v4l2_enc_fops;
208 s->video_dev->release = video_device_release; 208 s->video_dev->release = video_device_release;
209 s->video_dev->tvnorms = V4L2_STD_ALL; 209 s->video_dev->tvnorms = V4L2_STD_ALL;
210 set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
210 cx18_set_funcs(s->video_dev); 211 cx18_set_funcs(s->video_dev);
211 return 0; 212 return 0;
212} 213}
@@ -572,7 +573,7 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s)
572 * Set the MDL size to the exact size needed for one frame. 573 * Set the MDL size to the exact size needed for one frame.
573 * Use enough buffers per MDL to cover the MDL size 574 * Use enough buffers per MDL to cover the MDL size
574 */ 575 */
575 s->mdl_size = 720 * s->cx->params.height * 3 / 2; 576 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
576 s->bufs_per_mdl = s->mdl_size / s->buf_size; 577 s->bufs_per_mdl = s->mdl_size / s->buf_size;
577 if (s->mdl_size % s->buf_size) 578 if (s->mdl_size % s->buf_size)
578 s->bufs_per_mdl++; 579 s->bufs_per_mdl++;
@@ -607,7 +608,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
607 u32 data[MAX_MB_ARGUMENTS]; 608 u32 data[MAX_MB_ARGUMENTS];
608 struct cx18 *cx = s->cx; 609 struct cx18 *cx = s->cx;
609 int captype = 0; 610 int captype = 0;
610 struct cx18_api_func_private priv;
611 struct cx18_stream *s_idx; 611 struct cx18_stream *s_idx;
612 612
613 if (!cx18_stream_enabled(s)) 613 if (!cx18_stream_enabled(s))
@@ -620,7 +620,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
620 captype = CAPTURE_CHANNEL_TYPE_MPEG; 620 captype = CAPTURE_CHANNEL_TYPE_MPEG;
621 cx->mpg_data_received = cx->vbi_data_inserted = 0; 621 cx->mpg_data_received = cx->vbi_data_inserted = 0;
622 cx->dualwatch_jiffies = jiffies; 622 cx->dualwatch_jiffies = jiffies;
623 cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300; 623 cx->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
624 cx->search_pack_header = 0; 624 cx->search_pack_header = 0;
625 break; 625 break;
626 626
@@ -710,21 +710,21 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
710 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0); 710 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
711 711
712 /* Call out to the common CX2341x API setup for user controls */ 712 /* Call out to the common CX2341x API setup for user controls */
713 priv.cx = cx; 713 cx->cxhdl.priv = s;
714 priv.s = s; 714 cx2341x_handler_setup(&cx->cxhdl);
715 cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
716 715
717 /* 716 /*
718 * When starting a capture and we're set for radio, 717 * When starting a capture and we're set for radio,
719 * ensure the video is muted, despite the user control. 718 * ensure the video is muted, despite the user control.
720 */ 719 */
721 if (!cx->params.video_mute && 720 if (!cx->cxhdl.video_mute &&
722 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) 721 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
723 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, 722 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
724 (cx->params.video_mute_yuv << 8) | 1); 723 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
725 } 724 }
726 725
727 if (atomic_read(&cx->tot_capturing) == 0) { 726 if (atomic_read(&cx->tot_capturing) == 0) {
727 cx2341x_handler_set_busy(&cx->cxhdl, 1);
728 clear_bit(CX18_F_I_EOS, &cx->i_flags); 728 clear_bit(CX18_F_I_EOS, &cx->i_flags);
729 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK); 729 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
730 } 730 }
@@ -826,6 +826,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
826 if (atomic_read(&cx->tot_capturing) > 0) 826 if (atomic_read(&cx->tot_capturing) > 0)
827 return 0; 827 return 0;
828 828
829 cx2341x_handler_set_busy(&cx->cxhdl, 0);
829 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); 830 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
830 wake_up(&s->waitq); 831 wake_up(&s->waitq);
831 832
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 7e40035028d2..935f557acbd0 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -477,7 +477,7 @@
477/* The are no buffers ready. Try again soon! */ 477/* The are no buffers ready. Try again soon! */
478#define CXERR_NODATA_AGAIN 0x00001E 478#define CXERR_NODATA_AGAIN 0x00001E
479 479
480/* The stream is stopping. Function not alllowed now! */ 480/* The stream is stopping. Function not allowed now! */
481#define CXERR_STOPPING_STATUS 0x00001F 481#define CXERR_STOPPING_STATUS 0x00001F
482 482
483/* Trying to access hardware when the power is turned OFF */ 483/* Trying to access hardware when the power is turned OFF */
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
index fc9526a5b746..f8f0e59cd583 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/video/cx231xx/cx231xx-417.c
@@ -942,13 +942,13 @@ static int cx231xx_load_firmware(struct cx231xx *dev)
942 942
943 p_current_fw = vmalloc(1884180 * 4); 943 p_current_fw = vmalloc(1884180 * 4);
944 p_fw = p_current_fw; 944 p_fw = p_current_fw;
945 if (p_current_fw == 0) { 945 if (p_current_fw == NULL) {
946 dprintk(2, "FAIL!!!\n"); 946 dprintk(2, "FAIL!!!\n");
947 return -1; 947 return -1;
948 } 948 }
949 949
950 p_buffer = vmalloc(4096); 950 p_buffer = vmalloc(4096);
951 if (p_buffer == 0) { 951 if (p_buffer == NULL) {
952 dprintk(2, "FAIL!!!\n"); 952 dprintk(2, "FAIL!!!\n");
953 return -1; 953 return -1;
954 } 954 }
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index c53e97295a0d..62843d39817c 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -759,11 +759,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
759 case CX231XX_VMUX_TELEVISION: 759 case CX231XX_VMUX_TELEVISION:
760 case CX231XX_VMUX_CABLE: 760 case CX231XX_VMUX_CABLE:
761 default: 761 default:
762 switch (dev->model) { 762 /* TODO: Test if this is also needed for xc2028/xc3028 */
763 case CX231XX_BOARD_CNXT_CARRAERA: 763 if (dev->board.tuner_type == TUNER_XC5000) {
764 case CX231XX_BOARD_CNXT_RDE_250:
765 case CX231XX_BOARD_CNXT_SHELBY:
766 case CX231XX_BOARD_CNXT_RDU_250:
767 /* Disable the use of DIF */ 764 /* Disable the use of DIF */
768 765
769 status = vid_blk_read_word(dev, AFE_CTRL, &value); 766 status = vid_blk_read_word(dev, AFE_CTRL, &value);
@@ -820,8 +817,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
820 MODE_CTRL, FLD_INPUT_MODE, 817 MODE_CTRL, FLD_INPUT_MODE,
821 cx231xx_set_field(FLD_INPUT_MODE, 818 cx231xx_set_field(FLD_INPUT_MODE,
822 INPUT_MODE_CVBS_0)); 819 INPUT_MODE_CVBS_0));
823 break; 820 } else {
824 default:
825 /* Enable the DIF for the tuner */ 821 /* Enable the DIF for the tuner */
826 822
827 /* Reinitialize the DIF */ 823 /* Reinitialize the DIF */
@@ -1275,6 +1271,8 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
1275 int status = 0; 1271 int status = 0;
1276 bool current_is_port_3; 1272 bool current_is_port_3;
1277 1273
1274 if (dev->board.dont_use_port_3)
1275 is_port_3 = false;
1278 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, 1276 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
1279 PWR_CTL_EN, value, 4); 1277 PWR_CTL_EN, value, 4);
1280 if (status < 0) 1278 if (status < 0)
@@ -2550,7 +2548,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
2550 case 4: /* ts1 */ 2548 case 4: /* ts1 */
2551 cx231xx_info("%s: set ts1 registers", __func__); 2549 cx231xx_info("%s: set ts1 registers", __func__);
2552 2550
2553 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { 2551 if (dev->board.has_417) {
2554 cx231xx_info(" MPEG\n"); 2552 cx231xx_info(" MPEG\n");
2555 value &= 0xFFFFFFFC; 2553 value &= 0xFFFFFFFC;
2556 value |= 0x3; 2554 value |= 0x3;
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 588f3e8f028b..f49230d170e6 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -261,6 +261,9 @@ struct cx231xx_board cx231xx_boards[] = {
261 .agc_analog_digital_select_gpio = 0x1c, 261 .agc_analog_digital_select_gpio = 0x1c,
262 .gpio_pin_status_mask = 0x4001000, 262 .gpio_pin_status_mask = 0x4001000,
263 .norm = V4L2_STD_PAL, 263 .norm = V4L2_STD_PAL,
264 .no_alt_vanc = 1,
265 .external_av = 1,
266 .has_417 = 1,
264 267
265 .input = {{ 268 .input = {{
266 .type = CX231XX_VMUX_COMPOSITE1, 269 .type = CX231XX_VMUX_COMPOSITE1,
@@ -357,19 +360,19 @@ struct cx231xx_board cx231xx_boards[] = {
357 .type = CX231XX_VMUX_TELEVISION, 360 .type = CX231XX_VMUX_TELEVISION,
358 .vmux = CX231XX_VIN_3_1, 361 .vmux = CX231XX_VIN_3_1,
359 .amux = CX231XX_AMUX_VIDEO, 362 .amux = CX231XX_AMUX_VIDEO,
360 .gpio = 0, 363 .gpio = NULL,
361 }, { 364 }, {
362 .type = CX231XX_VMUX_COMPOSITE1, 365 .type = CX231XX_VMUX_COMPOSITE1,
363 .vmux = CX231XX_VIN_2_1, 366 .vmux = CX231XX_VIN_2_1,
364 .amux = CX231XX_AMUX_LINE_IN, 367 .amux = CX231XX_AMUX_LINE_IN,
365 .gpio = 0, 368 .gpio = NULL,
366 }, { 369 }, {
367 .type = CX231XX_VMUX_SVIDEO, 370 .type = CX231XX_VMUX_SVIDEO,
368 .vmux = CX231XX_VIN_1_1 | 371 .vmux = CX231XX_VIN_1_1 |
369 (CX231XX_VIN_1_2 << 8) | 372 (CX231XX_VIN_1_2 << 8) |
370 CX25840_SVIDEO_ON, 373 CX25840_SVIDEO_ON,
371 .amux = CX231XX_AMUX_LINE_IN, 374 .amux = CX231XX_AMUX_LINE_IN,
372 .gpio = 0, 375 .gpio = NULL,
373 } }, 376 } },
374 }, 377 },
375 [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = { 378 [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = {
@@ -382,18 +385,20 @@ struct cx231xx_board cx231xx_boards[] = {
382 .agc_analog_digital_select_gpio = 0x0c, 385 .agc_analog_digital_select_gpio = 0x0c,
383 .gpio_pin_status_mask = 0x4001000, 386 .gpio_pin_status_mask = 0x4001000,
384 .norm = V4L2_STD_NTSC, 387 .norm = V4L2_STD_NTSC,
388 .no_alt_vanc = 1,
389 .external_av = 1,
385 .input = {{ 390 .input = {{
386 .type = CX231XX_VMUX_COMPOSITE1, 391 .type = CX231XX_VMUX_COMPOSITE1,
387 .vmux = CX231XX_VIN_2_1, 392 .vmux = CX231XX_VIN_2_1,
388 .amux = CX231XX_AMUX_LINE_IN, 393 .amux = CX231XX_AMUX_LINE_IN,
389 .gpio = 0, 394 .gpio = NULL,
390 }, { 395 }, {
391 .type = CX231XX_VMUX_SVIDEO, 396 .type = CX231XX_VMUX_SVIDEO,
392 .vmux = CX231XX_VIN_1_1 | 397 .vmux = CX231XX_VIN_1_1 |
393 (CX231XX_VIN_1_2 << 8) | 398 (CX231XX_VIN_1_2 << 8) |
394 CX25840_SVIDEO_ON, 399 CX25840_SVIDEO_ON,
395 .amux = CX231XX_AMUX_LINE_IN, 400 .amux = CX231XX_AMUX_LINE_IN,
396 .gpio = 0, 401 .gpio = NULL,
397 } }, 402 } },
398 }, 403 },
399 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = { 404 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
@@ -420,21 +425,50 @@ struct cx231xx_board cx231xx_boards[] = {
420 .type = CX231XX_VMUX_TELEVISION, 425 .type = CX231XX_VMUX_TELEVISION,
421 .vmux = CX231XX_VIN_3_1, 426 .vmux = CX231XX_VIN_3_1,
422 .amux = CX231XX_AMUX_VIDEO, 427 .amux = CX231XX_AMUX_VIDEO,
423 .gpio = 0, 428 .gpio = NULL,
424 }, { 429 }, {
425 .type = CX231XX_VMUX_COMPOSITE1, 430 .type = CX231XX_VMUX_COMPOSITE1,
426 .vmux = CX231XX_VIN_2_1, 431 .vmux = CX231XX_VIN_2_1,
427 .amux = CX231XX_AMUX_LINE_IN, 432 .amux = CX231XX_AMUX_LINE_IN,
428 .gpio = 0, 433 .gpio = NULL,
429 }, { 434 }, {
430 .type = CX231XX_VMUX_SVIDEO, 435 .type = CX231XX_VMUX_SVIDEO,
431 .vmux = CX231XX_VIN_1_1 | 436 .vmux = CX231XX_VIN_1_1 |
432 (CX231XX_VIN_1_2 << 8) | 437 (CX231XX_VIN_1_2 << 8) |
433 CX25840_SVIDEO_ON, 438 CX25840_SVIDEO_ON,
434 .amux = CX231XX_AMUX_LINE_IN, 439 .amux = CX231XX_AMUX_LINE_IN,
435 .gpio = 0, 440 .gpio = NULL,
436 } }, 441 } },
437 }, 442 },
443 [CX231XX_BOARD_PV_XCAPTURE_USB] = {
444 .name = "Pixelview Xcapture USB",
445 .tuner_type = TUNER_ABSENT,
446 .decoder = CX231XX_AVDECODER,
447 .output_mode = OUT_MODE_VIP11,
448 .demod_xfer_mode = 0,
449 .ctl_pin_status_mask = 0xFFFFFFC4,
450 .agc_analog_digital_select_gpio = 0x0c,
451 .gpio_pin_status_mask = 0x4001000,
452 .norm = V4L2_STD_NTSC,
453 .no_alt_vanc = 1,
454 .external_av = 1,
455 .dont_use_port_3 = 1,
456
457 .input = {{
458 .type = CX231XX_VMUX_COMPOSITE1,
459 .vmux = CX231XX_VIN_2_1,
460 .amux = CX231XX_AMUX_LINE_IN,
461 .gpio = NULL,
462 }, {
463 .type = CX231XX_VMUX_SVIDEO,
464 .vmux = CX231XX_VIN_1_1 |
465 (CX231XX_VIN_1_2 << 8) |
466 CX25840_SVIDEO_ON,
467 .amux = CX231XX_AMUX_LINE_IN,
468 .gpio = NULL,
469 }
470 },
471 },
438}; 472};
439const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); 473const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
440 474
@@ -464,6 +498,8 @@ struct usb_device_id cx231xx_id_table[] = {
464 .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, 498 .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
465 {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001), 499 {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
466 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, 500 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
501 {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
502 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
467 {}, 503 {},
468}; 504};
469 505
@@ -772,7 +808,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
772 /* Reset other chips required if they are tied up with GPIO pins */ 808 /* Reset other chips required if they are tied up with GPIO pins */
773 cx231xx_add_into_devlist(dev); 809 cx231xx_add_into_devlist(dev);
774 810
775 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { 811 if (dev->board.has_417) {
776 printk(KERN_INFO "attach 417 %d\n", dev->model); 812 printk(KERN_INFO "attach 417 %d\n", dev->model);
777 if (cx231xx_417_register(dev) < 0) { 813 if (cx231xx_417_register(dev) < 0) {
778 printk(KERN_ERR 814 printk(KERN_ERR
@@ -844,110 +880,110 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
844 udev = usb_get_dev(interface_to_usbdev(interface)); 880 udev = usb_get_dev(interface_to_usbdev(interface));
845 ifnum = interface->altsetting[0].desc.bInterfaceNumber; 881 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
846 882
847 if (ifnum == 1) { 883 /*
848 /* 884 * Interface number 0 - IR interface (handled by mceusb driver)
849 * Interface number 0 - IR interface 885 * Interface number 1 - AV interface (handled by this driver)
850 */ 886 */
851 /* Check to see next free device and mark as used */ 887 if (ifnum != 1)
852 nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); 888 return -ENODEV;
853 cx231xx_devused |= 1 << nr;
854
855 if (nr >= CX231XX_MAXBOARDS) {
856 cx231xx_err(DRIVER_NAME
857 ": Supports only %i cx231xx boards.\n", CX231XX_MAXBOARDS);
858 cx231xx_devused &= ~(1 << nr);
859 return -ENOMEM;
860 }
861
862 /* allocate memory for our device state and initialize it */
863 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
864 if (dev == NULL) {
865 cx231xx_err(DRIVER_NAME ": out of memory!\n");
866 cx231xx_devused &= ~(1 << nr);
867 return -ENOMEM;
868 }
869
870 snprintf(dev->name, 29, "cx231xx #%d", nr);
871 dev->devno = nr;
872 dev->model = id->driver_info;
873 dev->video_mode.alt = -1;
874 dev->interface_count++;
875
876 /* reset gpio dir and value */
877 dev->gpio_dir = 0;
878 dev->gpio_val = 0;
879 dev->xc_fw_load_done = 0;
880 dev->has_alsa_audio = 1;
881 dev->power_mode = -1;
882 atomic_set(&dev->devlist_count, 0);
883
884 /* 0 - vbi ; 1 -sliced cc mode */
885 dev->vbi_or_sliced_cc_mode = 0;
886
887 /* get maximum no.of IAD interfaces */
888 assoc_desc = udev->actconfig->intf_assoc[0];
889 dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
890
891 /* init CIR module TBD */
892 889
893 /* store the current interface */ 890 /* Check to see next free device and mark as used */
894 lif = interface; 891 nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS);
892 cx231xx_devused |= 1 << nr;
895 893
896 /*mode_tv: digital=1 or analog=0*/ 894 if (nr >= CX231XX_MAXBOARDS) {
897 dev->mode_tv = 0; 895 cx231xx_err(DRIVER_NAME
896 ": Supports only %i cx231xx boards.\n", CX231XX_MAXBOARDS);
897 cx231xx_devused &= ~(1 << nr);
898 return -ENOMEM;
899 }
898 900
899 dev->USE_ISO = transfer_mode; 901 /* allocate memory for our device state and initialize it */
902 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
903 if (dev == NULL) {
904 cx231xx_err(DRIVER_NAME ": out of memory!\n");
905 cx231xx_devused &= ~(1 << nr);
906 return -ENOMEM;
907 }
900 908
901 switch (udev->speed) { 909 snprintf(dev->name, 29, "cx231xx #%d", nr);
902 case USB_SPEED_LOW: 910 dev->devno = nr;
903 speed = "1.5"; 911 dev->model = id->driver_info;
904 break; 912 dev->video_mode.alt = -1;
905 case USB_SPEED_UNKNOWN: 913
906 case USB_SPEED_FULL: 914 dev->interface_count++;
907 speed = "12"; 915 /* reset gpio dir and value */
908 break; 916 dev->gpio_dir = 0;
909 case USB_SPEED_HIGH: 917 dev->gpio_val = 0;
910 speed = "480"; 918 dev->xc_fw_load_done = 0;
911 break; 919 dev->has_alsa_audio = 1;
912 default: 920 dev->power_mode = -1;
913 speed = "unknown"; 921 atomic_set(&dev->devlist_count, 0);
914 } 922
923 /* 0 - vbi ; 1 -sliced cc mode */
924 dev->vbi_or_sliced_cc_mode = 0;
925
926 /* get maximum no.of IAD interfaces */
927 assoc_desc = udev->actconfig->intf_assoc[0];
928 dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
929
930 /* init CIR module TBD */
931
932 /* store the current interface */
933 lif = interface;
934
935 /*mode_tv: digital=1 or analog=0*/
936 dev->mode_tv = 0;
937
938 dev->USE_ISO = transfer_mode;
939
940 switch (udev->speed) {
941 case USB_SPEED_LOW:
942 speed = "1.5";
943 break;
944 case USB_SPEED_UNKNOWN:
945 case USB_SPEED_FULL:
946 speed = "12";
947 break;
948 case USB_SPEED_HIGH:
949 speed = "480";
950 break;
951 default:
952 speed = "unknown";
953 }
915 954
916 if (udev->manufacturer) 955 if (udev->manufacturer)
917 strlcpy(descr, udev->manufacturer, sizeof(descr)); 956 strlcpy(descr, udev->manufacturer, sizeof(descr));
918 957
919 if (udev->product) { 958 if (udev->product) {
920 if (*descr)
921 strlcat(descr, " ", sizeof(descr));
922 strlcat(descr, udev->product, sizeof(descr));
923 }
924 if (*descr) 959 if (*descr)
925 strlcat(descr, " ", sizeof(descr)); 960 strlcat(descr, " ", sizeof(descr));
926 961 strlcat(descr, udev->product, sizeof(descr));
927 cx231xx_info("New device %s@ %s Mbps " 962 }
928 "(%04x:%04x) with %d interfaces\n", 963 if (*descr)
929 descr, 964 strlcat(descr, " ", sizeof(descr));
930 speed, 965
931 le16_to_cpu(udev->descriptor.idVendor), 966 cx231xx_info("New device %s@ %s Mbps "
932 le16_to_cpu(udev->descriptor.idProduct), 967 "(%04x:%04x) with %d interfaces\n",
933 dev->max_iad_interface_count); 968 descr,
934 969 speed,
935 /* store the interface 0 back */ 970 le16_to_cpu(udev->descriptor.idVendor),
936 lif = udev->actconfig->interface[0]; 971 le16_to_cpu(udev->descriptor.idProduct),
937 972 dev->max_iad_interface_count);
938 /* increment interface count */ 973
939 dev->interface_count++; 974 /* store the interface 0 back */
940 975 lif = udev->actconfig->interface[0];
941 /* get device number */ 976
942 nr = dev->devno; 977 /* increment interface count */
943 978 dev->interface_count++;
944 assoc_desc = udev->actconfig->intf_assoc[0]; 979
945 if (assoc_desc->bFirstInterface != ifnum) { 980 /* get device number */
946 cx231xx_err(DRIVER_NAME ": Not found " 981 nr = dev->devno;
947 "matching IAD interface\n"); 982
948 return -ENODEV; 983 assoc_desc = udev->actconfig->intf_assoc[0];
949 } 984 if (assoc_desc->bFirstInterface != ifnum) {
950 } else { 985 cx231xx_err(DRIVER_NAME ": Not found "
986 "matching IAD interface\n");
951 return -ENODEV; 987 return -ENODEV;
952 } 988 }
953 989
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index 7d62d58617f5..abe500feb7dd 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -571,6 +571,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
571 alt]; 571 alt];
572 break; 572 break;
573 case INDEX_VANC: 573 case INDEX_VANC:
574 if (dev->board.no_alt_vanc)
575 return 0;
574 usb_interface_index = 576 usb_interface_index =
575 dev->current_pcb_config.hs_config_info[0].interface_info. 577 dev->current_pcb_config.hs_config_info[0].interface_info.
576 vanc_index + 1; 578 vanc_index + 1;
@@ -600,8 +602,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
600 usb_interface_index, alt); 602 usb_interface_index, alt);
601 /*To workaround error number=-71 on EP0 for videograbber, 603 /*To workaround error number=-71 on EP0 for videograbber,
602 need add following codes.*/ 604 need add following codes.*/
603 if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && 605 if (dev->board.no_alt_vanc)
604 dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
605 return -1; 606 return -1;
606 } 607 }
607 608
@@ -1301,8 +1302,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
1301 /* init hardware */ 1302 /* init hardware */
1302 /* Note : with out calling set power mode function, 1303 /* Note : with out calling set power mode function,
1303 afe can not be set up correctly */ 1304 afe can not be set up correctly */
1304 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || 1305 if (dev->board.external_av) {
1305 dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) {
1306 errCode = cx231xx_set_power_mode(dev, 1306 errCode = cx231xx_set_power_mode(dev,
1307 POLARIS_AVMODE_ENXTERNAL_AV); 1307 POLARIS_AVMODE_ENXTERNAL_AV);
1308 if (errCode < 0) { 1308 if (errCode < 0) {
@@ -1322,11 +1322,9 @@ int cx231xx_dev_init(struct cx231xx *dev)
1322 } 1322 }
1323 } 1323 }
1324 1324
1325 /* reset the Tuner */ 1325 /* reset the Tuner, if it is a Xceive tuner */
1326 if ((dev->model == CX231XX_BOARD_CNXT_CARRAERA) || 1326 if ((dev->board.tuner_type == TUNER_XC5000) ||
1327 (dev->model == CX231XX_BOARD_CNXT_RDE_250) || 1327 (dev->board.tuner_type == TUNER_XC2028))
1328 (dev->model == CX231XX_BOARD_CNXT_SHELBY) ||
1329 (dev->model == CX231XX_BOARD_CNXT_RDU_250))
1330 cx231xx_gpio_set(dev, dev->board.tuner_gpio); 1328 cx231xx_gpio_set(dev, dev->board.tuner_gpio);
1331 1329
1332 /* initialize Colibri block */ 1330 /* initialize Colibri block */
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index 835670623dfb..925f3a04e53c 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -54,6 +54,21 @@ do { \
54 } \ 54 } \
55} while (0) 55} while (0)
56 56
57static inline bool is_tuner(struct cx231xx *dev, struct cx231xx_i2c *bus,
58 const struct i2c_msg *msg, int tuner_type)
59{
60 if (bus->nr != dev->board.tuner_i2c_master)
61 return false;
62
63 if (msg->addr != dev->board.tuner_addr)
64 return false;
65
66 if (dev->tuner_type != tuner_type)
67 return false;
68
69 return true;
70}
71
57/* 72/*
58 * cx231xx_i2c_send_bytes() 73 * cx231xx_i2c_send_bytes()
59 */ 74 */
@@ -71,9 +86,7 @@ int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
71 u16 saddr = 0; 86 u16 saddr = 0;
72 u8 need_gpio = 0; 87 u8 need_gpio = 0;
73 88
74 if ((bus->nr == 1) && (msg->addr == 0x61) 89 if (is_tuner(dev, bus, msg, TUNER_XC5000)) {
75 && (dev->tuner_type == TUNER_XC5000)) {
76
77 size = msg->len; 90 size = msg->len;
78 91
79 if (size == 2) { /* register write sub addr */ 92 if (size == 2) { /* register write sub addr */
@@ -180,9 +193,7 @@ static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,
180 u16 saddr = 0; 193 u16 saddr = 0;
181 u8 need_gpio = 0; 194 u8 need_gpio = 0;
182 195
183 if ((bus->nr == 1) && (msg->addr == 0x61) 196 if (is_tuner(dev, bus, msg, TUNER_XC5000)) {
184 && dev->tuner_type == TUNER_XC5000) {
185
186 if (msg->len == 2) 197 if (msg->len == 2)
187 saddr = msg->buf[0] << 8 | msg->buf[1]; 198 saddr = msg->buf[0] << 8 | msg->buf[1];
188 else if (msg->len == 1) 199 else if (msg->len == 1)
@@ -274,9 +285,7 @@ static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,
274 else if (msg1->len == 1) 285 else if (msg1->len == 1)
275 saddr = msg1->buf[0]; 286 saddr = msg1->buf[0];
276 287
277 if ((bus->nr == 1) && (msg2->addr == 0x61) 288 if (is_tuner(dev, bus, msg2, TUNER_XC5000)) {
278 && dev->tuner_type == TUNER_XC5000) {
279
280 if ((msg2->len < 16)) { 289 if ((msg2->len < 16)) {
281 290
282 dprintk1(1, 291 dprintk1(1,
@@ -454,8 +463,8 @@ static char *i2c_devs[128] = {
454 [0x32 >> 1] = "GeminiIII", 463 [0x32 >> 1] = "GeminiIII",
455 [0x02 >> 1] = "Aquarius", 464 [0x02 >> 1] = "Aquarius",
456 [0xa0 >> 1] = "eeprom", 465 [0xa0 >> 1] = "eeprom",
457 [0xc0 >> 1] = "tuner/XC3028", 466 [0xc0 >> 1] = "tuner",
458 [0xc2 >> 1] = "tuner/XC5000", 467 [0xc2 >> 1] = "tuner",
459}; 468};
460 469
461/* 470/*
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 7e3e8c4f19b7..ffd5af914c44 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -2190,8 +2190,7 @@ static int cx231xx_v4l2_open(struct file *filp)
2190 dev->height = norm_maxh(dev); 2190 dev->height = norm_maxh(dev);
2191 2191
2192 /* Power up in Analog TV mode */ 2192 /* Power up in Analog TV mode */
2193 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || 2193 if (dev->board.external_av)
2194 dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
2195 cx231xx_set_power_mode(dev, 2194 cx231xx_set_power_mode(dev,
2196 POLARIS_AVMODE_ENXTERNAL_AV); 2195 POLARIS_AVMODE_ENXTERNAL_AV);
2197 else 2196 else
@@ -2231,9 +2230,7 @@ static int cx231xx_v4l2_open(struct file *filp)
2231 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 2230 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
2232 /* Set the required alternate setting VBI interface works in 2231 /* Set the required alternate setting VBI interface works in
2233 Bulk mode only */ 2232 Bulk mode only */
2234 if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && 2233 cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
2235 dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
2236 cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
2237 2234
2238 videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, 2235 videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops,
2239 NULL, &dev->vbi_mode.slock, 2236 NULL, &dev->vbi_mode.slock,
@@ -2275,7 +2272,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
2275 cx231xx_info("V4L2 device %s deregistered\n", 2272 cx231xx_info("V4L2 device %s deregistered\n",
2276 video_device_node_name(dev->vdev)); 2273 video_device_node_name(dev->vdev));
2277 2274
2278 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) 2275 if (dev->board.has_417)
2279 cx231xx_417_unregister(dev); 2276 cx231xx_417_unregister(dev);
2280 2277
2281 if (video_is_registered(dev->vdev)) 2278 if (video_is_registered(dev->vdev))
@@ -2302,10 +2299,13 @@ static int cx231xx_v4l2_close(struct file *filp)
2302 if (res_check(fh)) 2299 if (res_check(fh))
2303 res_free(fh); 2300 res_free(fh);
2304 2301
2305 /*To workaround error number=-71 on EP0 for VideoGrabber, 2302 /*
2306 need exclude following.*/ 2303 * To workaround error number=-71 on EP0 for VideoGrabber,
2307 if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && 2304 * need exclude following.
2308 dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2) 2305 * FIXME: It is probably safe to remove most of these, as we're
2306 * now avoiding the alternate setting for INDEX_VANC
2307 */
2308 if (!dev->board.no_alt_vanc)
2309 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 2309 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
2310 videobuf_stop(&fh->vb_vidq); 2310 videobuf_stop(&fh->vb_vidq);
2311 videobuf_mmap_free(&fh->vb_vidq); 2311 videobuf_mmap_free(&fh->vb_vidq);
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index 72bbea2bcd56..bd4a9cf29577 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -64,6 +64,7 @@
64#define CX231XX_BOARD_HAUPPAUGE_EXETER 8 64#define CX231XX_BOARD_HAUPPAUGE_EXETER 8
65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9 65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10 66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
67#define CX231XX_BOARD_PV_XCAPTURE_USB 11
67 68
68/* Limits minimum and default number of buffers */ 69/* Limits minimum and default number of buffers */
69#define CX231XX_MIN_BUF 4 70#define CX231XX_MIN_BUF 4
@@ -353,7 +354,11 @@ struct cx231xx_board {
353 354
354 unsigned int max_range_640_480:1; 355 unsigned int max_range_640_480:1;
355 unsigned int has_dvb:1; 356 unsigned int has_dvb:1;
357 unsigned int has_417:1;
356 unsigned int valid:1; 358 unsigned int valid:1;
359 unsigned int no_alt_vanc:1;
360 unsigned int external_av:1;
361 unsigned int dont_use_port_3:1;
357 362
358 unsigned char xclk, i2c_speed; 363 unsigned char xclk, i2c_speed;
359 364
@@ -464,7 +469,7 @@ struct cx231xx_fh {
464#define I2C_STOP 0x0 469#define I2C_STOP 0x0
465/* 1-- do not transmit STOP at end of transaction */ 470/* 1-- do not transmit STOP at end of transaction */
466#define I2C_NOSTOP 0x1 471#define I2C_NOSTOP 0x1
467/* 1--alllow slave to insert clock wait states */ 472/* 1--allow slave to insert clock wait states */
468#define I2C_SYNC 0x1 473#define I2C_SYNC 0x1
469 474
470struct cx231xx_i2c { 475struct cx231xx_i2c {
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 6b4a516addfe..3b6e7f28568e 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -1,6 +1,7 @@
1config VIDEO_CX23885 1config VIDEO_CX23885
2 tristate "Conexant cx23885 (2388x successor) support" 2 tristate "Conexant cx23885 (2388x successor) support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT 3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
4 select SND_PCM
4 select I2C_ALGOBIT 5 select I2C_ALGOBIT
5 select VIDEO_BTCX 6 select VIDEO_BTCX
6 select VIDEO_TUNER 7 select VIDEO_TUNER
@@ -33,3 +34,12 @@ config VIDEO_CX23885
33 To compile this driver as a module, choose M here: the 34 To compile this driver as a module, choose M here: the
34 module will be called cx23885 35 module will be called cx23885
35 36
37config MEDIA_ALTERA_CI
38 tristate "Altera FPGA based CI module"
39 depends on VIDEO_CX23885 && DVB_CORE
40 select STAPL_ALTERA
41 ---help---
42 An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card.
43
44 To compile this driver as a module, choose M here: the
45 module will be called altera-ci
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index e2ee95f660d8..23293c7b6ac7 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -5,6 +5,7 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
5 cx23885-f300.o 5 cx23885-f300.o
6 6
7obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 7obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
8obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
8 9
9EXTRA_CFLAGS += -Idrivers/media/video 10EXTRA_CFLAGS += -Idrivers/media/video
10EXTRA_CFLAGS += -Idrivers/media/common/tuners 11EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/cx23885/altera-ci.c b/drivers/media/video/cx23885/altera-ci.c
new file mode 100644
index 000000000000..678539b2acfa
--- /dev/null
+++ b/drivers/media/video/cx23885/altera-ci.c
@@ -0,0 +1,838 @@
1/*
2 * altera-ci.c
3 *
4 * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card
5 *
6 * Copyright (C) 2010,2011 NetUP Inc.
7 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 *
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25/*
26 * currently cx23885 GPIO's used.
27 * GPIO-0 ~INT in
28 * GPIO-1 TMS out
29 * GPIO-2 ~reset chips out
30 * GPIO-3 to GPIO-10 data/addr for CA in/out
31 * GPIO-11 ~CS out
32 * GPIO-12 AD_RG out
33 * GPIO-13 ~WR out
34 * GPIO-14 ~RD out
35 * GPIO-15 ~RDY in
36 * GPIO-16 TCK out
37 * GPIO-17 TDO in
38 * GPIO-18 TDI out
39 */
40/*
41 * Bit definitions for MC417_RWD and MC417_OEN registers
42 * bits 31-16
43 * +-----------+
44 * | Reserved |
45 * +-----------+
46 * bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
47 * +-------+-------+-------+-------+-------+-------+-------+-------+
48 * | TDI | TDO | TCK | RDY# | #RD | #WR | AD_RG | #CS |
49 * +-------+-------+-------+-------+-------+-------+-------+-------+
50 * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
51 * +-------+-------+-------+-------+-------+-------+-------+-------+
52 * | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
53 * +-------+-------+-------+-------+-------+-------+-------+-------+
54 */
55#include <linux/version.h>
56#include <media/videobuf-dma-sg.h>
57#include <media/videobuf-dvb.h>
58#include "altera-ci.h"
59#include "dvb_ca_en50221.h"
60
61/* FPGA regs */
62#define NETUP_CI_INT_CTRL 0x00
63#define NETUP_CI_BUSCTRL2 0x01
64#define NETUP_CI_ADDR0 0x04
65#define NETUP_CI_ADDR1 0x05
66#define NETUP_CI_DATA 0x06
67#define NETUP_CI_BUSCTRL 0x07
68#define NETUP_CI_PID_ADDR0 0x08
69#define NETUP_CI_PID_ADDR1 0x09
70#define NETUP_CI_PID_DATA 0x0a
71#define NETUP_CI_TSA_DIV 0x0c
72#define NETUP_CI_TSB_DIV 0x0d
73#define NETUP_CI_REVISION 0x0f
74
75/* const for ci op */
76#define NETUP_CI_FLG_CTL 1
77#define NETUP_CI_FLG_RD 1
78#define NETUP_CI_FLG_AD 1
79
80static unsigned int ci_dbg;
81module_param(ci_dbg, int, 0644);
82MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
83
84static unsigned int pid_dbg;
85module_param(pid_dbg, int, 0644);
86MODULE_PARM_DESC(pid_dbg, "Enable PID filtering debugging");
87
88MODULE_DESCRIPTION("altera FPGA CI module");
89MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");
90MODULE_LICENSE("GPL");
91
92#define ci_dbg_print(args...) \
93 do { \
94 if (ci_dbg) \
95 printk(KERN_DEBUG args); \
96 } while (0)
97
98#define pid_dbg_print(args...) \
99 do { \
100 if (pid_dbg) \
101 printk(KERN_DEBUG args); \
102 } while (0)
103
104struct altera_ci_state;
105struct netup_hw_pid_filter;
106
107struct fpga_internal {
108 void *dev;
109 struct mutex fpga_mutex;/* two CI's on the same fpga */
110 struct netup_hw_pid_filter *pid_filt[2];
111 struct altera_ci_state *state[2];
112 struct work_struct work;
113 int (*fpga_rw) (void *dev, int flag, int data, int rw);
114 int cis_used;
115 int filts_used;
116 int strt_wrk;
117};
118
119/* stores all private variables for communication with CI */
120struct altera_ci_state {
121 struct fpga_internal *internal;
122 struct dvb_ca_en50221 ca;
123 int status;
124 int nr;
125};
126
127/* stores all private variables for hardware pid filtering */
128struct netup_hw_pid_filter {
129 struct fpga_internal *internal;
130 struct dvb_demux *demux;
131 /* save old functions */
132 int (*start_feed)(struct dvb_demux_feed *feed);
133 int (*stop_feed)(struct dvb_demux_feed *feed);
134
135 int status;
136 int nr;
137};
138
139/* internal params node */
140struct fpga_inode {
141 /* pointer for internal params, one for each pair of CI's */
142 struct fpga_internal *internal;
143 struct fpga_inode *next_inode;
144};
145
146/* first internal params */
147static struct fpga_inode *fpga_first_inode;
148
149/* find chip by dev */
150static struct fpga_inode *find_inode(void *dev)
151{
152 struct fpga_inode *temp_chip = fpga_first_inode;
153
154 if (temp_chip == NULL)
155 return temp_chip;
156
157 /*
158 Search for the last fpga CI chip or
159 find it by dev */
160 while ((temp_chip != NULL) &&
161 (temp_chip->internal->dev != dev))
162 temp_chip = temp_chip->next_inode;
163
164 return temp_chip;
165}
166/* check demux */
167static struct fpga_internal *check_filter(struct fpga_internal *temp_int,
168 void *demux_dev, int filt_nr)
169{
170 if (temp_int == NULL)
171 return NULL;
172
173 if ((temp_int->pid_filt[filt_nr]) == NULL)
174 return NULL;
175
176 if (temp_int->pid_filt[filt_nr]->demux == demux_dev)
177 return temp_int;
178
179 return NULL;
180}
181
182/* find chip by demux */
183static struct fpga_inode *find_dinode(void *demux_dev)
184{
185 struct fpga_inode *temp_chip = fpga_first_inode;
186 struct fpga_internal *temp_int;
187
188 /*
189 * Search of the last fpga CI chip or
190 * find it by demux
191 */
192 while (temp_chip != NULL) {
193 if (temp_chip->internal != NULL) {
194 temp_int = temp_chip->internal;
195 if (check_filter(temp_int, demux_dev, 0))
196 break;
197 if (check_filter(temp_int, demux_dev, 1))
198 break;
199 }
200
201 temp_chip = temp_chip->next_inode;
202 }
203
204 return temp_chip;
205}
206
207/* deallocating chip */
208static void remove_inode(struct fpga_internal *internal)
209{
210 struct fpga_inode *prev_node = fpga_first_inode;
211 struct fpga_inode *del_node = find_inode(internal->dev);
212
213 if (del_node != NULL) {
214 if (del_node == fpga_first_inode) {
215 fpga_first_inode = del_node->next_inode;
216 } else {
217 while (prev_node->next_inode != del_node)
218 prev_node = prev_node->next_inode;
219
220 if (del_node->next_inode == NULL)
221 prev_node->next_inode = NULL;
222 else
223 prev_node->next_inode =
224 prev_node->next_inode->next_inode;
225 }
226
227 kfree(del_node);
228 }
229}
230
231/* allocating new chip */
232static struct fpga_inode *append_internal(struct fpga_internal *internal)
233{
234 struct fpga_inode *new_node = fpga_first_inode;
235
236 if (new_node == NULL) {
237 new_node = kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
238 fpga_first_inode = new_node;
239 } else {
240 while (new_node->next_inode != NULL)
241 new_node = new_node->next_inode;
242
243 new_node->next_inode =
244 kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
245 if (new_node->next_inode != NULL)
246 new_node = new_node->next_inode;
247 else
248 new_node = NULL;
249 }
250
251 if (new_node != NULL) {
252 new_node->internal = internal;
253 new_node->next_inode = NULL;
254 }
255
256 return new_node;
257}
258
259static int netup_fpga_op_rw(struct fpga_internal *inter, int addr,
260 u8 val, u8 read)
261{
262 inter->fpga_rw(inter->dev, NETUP_CI_FLG_AD, addr, 0);
263 return inter->fpga_rw(inter->dev, 0, val, read);
264}
265
266/* flag - mem/io, read - read/write */
267int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
268 u8 flag, u8 read, int addr, u8 val)
269{
270
271 struct altera_ci_state *state = en50221->data;
272 struct fpga_internal *inter = state->internal;
273
274 u8 store;
275 int mem = 0;
276
277 if (0 != slot)
278 return -EINVAL;
279
280 mutex_lock(&inter->fpga_mutex);
281
282 netup_fpga_op_rw(inter, NETUP_CI_ADDR0, ((addr << 1) & 0xfe), 0);
283 netup_fpga_op_rw(inter, NETUP_CI_ADDR1, ((addr >> 7) & 0x7f), 0);
284 store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
285
286 store &= 0x0f;
287 store |= ((state->nr << 7) | (flag << 6));
288
289 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, store, 0);
290 mem = netup_fpga_op_rw(inter, NETUP_CI_DATA, val, read);
291
292 mutex_unlock(&inter->fpga_mutex);
293
294 ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
295 (read) ? "read" : "write", addr,
296 (flag == NETUP_CI_FLG_CTL) ? "ctl" : "mem",
297 (read) ? mem : val);
298
299 return mem;
300}
301
302int altera_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
303 int slot, int addr)
304{
305 return altera_ci_op_cam(en50221, slot, 0, NETUP_CI_FLG_RD, addr, 0);
306}
307
308int altera_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
309 int slot, int addr, u8 data)
310{
311 return altera_ci_op_cam(en50221, slot, 0, 0, addr, data);
312}
313
314int altera_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
315{
316 return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL,
317 NETUP_CI_FLG_RD, addr, 0);
318}
319
320int altera_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
321 u8 addr, u8 data)
322{
323 return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL, 0, addr, data);
324}
325
326int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
327{
328 struct altera_ci_state *state = en50221->data;
329 struct fpga_internal *inter = state->internal;
330 /* reasonable timeout for CI reset is 10 seconds */
331 unsigned long t_out = jiffies + msecs_to_jiffies(9999);
332 int ret;
333
334 ci_dbg_print("%s\n", __func__);
335
336 if (0 != slot)
337 return -EINVAL;
338
339 mutex_lock(&inter->fpga_mutex);
340
341 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
342 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
343 (ret & 0xcf) | (1 << (5 - state->nr)), 0);
344
345 mutex_unlock(&inter->fpga_mutex);
346
347 for (;;) {
348 mdelay(50);
349
350 mutex_lock(&inter->fpga_mutex);
351
352 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
353 0, NETUP_CI_FLG_RD);
354 mutex_unlock(&inter->fpga_mutex);
355
356 if ((ret & (1 << (5 - state->nr))) == 0)
357 break;
358 if (time_after(jiffies, t_out))
359 break;
360 }
361
362
363 ci_dbg_print("%s: %d msecs\n", __func__,
364 jiffies_to_msecs(jiffies + msecs_to_jiffies(9999) - t_out));
365
366 return 0;
367}
368
369int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
370{
371 /* not implemented */
372 return 0;
373}
374
375int altera_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
376{
377 struct altera_ci_state *state = en50221->data;
378 struct fpga_internal *inter = state->internal;
379 int ret;
380
381 ci_dbg_print("%s\n", __func__);
382
383 if (0 != slot)
384 return -EINVAL;
385
386 mutex_lock(&inter->fpga_mutex);
387
388 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
389 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
390 (ret & 0x0f) | (1 << (3 - state->nr)), 0);
391
392 mutex_unlock(&inter->fpga_mutex);
393
394 return 0;
395}
396
397/* work handler */
398static void netup_read_ci_status(struct work_struct *work)
399{
400 struct fpga_internal *inter =
401 container_of(work, struct fpga_internal, work);
402 int ret;
403
404 ci_dbg_print("%s\n", __func__);
405
406 mutex_lock(&inter->fpga_mutex);
407 /* ack' irq */
408 ret = netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0, NETUP_CI_FLG_RD);
409 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
410
411 mutex_unlock(&inter->fpga_mutex);
412
413 if (inter->state[1] != NULL) {
414 inter->state[1]->status =
415 ((ret & 1) == 0 ?
416 DVB_CA_EN50221_POLL_CAM_PRESENT |
417 DVB_CA_EN50221_POLL_CAM_READY : 0);
418 ci_dbg_print("%s: setting CI[1] status = 0x%x\n",
419 __func__, inter->state[1]->status);
420 };
421
422 if (inter->state[0] != NULL) {
423 inter->state[0]->status =
424 ((ret & 2) == 0 ?
425 DVB_CA_EN50221_POLL_CAM_PRESENT |
426 DVB_CA_EN50221_POLL_CAM_READY : 0);
427 ci_dbg_print("%s: setting CI[0] status = 0x%x\n",
428 __func__, inter->state[0]->status);
429 };
430}
431
432/* CI irq handler */
433int altera_ci_irq(void *dev)
434{
435 struct fpga_inode *temp_int = NULL;
436 struct fpga_internal *inter = NULL;
437
438 ci_dbg_print("%s\n", __func__);
439
440 if (dev != NULL) {
441 temp_int = find_inode(dev);
442 if (temp_int != NULL) {
443 inter = temp_int->internal;
444 schedule_work(&inter->work);
445 }
446 }
447
448 return 1;
449}
450EXPORT_SYMBOL(altera_ci_irq);
451
452int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot,
453 int open)
454{
455 struct altera_ci_state *state = en50221->data;
456
457 if (0 != slot)
458 return -EINVAL;
459
460 return state->status;
461}
462
463void altera_hw_filt_release(void *main_dev, int filt_nr)
464{
465 struct fpga_inode *temp_int = find_inode(main_dev);
466 struct netup_hw_pid_filter *pid_filt = NULL;
467
468 ci_dbg_print("%s\n", __func__);
469
470 if (temp_int != NULL) {
471 pid_filt = temp_int->internal->pid_filt[filt_nr - 1];
472 /* stored old feed controls */
473 pid_filt->demux->start_feed = pid_filt->start_feed;
474 pid_filt->demux->stop_feed = pid_filt->stop_feed;
475
476 if (((--(temp_int->internal->filts_used)) <= 0) &&
477 ((temp_int->internal->cis_used) <= 0)) {
478
479 ci_dbg_print("%s: Actually removing\n", __func__);
480
481 remove_inode(temp_int->internal);
482 kfree(pid_filt->internal);
483 }
484
485 kfree(pid_filt);
486
487 }
488
489}
490EXPORT_SYMBOL(altera_hw_filt_release);
491
492void altera_ci_release(void *dev, int ci_nr)
493{
494 struct fpga_inode *temp_int = find_inode(dev);
495 struct altera_ci_state *state = NULL;
496
497 ci_dbg_print("%s\n", __func__);
498
499 if (temp_int != NULL) {
500 state = temp_int->internal->state[ci_nr - 1];
501 altera_hw_filt_release(dev, ci_nr);
502
503
504 if (((temp_int->internal->filts_used) <= 0) &&
505 ((--(temp_int->internal->cis_used)) <= 0)) {
506
507 ci_dbg_print("%s: Actually removing\n", __func__);
508
509 remove_inode(temp_int->internal);
510 kfree(state->internal);
511 }
512
513 if (state != NULL) {
514 if (state->ca.data != NULL)
515 dvb_ca_en50221_release(&state->ca);
516
517 kfree(state);
518 }
519 }
520
521}
522EXPORT_SYMBOL(altera_ci_release);
523
524static void altera_pid_control(struct netup_hw_pid_filter *pid_filt,
525 u16 pid, int onoff)
526{
527 struct fpga_internal *inter = pid_filt->internal;
528 u8 store = 0;
529
530 /* pid 0-0x1f always enabled, don't touch them */
531 if ((pid == 0x2000) || (pid < 0x20))
532 return;
533
534 mutex_lock(&inter->fpga_mutex);
535
536 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, (pid >> 3) & 0xff, 0);
537 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
538 ((pid >> 11) & 0x03) | (pid_filt->nr << 2), 0);
539
540 store = netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, 0, NETUP_CI_FLG_RD);
541
542 if (onoff)/* 0 - on, 1 - off */
543 store |= (1 << (pid & 7));
544 else
545 store &= ~(1 << (pid & 7));
546
547 netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, store, 0);
548
549 mutex_unlock(&inter->fpga_mutex);
550
551 pid_dbg_print("%s: (%d) set pid: %5d 0x%04x '%s'\n", __func__,
552 pid_filt->nr, pid, pid, onoff ? "off" : "on");
553}
554
555static void altera_toggle_fullts_streaming(struct netup_hw_pid_filter *pid_filt,
556 int filt_nr, int onoff)
557{
558 struct fpga_internal *inter = pid_filt->internal;
559 u8 store = 0;
560 int i;
561
562 pid_dbg_print("%s: pid_filt->nr[%d] now %s\n", __func__, pid_filt->nr,
563 onoff ? "off" : "on");
564
565 if (onoff)/* 0 - on, 1 - off */
566 store = 0xff;/* ignore pid */
567 else
568 store = 0;/* enable pid */
569
570 mutex_lock(&inter->fpga_mutex);
571
572 for (i = 0; i < 1024; i++) {
573 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, i & 0xff, 0);
574
575 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
576 ((i >> 8) & 0x03) | (pid_filt->nr << 2), 0);
577 /* pid 0-0x1f always enabled */
578 netup_fpga_op_rw(inter, NETUP_CI_PID_DATA,
579 (i > 3 ? store : 0), 0);
580 }
581
582 mutex_unlock(&inter->fpga_mutex);
583}
584
585int altera_pid_feed_control(void *demux_dev, int filt_nr,
586 struct dvb_demux_feed *feed, int onoff)
587{
588 struct fpga_inode *temp_int = find_dinode(demux_dev);
589 struct fpga_internal *inter = temp_int->internal;
590 struct netup_hw_pid_filter *pid_filt = inter->pid_filt[filt_nr - 1];
591
592 altera_pid_control(pid_filt, feed->pid, onoff ? 0 : 1);
593 /* call old feed proc's */
594 if (onoff)
595 pid_filt->start_feed(feed);
596 else
597 pid_filt->stop_feed(feed);
598
599 if (feed->pid == 0x2000)
600 altera_toggle_fullts_streaming(pid_filt, filt_nr,
601 onoff ? 0 : 1);
602
603 return 0;
604}
605EXPORT_SYMBOL(altera_pid_feed_control);
606
607int altera_ci_start_feed(struct dvb_demux_feed *feed, int num)
608{
609 altera_pid_feed_control(feed->demux, num, feed, 1);
610
611 return 0;
612}
613
614int altera_ci_stop_feed(struct dvb_demux_feed *feed, int num)
615{
616 altera_pid_feed_control(feed->demux, num, feed, 0);
617
618 return 0;
619}
620
621int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
622{
623 return altera_ci_start_feed(feed, 1);
624}
625
626int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
627{
628 return altera_ci_stop_feed(feed, 1);
629}
630
631int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
632{
633 return altera_ci_start_feed(feed, 2);
634}
635
636int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
637{
638 return altera_ci_stop_feed(feed, 2);
639}
640
641int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
642{
643 struct netup_hw_pid_filter *pid_filt = NULL;
644 struct fpga_inode *temp_int = find_inode(config->dev);
645 struct fpga_internal *inter = NULL;
646 int ret = 0;
647
648 pid_filt = kzalloc(sizeof(struct netup_hw_pid_filter), GFP_KERNEL);
649
650 ci_dbg_print("%s\n", __func__);
651
652 if (!pid_filt) {
653 ret = -ENOMEM;
654 goto err;
655 }
656
657 if (temp_int != NULL) {
658 inter = temp_int->internal;
659 (inter->filts_used)++;
660 ci_dbg_print("%s: Find Internal Structure!\n", __func__);
661 } else {
662 inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
663 if (!inter) {
664 ret = -ENOMEM;
665 goto err;
666 }
667
668 temp_int = append_internal(inter);
669 inter->filts_used = 1;
670 inter->dev = config->dev;
671 inter->fpga_rw = config->fpga_rw;
672 mutex_init(&inter->fpga_mutex);
673 inter->strt_wrk = 1;
674 ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
675 }
676
677 ci_dbg_print("%s: setting hw pid filter = %p for ci = %d\n", __func__,
678 pid_filt, hw_filt_nr - 1);
679 inter->pid_filt[hw_filt_nr - 1] = pid_filt;
680 pid_filt->demux = config->demux;
681 pid_filt->internal = inter;
682 pid_filt->nr = hw_filt_nr - 1;
683 /* store old feed controls */
684 pid_filt->start_feed = config->demux->start_feed;
685 pid_filt->stop_feed = config->demux->stop_feed;
686 /* replace with new feed controls */
687 if (hw_filt_nr == 1) {
688 pid_filt->demux->start_feed = altera_ci_start_feed_1;
689 pid_filt->demux->stop_feed = altera_ci_stop_feed_1;
690 } else if (hw_filt_nr == 2) {
691 pid_filt->demux->start_feed = altera_ci_start_feed_2;
692 pid_filt->demux->stop_feed = altera_ci_stop_feed_2;
693 }
694
695 altera_toggle_fullts_streaming(pid_filt, 0, 1);
696
697 return 0;
698err:
699 ci_dbg_print("%s: Can't init hardware filter: Error %d\n",
700 __func__, ret);
701
702 kfree(pid_filt);
703
704 return ret;
705}
706EXPORT_SYMBOL(altera_hw_filt_init);
707
708int altera_ci_init(struct altera_ci_config *config, int ci_nr)
709{
710 struct altera_ci_state *state;
711 struct fpga_inode *temp_int = find_inode(config->dev);
712 struct fpga_internal *inter = NULL;
713 int ret = 0;
714 u8 store = 0;
715
716 state = kzalloc(sizeof(struct altera_ci_state), GFP_KERNEL);
717
718 ci_dbg_print("%s\n", __func__);
719
720 if (!state) {
721 ret = -ENOMEM;
722 goto err;
723 }
724
725 if (temp_int != NULL) {
726 inter = temp_int->internal;
727 (inter->cis_used)++;
728 ci_dbg_print("%s: Find Internal Structure!\n", __func__);
729 } else {
730 inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
731 if (!inter) {
732 ret = -ENOMEM;
733 goto err;
734 }
735
736 temp_int = append_internal(inter);
737 inter->cis_used = 1;
738 inter->dev = config->dev;
739 inter->fpga_rw = config->fpga_rw;
740 mutex_init(&inter->fpga_mutex);
741 inter->strt_wrk = 1;
742 ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
743 }
744
745 ci_dbg_print("%s: setting state = %p for ci = %d\n", __func__,
746 state, ci_nr - 1);
747 inter->state[ci_nr - 1] = state;
748 state->internal = inter;
749 state->nr = ci_nr - 1;
750
751 state->ca.owner = THIS_MODULE;
752 state->ca.read_attribute_mem = altera_ci_read_attribute_mem;
753 state->ca.write_attribute_mem = altera_ci_write_attribute_mem;
754 state->ca.read_cam_control = altera_ci_read_cam_ctl;
755 state->ca.write_cam_control = altera_ci_write_cam_ctl;
756 state->ca.slot_reset = altera_ci_slot_reset;
757 state->ca.slot_shutdown = altera_ci_slot_shutdown;
758 state->ca.slot_ts_enable = altera_ci_slot_ts_ctl;
759 state->ca.poll_slot_status = altera_poll_ci_slot_status;
760 state->ca.data = state;
761
762 ret = dvb_ca_en50221_init(config->adapter,
763 &state->ca,
764 /* flags */ 0,
765 /* n_slots */ 1);
766 if (0 != ret)
767 goto err;
768
769 altera_hw_filt_init(config, ci_nr);
770
771 if (inter->strt_wrk) {
772 INIT_WORK(&inter->work, netup_read_ci_status);
773 inter->strt_wrk = 0;
774 }
775
776 ci_dbg_print("%s: CI initialized!\n", __func__);
777
778 mutex_lock(&inter->fpga_mutex);
779
780 /* Enable div */
781 netup_fpga_op_rw(inter, NETUP_CI_TSA_DIV, 0x0, 0);
782 netup_fpga_op_rw(inter, NETUP_CI_TSB_DIV, 0x0, 0);
783
784 /* enable TS out */
785 store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
786 store |= (3 << 4);
787 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
788
789 ret = netup_fpga_op_rw(inter, NETUP_CI_REVISION, 0, NETUP_CI_FLG_RD);
790 /* enable irq */
791 netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0x44, 0);
792
793 mutex_unlock(&inter->fpga_mutex);
794
795 ci_dbg_print("%s: NetUP CI Revision = 0x%x\n", __func__, ret);
796
797 schedule_work(&inter->work);
798
799 return 0;
800err:
801 ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
802
803 kfree(state);
804
805 return ret;
806}
807EXPORT_SYMBOL(altera_ci_init);
808
809int altera_ci_tuner_reset(void *dev, int ci_nr)
810{
811 struct fpga_inode *temp_int = find_inode(dev);
812 struct fpga_internal *inter = NULL;
813 u8 store;
814
815 ci_dbg_print("%s\n", __func__);
816
817 if (temp_int == NULL)
818 return -1;
819
820 if (temp_int->internal == NULL)
821 return -1;
822
823 inter = temp_int->internal;
824
825 mutex_lock(&inter->fpga_mutex);
826
827 store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
828 store &= ~(4 << (2 - ci_nr));
829 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
830 msleep(100);
831 store |= (4 << (2 - ci_nr));
832 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
833
834 mutex_unlock(&inter->fpga_mutex);
835
836 return 0;
837}
838EXPORT_SYMBOL(altera_ci_tuner_reset);
diff --git a/drivers/media/video/cx23885/altera-ci.h b/drivers/media/video/cx23885/altera-ci.h
new file mode 100644
index 000000000000..70e4fd69ad9e
--- /dev/null
+++ b/drivers/media/video/cx23885/altera-ci.h
@@ -0,0 +1,100 @@
1/*
2 * altera-ci.c
3 *
4 * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card
5 *
6 * Copyright (C) 2010 NetUP Inc.
7 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 *
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24#ifndef __ALTERA_CI_H
25#define __ALTERA_CI_H
26
27#define ALT_DATA 0x000000ff
28#define ALT_TDI 0x00008000
29#define ALT_TDO 0x00004000
30#define ALT_TCK 0x00002000
31#define ALT_RDY 0x00001000
32#define ALT_RD 0x00000800
33#define ALT_WR 0x00000400
34#define ALT_AD_RG 0x00000200
35#define ALT_CS 0x00000100
36
37struct altera_ci_config {
38 void *dev;/* main dev, for example cx23885_dev */
39 void *adapter;/* for CI to connect to */
40 struct dvb_demux *demux;/* for hardware PID filter to connect to */
41 int (*fpga_rw) (void *dev, int ad_rg, int val, int rw);
42};
43
44#if defined(CONFIG_MEDIA_ALTERA_CI) || (defined(CONFIG_MEDIA_ALTERA_CI_MODULE) \
45 && defined(MODULE))
46
47extern int altera_ci_init(struct altera_ci_config *config, int ci_nr);
48extern void altera_ci_release(void *dev, int ci_nr);
49extern int altera_ci_irq(void *dev);
50extern int altera_ci_tuner_reset(void *dev, int ci_nr);
51
52#else
53
54static inline int altera_ci_init(struct altera_ci_config *config, int ci_nr)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return 0;
58}
59
60static inline void altera_ci_release(void *dev, int ci_nr)
61{
62 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
63}
64
65static inline int altera_ci_irq(void *dev)
66{
67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
68 return 0;
69}
70
71static inline int altera_ci_tuner_reset(void *dev, int ci_nr)
72{
73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
74 return 0;
75}
76
77#endif
78#if 0
79static inline int altera_hw_filt_init(struct altera_ci_config *config,
80 int hw_filt_nr)
81{
82 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
83 return 0;
84}
85
86static inline void altera_hw_filt_release(void *dev, int filt_nr)
87{
88 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
89}
90
91static inline int altera_pid_feed_control(void *dev, int filt_nr,
92 struct dvb_demux_feed *dvbdmxfeed, int onoff)
93{
94 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
95 return 0;
96}
97
98#endif /* CONFIG_MEDIA_ALTERA_CI */
99
100#endif /* __ALTERA_CI_H */
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index b298b730943c..ea88722cb4ab 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -24,10 +24,14 @@
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <media/cx25840.h> 26#include <media/cx25840.h>
27#include <linux/firmware.h>
28#include <staging/altera.h>
27 29
28#include "cx23885.h" 30#include "cx23885.h"
29#include "tuner-xc2028.h" 31#include "tuner-xc2028.h"
30#include "netup-init.h" 32#include "netup-init.h"
33#include "altera-ci.h"
34#include "xc5000.h"
31#include "cx23888-ir.h" 35#include "cx23888-ir.h"
32 36
33static unsigned int enable_885_ir; 37static unsigned int enable_885_ir;
@@ -90,6 +94,7 @@ struct cx23885_board cx23885_boards[] = {
90 .portc = CX23885_MPEG_DVB, 94 .portc = CX23885_MPEG_DVB,
91 .tuner_type = TUNER_PHILIPS_TDA8290, 95 .tuner_type = TUNER_PHILIPS_TDA8290,
92 .tuner_addr = 0x42, /* 0x84 >> 1 */ 96 .tuner_addr = 0x42, /* 0x84 >> 1 */
97 .tuner_bus = 1,
93 .input = {{ 98 .input = {{
94 .type = CX23885_VMUX_TELEVISION, 99 .type = CX23885_VMUX_TELEVISION,
95 .vmux = CX25840_VIN7_CH3 | 100 .vmux = CX25840_VIN7_CH3 |
@@ -187,7 +192,7 @@ struct cx23885_board cx23885_boards[] = {
187 .portb = CX23885_MPEG_DVB, 192 .portb = CX23885_MPEG_DVB,
188 }, 193 },
189 [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = { 194 [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = {
190 .cimax = 1, 195 .ci_type = 1,
191 .name = "NetUP Dual DVB-S2 CI", 196 .name = "NetUP Dual DVB-S2 CI",
192 .portb = CX23885_MPEG_DVB, 197 .portb = CX23885_MPEG_DVB,
193 .portc = CX23885_MPEG_DVB, 198 .portc = CX23885_MPEG_DVB,
@@ -212,6 +217,7 @@ struct cx23885_board cx23885_boards[] = {
212 .name = "Mygica X8506 DMB-TH", 217 .name = "Mygica X8506 DMB-TH",
213 .tuner_type = TUNER_XC5000, 218 .tuner_type = TUNER_XC5000,
214 .tuner_addr = 0x61, 219 .tuner_addr = 0x61,
220 .tuner_bus = 1,
215 .porta = CX23885_ANALOG_VIDEO, 221 .porta = CX23885_ANALOG_VIDEO,
216 .portb = CX23885_MPEG_DVB, 222 .portb = CX23885_MPEG_DVB,
217 .input = { 223 .input = {
@@ -241,6 +247,7 @@ struct cx23885_board cx23885_boards[] = {
241 .name = "Magic-Pro ProHDTV Extreme 2", 247 .name = "Magic-Pro ProHDTV Extreme 2",
242 .tuner_type = TUNER_XC5000, 248 .tuner_type = TUNER_XC5000,
243 .tuner_addr = 0x61, 249 .tuner_addr = 0x61,
250 .tuner_bus = 1,
244 .porta = CX23885_ANALOG_VIDEO, 251 .porta = CX23885_ANALOG_VIDEO,
245 .portb = CX23885_MPEG_DVB, 252 .portb = CX23885_MPEG_DVB,
246 .input = { 253 .input = {
@@ -289,6 +296,7 @@ struct cx23885_board cx23885_boards[] = {
289 .porta = CX23885_ANALOG_VIDEO, 296 .porta = CX23885_ANALOG_VIDEO,
290 .tuner_type = TUNER_XC2028, 297 .tuner_type = TUNER_XC2028,
291 .tuner_addr = 0x61, 298 .tuner_addr = 0x61,
299 .tuner_bus = 1,
292 .input = {{ 300 .input = {{
293 .type = CX23885_VMUX_TELEVISION, 301 .type = CX23885_VMUX_TELEVISION,
294 .vmux = CX25840_VIN2_CH1 | 302 .vmux = CX25840_VIN2_CH1 |
@@ -313,6 +321,7 @@ struct cx23885_board cx23885_boards[] = {
313 .name = "GoTView X5 3D Hybrid", 321 .name = "GoTView X5 3D Hybrid",
314 .tuner_type = TUNER_XC5000, 322 .tuner_type = TUNER_XC5000,
315 .tuner_addr = 0x64, 323 .tuner_addr = 0x64,
324 .tuner_bus = 1,
316 .porta = CX23885_ANALOG_VIDEO, 325 .porta = CX23885_ANALOG_VIDEO,
317 .portb = CX23885_MPEG_DVB, 326 .portb = CX23885_MPEG_DVB,
318 .input = {{ 327 .input = {{
@@ -329,6 +338,21 @@ struct cx23885_board cx23885_boards[] = {
329 CX25840_SVIDEO_CHROMA4, 338 CX25840_SVIDEO_CHROMA4,
330 } }, 339 } },
331 }, 340 },
341 [CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF] = {
342 .ci_type = 2,
343 .name = "NetUP Dual DVB-T/C-CI RF",
344 .porta = CX23885_ANALOG_VIDEO,
345 .portb = CX23885_MPEG_DVB,
346 .portc = CX23885_MPEG_DVB,
347 .num_fds_portb = 2,
348 .num_fds_portc = 2,
349 .tuner_type = TUNER_XC5000,
350 .tuner_addr = 0x64,
351 .input = { {
352 .type = CX23885_VMUX_TELEVISION,
353 .vmux = CX25840_COMPOSITE1,
354 } },
355 },
332}; 356};
333const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 357const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
334 358
@@ -520,6 +544,10 @@ struct cx23885_subid cx23885_subids[] = {
520 .subvendor = 0x5654, 544 .subvendor = 0x5654,
521 .subdevice = 0x2390, 545 .subdevice = 0x2390,
522 .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID, 546 .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID,
547 }, {
548 .subvendor = 0x1b55,
549 .subdevice = 0xe2e4,
550 .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF,
523 }, 551 },
524}; 552};
525const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 553const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -740,6 +768,9 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
740 /* Tuner Reset Command */ 768 /* Tuner Reset Command */
741 bitmask = 0x02; 769 bitmask = 0x02;
742 break; 770 break;
771 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
772 altera_ci_tuner_reset(dev, port->nr);
773 break;
743 } 774 }
744 775
745 if (bitmask) { 776 if (bitmask) {
@@ -998,6 +1029,33 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
998 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: 1029 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
999 cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ 1030 cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
1000 break; 1031 break;
1032 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1033 /* GPIO-0 ~INT in
1034 GPIO-1 TMS out
1035 GPIO-2 ~reset chips out
1036 GPIO-3 to GPIO-10 data/addr for CA in/out
1037 GPIO-11 ~CS out
1038 GPIO-12 ADDR out
1039 GPIO-13 ~WR out
1040 GPIO-14 ~RD out
1041 GPIO-15 ~RDY in
1042 GPIO-16 TCK out
1043 GPIO-17 TDO in
1044 GPIO-18 TDI out
1045 */
1046 cx_set(GP0_IO, 0x00060000); /* GPIO-1,2 as out */
1047 /* GPIO-0 as INT, reset & TMS low */
1048 cx_clear(GP0_IO, 0x00010006);
1049 mdelay(100);/* reset delay */
1050 cx_set(GP0_IO, 0x00000004); /* reset high */
1051 cx_write(MC417_CTL, 0x00000037);/* enable GPIO-3..18 pins */
1052 /* GPIO-17 is TDO in, GPIO-15 is ~RDY in, rest is out */
1053 cx_write(MC417_OEN, 0x00005000);
1054 /* ~RD, ~WR high; ADDR low; ~CS high */
1055 cx_write(MC417_RWD, 0x00000d00);
1056 /* enable irq */
1057 cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
1058 break;
1001 } 1059 }
1002} 1060}
1003 1061
@@ -1113,6 +1171,31 @@ void cx23885_ir_fini(struct cx23885_dev *dev)
1113 } 1171 }
1114} 1172}
1115 1173
1174int netup_jtag_io(void *device, int tms, int tdi, int read_tdo)
1175{
1176 int data;
1177 int tdo = 0;
1178 struct cx23885_dev *dev = (struct cx23885_dev *)device;
1179 /*TMS*/
1180 data = ((cx_read(GP0_IO)) & (~0x00000002));
1181 data |= (tms ? 0x00020002 : 0x00020000);
1182 cx_write(GP0_IO, data);
1183
1184 /*TDI*/
1185 data = ((cx_read(MC417_RWD)) & (~0x0000a000));
1186 data |= (tdi ? 0x00008000 : 0);
1187 cx_write(MC417_RWD, data);
1188 if (read_tdo)
1189 tdo = (data & 0x00004000) ? 1 : 0; /*TDO*/
1190
1191 cx_write(MC417_RWD, data | 0x00002000);
1192 udelay(1);
1193 /*TCK*/
1194 cx_write(MC417_RWD, data);
1195
1196 return tdo;
1197}
1198
1116void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) 1199void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
1117{ 1200{
1118 switch (dev->board) { 1201 switch (dev->board) {
@@ -1212,6 +1295,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1212 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1295 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1213 break; 1296 break;
1214 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1297 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1298 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1215 ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 1299 ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
1216 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1300 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1217 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1301 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
@@ -1271,6 +1355,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1271 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 1355 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
1272 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 1356 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
1273 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1357 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1358 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1274 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1359 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1275 case CX23885_BOARD_HAUPPAUGE_HVR1850: 1360 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1276 case CX23885_BOARD_MYGICA_X8506: 1361 case CX23885_BOARD_MYGICA_X8506:
@@ -1293,6 +1378,29 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1293 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1378 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1294 netup_initialize(dev); 1379 netup_initialize(dev);
1295 break; 1380 break;
1381 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
1382 int ret;
1383 const struct firmware *fw;
1384 const char *filename = "dvb-netup-altera-01.fw";
1385 char *action = "configure";
1386 struct altera_config netup_config = {
1387 .dev = dev,
1388 .action = action,
1389 .jtag_io = netup_jtag_io,
1390 };
1391
1392 netup_initialize(dev);
1393
1394 ret = request_firmware(&fw, filename, &dev->pci->dev);
1395 if (ret != 0)
1396 printk(KERN_ERR "did not find the firmware file. (%s) "
1397 "Please see linux/Documentation/dvb/ for more details "
1398 "on firmware-problems.", filename);
1399 else
1400 altera_init(&netup_config, fw);
1401
1402 break;
1403 }
1296 } 1404 }
1297} 1405}
1298 1406
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 359882419b7f..9933810b4e33 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -29,9 +29,11 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <asm/div64.h> 31#include <asm/div64.h>
32#include <linux/firmware.h>
32 33
33#include "cx23885.h" 34#include "cx23885.h"
34#include "cimax2.h" 35#include "cimax2.h"
36#include "altera-ci.h"
35#include "cx23888-ir.h" 37#include "cx23888-ir.h"
36#include "cx23885-ir.h" 38#include "cx23885-ir.h"
37#include "cx23885-av.h" 39#include "cx23885-av.h"
@@ -902,8 +904,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
902 dev->pci_bus = dev->pci->bus->number; 904 dev->pci_bus = dev->pci->bus->number;
903 dev->pci_slot = PCI_SLOT(dev->pci->devfn); 905 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
904 cx23885_irq_add(dev, 0x001f00); 906 cx23885_irq_add(dev, 0x001f00);
905 if (cx23885_boards[dev->board].cimax > 0)
906 cx23885_irq_add(dev, 0x01800000); /* for CiMaxes */
907 907
908 /* External Master 1 Bus */ 908 /* External Master 1 Bus */
909 dev->i2c_bus[0].nr = 0; 909 dev->i2c_bus[0].nr = 0;
@@ -970,11 +970,12 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
970 /* Assume some sensible defaults */ 970 /* Assume some sensible defaults */
971 dev->tuner_type = cx23885_boards[dev->board].tuner_type; 971 dev->tuner_type = cx23885_boards[dev->board].tuner_type;
972 dev->tuner_addr = cx23885_boards[dev->board].tuner_addr; 972 dev->tuner_addr = cx23885_boards[dev->board].tuner_addr;
973 dev->tuner_bus = cx23885_boards[dev->board].tuner_bus;
973 dev->radio_type = cx23885_boards[dev->board].radio_type; 974 dev->radio_type = cx23885_boards[dev->board].radio_type;
974 dev->radio_addr = cx23885_boards[dev->board].radio_addr; 975 dev->radio_addr = cx23885_boards[dev->board].radio_addr;
975 976
976 dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", 977 dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x tuner_bus = %d\n",
977 __func__, dev->tuner_type, dev->tuner_addr); 978 __func__, dev->tuner_type, dev->tuner_addr, dev->tuner_bus);
978 dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", 979 dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n",
979 __func__, dev->radio_type, dev->radio_addr); 980 __func__, dev->radio_type, dev->radio_addr);
980 981
@@ -1004,6 +1005,9 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
1004 } 1005 }
1005 1006
1006 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { 1007 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
1008 if (cx23885_boards[dev->board].num_fds_portb)
1009 dev->ts1.num_frontends =
1010 cx23885_boards[dev->board].num_fds_portb;
1007 if (cx23885_dvb_register(&dev->ts1) < 0) { 1011 if (cx23885_dvb_register(&dev->ts1) < 0) {
1008 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", 1012 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n",
1009 __func__); 1013 __func__);
@@ -1018,6 +1022,9 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
1018 } 1022 }
1019 1023
1020 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { 1024 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
1025 if (cx23885_boards[dev->board].num_fds_portc)
1026 dev->ts2.num_frontends =
1027 cx23885_boards[dev->board].num_fds_portc;
1021 if (cx23885_dvb_register(&dev->ts2) < 0) { 1028 if (cx23885_dvb_register(&dev->ts2) < 0) {
1022 printk(KERN_ERR 1029 printk(KERN_ERR
1023 "%s() Failed to register dvb on VID_C\n", 1030 "%s() Failed to register dvb on VID_C\n",
@@ -1034,6 +1041,10 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
1034 1041
1035 cx23885_dev_checkrevision(dev); 1042 cx23885_dev_checkrevision(dev);
1036 1043
1044 /* disable MSI for NetUP cards, otherwise CI is not working */
1045 if (cx23885_boards[dev->board].ci_type > 0)
1046 cx_clear(RDR_RDRCTL1, 1 << 8);
1047
1037 return 0; 1048 return 0;
1038} 1049}
1039 1050
@@ -1822,14 +1833,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1822 PCI_MSK_IR); 1833 PCI_MSK_IR);
1823 } 1834 }
1824 1835
1825 if (cx23885_boards[dev->board].cimax > 0 && 1836 if (cx23885_boards[dev->board].ci_type == 1 &&
1826 ((pci_status & PCI_MSK_GPIO0) || 1837 (pci_status & (PCI_MSK_GPIO1 | PCI_MSK_GPIO0)))
1827 (pci_status & PCI_MSK_GPIO1))) { 1838 handled += netup_ci_slot_status(dev, pci_status);
1828
1829 if (cx23885_boards[dev->board].cimax > 0)
1830 handled += netup_ci_slot_status(dev, pci_status);
1831 1839
1832 } 1840 if (cx23885_boards[dev->board].ci_type == 2 &&
1841 (pci_status & PCI_MSK_GPIO0))
1842 handled += altera_ci_irq(dev);
1833 1843
1834 if (ts1_status) { 1844 if (ts1_status) {
1835 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 1845 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
@@ -2064,7 +2074,10 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
2064 2074
2065 switch (dev->board) { 2075 switch (dev->board) {
2066 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 2076 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
2067 cx23885_irq_add_enable(dev, 0x01800000); /* for NetUP */ 2077 cx23885_irq_add_enable(dev, PCI_MSK_GPIO1 | PCI_MSK_GPIO0);
2078 break;
2079 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
2080 cx23885_irq_add_enable(dev, PCI_MSK_GPIO0);
2068 break; 2081 break;
2069 } 2082 }
2070 2083
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 5958cb882e93..3c315f94cc85 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -58,6 +58,8 @@
58#include "atbm8830.h" 58#include "atbm8830.h"
59#include "ds3000.h" 59#include "ds3000.h"
60#include "cx23885-f300.h" 60#include "cx23885-f300.h"
61#include "altera-ci.h"
62#include "stv0367.h"
61 63
62static unsigned int debug; 64static unsigned int debug;
63 65
@@ -108,6 +110,22 @@ static void dvb_buf_release(struct videobuf_queue *q,
108 cx23885_free_buffer(q, (struct cx23885_buffer *)vb); 110 cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
109} 111}
110 112
113static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open)
114{
115 struct videobuf_dvb_frontends *f;
116 struct videobuf_dvb_frontend *fe;
117
118 f = &port->frontends;
119
120 if (f->gate <= 1) /* undefined or fe0 */
121 fe = videobuf_dvb_get_frontend(f, 1);
122 else
123 fe = videobuf_dvb_get_frontend(f, f->gate);
124
125 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
126 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
127}
128
111static struct videobuf_queue_ops dvb_qops = { 129static struct videobuf_queue_ops dvb_qops = {
112 .buf_setup = dvb_buf_setup, 130 .buf_setup = dvb_buf_setup,
113 .buf_prepare = dvb_buf_prepare, 131 .buf_prepare = dvb_buf_prepare,
@@ -570,12 +588,84 @@ static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
570 .i2c_address = 0x60, 588 .i2c_address = 0x60,
571 .osc_clk = 20 589 .osc_clk = 20
572}; 590};
591static struct stv0367_config netup_stv0367_config[] = {
592 {
593 .demod_address = 0x1c,
594 .xtal = 27000000,
595 .if_khz = 4500,
596 .if_iq_mode = 0,
597 .ts_mode = 1,
598 .clk_pol = 0,
599 }, {
600 .demod_address = 0x1d,
601 .xtal = 27000000,
602 .if_khz = 4500,
603 .if_iq_mode = 0,
604 .ts_mode = 1,
605 .clk_pol = 0,
606 },
607};
608
609static struct xc5000_config netup_xc5000_config[] = {
610 {
611 .i2c_address = 0x61,
612 .if_khz = 4500,
613 }, {
614 .i2c_address = 0x64,
615 .if_khz = 4500,
616 },
617};
618
619int netup_altera_fpga_rw(void *device, int flag, int data, int read)
620{
621 struct cx23885_dev *dev = (struct cx23885_dev *)device;
622 unsigned long timeout = jiffies + msecs_to_jiffies(1);
623 uint32_t mem = 0;
624
625 mem = cx_read(MC417_RWD);
626 if (read)
627 cx_set(MC417_OEN, ALT_DATA);
628 else {
629 cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */
630 mem &= ~ALT_DATA;
631 mem |= (data & ALT_DATA);
632 }
633
634 if (flag)
635 mem |= ALT_AD_RG;
636 else
637 mem &= ~ALT_AD_RG;
638
639 mem &= ~ALT_CS;
640 if (read)
641 mem = (mem & ~ALT_RD) | ALT_WR;
642 else
643 mem = (mem & ~ALT_WR) | ALT_RD;
644
645 cx_write(MC417_RWD, mem); /* start RW cycle */
646
647 for (;;) {
648 mem = cx_read(MC417_RWD);
649 if ((mem & ALT_RDY) == 0)
650 break;
651 if (time_after(jiffies, timeout))
652 break;
653 udelay(1);
654 }
655
656 cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS);
657 if (read)
658 return mem & ALT_DATA;
659
660 return 0;
661};
573 662
574static int dvb_register(struct cx23885_tsport *port) 663static int dvb_register(struct cx23885_tsport *port)
575{ 664{
576 struct cx23885_dev *dev = port->dev; 665 struct cx23885_dev *dev = port->dev;
577 struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; 666 struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
578 struct videobuf_dvb_frontend *fe0; 667 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
668 int mfe_shared = 0; /* bus not shared by default */
579 int ret; 669 int ret;
580 670
581 /* Get the first frontend */ 671 /* Get the first frontend */
@@ -586,6 +676,12 @@ static int dvb_register(struct cx23885_tsport *port)
586 /* init struct videobuf_dvb */ 676 /* init struct videobuf_dvb */
587 fe0->dvb.name = dev->name; 677 fe0->dvb.name = dev->name;
588 678
679 /* multi-frontend gate control is undefined or defaults to fe0 */
680 port->frontends.gate = 0;
681
682 /* Sets the gate control callback to be used by i2c command calls */
683 port->gate_ctrl = cx23885_dvb_gate_ctrl;
684
589 /* init frontend */ 685 /* init frontend */
590 switch (dev->board) { 686 switch (dev->board) {
591 case CX23885_BOARD_HAUPPAUGE_HVR1250: 687 case CX23885_BOARD_HAUPPAUGE_HVR1250:
@@ -966,20 +1062,64 @@ static int dvb_register(struct cx23885_tsport *port)
966 break; 1062 break;
967 } 1063 }
968 break; 1064 break;
969 1065 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1066 i2c_bus = &dev->i2c_bus[0];
1067 mfe_shared = 1;/* MFE */
1068 port->frontends.gate = 0;/* not clear for me yet */
1069 /* ports B, C */
1070 /* MFE frontend 1 DVB-T */
1071 fe0->dvb.frontend = dvb_attach(stv0367ter_attach,
1072 &netup_stv0367_config[port->nr - 1],
1073 &i2c_bus->i2c_adap);
1074 if (fe0->dvb.frontend != NULL) {
1075 if (NULL == dvb_attach(xc5000_attach,
1076 fe0->dvb.frontend,
1077 &i2c_bus->i2c_adap,
1078 &netup_xc5000_config[port->nr - 1]))
1079 goto frontend_detach;
1080 /* load xc5000 firmware */
1081 fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend);
1082 }
1083 /* MFE frontend 2 */
1084 fe1 = videobuf_dvb_get_frontend(&port->frontends, 2);
1085 if (fe1 == NULL)
1086 goto frontend_detach;
1087 /* DVB-C init */
1088 fe1->dvb.frontend = dvb_attach(stv0367cab_attach,
1089 &netup_stv0367_config[port->nr - 1],
1090 &i2c_bus->i2c_adap);
1091 if (fe1->dvb.frontend != NULL) {
1092 fe1->dvb.frontend->id = 1;
1093 if (NULL == dvb_attach(xc5000_attach,
1094 fe1->dvb.frontend,
1095 &i2c_bus->i2c_adap,
1096 &netup_xc5000_config[port->nr - 1]))
1097 goto frontend_detach;
1098 }
1099 break;
970 default: 1100 default:
971 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 1101 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
972 " isn't supported yet\n", 1102 " isn't supported yet\n",
973 dev->name); 1103 dev->name);
974 break; 1104 break;
975 } 1105 }
976 if (NULL == fe0->dvb.frontend) { 1106
1107 if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) {
977 printk(KERN_ERR "%s: frontend initialization failed\n", 1108 printk(KERN_ERR "%s: frontend initialization failed\n",
978 dev->name); 1109 dev->name);
979 return -1; 1110 goto frontend_detach;
980 } 1111 }
1112
981 /* define general-purpose callback pointer */ 1113 /* define general-purpose callback pointer */
982 fe0->dvb.frontend->callback = cx23885_tuner_callback; 1114 fe0->dvb.frontend->callback = cx23885_tuner_callback;
1115 if (fe1)
1116 fe1->dvb.frontend->callback = cx23885_tuner_callback;
1117#if 0
1118 /* Ensure all frontends negotiate bus access */
1119 fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
1120 if (fe1)
1121 fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
1122#endif
983 1123
984 /* Put the analog decoder in standby to keep it quiet */ 1124 /* Put the analog decoder in standby to keep it quiet */
985 call_all(dev, core, s_power, 0); 1125 call_all(dev, core, s_power, 0);
@@ -989,10 +1129,10 @@ static int dvb_register(struct cx23885_tsport *port)
989 1129
990 /* register everything */ 1130 /* register everything */
991 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 1131 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
992 &dev->pci->dev, adapter_nr, 0, 1132 &dev->pci->dev, adapter_nr, mfe_shared,
993 cx23885_dvb_fe_ioctl_override); 1133 cx23885_dvb_fe_ioctl_override);
994 if (ret) 1134 if (ret)
995 return ret; 1135 goto frontend_detach;
996 1136
997 /* init CI & MAC */ 1137 /* init CI & MAC */
998 switch (dev->board) { 1138 switch (dev->board) {
@@ -1008,6 +1148,17 @@ static int dvb_register(struct cx23885_tsport *port)
1008 netup_ci_init(port); 1148 netup_ci_init(port);
1009 break; 1149 break;
1010 } 1150 }
1151 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
1152 struct altera_ci_config netup_ci_cfg = {
1153 .dev = dev,/* magic number to identify*/
1154 .adapter = &port->frontends.adapter,/* for CI */
1155 .demux = &fe0->dvb.demux,/* for hw pid filter */
1156 .fpga_rw = netup_altera_fpga_rw,
1157 };
1158
1159 altera_ci_init(&netup_ci_cfg, port->nr);
1160 break;
1161 }
1011 case CX23885_BOARD_TEVII_S470: { 1162 case CX23885_BOARD_TEVII_S470: {
1012 u8 eeprom[256]; /* 24C02 i2c eeprom */ 1163 u8 eeprom[256]; /* 24C02 i2c eeprom */
1013 1164
@@ -1024,6 +1175,11 @@ static int dvb_register(struct cx23885_tsport *port)
1024 } 1175 }
1025 1176
1026 return ret; 1177 return ret;
1178
1179frontend_detach:
1180 port->gate_ctrl = NULL;
1181 videobuf_dvb_dealloc_frontends(&port->frontends);
1182 return -EINVAL;
1027} 1183}
1028 1184
1029int cx23885_dvb_register(struct cx23885_tsport *port) 1185int cx23885_dvb_register(struct cx23885_tsport *port)
@@ -1100,8 +1256,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
1100 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1256 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1101 netup_ci_exit(port); 1257 netup_ci_exit(port);
1102 break; 1258 break;
1259 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1260 altera_ci_release(port->dev, port->nr);
1261 break;
1103 } 1262 }
1104 1263
1264 port->gate_ctrl = NULL;
1265
1105 return 0; 1266 return 0;
1106} 1267}
1107 1268
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 199b9964bbe5..e97cafd83984 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -264,7 +264,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
264 driver_type = RC_DRIVER_IR_RAW; 264 driver_type = RC_DRIVER_IR_RAW;
265 allowed_protos = RC_TYPE_ALL; 265 allowed_protos = RC_TYPE_ALL;
266 /* The grey Hauppauge RC-5 remote */ 266 /* The grey Hauppauge RC-5 remote */
267 rc_map = RC_MAP_RC5_HAUPPAUGE_NEW; 267 rc_map = RC_MAP_HAUPPAUGE;
268 break; 268 break;
269 case CX23885_BOARD_TEVII_S470: 269 case CX23885_BOARD_TEVII_S470:
270 /* Integrated CX23885 IR controller */ 270 /* Integrated CX23885 IR controller */
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index a28772db11f0..c87ac682ebbe 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -292,6 +292,7 @@ Channel manager Data Structure entry = 20 DWORD
292#define RDR_CFG0 0x00050000 292#define RDR_CFG0 0x00050000
293#define RDR_CFG1 0x00050004 293#define RDR_CFG1 0x00050004
294#define RDR_CFG2 0x00050008 294#define RDR_CFG2 0x00050008
295#define RDR_RDRCTL1 0x0005030c
295#define RDR_TLCTL0 0x00050318 296#define RDR_TLCTL0 0x00050318
296 297
297/* APB DMAC Current Buffer Pointer */ 298/* APB DMAC Current Buffer Pointer */
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 644fcb808c0b..ee57f6bedbe3 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1468,16 +1468,17 @@ int cx23885_video_register(struct cx23885_dev *dev)
1468 1468
1469 cx23885_irq_add_enable(dev, 0x01); 1469 cx23885_irq_add_enable(dev, 0x01);
1470 1470
1471 if (TUNER_ABSENT != dev->tuner_type) { 1471 if ((TUNER_ABSENT != dev->tuner_type) &&
1472 ((dev->tuner_bus == 0) || (dev->tuner_bus == 1))) {
1472 struct v4l2_subdev *sd = NULL; 1473 struct v4l2_subdev *sd = NULL;
1473 1474
1474 if (dev->tuner_addr) 1475 if (dev->tuner_addr)
1475 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1476 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1476 &dev->i2c_bus[1].i2c_adap, 1477 &dev->i2c_bus[dev->tuner_bus].i2c_adap,
1477 "tuner", dev->tuner_addr, NULL); 1478 "tuner", dev->tuner_addr, NULL);
1478 else 1479 else
1479 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1480 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1480 &dev->i2c_bus[1].i2c_adap, 1481 &dev->i2c_bus[dev->tuner_bus].i2c_adap,
1481 "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV)); 1482 "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
1482 if (sd) { 1483 if (sd) {
1483 struct tuner_setup tun_setup; 1484 struct tuner_setup tun_setup;
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 62e41ab65810..8db2797bc7c3 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -85,6 +85,7 @@
85#define CX23885_BOARD_MYGICA_X8558PRO 27 85#define CX23885_BOARD_MYGICA_X8558PRO 27
86#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28 86#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
87#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29 87#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29
88#define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30
88 89
89#define GPIO_0 0x00000001 90#define GPIO_0 0x00000001
90#define GPIO_1 0x00000002 91#define GPIO_1 0x00000002
@@ -204,10 +205,12 @@ typedef enum {
204struct cx23885_board { 205struct cx23885_board {
205 char *name; 206 char *name;
206 port_t porta, portb, portc; 207 port_t porta, portb, portc;
208 int num_fds_portb, num_fds_portc;
207 unsigned int tuner_type; 209 unsigned int tuner_type;
208 unsigned int radio_type; 210 unsigned int radio_type;
209 unsigned char tuner_addr; 211 unsigned char tuner_addr;
210 unsigned char radio_addr; 212 unsigned char radio_addr;
213 unsigned int tuner_bus;
211 214
212 /* Vendors can and do run the PCIe bridge at different 215 /* Vendors can and do run the PCIe bridge at different
213 * clock rates, driven physically by crystals on the PCBs. 216 * clock rates, driven physically by crystals on the PCBs.
@@ -220,7 +223,7 @@ struct cx23885_board {
220 */ 223 */
221 u32 clk_freq; 224 u32 clk_freq;
222 struct cx23885_input input[MAX_CX23885_INPUT]; 225 struct cx23885_input input[MAX_CX23885_INPUT];
223 int cimax; /* for NetUP */ 226 int ci_type; /* for NetUP */
224}; 227};
225 228
226struct cx23885_subid { 229struct cx23885_subid {
@@ -303,6 +306,7 @@ struct cx23885_tsport {
303 306
304 /* Allow a single tsport to have multiple frontends */ 307 /* Allow a single tsport to have multiple frontends */
305 u32 num_frontends; 308 u32 num_frontends;
309 void (*gate_ctrl)(struct cx23885_tsport *port, int open);
306 void *port_priv; 310 void *port_priv;
307}; 311};
308 312
@@ -362,6 +366,7 @@ struct cx23885_dev {
362 v4l2_std_id tvnorm; 366 v4l2_std_id tvnorm;
363 unsigned int tuner_type; 367 unsigned int tuner_type;
364 unsigned char tuner_addr; 368 unsigned char tuner_addr;
369 unsigned int tuner_bus;
365 unsigned int radio_type; 370 unsigned int radio_type;
366 unsigned char radio_addr; 371 unsigned char radio_addr;
367 unsigned int has_radio; 372 unsigned int has_radio;
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 54b7fcd469a8..423c1af8a782 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -40,6 +40,7 @@
40#include <sound/control.h> 40#include <sound/control.h>
41#include <sound/initval.h> 41#include <sound/initval.h>
42#include <sound/tlv.h> 42#include <sound/tlv.h>
43#include <media/wm8775.h>
43 44
44#include "cx88.h" 45#include "cx88.h"
45#include "cx88-reg.h" 46#include "cx88-reg.h"
@@ -577,6 +578,35 @@ static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
577 return 0; 578 return 0;
578} 579}
579 580
581static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *value)
583{
584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
585 struct cx88_core *core = chip->core;
586 struct v4l2_control client_ctl;
587 int left = value->value.integer.value[0];
588 int right = value->value.integer.value[1];
589 int v, b;
590
591 memset(&client_ctl, 0, sizeof(client_ctl));
592
593 /* Pass volume & balance onto any WM8775 */
594 if (left >= right) {
595 v = left << 10;
596 b = left ? (0x8000 * right) / left : 0x8000;
597 } else {
598 v = right << 10;
599 b = right ? 0xffff - (0x8000 * left) / right : 0x8000;
600 }
601 client_ctl.value = v;
602 client_ctl.id = V4L2_CID_AUDIO_VOLUME;
603 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
604
605 client_ctl.value = b;
606 client_ctl.id = V4L2_CID_AUDIO_BALANCE;
607 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
608}
609
580/* OK - TODO: test it */ 610/* OK - TODO: test it */
581static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, 611static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *value) 612 struct snd_ctl_elem_value *value)
@@ -587,25 +617,28 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
587 int changed = 0; 617 int changed = 0;
588 u32 old; 618 u32 old;
589 619
620 if (core->board.audio_chip == V4L2_IDENT_WM8775)
621 snd_cx88_wm8775_volume_put(kcontrol, value);
622
590 left = value->value.integer.value[0] & 0x3f; 623 left = value->value.integer.value[0] & 0x3f;
591 right = value->value.integer.value[1] & 0x3f; 624 right = value->value.integer.value[1] & 0x3f;
592 b = right - left; 625 b = right - left;
593 if (b < 0) { 626 if (b < 0) {
594 v = 0x3f - left; 627 v = 0x3f - left;
595 b = (-b) | 0x40; 628 b = (-b) | 0x40;
596 } else { 629 } else {
597 v = 0x3f - right; 630 v = 0x3f - right;
598 } 631 }
599 /* Do we really know this will always be called with IRQs on? */ 632 /* Do we really know this will always be called with IRQs on? */
600 spin_lock_irq(&chip->reg_lock); 633 spin_lock_irq(&chip->reg_lock);
601 old = cx_read(AUD_VOL_CTL); 634 old = cx_read(AUD_VOL_CTL);
602 if (v != (old & 0x3f)) { 635 if (v != (old & 0x3f)) {
603 cx_write(AUD_VOL_CTL, (old & ~0x3f) | v); 636 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v);
604 changed = 1; 637 changed = 1;
605 } 638 }
606 if (cx_read(AUD_BAL_CTL) != b) { 639 if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) {
607 cx_write(AUD_BAL_CTL, b); 640 cx_write(AUD_BAL_CTL, b);
608 changed = 1; 641 changed = 1;
609 } 642 }
610 spin_unlock_irq(&chip->reg_lock); 643 spin_unlock_irq(&chip->reg_lock);
611 644
@@ -618,7 +651,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = {
618 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
619 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 652 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
620 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 653 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
621 .name = "Playback Volume", 654 .name = "Analog-TV Volume",
622 .info = snd_cx88_volume_info, 655 .info = snd_cx88_volume_info,
623 .get = snd_cx88_volume_get, 656 .get = snd_cx88_volume_get,
624 .put = snd_cx88_volume_put, 657 .put = snd_cx88_volume_put,
@@ -649,7 +682,17 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
649 vol = cx_read(AUD_VOL_CTL); 682 vol = cx_read(AUD_VOL_CTL);
650 if (value->value.integer.value[0] != !(vol & bit)) { 683 if (value->value.integer.value[0] != !(vol & bit)) {
651 vol ^= bit; 684 vol ^= bit;
652 cx_write(AUD_VOL_CTL, vol); 685 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
686 /* Pass mute onto any WM8775 */
687 if ((core->board.audio_chip == V4L2_IDENT_WM8775) &&
688 ((1<<6) == bit)) {
689 struct v4l2_control client_ctl;
690
691 memset(&client_ctl, 0, sizeof(client_ctl));
692 client_ctl.value = 0 != (vol & bit);
693 client_ctl.id = V4L2_CID_AUDIO_MUTE;
694 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
695 }
653 ret = 1; 696 ret = 1;
654 } 697 }
655 spin_unlock_irq(&chip->reg_lock); 698 spin_unlock_irq(&chip->reg_lock);
@@ -658,7 +701,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
658 701
659static const struct snd_kcontrol_new snd_cx88_dac_switch = { 702static const struct snd_kcontrol_new snd_cx88_dac_switch = {
660 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 703 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
661 .name = "Playback Switch", 704 .name = "Audio-Out Switch",
662 .info = snd_ctl_boolean_mono_info, 705 .info = snd_ctl_boolean_mono_info,
663 .get = snd_cx88_switch_get, 706 .get = snd_cx88_switch_get,
664 .put = snd_cx88_switch_put, 707 .put = snd_cx88_switch_put,
@@ -667,13 +710,51 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = {
667 710
668static const struct snd_kcontrol_new snd_cx88_source_switch = { 711static const struct snd_kcontrol_new snd_cx88_source_switch = {
669 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
670 .name = "Capture Switch", 713 .name = "Analog-TV Switch",
671 .info = snd_ctl_boolean_mono_info, 714 .info = snd_ctl_boolean_mono_info,
672 .get = snd_cx88_switch_get, 715 .get = snd_cx88_switch_get,
673 .put = snd_cx88_switch_put, 716 .put = snd_cx88_switch_put,
674 .private_value = (1<<6), 717 .private_value = (1<<6),
675}; 718};
676 719
720static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
721 struct snd_ctl_elem_value *value)
722{
723 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
724 struct cx88_core *core = chip->core;
725 struct v4l2_control client_ctl;
726
727 memset(&client_ctl, 0, sizeof(client_ctl));
728 client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
729 call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl);
730 value->value.integer.value[0] = client_ctl.value ? 1 : 0;
731
732 return 0;
733}
734
735static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
736 struct snd_ctl_elem_value *value)
737{
738 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
739 struct cx88_core *core = chip->core;
740 struct v4l2_control client_ctl;
741
742 memset(&client_ctl, 0, sizeof(client_ctl));
743 client_ctl.value = 0 != value->value.integer.value[0];
744 client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
745 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
746
747 return 0;
748}
749
750static struct snd_kcontrol_new snd_cx88_alc_switch = {
751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
752 .name = "Line-In ALC Switch",
753 .info = snd_ctl_boolean_mono_info,
754 .get = snd_cx88_alc_get,
755 .put = snd_cx88_alc_put,
756};
757
677/**************************************************************************** 758/****************************************************************************
678 Basic Flow for Sound Devices 759 Basic Flow for Sound Devices
679 ****************************************************************************/ 760 ****************************************************************************/
@@ -724,7 +805,8 @@ static void snd_cx88_dev_free(struct snd_card * card)
724static int devno; 805static int devno;
725static int __devinit snd_cx88_create(struct snd_card *card, 806static int __devinit snd_cx88_create(struct snd_card *card,
726 struct pci_dev *pci, 807 struct pci_dev *pci,
727 snd_cx88_card_t **rchip) 808 snd_cx88_card_t **rchip,
809 struct cx88_core **core_ptr)
728{ 810{
729 snd_cx88_card_t *chip; 811 snd_cx88_card_t *chip;
730 struct cx88_core *core; 812 struct cx88_core *core;
@@ -750,7 +832,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
750 if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) { 832 if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) {
751 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); 833 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
752 err = -EIO; 834 err = -EIO;
753 cx88_core_put(core,pci); 835 cx88_core_put(core, pci);
754 return err; 836 return err;
755 } 837 }
756 838
@@ -786,6 +868,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
786 snd_card_set_dev(card, &pci->dev); 868 snd_card_set_dev(card, &pci->dev);
787 869
788 *rchip = chip; 870 *rchip = chip;
871 *core_ptr = core;
789 872
790 return 0; 873 return 0;
791} 874}
@@ -795,6 +878,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
795{ 878{
796 struct snd_card *card; 879 struct snd_card *card;
797 snd_cx88_card_t *chip; 880 snd_cx88_card_t *chip;
881 struct cx88_core *core = NULL;
798 int err; 882 int err;
799 883
800 if (devno >= SNDRV_CARDS) 884 if (devno >= SNDRV_CARDS)
@@ -812,7 +896,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
812 896
813 card->private_free = snd_cx88_dev_free; 897 card->private_free = snd_cx88_dev_free;
814 898
815 err = snd_cx88_create(card, pci, &chip); 899 err = snd_cx88_create(card, pci, &chip, &core);
816 if (err < 0) 900 if (err < 0)
817 goto error; 901 goto error;
818 902
@@ -830,6 +914,10 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
830 if (err < 0) 914 if (err < 0)
831 goto error; 915 goto error;
832 916
917 /* If there's a wm8775 then add a Line-In ALC switch */
918 if (core->board.audio_chip == V4L2_IDENT_WM8775)
919 snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip));
920
833 strcpy (card->driver, "CX88x"); 921 strcpy (card->driver, "CX88x");
834 sprintf(card->shortname, "Conexant CX%x", pci->device); 922 sprintf(card->shortname, "Conexant CX%x", pci->device);
835 sprintf(card->longname, "%s at %#llx", 923 sprintf(card->longname, "%s at %#llx",
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 4e6ee5584cb3..27222c92b603 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -970,7 +970,8 @@ static const struct cx88_board cx88_boards[] = {
970 .radio_type = UNSET, 970 .radio_type = UNSET,
971 .tuner_addr = ADDR_UNSET, 971 .tuner_addr = ADDR_UNSET,
972 .radio_addr = ADDR_UNSET, 972 .radio_addr = ADDR_UNSET,
973 .audio_chip = V4L2_IDENT_WM8775, 973 .audio_chip = V4L2_IDENT_WM8775,
974 .i2sinputcntl = 2,
974 .input = {{ 975 .input = {{
975 .type = CX88_VMUX_DVB, 976 .type = CX88_VMUX_DVB,
976 .vmux = 0, 977 .vmux = 0,
@@ -1952,6 +1953,18 @@ static const struct cx88_board cx88_boards[] = {
1952 } }, 1953 } },
1953 .mpeg = CX88_MPEG_DVB, 1954 .mpeg = CX88_MPEG_DVB,
1954 }, 1955 },
1956 [CX88_BOARD_TEVII_S464] = {
1957 .name = "TeVii S464 DVB-S/S2",
1958 .tuner_type = UNSET,
1959 .radio_type = UNSET,
1960 .tuner_addr = ADDR_UNSET,
1961 .radio_addr = ADDR_UNSET,
1962 .input = {{
1963 .type = CX88_VMUX_DVB,
1964 .vmux = 0,
1965 } },
1966 .mpeg = CX88_MPEG_DVB,
1967 },
1955 [CX88_BOARD_OMICOM_SS4_PCI] = { 1968 [CX88_BOARD_OMICOM_SS4_PCI] = {
1956 .name = "Omicom SS4 DVB-S/S2 PCI", 1969 .name = "Omicom SS4 DVB-S/S2 PCI",
1957 .tuner_type = UNSET, 1970 .tuner_type = UNSET,
@@ -2528,6 +2541,10 @@ static const struct cx88_subid cx88_subids[] = {
2528 .subdevice = 0x9022, 2541 .subdevice = 0x9022,
2529 .card = CX88_BOARD_TEVII_S460, 2542 .card = CX88_BOARD_TEVII_S460,
2530 }, { 2543 }, {
2544 .subvendor = 0xd464,
2545 .subdevice = 0x9022,
2546 .card = CX88_BOARD_TEVII_S464,
2547 }, {
2531 .subvendor = 0xA044, 2548 .subvendor = 0xA044,
2532 .subdevice = 0x2011, 2549 .subdevice = 0x2011,
2533 .card = CX88_BOARD_OMICOM_SS4_PCI, 2550 .card = CX88_BOARD_OMICOM_SS4_PCI,
@@ -3165,9 +3182,7 @@ static void cx88_card_setup(struct cx88_core *core)
3165{ 3182{
3166 static u8 eeprom[256]; 3183 static u8 eeprom[256];
3167 struct tuner_setup tun_setup; 3184 struct tuner_setup tun_setup;
3168 unsigned int mode_mask = T_RADIO | 3185 unsigned int mode_mask = T_RADIO | T_ANALOG_TV;
3169 T_ANALOG_TV |
3170 T_DIGITAL_TV;
3171 3186
3172 memset(&tun_setup, 0, sizeof(tun_setup)); 3187 memset(&tun_setup, 0, sizeof(tun_setup));
3173 3188
@@ -3287,6 +3302,7 @@ static void cx88_card_setup(struct cx88_core *core)
3287 } 3302 }
3288 case CX88_BOARD_TEVII_S420: 3303 case CX88_BOARD_TEVII_S420:
3289 case CX88_BOARD_TEVII_S460: 3304 case CX88_BOARD_TEVII_S460:
3305 case CX88_BOARD_TEVII_S464:
3290 case CX88_BOARD_OMICOM_SS4_PCI: 3306 case CX88_BOARD_OMICOM_SS4_PCI:
3291 case CX88_BOARD_TBS_8910: 3307 case CX88_BOARD_TBS_8910:
3292 case CX88_BOARD_TBS_8920: 3308 case CX88_BOARD_TBS_8920:
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 90717ee944ec..7b8c9d3b6efc 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -57,6 +57,7 @@
57#include "stb6100.h" 57#include "stb6100.h"
58#include "stb6100_proc.h" 58#include "stb6100_proc.h"
59#include "mb86a16.h" 59#include "mb86a16.h"
60#include "ds3000.h"
60 61
61MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 62MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
62MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 63MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -648,6 +649,20 @@ static const struct cx24116_config tevii_s460_config = {
648 .reset_device = cx24116_reset_device, 649 .reset_device = cx24116_reset_device,
649}; 650};
650 651
652static int ds3000_set_ts_param(struct dvb_frontend *fe,
653 int is_punctured)
654{
655 struct cx8802_dev *dev = fe->dvb->priv;
656 dev->ts_gen_cntrl = 4;
657
658 return 0;
659}
660
661static struct ds3000_config tevii_ds3000_config = {
662 .demod_address = 0x68,
663 .set_ts_params = ds3000_set_ts_param,
664};
665
651static const struct stv0900_config prof_7301_stv0900_config = { 666static const struct stv0900_config prof_7301_stv0900_config = {
652 .demod_address = 0x6a, 667 .demod_address = 0x6a,
653/* demod_mode = 0,*/ 668/* demod_mode = 0,*/
@@ -1381,6 +1396,14 @@ static int dvb_register(struct cx8802_dev *dev)
1381 if (fe0->dvb.frontend != NULL) 1396 if (fe0->dvb.frontend != NULL)
1382 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1397 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1383 break; 1398 break;
1399 case CX88_BOARD_TEVII_S464:
1400 fe0->dvb.frontend = dvb_attach(ds3000_attach,
1401 &tevii_ds3000_config,
1402 &core->i2c_adap);
1403 if (fe0->dvb.frontend != NULL)
1404 fe0->dvb.frontend->ops.set_voltage =
1405 tevii_dvbs_set_voltage;
1406 break;
1384 case CX88_BOARD_OMICOM_SS4_PCI: 1407 case CX88_BOARD_OMICOM_SS4_PCI:
1385 case CX88_BOARD_TBS_8920: 1408 case CX88_BOARD_TBS_8920:
1386 case CX88_BOARD_PROF_7300: 1409 case CX88_BOARD_PROF_7300:
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 06f7d1d00944..c820e2f53527 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -283,7 +283,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
283 case CX88_BOARD_PCHDTV_HD3000: 283 case CX88_BOARD_PCHDTV_HD3000:
284 case CX88_BOARD_PCHDTV_HD5500: 284 case CX88_BOARD_PCHDTV_HD5500:
285 case CX88_BOARD_HAUPPAUGE_IRONLY: 285 case CX88_BOARD_HAUPPAUGE_IRONLY:
286 ir_codes = RC_MAP_HAUPPAUGE_NEW; 286 ir_codes = RC_MAP_HAUPPAUGE;
287 ir->sampling = 1; 287 ir->sampling = 1;
288 break; 288 break;
289 case CX88_BOARD_WINFAST_DTV2000H: 289 case CX88_BOARD_WINFAST_DTV2000H:
@@ -373,6 +373,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
373 ir_codes = RC_MAP_TBS_NEC; 373 ir_codes = RC_MAP_TBS_NEC;
374 ir->sampling = 0xff00; /* address */ 374 ir->sampling = 0xff00; /* address */
375 break; 375 break;
376 case CX88_BOARD_TEVII_S464:
376 case CX88_BOARD_TEVII_S460: 377 case CX88_BOARD_TEVII_S460:
377 case CX88_BOARD_TEVII_S420: 378 case CX88_BOARD_TEVII_S420:
378 ir_codes = RC_MAP_TEVII_NEC; 379 ir_codes = RC_MAP_TEVII_NEC;
@@ -603,7 +604,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
603 if (*addrp == 0x71) { 604 if (*addrp == 0x71) {
604 /* Hauppauge XVR */ 605 /* Hauppauge XVR */
605 core->init_data.name = "cx88 Hauppauge XVR remote"; 606 core->init_data.name = "cx88 Hauppauge XVR remote";
606 core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; 607 core->init_data.ir_codes = RC_MAP_HAUPPAUGE;
607 core->init_data.type = RC_TYPE_RC5; 608 core->init_data.type = RC_TYPE_RC5;
608 core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 609 core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
609 610
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 08220de3d74d..770ec05b5e9b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -786,8 +786,12 @@ void cx88_set_tvaudio(struct cx88_core *core)
786 break; 786 break;
787 case WW_I2SADC: 787 case WW_I2SADC:
788 set_audio_start(core, 0x01); 788 set_audio_start(core, 0x01);
789 /* Slave/Philips/Autobaud */ 789 /*
790 cx_write(AUD_I2SINPUTCNTL, 0); 790 * Slave/Philips/Autobaud
791 * NB on Nova-S bit1 NPhilipsSony appears to be inverted:
792 * 0= Sony, 1=Philips
793 */
794 cx_write(AUD_I2SINPUTCNTL, core->board.i2sinputcntl);
791 /* Switch to "I2S ADC mode" */ 795 /* Switch to "I2S ADC mode" */
792 cx_write(AUD_I2SCNTL, 0x1); 796 cx_write(AUD_I2SCNTL, 0x1);
793 set_audio_finish(core, EN_I2SIN_ENABLE); 797 set_audio_finish(core, EN_I2SIN_ENABLE);
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 508dabbed986..287a41ee1c4f 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -40,6 +40,7 @@
40#include "cx88.h" 40#include "cx88.h"
41#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
42#include <media/v4l2-ioctl.h> 42#include <media/v4l2-ioctl.h>
43#include <media/wm8775.h>
43 44
44MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 45MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
45MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 46MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -989,6 +990,32 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
989 ctl->value = c->v.minimum; 990 ctl->value = c->v.minimum;
990 if (ctl->value > c->v.maximum) 991 if (ctl->value > c->v.maximum)
991 ctl->value = c->v.maximum; 992 ctl->value = c->v.maximum;
993
994 /* Pass changes onto any WM8775 */
995 if (core->board.audio_chip == V4L2_IDENT_WM8775) {
996 struct v4l2_control client_ctl;
997 memset(&client_ctl, 0, sizeof(client_ctl));
998 client_ctl.id = ctl->id;
999
1000 switch (ctl->id) {
1001 case V4L2_CID_AUDIO_MUTE:
1002 client_ctl.value = ctl->value;
1003 break;
1004 case V4L2_CID_AUDIO_VOLUME:
1005 client_ctl.value = (ctl->value) ?
1006 (0x90 + ctl->value) << 8 : 0;
1007 break;
1008 case V4L2_CID_AUDIO_BALANCE:
1009 client_ctl.value = ctl->value << 9;
1010 break;
1011 default:
1012 client_ctl.id = 0;
1013 break;
1014 }
1015 if (client_ctl.id)
1016 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
1017 }
1018
992 mask=c->mask; 1019 mask=c->mask;
993 switch (ctl->id) { 1020 switch (ctl->id) {
994 case V4L2_CID_AUDIO_BALANCE: 1021 case V4L2_CID_AUDIO_BALANCE:
@@ -1526,7 +1553,9 @@ static int radio_queryctrl (struct file *file, void *priv,
1526 if (c->id < V4L2_CID_BASE || 1553 if (c->id < V4L2_CID_BASE ||
1527 c->id >= V4L2_CID_LASTP1) 1554 c->id >= V4L2_CID_LASTP1)
1528 return -EINVAL; 1555 return -EINVAL;
1529 if (c->id == V4L2_CID_AUDIO_MUTE) { 1556 if (c->id == V4L2_CID_AUDIO_MUTE ||
1557 c->id == V4L2_CID_AUDIO_VOLUME ||
1558 c->id == V4L2_CID_AUDIO_BALANCE) {
1530 for (i = 0; i < CX8800_CTLS; i++) { 1559 for (i = 0; i < CX8800_CTLS; i++) {
1531 if (cx8800_ctls[i].v.id == c->id) 1560 if (cx8800_ctls[i].v.id == c->id)
1532 break; 1561 break;
@@ -1672,7 +1701,7 @@ static const struct v4l2_file_operations video_fops =
1672 .read = video_read, 1701 .read = video_read,
1673 .poll = video_poll, 1702 .poll = video_poll,
1674 .mmap = video_mmap, 1703 .mmap = video_mmap,
1675 .ioctl = video_ioctl2, 1704 .unlocked_ioctl = video_ioctl2,
1676}; 1705};
1677 1706
1678static const struct v4l2_ioctl_ops video_ioctl_ops = { 1707static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1722,7 +1751,7 @@ static const struct v4l2_file_operations radio_fops =
1722 .owner = THIS_MODULE, 1751 .owner = THIS_MODULE,
1723 .open = video_open, 1752 .open = video_open,
1724 .release = video_release, 1753 .release = video_release,
1725 .ioctl = video_ioctl2, 1754 .unlocked_ioctl = video_ioctl2,
1726}; 1755};
1727 1756
1728static const struct v4l2_ioctl_ops radio_ioctl_ops = { 1757static const struct v4l2_ioctl_ops radio_ioctl_ops = {
@@ -1856,9 +1885,24 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1856 1885
1857 /* load and configure helper modules */ 1886 /* load and configure helper modules */
1858 1887
1859 if (core->board.audio_chip == V4L2_IDENT_WM8775) 1888 if (core->board.audio_chip == V4L2_IDENT_WM8775) {
1860 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, 1889 struct i2c_board_info wm8775_info = {
1861 "wm8775", 0x36 >> 1, NULL); 1890 .type = "wm8775",
1891 .addr = 0x36 >> 1,
1892 .platform_data = &core->wm8775_data,
1893 };
1894 struct v4l2_subdev *sd;
1895
1896 if (core->boardnr == CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1)
1897 core->wm8775_data.is_nova_s = true;
1898 else
1899 core->wm8775_data.is_nova_s = false;
1900
1901 sd = v4l2_i2c_new_subdev_board(&core->v4l2_dev, &core->i2c_adap,
1902 &wm8775_info, NULL);
1903 if (sd != NULL)
1904 sd->grp_id = WM8775_GID;
1905 }
1862 1906
1863 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { 1907 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
1864 /* This probes for a tda9874 as is used on some 1908 /* This probes for a tda9874 as is used on some
@@ -1882,6 +1926,15 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1882 request_module("ir-kbd-i2c"); 1926 request_module("ir-kbd-i2c");
1883 } 1927 }
1884 1928
1929 /* Sets device info at pci_dev */
1930 pci_set_drvdata(pci_dev, dev);
1931
1932 /* initial device configuration */
1933 mutex_lock(&core->lock);
1934 cx88_set_tvnorm(core, core->tvnorm);
1935 init_controls(core);
1936 cx88_video_mux(core, 0);
1937
1885 /* register v4l devices */ 1938 /* register v4l devices */
1886 dev->video_dev = cx88_vdev_init(core,dev->pci, 1939 dev->video_dev = cx88_vdev_init(core,dev->pci,
1887 &cx8800_video_template,"video"); 1940 &cx8800_video_template,"video");
@@ -1923,16 +1976,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1923 core->name, video_device_node_name(dev->radio_dev)); 1976 core->name, video_device_node_name(dev->radio_dev));
1924 } 1977 }
1925 1978
1926 /* everything worked */
1927 pci_set_drvdata(pci_dev,dev);
1928
1929 /* initial device configuration */
1930 mutex_lock(&core->lock);
1931 cx88_set_tvnorm(core,core->tvnorm);
1932 init_controls(core);
1933 cx88_video_mux(core,0);
1934 mutex_unlock(&core->lock);
1935
1936 /* start tvaudio thread */ 1979 /* start tvaudio thread */
1937 if (core->board.tuner_type != TUNER_ABSENT) { 1980 if (core->board.tuner_type != TUNER_ABSENT) {
1938 core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); 1981 core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
@@ -1942,11 +1985,14 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1942 core->name, err); 1985 core->name, err);
1943 } 1986 }
1944 } 1987 }
1988 mutex_unlock(&core->lock);
1989
1945 return 0; 1990 return 0;
1946 1991
1947fail_unreg: 1992fail_unreg:
1948 cx8800_unregister_video(dev); 1993 cx8800_unregister_video(dev);
1949 free_irq(pci_dev->irq, dev); 1994 free_irq(pci_dev->irq, dev);
1995 mutex_unlock(&core->lock);
1950fail_core: 1996fail_core:
1951 cx88_core_put(core,dev->pci); 1997 cx88_core_put(core,dev->pci);
1952fail_free: 1998fail_free:
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index c9981e77416a..9b3742a7746c 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -33,6 +33,7 @@
33#include <media/cx2341x.h> 33#include <media/cx2341x.h>
34#include <media/videobuf-dvb.h> 34#include <media/videobuf-dvb.h>
35#include <media/ir-kbd-i2c.h> 35#include <media/ir-kbd-i2c.h>
36#include <media/wm8775.h>
36 37
37#include "btcx-risc.h" 38#include "btcx-risc.h"
38#include "cx88-reg.h" 39#include "cx88-reg.h"
@@ -240,6 +241,7 @@ extern const struct sram_channel const cx88_sram_channels[];
240#define CX88_BOARD_PROF_7301 83 241#define CX88_BOARD_PROF_7301 83
241#define CX88_BOARD_SAMSUNG_SMT_7020 84 242#define CX88_BOARD_SAMSUNG_SMT_7020 84
242#define CX88_BOARD_TWINHAN_VP1027_DVBS 85 243#define CX88_BOARD_TWINHAN_VP1027_DVBS 85
244#define CX88_BOARD_TEVII_S464 86
243 245
244enum cx88_itype { 246enum cx88_itype {
245 CX88_VMUX_COMPOSITE1 = 1, 247 CX88_VMUX_COMPOSITE1 = 1,
@@ -273,6 +275,9 @@ struct cx88_board {
273 enum cx88_board_type mpeg; 275 enum cx88_board_type mpeg;
274 unsigned int audio_chip; 276 unsigned int audio_chip;
275 int num_frontends; 277 int num_frontends;
278
279 /* Used for I2S devices */
280 int i2sinputcntl;
276}; 281};
277 282
278struct cx88_subid { 283struct cx88_subid {
@@ -379,6 +384,7 @@ struct cx88_core {
379 384
380 /* I2C remote data */ 385 /* I2C remote data */
381 struct IR_i2c_init_data init_data; 386 struct IR_i2c_init_data init_data;
387 struct wm8775_platform_data wm8775_data;
382 388
383 struct mutex lock; 389 struct mutex lock;
384 /* various v4l controls */ 390 /* various v4l controls */
@@ -398,17 +404,21 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
398 return container_of(v4l2_dev, struct cx88_core, v4l2_dev); 404 return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
399} 405}
400 406
401#define call_all(core, o, f, args...) \ 407#define WM8775_GID (1 << 0)
408
409#define call_hw(core, grpid, o, f, args...) \
402 do { \ 410 do { \
403 if (!core->i2c_rc) { \ 411 if (!core->i2c_rc) { \
404 if (core->gate_ctrl) \ 412 if (core->gate_ctrl) \
405 core->gate_ctrl(core, 1); \ 413 core->gate_ctrl(core, 1); \
406 v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \ 414 v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \
407 if (core->gate_ctrl) \ 415 if (core->gate_ctrl) \
408 core->gate_ctrl(core, 0); \ 416 core->gate_ctrl(core, 0); \
409 } \ 417 } \
410 } while (0) 418 } while (0)
411 419
420#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args)
421
412struct cx8800_dev; 422struct cx8800_dev;
413struct cx8802_dev; 423struct cx8802_dev;
414 424
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 353eadaa823e..71e961e53a56 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -1719,7 +1719,7 @@ unlock_out:
1719 1719
1720 1720
1721static long vpfe_param_handler(struct file *file, void *priv, 1721static long vpfe_param_handler(struct file *file, void *priv,
1722 int cmd, void *param) 1722 bool valid_prio, int cmd, void *param)
1723{ 1723{
1724 struct vpfe_device *vpfe_dev = video_drvdata(file); 1724 struct vpfe_device *vpfe_dev = video_drvdata(file);
1725 int ret = 0; 1725 int ret = 0;
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 87f77a34eeab..69fcea82d01c 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -834,7 +834,7 @@ struct em28xx_board em28xx_boards[] = {
834 .mts_firmware = 1, 834 .mts_firmware = 1,
835 .has_dvb = 1, 835 .has_dvb = 1,
836 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 836 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
837 .ir_codes = RC_MAP_HAUPPAUGE_NEW, 837 .ir_codes = RC_MAP_HAUPPAUGE,
838 .decoder = EM28XX_TVP5150, 838 .decoder = EM28XX_TVP5150,
839 .input = { { 839 .input = { {
840 .type = EM28XX_VMUX_TELEVISION, 840 .type = EM28XX_VMUX_TELEVISION,
@@ -859,7 +859,7 @@ struct em28xx_board em28xx_boards[] = {
859 .tuner_type = TUNER_XC2028, 859 .tuner_type = TUNER_XC2028,
860 .tuner_gpio = default_tuner_gpio, 860 .tuner_gpio = default_tuner_gpio,
861 .mts_firmware = 1, 861 .mts_firmware = 1,
862 .ir_codes = RC_MAP_HAUPPAUGE_NEW, 862 .ir_codes = RC_MAP_HAUPPAUGE,
863 .decoder = EM28XX_TVP5150, 863 .decoder = EM28XX_TVP5150,
864 .input = { { 864 .input = { {
865 .type = EM28XX_VMUX_TELEVISION, 865 .type = EM28XX_VMUX_TELEVISION,
@@ -885,7 +885,7 @@ struct em28xx_board em28xx_boards[] = {
885 .mts_firmware = 1, 885 .mts_firmware = 1,
886 .has_dvb = 1, 886 .has_dvb = 1,
887 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 887 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
888 .ir_codes = RC_MAP_HAUPPAUGE_NEW, 888 .ir_codes = RC_MAP_HAUPPAUGE,
889 .decoder = EM28XX_TVP5150, 889 .decoder = EM28XX_TVP5150,
890 .input = { { 890 .input = { {
891 .type = EM28XX_VMUX_TELEVISION, 891 .type = EM28XX_VMUX_TELEVISION,
@@ -911,7 +911,7 @@ struct em28xx_board em28xx_boards[] = {
911 .mts_firmware = 1, 911 .mts_firmware = 1,
912 .has_dvb = 1, 912 .has_dvb = 1,
913 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 913 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
914 .ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW, 914 .ir_codes = RC_MAP_HAUPPAUGE,
915 .decoder = EM28XX_TVP5150, 915 .decoder = EM28XX_TVP5150,
916 .input = { { 916 .input = { {
917 .type = EM28XX_VMUX_TELEVISION, 917 .type = EM28XX_VMUX_TELEVISION,
@@ -2430,7 +2430,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2430 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; 2430 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
2431 break; 2431 break;
2432 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: 2432 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
2433 dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW; 2433 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
2434 dev->init_data.get_key = em28xx_get_key_em_haup; 2434 dev->init_data.get_key = em28xx_get_key_em_haup;
2435 dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; 2435 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
2436 break; 2436 break;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index f34d524ccb09..a83131bd00b2 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1387,6 +1387,27 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1387 return -EINVAL; 1387 return -EINVAL;
1388} 1388}
1389 1389
1390/*
1391 * FIXME: This is an indirect way to check if a control exists at a
1392 * subdev. Instead of that hack, maybe the better would be to change all
1393 * subdevs to return -ENOIOCTLCMD, if an ioctl is not supported.
1394 */
1395static int check_subdev_ctrl(struct em28xx *dev, int id)
1396{
1397 struct v4l2_queryctrl qc;
1398
1399 memset(&qc, 0, sizeof(qc));
1400 qc.id = id;
1401
1402 /* enumerate V4L2 device controls */
1403 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, &qc);
1404
1405 if (qc.type)
1406 return 0;
1407 else
1408 return -EINVAL;
1409}
1410
1390static int vidioc_g_ctrl(struct file *file, void *priv, 1411static int vidioc_g_ctrl(struct file *file, void *priv,
1391 struct v4l2_control *ctrl) 1412 struct v4l2_control *ctrl)
1392{ 1413{
@@ -1399,7 +1420,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1399 return rc; 1420 return rc;
1400 rc = 0; 1421 rc = 0;
1401 1422
1402
1403 /* Set an AC97 control */ 1423 /* Set an AC97 control */
1404 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) 1424 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1405 rc = ac97_get_ctrl(dev, ctrl); 1425 rc = ac97_get_ctrl(dev, ctrl);
@@ -1408,6 +1428,9 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1408 1428
1409 /* It were not an AC97 control. Sends it to the v4l2 dev interface */ 1429 /* It were not an AC97 control. Sends it to the v4l2 dev interface */
1410 if (rc == 1) { 1430 if (rc == 1) {
1431 if (check_subdev_ctrl(dev, ctrl->id))
1432 return -EINVAL;
1433
1411 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); 1434 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
1412 rc = 0; 1435 rc = 0;
1413 } 1436 }
@@ -1434,8 +1457,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1434 1457
1435 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */ 1458 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */
1436 if (rc == 1) { 1459 if (rc == 1) {
1437 rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); 1460 rc = check_subdev_ctrl(dev, ctrl->id);
1438 1461 if (!rc)
1462 v4l2_device_call_all(&dev->v4l2_dev, 0,
1463 core, s_ctrl, ctrl);
1439 /* 1464 /*
1440 * In the case of non-AC97 volume controls, we still need 1465 * In the case of non-AC97 volume controls, we still need
1441 * to do some setups at em28xx, in order to mute/unmute 1466 * to do some setups at em28xx, in order to mute/unmute
@@ -1452,7 +1477,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1452 rc = em28xx_audio_analog_set(dev); 1477 rc = em28xx_audio_analog_set(dev);
1453 } 1478 }
1454 } 1479 }
1455 return rc; 1480 return (rc < 0) ? rc : 0;
1456} 1481}
1457 1482
1458static int vidioc_g_tuner(struct file *file, void *priv, 1483static int vidioc_g_tuner(struct file *file, void *priv,
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index dda56ff834f4..eb04e8b59989 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -104,6 +104,15 @@ config USB_GSPCA_MR97310A
104 To compile this driver as a module, choose M here: the 104 To compile this driver as a module, choose M here: the
105 module will be called gspca_mr97310a. 105 module will be called gspca_mr97310a.
106 106
107config USB_GSPCA_NW80X
108 tristate "Divio based (NW80x) USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA
110 help
111 Say Y here if you want support for cameras based on the NW80x chips.
112
113 To compile this driver as a module, choose M here: the
114 module will be called gspca_nw80x.
115
107config USB_GSPCA_OV519 116config USB_GSPCA_OV519
108 tristate "OV51x / OVFX2 / W996xCF USB Camera Driver" 117 tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA 118 depends on VIDEO_V4L2 && USB_GSPCA
@@ -346,6 +355,16 @@ config USB_GSPCA_VC032X
346 To compile this driver as a module, choose M here: the 355 To compile this driver as a module, choose M here: the
347 module will be called gspca_vc032x. 356 module will be called gspca_vc032x.
348 357
358config USB_GSPCA_VICAM
359 tristate "ViCam USB Camera Driver"
360 depends on VIDEO_V4L2 && USB_GSPCA
361 help
362 Say Y here if you want support for the 3com homeconnect camera
363 (vicam).
364
365 To compile this driver as a module, choose M here: the
366 module will be called gspca_vicam.
367
349config USB_GSPCA_XIRLINK_CIT 368config USB_GSPCA_XIRLINK_CIT
350 tristate "Xirlink C-It USB Camera Driver" 369 tristate "Xirlink C-It USB Camera Driver"
351 depends on VIDEO_V4L2 && USB_GSPCA 370 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 24e695b8b077..855fbc8c9c47 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
8obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o 8obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o
9obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o 9obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
10obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 10obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
11obj-$(CONFIG_USB_GSPCA_NW80X) += gspca_nw80x.o
11obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 12obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
12obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 13obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
13obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o 14obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o
@@ -34,6 +35,7 @@ obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
34obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o 35obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
35obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o 36obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
36obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o 37obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
38obj-$(CONFIG_USB_GSPCA_VICAM) += gspca_vicam.o
37obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o 39obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o
38obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o 40obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
39 41
@@ -47,6 +49,7 @@ gspca_jeilinj-objs := jeilinj.o
47gspca_konica-objs := konica.o 49gspca_konica-objs := konica.o
48gspca_mars-objs := mars.o 50gspca_mars-objs := mars.o
49gspca_mr97310a-objs := mr97310a.o 51gspca_mr97310a-objs := mr97310a.o
52gspca_nw80x-objs := nw80x.o
50gspca_ov519-objs := ov519.o 53gspca_ov519-objs := ov519.o
51gspca_ov534-objs := ov534.o 54gspca_ov534-objs := ov534.o
52gspca_ov534_9-objs := ov534_9.o 55gspca_ov534_9-objs := ov534_9.o
@@ -73,6 +76,7 @@ gspca_sunplus-objs := sunplus.o
73gspca_t613-objs := t613.o 76gspca_t613-objs := t613.o
74gspca_tv8532-objs := tv8532.o 77gspca_tv8532-objs := tv8532.o
75gspca_vc032x-objs := vc032x.o 78gspca_vc032x-objs := vc032x.o
79gspca_vicam-objs := vicam.o
76gspca_xirlink_cit-objs := xirlink_cit.o 80gspca_xirlink_cit-objs := xirlink_cit.o
77gspca_zc3xx-objs := zc3xx.o 81gspca_zc3xx-objs := zc3xx.o
78 82
diff --git a/drivers/media/video/gspca/autogain_functions.h b/drivers/media/video/gspca/autogain_functions.h
new file mode 100644
index 000000000000..46777eee678b
--- /dev/null
+++ b/drivers/media/video/gspca/autogain_functions.h
@@ -0,0 +1,179 @@
1/*
2 * Functions for auto gain.
3 *
4 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* auto gain and exposure algorithm based on the knee algorithm described here:
22 http://ytse.tricolour.net/docs/LowLightOptimization.html
23
24 Returns 0 if no changes were made, 1 if the gain and or exposure settings
25 where changed. */
26static inline int auto_gain_n_exposure(
27 struct gspca_dev *gspca_dev,
28 int avg_lum,
29 int desired_avg_lum,
30 int deadzone,
31 int gain_knee,
32 int exposure_knee)
33{
34 struct sd *sd = (struct sd *) gspca_dev;
35 int i, steps, gain, orig_gain, exposure, orig_exposure;
36 int retval = 0;
37
38 orig_gain = gain = sd->ctrls[GAIN].val;
39 orig_exposure = exposure = sd->ctrls[EXPOSURE].val;
40
41 /* If we are of a multiple of deadzone, do multiple steps to reach the
42 desired lumination fast (with the risc of a slight overshoot) */
43 steps = abs(desired_avg_lum - avg_lum) / deadzone;
44
45 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
46 avg_lum, desired_avg_lum, steps);
47
48 for (i = 0; i < steps; i++) {
49 if (avg_lum > desired_avg_lum) {
50 if (gain > gain_knee)
51 gain--;
52 else if (exposure > exposure_knee)
53 exposure--;
54 else if (gain > sd->ctrls[GAIN].def)
55 gain--;
56 else if (exposure > sd->ctrls[EXPOSURE].min)
57 exposure--;
58 else if (gain > sd->ctrls[GAIN].min)
59 gain--;
60 else
61 break;
62 } else {
63 if (gain < sd->ctrls[GAIN].def)
64 gain++;
65 else if (exposure < exposure_knee)
66 exposure++;
67 else if (gain < gain_knee)
68 gain++;
69 else if (exposure < sd->ctrls[EXPOSURE].max)
70 exposure++;
71 else if (gain < sd->ctrls[GAIN].max)
72 gain++;
73 else
74 break;
75 }
76 }
77
78 if (gain != orig_gain) {
79 sd->ctrls[GAIN].val = gain;
80 setgain(gspca_dev);
81 retval = 1;
82 }
83 if (exposure != orig_exposure) {
84 sd->ctrls[EXPOSURE].val = exposure;
85 setexposure(gspca_dev);
86 retval = 1;
87 }
88
89 if (retval)
90 PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
91 gain, exposure);
92 return retval;
93}
94
95/* Autogain + exposure algorithm for cameras with a coarse exposure control
96 (usually this means we can only control the clockdiv to change exposure)
97 As changing the clockdiv so that the fps drops from 30 to 15 fps for
98 example, will lead to a huge exposure change (it effectively doubles),
99 this algorithm normally tries to only adjust the gain (between 40 and
100 80 %) and if that does not help, only then changes exposure. This leads
101 to a much more stable image then using the knee algorithm which at
102 certain points of the knee graph will only try to adjust exposure,
103 which leads to oscilating as one exposure step is huge.
104
105 Note this assumes that the sd struct for the cam in question has
106 exp_too_high_cnt and exp_too_high_cnt int members for use by this function.
107
108 Returns 0 if no changes were made, 1 if the gain and or exposure settings
109 where changed. */
110static inline int coarse_grained_expo_autogain(
111 struct gspca_dev *gspca_dev,
112 int avg_lum,
113 int desired_avg_lum,
114 int deadzone)
115{
116 struct sd *sd = (struct sd *) gspca_dev;
117 int steps, gain, orig_gain, exposure, orig_exposure;
118 int gain_low, gain_high;
119 int retval = 0;
120
121 orig_gain = gain = sd->ctrls[GAIN].val;
122 orig_exposure = exposure = sd->ctrls[EXPOSURE].val;
123
124 gain_low = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 2;
125 gain_low += sd->ctrls[GAIN].min;
126 gain_high = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 4;
127 gain_high += sd->ctrls[GAIN].min;
128
129 /* If we are of a multiple of deadzone, do multiple steps to reach the
130 desired lumination fast (with the risc of a slight overshoot) */
131 steps = (desired_avg_lum - avg_lum) / deadzone;
132
133 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
134 avg_lum, desired_avg_lum, steps);
135
136 if ((gain + steps) > gain_high &&
137 exposure < sd->ctrls[EXPOSURE].max) {
138 gain = gain_high;
139 sd->exp_too_low_cnt++;
140 sd->exp_too_high_cnt = 0;
141 } else if ((gain + steps) < gain_low &&
142 exposure > sd->ctrls[EXPOSURE].min) {
143 gain = gain_low;
144 sd->exp_too_high_cnt++;
145 sd->exp_too_low_cnt = 0;
146 } else {
147 gain += steps;
148 if (gain > sd->ctrls[GAIN].max)
149 gain = sd->ctrls[GAIN].max;
150 else if (gain < sd->ctrls[GAIN].min)
151 gain = sd->ctrls[GAIN].min;
152 sd->exp_too_high_cnt = 0;
153 sd->exp_too_low_cnt = 0;
154 }
155
156 if (sd->exp_too_high_cnt > 3) {
157 exposure--;
158 sd->exp_too_high_cnt = 0;
159 } else if (sd->exp_too_low_cnt > 3) {
160 exposure++;
161 sd->exp_too_low_cnt = 0;
162 }
163
164 if (gain != orig_gain) {
165 sd->ctrls[GAIN].val = gain;
166 setgain(gspca_dev);
167 retval = 1;
168 }
169 if (exposure != orig_exposure) {
170 sd->ctrls[EXPOSURE].val = exposure;
171 setexposure(gspca_dev);
172 retval = 1;
173 }
174
175 if (retval)
176 PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
177 gain, exposure);
178 return retval;
179}
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 4bf2cab98d64..9ddbac680663 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * cpia CPiA (1) gspca driver 2 * cpia CPiA (1) gspca driver
3 * 3 *
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com> 4 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
5 * 5 *
6 * This module is adapted from the in kernel v4l1 cpia driver which is : 6 * This module is adapted from the in kernel v4l1 cpia driver which is :
7 * 7 *
@@ -28,6 +28,7 @@
28 28
29#define MODULE_NAME "cpia1" 29#define MODULE_NAME "cpia1"
30 30
31#include <linux/input.h>
31#include "gspca.h" 32#include "gspca.h"
32 33
33MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 34MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
@@ -653,10 +654,15 @@ static int do_command(struct gspca_dev *gspca_dev, u16 command,
653 break; 654 break;
654 655
655 case CPIA_COMMAND_ReadMCPorts: 656 case CPIA_COMMAND_ReadMCPorts:
656 if (!sd->params.qx3.qx3_detected)
657 break;
658 /* test button press */ 657 /* test button press */
659 sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0); 658 a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
659 if (a != sd->params.qx3.button) {
660#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
661 input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
662 input_sync(gspca_dev->input_dev);
663#endif
664 sd->params.qx3.button = a;
665 }
660 if (sd->params.qx3.button) { 666 if (sd->params.qx3.button) {
661 /* button pressed - unlock the latch */ 667 /* button pressed - unlock the latch */
662 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 668 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
@@ -1400,7 +1406,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
1400 if ((sd->exposure_status == EXPOSURE_VERY_DARK || 1406 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1401 sd->exposure_status == EXPOSURE_DARK) && 1407 sd->exposure_status == EXPOSURE_DARK) &&
1402 sd->exposure_count >= DARK_TIME * framerate && 1408 sd->exposure_count >= DARK_TIME * framerate &&
1403 sd->params.sensorFps.divisor < 3) { 1409 sd->params.sensorFps.divisor < 2) {
1404 1410
1405 /* dark for too long */ 1411 /* dark for too long */
1406 ++sd->params.sensorFps.divisor; 1412 ++sd->params.sensorFps.divisor;
@@ -1456,7 +1462,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
1456 if ((sd->exposure_status == EXPOSURE_VERY_DARK || 1462 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1457 sd->exposure_status == EXPOSURE_DARK) && 1463 sd->exposure_status == EXPOSURE_DARK) &&
1458 sd->exposure_count >= DARK_TIME * framerate && 1464 sd->exposure_count >= DARK_TIME * framerate &&
1459 sd->params.sensorFps.divisor < 3) { 1465 sd->params.sensorFps.divisor < 2) {
1460 1466
1461 /* dark for too long */ 1467 /* dark for too long */
1462 ++sd->params.sensorFps.divisor; 1468 ++sd->params.sensorFps.divisor;
@@ -1738,6 +1744,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1738 1744
1739static void sd_stopN(struct gspca_dev *gspca_dev) 1745static void sd_stopN(struct gspca_dev *gspca_dev)
1740{ 1746{
1747 struct sd *sd = (struct sd *) gspca_dev;
1748
1741 command_pause(gspca_dev); 1749 command_pause(gspca_dev);
1742 1750
1743 /* save camera state for later open (developers guide ch 3.5.3) */ 1751 /* save camera state for later open (developers guide ch 3.5.3) */
@@ -1748,6 +1756,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1748 1756
1749 /* Update the camera status */ 1757 /* Update the camera status */
1750 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); 1758 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1759
1760#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1761 /* If the last button state is pressed, release it now! */
1762 if (sd->params.qx3.button) {
1763 /* The camera latch will hold the pressed state until we reset
1764 the latch, so we do not reset sd->params.qx3.button now, to
1765 avoid a false keypress being reported the next sd_start */
1766 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1767 input_sync(gspca_dev->input_dev);
1768 }
1769#endif
1751} 1770}
1752 1771
1753/* this function is called at probe and resume time */ 1772/* this function is called at probe and resume time */
@@ -1852,8 +1871,7 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev)
1852 1871
1853 /* Update our knowledge of the camera state */ 1872 /* Update our knowledge of the camera state */
1854 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); 1873 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1855 if (sd->params.qx3.qx3_detected) 1874 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1856 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1857} 1875}
1858 1876
1859static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1877static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2085,6 +2103,9 @@ static const struct sd_desc sd_desc = {
2085 .dq_callback = sd_dq_callback, 2103 .dq_callback = sd_dq_callback,
2086 .pkt_scan = sd_pkt_scan, 2104 .pkt_scan = sd_pkt_scan,
2087 .querymenu = sd_querymenu, 2105 .querymenu = sd_querymenu,
2106#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2107 .other_input = 1,
2108#endif
2088}; 2109};
2089 2110
2090/* -- module initialisation -- */ 2111/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index f21f2a258ae0..9c6a643caf01 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Main USB camera driver 2 * Main USB camera driver
3 * 3 *
4 * Copyright (C) 2008-2010 Jean-François Moine <http://moinejf.free.fr> 4 * Copyright (C) 2008-2011 Jean-François Moine <http://moinejf.free.fr>
5 * 5 *
6 * Camera button input handling by Márton Németh 6 * Camera button input handling by Márton Németh
7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> 7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
@@ -414,7 +414,6 @@ resubmit:
414 * - 0 or many INTER_PACKETs 414 * - 0 or many INTER_PACKETs
415 * - one LAST_PACKET 415 * - one LAST_PACKET
416 * DISCARD_PACKET invalidates the whole frame. 416 * DISCARD_PACKET invalidates the whole frame.
417 * On LAST_PACKET, a new frame is returned.
418 */ 417 */
419void gspca_frame_add(struct gspca_dev *gspca_dev, 418void gspca_frame_add(struct gspca_dev *gspca_dev,
420 enum gspca_packet_type packet_type, 419 enum gspca_packet_type packet_type,
@@ -631,7 +630,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
631 ep = &alt->endpoint[i]; 630 ep = &alt->endpoint[i];
632 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; 631 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
633 if (attr == xfer 632 if (attr == xfer
634 && ep->desc.wMaxPacketSize != 0) 633 && ep->desc.wMaxPacketSize != 0
634 && usb_endpoint_dir_in(&ep->desc))
635 return ep; 635 return ep;
636 } 636 }
637 return NULL; 637 return NULL;
@@ -1525,10 +1525,12 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1525 gspca_dev->usb_err = 0; 1525 gspca_dev->usb_err = 0;
1526 gspca_stream_off(gspca_dev); 1526 gspca_stream_off(gspca_dev);
1527 mutex_unlock(&gspca_dev->usb_lock); 1527 mutex_unlock(&gspca_dev->usb_lock);
1528
1529 /* Don't restart the stream when switching from read
1530 * to mmap mode */
1531 if (gspca_dev->memory == GSPCA_MEMORY_READ)
1532 streaming = 0;
1528 } 1533 }
1529 /* Don't restart the stream when switching from read to mmap mode */
1530 if (gspca_dev->memory == GSPCA_MEMORY_READ)
1531 streaming = 0;
1532 1534
1533 /* free the previous allocated buffers, if any */ 1535 /* free the previous allocated buffers, if any */
1534 if (gspca_dev->nframes != 0) 1536 if (gspca_dev->nframes != 0)
@@ -2152,7 +2154,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
2152 .vidioc_g_chip_ident = vidioc_g_chip_ident, 2154 .vidioc_g_chip_ident = vidioc_g_chip_ident,
2153}; 2155};
2154 2156
2155static struct video_device gspca_template = { 2157static const struct video_device gspca_template = {
2156 .name = "gspca main driver", 2158 .name = "gspca main driver",
2157 .fops = &dev_fops, 2159 .fops = &dev_fops,
2158 .ioctl_ops = &dev_ioctl_ops, 2160 .ioctl_ops = &dev_ioctl_ops,
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index 06b777f5379e..36dae38b1e38 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -183,7 +183,6 @@ static void jlj_dostream(struct work_struct *work)
183 struct sd *dev = container_of(work, struct sd, work_struct); 183 struct sd *dev = container_of(work, struct sd, work_struct);
184 struct gspca_dev *gspca_dev = &dev->gspca_dev; 184 struct gspca_dev *gspca_dev = &dev->gspca_dev;
185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */ 185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */
186 int size_in_blocks;
187 int act_len; 186 int act_len;
188 int packet_type; 187 int packet_type;
189 int ret; 188 int ret;
@@ -209,7 +208,6 @@ static void jlj_dostream(struct work_struct *work)
209 act_len, JEILINJ_MAX_TRANSFER); 208 act_len, JEILINJ_MAX_TRANSFER);
210 if (ret < 0 || act_len < FRAME_HEADER_LEN) 209 if (ret < 0 || act_len < FRAME_HEADER_LEN)
211 goto quit_stream; 210 goto quit_stream;
212 size_in_blocks = buffer[0x0a];
213 blocks_left = buffer[0x0a] - 1; 211 blocks_left = buffer[0x0a] - 1;
214 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left); 212 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
215 213
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c
new file mode 100644
index 000000000000..8e754fd4dc5e
--- /dev/null
+++ b/drivers/media/video/gspca/nw80x.c
@@ -0,0 +1,2145 @@
1/*
2 * DivIO nw80x subdriver
3 *
4 * Copyright (C) 2011 Jean-François Moine (http://moinejf.free.fr)
5 * Copyright (C) 2003 Sylvain Munaut <tnt@246tNt.com>
6 * Kjell Claesson <keyson@users.sourceforge.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#define MODULE_NAME "nw80x"
24
25#include "gspca.h"
26
27MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
28MODULE_DESCRIPTION("NW80x USB Camera Driver");
29MODULE_LICENSE("GPL");
30
31static int webcam;
32
33/* controls */
34enum e_ctrl {
35 GAIN,
36 EXPOSURE,
37 AUTOGAIN,
38 NCTRLS /* number of controls */
39};
40
41#define AUTOGAIN_DEF 1
42
43/* specific webcam descriptor */
44struct sd {
45 struct gspca_dev gspca_dev; /* !! must be the first item */
46
47 struct gspca_ctrl ctrls[NCTRLS];
48
49 u32 ae_res;
50 s8 ag_cnt;
51#define AG_CNT_START 13
52 u8 exp_too_low_cnt;
53 u8 exp_too_high_cnt;
54
55 u8 bridge;
56 u8 webcam;
57};
58
59enum bridges {
60 BRIDGE_NW800, /* and et31x110 */
61 BRIDGE_NW801,
62 BRIDGE_NW802,
63};
64enum webcams {
65 Generic800,
66 SpaceCam, /* Trust 120 SpaceCam */
67 SpaceCam2, /* other Trust 120 SpaceCam */
68 Cvideopro, /* Conceptronic Video Pro */
69 Dlink350c,
70 DS3303u,
71 Kr651us,
72 Kritter,
73 Mustek300,
74 Proscope,
75 Twinkle,
76 DvcV6,
77 P35u,
78 Generic802,
79 NWEBCAMS /* number of webcams */
80};
81
82static const u8 webcam_chip[NWEBCAMS] = {
83 [Generic800] = BRIDGE_NW800, /* 06a5:0000
84 * Typhoon Webcam 100 USB */
85
86 [SpaceCam] = BRIDGE_NW800, /* 06a5:d800
87 * Trust SpaceCam120 or SpaceCam100 PORTABLE */
88
89 [SpaceCam2] = BRIDGE_NW800, /* 06a5:d800 - pas106
90 * other Trust SpaceCam120 or SpaceCam100 PORTABLE */
91
92 [Cvideopro] = BRIDGE_NW802, /* 06a5:d001
93 * Conceptronic Video Pro 'CVIDEOPRO USB Webcam CCD' */
94
95 [Dlink350c] = BRIDGE_NW802, /* 06a5:d001
96 * D-Link NetQam Pro 250plus */
97
98 [DS3303u] = BRIDGE_NW801, /* 06a5:d001
99 * Plustek Opticam 500U or ProLink DS3303u */
100
101 [Kr651us] = BRIDGE_NW802, /* 06a5:d001
102 * Panasonic GP-KR651US */
103
104 [Kritter] = BRIDGE_NW802, /* 06a5:d001
105 * iRez Kritter cam */
106
107 [Mustek300] = BRIDGE_NW802, /* 055f:d001
108 * Mustek Wcam 300 mini */
109
110 [Proscope] = BRIDGE_NW802, /* 06a5:d001
111 * Scalar USB Microscope (ProScope) */
112
113 [Twinkle] = BRIDGE_NW800, /* 06a5:d800 - hv7121b? (seems pas106)
114 * Divio Chicony TwinkleCam
115 * DSB-C110 */
116
117 [DvcV6] = BRIDGE_NW802, /* 0502:d001
118 * DVC V6 */
119
120 [P35u] = BRIDGE_NW801, /* 052b:d001, 06a5:d001 and 06be:d001
121 * EZCam Pro p35u */
122
123 [Generic802] = BRIDGE_NW802,
124};
125/*
126 * other webcams:
127 * - nw801 046d:d001
128 * Logitech QuickCam Pro (dark focus ring)
129 * - nw801 0728:d001
130 * AVerMedia Camguard
131 * - nw??? 06a5:d001
132 * D-Link NetQam Pro 250plus
133 * - nw800 065a:d800
134 * Showcam NGS webcam
135 * - nw??? ????:????
136 * Sceptre svc300
137 */
138
139/*
140 * registers
141 * nw800/et31x110 nw801 nw802
142 * 0000..009e 0000..00a1 0000..009e
143 * 0200..0211 id id
144 * 0300..0302 id id
145 * 0400..0406 (inex) 0400..0406
146 * 0500..0505 0500..0506 (inex)
147 * 0600..061a 0600..0601 0600..0601
148 * 0800..0814 id id
149 * 1000..109c 1000..10a1 1000..109a
150 */
151
152/* resolutions
153 * nw800: 320x240, 352x288
154 * nw801/802: 320x240, 640x480
155 */
156static const struct v4l2_pix_format cif_mode[] = {
157 {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
158 .bytesperline = 320,
159 .sizeimage = 320 * 240 * 4 / 8,
160 .colorspace = V4L2_COLORSPACE_JPEG},
161 {352, 288, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
162 .bytesperline = 352,
163 .sizeimage = 352 * 288 * 4 / 8,
164 .colorspace = V4L2_COLORSPACE_JPEG}
165};
166static const struct v4l2_pix_format vga_mode[] = {
167 {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
168 .bytesperline = 320,
169 .sizeimage = 320 * 240 * 4 / 8,
170 .colorspace = V4L2_COLORSPACE_JPEG},
171 {640, 480, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
172 .bytesperline = 640,
173 .sizeimage = 640 * 480 * 3 / 8,
174 .colorspace = V4L2_COLORSPACE_JPEG},
175};
176
177/*
178 * The sequences below contain:
179 * - 1st and 2nd bytes: either
180 * - register number (BE)
181 * - I2C0 + i2c address
182 * - 3rd byte: data length (=0 for end of sequence)
183 * - n bytes: data
184 */
185#define I2C0 0xff
186
187static const u8 nw800_init[] = {
188 0x04, 0x05, 0x01, 0x61,
189 0x04, 0x04, 0x01, 0x01,
190 0x04, 0x06, 0x01, 0x04,
191 0x04, 0x04, 0x03, 0x00, 0x00, 0x00,
192 0x05, 0x05, 0x01, 0x00,
193 0, 0, 0
194};
195static const u8 nw800_start[] = {
196 0x04, 0x06, 0x01, 0xc0,
197 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
198 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
199 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
200 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
201 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
202 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
203 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
204 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
205 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
206 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
207 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
208 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
209 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
210 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
212 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
213 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
215 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
216 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
217 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
218 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
219 0x40, 0x20,
220 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
221 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0,
222 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20,
223 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00,
227 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
232 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
235 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
236 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
237 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
238 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
239 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
240 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
241 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
242 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
243 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
244 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
245 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
246 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
248 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
249 0x01, 0x60, 0x01, 0x00, 0x00,
250
251 0x04, 0x04, 0x01, 0xff,
252 0x04, 0x06, 0x01, 0xc4,
253
254 0x04, 0x06, 0x01, 0xc0,
255 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
256 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
257 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
258 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
259 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
260 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
261 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
262 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
263 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
264 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
265 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
266 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
267 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
268 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
270 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
271 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
273 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
274 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
275 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
276 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
277 0x40, 0x20,
278 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
279 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0,
280 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20,
281 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00,
285 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
290 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
293 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
294 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
295 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
296 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
297 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
298 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
299 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
300 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
301 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
302 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
303 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
304 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
306 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
307 0x01, 0x60, 0x01, 0x00, 0x00,
308
309 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
310 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
311 0x40,
312 0x00, 0x80, 0x01, 0xa0,
313 0x10, 0x1a, 0x01, 0x00,
314 0x00, 0x91, 0x02, 0x6c, 0x01,
315 0x00, 0x03, 0x02, 0xc8, 0x01,
316 0x10, 0x1a, 0x01, 0x00,
317 0x10, 0x00, 0x01, 0x83,
318 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
319 0x20, 0x01, 0x60, 0x01,
320 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
321 0x10, 0x1b, 0x02, 0x69, 0x00,
322 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
323 0x05, 0x02, 0x01, 0x02,
324 0x06, 0x00, 0x02, 0x04, 0xd9,
325 0x05, 0x05, 0x01, 0x20,
326 0x05, 0x05, 0x01, 0x21,
327 0x10, 0x0e, 0x01, 0x08,
328 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83,
329 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0,
330 0xea,
331 0x10, 0x03, 0x01, 0x00,
332 0x10, 0x0f, 0x02, 0x13, 0x13,
333 0x10, 0x03, 0x01, 0x14,
334 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83,
335 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0,
336 0xea,
337 0x10, 0x0b, 0x01, 0x14,
338 0x10, 0x0d, 0x01, 0x20,
339 0x10, 0x0c, 0x01, 0x34,
340 0x04, 0x06, 0x01, 0xc3,
341 0x04, 0x04, 0x01, 0x00,
342 0x05, 0x02, 0x01, 0x02,
343 0x06, 0x00, 0x02, 0x00, 0x48,
344 0x05, 0x05, 0x01, 0x20,
345 0x05, 0x05, 0x01, 0x21,
346 0, 0, 0
347};
348
349/* 06a5:d001 - nw801 - Panasonic
350 * P35u */
351static const u8 nw801_start_1[] = {
352 0x05, 0x06, 0x01, 0x04,
353 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e,
354 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
355 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
356 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
357 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
358 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
359 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
360 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
361 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
362 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
363 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
364 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
365 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
366 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
368 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
369 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x69, 0xa8, 0x1f, 0x00,
371 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00,
372 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00,
373 0x36, 0x00,
374 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
375 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
376 0x40, 0x20,
377 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
378 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x06, 0x00, 0x02, 0x09, 0x99,
380 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x10, 0x00, 0x40, 0x22, 0x02, 0x80, 0x00, 0x1e, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x0a, 0x15, 0x08, 0x08, 0x0a,
385 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x01, 0x35, 0xfd, 0x07, 0x3d, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x02,
388 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
389 0x40, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x06,
390 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7,
391 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80,
392 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, 0xa4,
393 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, 0xcf,
394 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64,
395 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2,
396 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
397 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
398 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
399 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
400 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x82, 0x02,
402 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01,
403 0xf0, 0x00,
404 0, 0, 0,
405};
406static const u8 nw801_start_qvga[] = {
407 0x02, 0x00, 0x10, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
408 0x00, 0x78, 0x18, 0x0b, 0x06, 0xa2, 0x86, 0x78,
409 0x02, 0x0f, 0x01, 0x6b,
410 0x10, 0x1a, 0x01, 0x15,
411 0x00, 0x00, 0x01, 0x1e,
412 0x10, 0x00, 0x01, 0x2f,
413 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
414 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00,
415 /* AE window */
416 0, 0, 0,
417};
418static const u8 nw801_start_vga[] = {
419 0x02, 0x00, 0x10, 0x78, 0xa0, 0x97, 0x78, 0xa0, 0x00, 0x00, 0x00,
420 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xf0,
421 0x02, 0x0f, 0x01, 0xd5,
422 0x10, 0x1a, 0x01, 0x15,
423 0x00, 0x00, 0x01, 0x0e,
424 0x10, 0x00, 0x01, 0x22,
425 0x10, 0x8c, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
426 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01,
427 0, 0, 0,
428};
429static const u8 nw801_start_2[] = {
430 0x10, 0x04, 0x01, 0x1a,
431 0x10, 0x19, 0x01, 0x09, /* clock */
432 0x10, 0x24, 0x06, 0xc0, 0x00, 0x3f, 0x02, 0x00, 0x01,
433 /* .. gain .. */
434 0x00, 0x03, 0x02, 0x92, 0x03,
435 0x00, 0x1d, 0x04, 0xf2, 0x00, 0x24, 0x07,
436 0x00, 0x7b, 0x01, 0xcf,
437 0x10, 0x94, 0x01, 0x07,
438 0x05, 0x05, 0x01, 0x01,
439 0x05, 0x04, 0x01, 0x01,
440 0x10, 0x0e, 0x01, 0x08,
441 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8,
442 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0,
443 0xf0,
444 0x10, 0x03, 0x01, 0x00,
445 0x10, 0x0f, 0x02, 0x0c, 0x0c,
446 0x10, 0x03, 0x01, 0x08,
447 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8,
448 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0,
449 0xf0,
450 0x10, 0x0b, 0x01, 0x0b,
451 0x10, 0x0d, 0x01, 0x0b,
452 0x10, 0x0c, 0x01, 0x1f,
453 0x05, 0x06, 0x01, 0x03,
454 0, 0, 0
455};
456
457/* nw802 (sharp IR3Y38M?) */
458static const u8 nw802_start[] = {
459 0x04, 0x06, 0x01, 0x04,
460 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x4d,
461 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
462 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
463 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
464 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
465 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
466 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
467 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
468 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
469 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
470 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
471 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
472 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
473 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
474 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
475 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
476 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
478 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
479 0x00, 0x10, 0x06, 0x08, 0x00, 0x18, 0x00,
480 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
481 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
482 0x40, 0x20,
483 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
484 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
485 0x06, 0x00, 0x02, 0x09, 0x99,
486 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x1d, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
491 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x49, 0x13, 0xff, 0x01, 0xc0, 0x00, 0x14,
493 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
494 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
495 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
496 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
497 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
498 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
499 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
500 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
501 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
502 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
503 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
504 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
505 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x05, 0x82,
507 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
508 0x01, 0xf0, 0x00,
509 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
510 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
511 0x40,
512 0x10, 0x1a, 0x01, 0x00,
513 0x10, 0x00, 0x01, 0xad,
514 0x00, 0x00, 0x01, 0x08,
515 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
516 0x10, 0x1b, 0x02, 0x00, 0x00,
517 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00,
518 0x10, 0x1d, 0x08, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
519 0x10, 0x0e, 0x01, 0x27,
520 0x10, 0x41, 0x11, 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b,
521 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2,
522 0xd8,
523 0x10, 0x03, 0x01, 0x00,
524 0x10, 0x0f, 0x02, 0x14, 0x14,
525 0x10, 0x03, 0x01, 0x0c,
526 0x10, 0x41, 0x11, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64, 0x74,
527 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2, 0xf1,
528 0xff,
529/* 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b,
530 * 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2,
531 * 0xd8, */
532 0x10, 0x0b, 0x01, 0x10,
533 0x10, 0x0d, 0x01, 0x11,
534 0x10, 0x0c, 0x01, 0x1c,
535 0x04, 0x06, 0x01, 0x03,
536 0x04, 0x04, 0x01, 0x00,
537 0, 0, 0
538};
539/* et31x110 - Trust 120 SpaceCam */
540static const u8 spacecam_init[] = {
541 0x04, 0x05, 0x01, 0x01,
542 0x04, 0x04, 0x01, 0x01,
543 0x04, 0x06, 0x01, 0x04,
544 0x04, 0x04, 0x03, 0x00, 0x00, 0x00,
545 0x05, 0x05, 0x01, 0x00,
546 0, 0, 0
547};
548static const u8 spacecam_start[] = {
549 0x04, 0x06, 0x01, 0x44,
550 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
551 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
552 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
553 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
554 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
555 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
556 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
557 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
558 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
559 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
560 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
561 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
562 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
563 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
565 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
566 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
568 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
569 0x00, 0x4b, 0x00, 0x7c, 0x00, 0x80, 0x00,
570 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
571 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
572 0x40, 0x20,
573 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
574 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00,
580 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
585 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
588 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
589 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
590 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
591 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
592 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
593 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
594 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
595 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
596 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
597 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
598 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
599 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
601 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
602 0x01, 0x60, 0x01, 0x00, 0x00,
603 0x04, 0x06, 0x01, 0xc0,
604 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
605 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
606 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
607 0x40,
608 0x00, 0x80, 0x01, 0xa0,
609 0x10, 0x1a, 0x01, 0x00,
610 0x00, 0x91, 0x02, 0x32, 0x01,
611 0x00, 0x03, 0x02, 0x08, 0x02,
612 0x10, 0x00, 0x01, 0x83,
613 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
614 0x20, 0x01, 0x60, 0x01,
615 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
616 0x10, 0x0e, 0x01, 0x08,
617 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9,
618 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
619 0xf9,
620 0x10, 0x03, 0x01, 0x00,
621 0x10, 0x0f, 0x02, 0x13, 0x13,
622 0x10, 0x03, 0x01, 0x06,
623 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9,
624 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
625 0xf9,
626 0x10, 0x0b, 0x01, 0x08,
627 0x10, 0x0d, 0x01, 0x10,
628 0x10, 0x0c, 0x01, 0x1f,
629 0x04, 0x06, 0x01, 0xc3,
630 0x04, 0x05, 0x01, 0x40,
631 0x04, 0x04, 0x01, 0x40,
632 0, 0, 0
633};
634/* et31x110 - pas106 - other Trust SpaceCam120 */
635static const u8 spacecam2_start[] = {
636 0x04, 0x06, 0x01, 0x44,
637 0x04, 0x06, 0x01, 0x00,
638 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f,
639 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19,
640 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
641 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc,
642 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
643 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
644 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
645 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
646 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
647 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
648 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
649 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
650 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
651 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
653 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
654 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03,
656 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
657 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
658 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
659 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
660 0x40, 0x20,
661 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
662 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00,
663 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00,
668 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
673 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
676 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
677 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
678 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
679 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
680 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
681 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
682 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
683 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
684 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
685 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
686 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
687 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62,
689 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
690 0x01, 0x60, 0x01, 0x00, 0x00,
691 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
692 0x04, 0x04, 0x01, 0x40,
693 0x04, 0x04, 0x01, 0x00,
694 I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x05,
695 0x00, 0x00, 0x05, 0x05,
696 I2C0, 0x40, 0x02, 0x11, 0x06,
697 I2C0, 0x40, 0x02, 0x14, 0x00,
698 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
699 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
700 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
701 0x40,
702 I2C0, 0x40, 0x02, 0x02, 0x0c, /* pixel clock */
703 I2C0, 0x40, 0x02, 0x0f, 0x00,
704 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
705 0x10, 0x00, 0x01, 0x01,
706 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
707 0x20, 0x01, 0x60, 0x01,
708 I2C0, 0x40, 0x02, 0x05, 0x0f, /* exposure */
709 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
710 I2C0, 0x40, 0x07, 0x09, 0x0b, 0x0f, 0x05, 0x05, 0x0f, 0x00,
711 /* gains */
712 I2C0, 0x40, 0x03, 0x12, 0x04, 0x01,
713 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
714 0x10, 0x0e, 0x01, 0x08,
715 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
716 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
717 0xf9,
718 0x10, 0x03, 0x01, 0x00,
719 0x10, 0x0f, 0x02, 0x13, 0x13,
720 0x10, 0x03, 0x01, 0x06,
721 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
722 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
723 0xf9,
724 0x10, 0x0b, 0x01, 0x11,
725 0x10, 0x0d, 0x01, 0x10,
726 0x10, 0x0c, 0x01, 0x14,
727 0x04, 0x06, 0x01, 0x03,
728 0x04, 0x05, 0x01, 0x61,
729 0x04, 0x04, 0x01, 0x00,
730 0, 0, 0
731};
732
733/* nw802 - Conceptronic Video Pro */
734static const u8 cvideopro_start[] = {
735 0x04, 0x06, 0x01, 0x04,
736 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c,
737 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
738 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
739 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
740 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
741 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
742 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
743 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
744 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
745 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
746 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
747 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
748 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
749 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
751 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
752 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
753 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
754 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
755 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
756 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
757 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
758 0x40, 0x20,
759 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
760 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
761 0x06, 0x00, 0x02, 0x09, 0x99,
762 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764 0x00, 0x00, 0x00, 0x00, 0x00,
765 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
766 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
767 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
769 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
770 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
771 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
772 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
773 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
774 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
775 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
776 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
777 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
778 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
779 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
780 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
781 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
783 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
784 0x01, 0xf0, 0x00,
785 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00,
786 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
787 0x40,
788 0x10, 0x1a, 0x01, 0x03,
789 0x10, 0x00, 0x01, 0xac,
790 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
791 0x10, 0x1b, 0x02, 0x3b, 0x01,
792 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
793 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
794 0x10, 0x1d, 0x02, 0x40, 0x06,
795 0x10, 0x0e, 0x01, 0x08,
796 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0,
797 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc,
798 0xdc,
799 0x10, 0x03, 0x01, 0x00,
800 0x10, 0x0f, 0x02, 0x12, 0x12,
801 0x10, 0x03, 0x01, 0x0c,
802 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0,
803 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc,
804 0xdc,
805 0x10, 0x0b, 0x01, 0x09,
806 0x10, 0x0d, 0x01, 0x10,
807 0x10, 0x0c, 0x01, 0x2f,
808 0x04, 0x06, 0x01, 0x03,
809 0x04, 0x04, 0x01, 0x00,
810 0, 0, 0
811};
812
813/* nw802 - D-link dru-350c cam */
814static const u8 dlink_start[] = {
815 0x04, 0x06, 0x01, 0x04,
816 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d,
817 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
818 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
819 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
820 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
821 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
822 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
823 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
824 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
825 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
826 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
827 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
828 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
829 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
830 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
831 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
832 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
833 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
834 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
835 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00,
836 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
837 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
838 0x40, 0x20,
839 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
840 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
841 0x06, 0x00, 0x02, 0x09, 0x99,
842 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
844 0x00, 0x00, 0x00, 0x00, 0x00,
845 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
846 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
847 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14,
849 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
850 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
851 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
852 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
853 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
854 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
855 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
856 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
857 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
858 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
859 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
860 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
861 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
862 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x82,
863 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
864 0x01, 0xf0, 0x00,
865 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
866 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
867 0x40,
868 0x10, 0x1a, 0x01, 0x00,
869 0x10, 0x00, 0x01, 0xad,
870 0x00, 0x00, 0x01, 0x08,
871 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
872 0x10, 0x1b, 0x02, 0x00, 0x00,
873 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00,
874 0x10, 0x1d, 0x08, 0x40, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
875 0x10, 0x0e, 0x01, 0x20,
876 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f,
877 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf,
878 0xea,
879 0x10, 0x03, 0x01, 0x00,
880 0x10, 0x0f, 0x02, 0x11, 0x11,
881 0x10, 0x03, 0x01, 0x10,
882 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f,
883 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf,
884 0xea,
885 0x10, 0x0b, 0x01, 0x19,
886 0x10, 0x0d, 0x01, 0x10,
887 0x10, 0x0c, 0x01, 0x1e,
888 0x04, 0x06, 0x01, 0x03,
889 0x04, 0x04, 0x01, 0x00,
890 0, 0, 0
891};
892
893/* 06a5:d001 - nw801 - Sony
894 * Plustek Opticam 500U or ProLink DS3303u (Hitachi HD49322BF) */
895/*fixme: 320x240 only*/
896static const u8 ds3303_start[] = {
897 0x05, 0x06, 0x01, 0x04,
898 0x00, 0x00, 0x40, 0x16, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e,
899 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
900 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
901 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
902 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
903 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
904 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
905 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
906 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
907 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
908 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
909 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
910 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
911 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
912 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
913 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
914 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00,
915 0x00, 0x00, 0x00, 0x00, 0xa9, 0xa8, 0x1f, 0x00,
916 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00,
917 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00,
918 0x36, 0x00,
919 0x02, 0x00, 0x12, 0x03, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
920 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0x50,
921 0x40, 0x20,
922 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
923 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
924 0x06, 0x00, 0x02, 0x09, 0x99,
925 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
926 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
927 0x00, 0x00, 0x00, 0x00, 0x00,
928 0x10, 0x00, 0x40, 0x2f, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
929 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a,
930 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4,
931 0x00, 0x01, 0x15, 0xfd, 0x07, 0x3d, 0x00, 0x00,
932 0x00, 0x00, 0x00, 0x00, 0x8c, 0x04, 0x01, 0x20,
933 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00,
934 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x03,
935 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7,
936 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80,
937 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f, 0x88,
938 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4, 0xcb,
939 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64,
940 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2,
941 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
942 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
943 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
944 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
945 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f, 0x01,
946 0x00, 0x00, 0xef, 0x00, 0x02, 0x0a, 0x82, 0x02,
947 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01,
948 0xf0, 0x00,
949
950 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
951 0x00, 0x78, 0x3f, 0x3f, 0x00, 0xf2, 0x8f, 0x81,
952 0x40,
953 0x10, 0x1a, 0x01, 0x15,
954 0x10, 0x00, 0x01, 0x2f,
955 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
956 0x10, 0x1b, 0x02, 0x00, 0x00,
957 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
958 0x10, 0x26, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
959 0x10, 0x24, 0x02, 0x40, 0x06,
960 0x10, 0x0e, 0x01, 0x08,
961 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6,
962 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
963 0xf9,
964 0x10, 0x03, 0x01, 0x00,
965 0x10, 0x0f, 0x02, 0x16, 0x16,
966 0x10, 0x03, 0x01, 0x0c,
967 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6,
968 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
969 0xf9,
970 0x10, 0x0b, 0x01, 0x26,
971 0x10, 0x0d, 0x01, 0x10,
972 0x10, 0x0c, 0x01, 0x1c,
973 0x05, 0x06, 0x01, 0x03,
974 0x05, 0x04, 0x01, 0x00,
975 0, 0, 0
976};
977
978/* 06a5:d001 - nw802 - Panasonic
979 * GP-KR651US (Philips TDA8786) */
980static const u8 kr651_start_1[] = {
981 0x04, 0x06, 0x01, 0x04,
982 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x48,
983 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
984 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
985 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
986 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
987 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
988 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
989 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
990 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
991 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
992 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
993 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
994 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
995 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
997 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
998 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
999 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1000 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
1001 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
1002 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1003 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1004 0x40, 0x20,
1005 0x03, 0x00, 0x03, 0x02, 0x00, 0x00,
1006 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
1007 0x06, 0x00, 0x02, 0x09, 0x99,
1008 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010 0x00, 0x00, 0x00, 0x00, 0x00,
1011 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1012 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1013 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
1015 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1016 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1017 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1018 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1019 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1020 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1021 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1022 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1023 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1024 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1025 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1026 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1027 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1028 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
1029 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1030 0x01, 0xf0, 0x00,
1031 0, 0, 0
1032};
1033static const u8 kr651_start_qvga[] = {
1034 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
1035 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
1036 0x40,
1037 0x10, 0x1a, 0x01, 0x03,
1038 0x10, 0x00, 0x01, 0xac,
1039 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1040 0x10, 0x1b, 0x02, 0x00, 0x00,
1041 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00,
1042 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
1043 0x10, 0x1d, 0x02, 0x28, 0x01,
1044 0, 0, 0
1045};
1046static const u8 kr651_start_vga[] = {
1047 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00,
1048 0x00, 0xf0, 0x30, 0x03, 0x01, 0x82, 0x82, 0x98,
1049 0x80,
1050 0x10, 0x1a, 0x01, 0x03,
1051 0x10, 0x00, 0x01, 0xa0,
1052 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
1053 0x10, 0x1b, 0x02, 0x00, 0x00,
1054 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01,
1055 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
1056 0x10, 0x1d, 0x02, 0x68, 0x00,
1057};
1058static const u8 kr651_start_2[] = {
1059 0x10, 0x0e, 0x01, 0x08,
1060 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8,
1061 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
1062 0xdc,
1063 0x10, 0x03, 0x01, 0x00,
1064 0x10, 0x0f, 0x02, 0x0c, 0x0c,
1065 0x10, 0x03, 0x01, 0x0c,
1066 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8,
1067 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
1068 0xdc,
1069 0x10, 0x0b, 0x01, 0x10,
1070 0x10, 0x0d, 0x01, 0x10,
1071 0x10, 0x0c, 0x01, 0x2d,
1072 0x04, 0x06, 0x01, 0x03,
1073 0x04, 0x04, 0x01, 0x00,
1074 0, 0, 0
1075};
1076
1077/* nw802 - iRez Kritter cam */
1078static const u8 kritter_start[] = {
1079 0x04, 0x06, 0x01, 0x06,
1080 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0x94, 0x03, 0x18, 0x00, 0x48,
1081 0x0f, 0x1e, 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19,
1082 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1083 0x00, 0x0b, 0x00, 0x1b, 0x00, 0x0a, 0x01, 0x28,
1084 0x07, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
1085 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1086 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
1087 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1088 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
1089 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1090 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
1091 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1092 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
1093 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1094 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
1095 0x00, 0x5d, 0x00, 0x0e, 0x00, 0x7e, 0x00, 0x30,
1096 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
1097 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1098 0x00, 0x0b, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
1099 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
1100 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1101 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1102 0x40, 0x20,
1103 0x03, 0x00, 0x03, 0x02, 0x00, 0x00,
1104 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
1105 0x06, 0x00, 0x02, 0x09, 0x99,
1106 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00,
1109 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1111 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
1113 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1114 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1115 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1116 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1117 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1118 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1119 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1120 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1121 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1122 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1123 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1124 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1125 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x82,
1127 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1128 0x01, 0xf0, 0x00,
1129 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00,
1130 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
1131 0x40,
1132 0x10, 0x1a, 0x01, 0x03,
1133 0x10, 0x00, 0x01, 0xaf,
1134 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1135 0x10, 0x1b, 0x02, 0x3b, 0x01,
1136 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
1137 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
1138 0x10, 0x1d, 0x02, 0x00, 0x00,
1139 0x10, 0x0e, 0x01, 0x08,
1140 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86,
1141 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4,
1142 0xcb,
1143 0x10, 0x03, 0x01, 0x00,
1144 0x10, 0x0f, 0x02, 0x0d, 0x0d,
1145 0x10, 0x03, 0x01, 0x02,
1146 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86,
1147 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4,
1148 0xcb,
1149 0x10, 0x0b, 0x01, 0x17,
1150 0x10, 0x0d, 0x01, 0x10,
1151 0x10, 0x0c, 0x01, 0x1e,
1152 0x04, 0x06, 0x01, 0x03,
1153 0x04, 0x04, 0x01, 0x00,
1154 0, 0, 0
1155};
1156
1157/* nw802 - Mustek Wcam 300 mini */
1158static const u8 mustek_start[] = {
1159 0x04, 0x06, 0x01, 0x04,
1160 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d,
1161 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
1162 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1163 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
1164 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
1165 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
1166 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
1167 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
1168 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1169 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1170 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1171 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1172 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
1173 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1174 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
1175 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
1176 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1178 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
1179 0x00, 0x10, 0x06, 0xfc, 0x05, 0x0c, 0x06,
1180 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1181 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1182 0x40, 0x20,
1183 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1184 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
1185 0x06, 0x00, 0x02, 0x09, 0x99,
1186 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0x00, 0x00, 0x00, 0x00,
1189 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x13, 0x00, 0x00, 0x00,
1190 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1191 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1192 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14,
1193 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
1194 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1195 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1196 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1197 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1198 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1199 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1200 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1201 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1202 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1203 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1204 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1205 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1206 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x82,
1207 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1208 0x01, 0xf0, 0x00,
1209 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
1210 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
1211 0x40,
1212 0x10, 0x1a, 0x01, 0x00,
1213 0x10, 0x00, 0x01, 0xad,
1214 0x00, 0x00, 0x01, 0x08,
1215 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1216 0x10, 0x1b, 0x02, 0x00, 0x00,
1217 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1218 0x10, 0x1d, 0x08, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
1219 0x10, 0x0e, 0x01, 0x0f,
1220 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e,
1221 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9,
1222 0xff,
1223 0x10, 0x0f, 0x02, 0x11, 0x11,
1224 0x10, 0x03, 0x01, 0x0c,
1225 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e,
1226 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9,
1227 0xff,
1228 0x10, 0x0b, 0x01, 0x1c,
1229 0x10, 0x0d, 0x01, 0x1a,
1230 0x10, 0x0c, 0x01, 0x34,
1231 0x04, 0x05, 0x01, 0x61,
1232 0x04, 0x04, 0x01, 0x40,
1233 0x04, 0x06, 0x01, 0x03,
1234 0, 0, 0
1235};
1236
1237/* nw802 - Scope USB Microscope M2 (ProScope) (Hitachi HD49322BF) */
1238static const u8 proscope_init[] = {
1239 0x04, 0x05, 0x01, 0x21,
1240 0x04, 0x04, 0x01, 0x01,
1241 0, 0, 0
1242};
1243static const u8 proscope_start_1[] = {
1244 0x04, 0x06, 0x01, 0x04,
1245 0x00, 0x00, 0x40, 0x10, 0x01, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x04,
1246 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
1247 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1248 0x00, 0x08, 0x00, 0x17, 0x00, 0xce, 0x00, 0xf4,
1249 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
1250 0x00, 0xce, 0x00, 0xf8, 0x03, 0x3e, 0x00, 0x86,
1251 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
1252 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
1253 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0xb6,
1254 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1255 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1256 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1257 0x00, 0xf6, 0x03, 0x34, 0x04, 0xf6, 0x03, 0x34,
1258 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1259 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xe8,
1260 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
1261 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x1f, 0x0f, 0x08, 0x20, 0xa8, 0x00,
1262 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1263 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19, 0x00, 0x94,
1264 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00,
1265 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1266 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1267 0x40, 0x20,
1268 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1269 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
1270 0x06, 0x00, 0x02, 0x09, 0x99,
1271 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1273 0x00, 0x00, 0x00, 0x00, 0x00,
1274 0x10, 0x00, 0x40, 0xad, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1275 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a,
1276 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4,
1277 0x00, 0x49, 0x13, 0x00, 0x00, 0x8c, 0x04, 0x01,
1278 0x20, 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00,
1279 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1280 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1281 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1282 0x10, 0x40, 0x40, 0x80, 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f,
1283 0x88, 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4,
1284 0xcb, 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1285 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1286 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1287 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1288 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1289 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1290 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f,
1291 0x01, 0x00, 0x00, 0xef, 0x00, 0x09, 0x05, 0x82,
1292 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1293 0x01, 0xf0, 0x00,
1294 0, 0, 0
1295};
1296static const u8 proscope_start_qvga[] = {
1297 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
1298 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
1299 0x40,
1300 0x10, 0x1a, 0x01, 0x06,
1301 0x00, 0x03, 0x02, 0xf9, 0x02,
1302 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1303 0x10, 0x1b, 0x02, 0x00, 0x00,
1304 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1305 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
1306 0x10, 0x0e, 0x01, 0x10,
1307 0, 0, 0
1308};
1309static const u8 proscope_start_vga[] = {
1310 0x00, 0x03, 0x02, 0xf9, 0x02,
1311 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
1312 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00,
1313 0x00, 0xf0, 0x16, 0x00, 0x00, 0x82, 0x84, 0x00,
1314 0x80,
1315 0x10, 0x1a, 0x01, 0x06,
1316 0x10, 0x00, 0x01, 0xa1,
1317 0x10, 0x1b, 0x02, 0x00, 0x00,
1318 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
1319 0x10, 0x11, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
1320 0x10, 0x0e, 0x01, 0x10,
1321 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae,
1322 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2,
1323 0xf9,
1324 0x10, 0x03, 0x01, 0x00,
1325 0, 0, 0
1326};
1327static const u8 proscope_start_2[] = {
1328 0x10, 0x0f, 0x02, 0x0c, 0x0c,
1329 0x10, 0x03, 0x01, 0x0c,
1330 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae,
1331 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2,
1332 0xf9,
1333 0x10, 0x0b, 0x01, 0x0b,
1334 0x10, 0x0d, 0x01, 0x10,
1335 0x10, 0x0c, 0x01, 0x1b,
1336 0x04, 0x06, 0x01, 0x03,
1337 0x04, 0x05, 0x01, 0x21,
1338 0x04, 0x04, 0x01, 0x00,
1339 0, 0, 0
1340};
1341
1342/* nw800 - hv7121b? (seems pas106) - Divio Chicony TwinkleCam */
1343static const u8 twinkle_start[] = {
1344 0x04, 0x06, 0x01, 0x44,
1345 0x04, 0x06, 0x01, 0x00,
1346 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f,
1347 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19,
1348 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1349 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc,
1350 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
1351 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
1352 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
1353 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
1354 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1355 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1356 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1357 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1358 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
1359 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
1361 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
1362 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00,
1363 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03,
1364 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
1365 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
1366 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1367 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1368 0x40, 0x20,
1369 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1370 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00,
1371 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1375 0x00, 0x00, 0x00,
1376 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1378 0x00, 0x00, 0x00, 0x00, 0x00,
1379 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00,
1380 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x08,
1381 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1384 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1385 0x03, 0x00, 0x00, 0x10, 0x00, 0x20, 0x10, 0x06,
1386 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x00, 0x80,
1387 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1388 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1389 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1390 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1391 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1392 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1393 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1394 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1395 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62,
1397 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
1398 0x01, 0x60, 0x01, 0x00, 0x00,
1399
1400 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
1401 0x04, 0x04, 0x01, 0x10,
1402 0x04, 0x04, 0x01, 0x00,
1403 0x04, 0x05, 0x01, 0x61,
1404 0x04, 0x04, 0x01, 0x01,
1405 I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x00,
1406 0x00, 0x00, 0x00, 0x0a,
1407 I2C0, 0x40, 0x02, 0x11, 0x06,
1408 I2C0, 0x40, 0x02, 0x14, 0x00,
1409 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
1410 I2C0, 0x40, 0x02, 0x07, 0x01,
1411 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
1412 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
1413 0x40,
1414 I2C0, 0x40, 0x02, 0x02, 0x0c,
1415 I2C0, 0x40, 0x02, 0x13, 0x01,
1416 0x10, 0x00, 0x01, 0x01,
1417 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
1418 0x20, 0x01, 0x60, 0x01,
1419 I2C0, 0x40, 0x02, 0x05, 0x0f,
1420 I2C0, 0x40, 0x02, 0x13, 0x01,
1421 I2C0, 0x40, 0x08, 0x08, 0x04, 0x0b, 0x01, 0x01, 0x02, 0x00, 0x17,
1422 I2C0, 0x40, 0x03, 0x12, 0x00, 0x01,
1423 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
1424 I2C0, 0x40, 0x02, 0x12, 0x00,
1425 I2C0, 0x40, 0x02, 0x0e, 0x00,
1426 I2C0, 0x40, 0x02, 0x11, 0x06,
1427 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
1428 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
1429 0xf9,
1430 0x10, 0x03, 0x01, 0x00,
1431 0x10, 0x0f, 0x02, 0x0c, 0x0c,
1432 0x10, 0x03, 0x01, 0x06,
1433 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
1434 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
1435 0xf9,
1436 0x10, 0x0b, 0x01, 0x19,
1437 0x10, 0x0d, 0x01, 0x10,
1438 0x10, 0x0c, 0x01, 0x0d,
1439 0x04, 0x06, 0x01, 0x03,
1440 0x04, 0x05, 0x01, 0x61,
1441 0x04, 0x04, 0x01, 0x41,
1442 0, 0, 0
1443};
1444
1445/* nw802 dvc-v6 */
1446static const u8 dvcv6_start[] = {
1447 0x04, 0x06, 0x01, 0x06,
1448 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c,
1449 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
1450 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1451 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
1452 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
1453 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1454 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
1455 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1456 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
1457 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1458 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
1459 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1460 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
1461 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
1463 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
1464 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
1465 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1466 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
1467 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
1468 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1469 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1470 0x40, 0x20,
1471 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1472 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
1473 0x06, 0x00, 0x02, 0x09, 0x99,
1474 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476 0x00, 0x00, 0x00, 0x00, 0x00,
1477 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1478 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1479 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1480 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
1481 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1482 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1483 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1484 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1485 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1486 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1487 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1488 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1489 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1490 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1491 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1492 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1493 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
1495 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1496 0x01, 0xf0, 0x00,
1497 0x00, 0x03, 0x02, 0x94, 0x03,
1498 0x00, 0x1d, 0x04, 0x0a, 0x01, 0x28, 0x07,
1499 0x00, 0x7b, 0x02, 0xe0, 0x00,
1500 0x10, 0x8d, 0x01, 0x00,
1501 0x00, 0x09, 0x04, 0x1e, 0x00, 0x0c, 0x02,
1502 0x00, 0x91, 0x02, 0x0b, 0x02,
1503 0x10, 0x00, 0x01, 0xaf,
1504 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8f, 0x3c, 0x50, 0x00, 0x00, 0x00,
1505 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
1506 0x40,
1507 0x10, 0x1a, 0x01, 0x02,
1508 0x10, 0x00, 0x01, 0xaf,
1509 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1510 0x10, 0x1b, 0x02, 0x07, 0x01,
1511 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
1512 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
1513 0x10, 0x1d, 0x02, 0x40, 0x06,
1514 0x10, 0x0e, 0x01, 0x08,
1515 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa,
1516 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc,
1517 0xdc,
1518 0x10, 0x03, 0x01, 0x00,
1519 0x10, 0x0f, 0x02, 0x12, 0x12,
1520 0x10, 0x03, 0x01, 0x11,
1521 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa,
1522 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc,
1523 0xdc,
1524 0x10, 0x0b, 0x01, 0x16,
1525 0x10, 0x0d, 0x01, 0x10,
1526 0x10, 0x0c, 0x01, 0x1a,
1527 0x04, 0x06, 0x01, 0x03,
1528 0x04, 0x04, 0x01, 0x00,
1529};
1530
1531static const u8 *webcam_start[] = {
1532 [Generic800] = nw800_start,
1533 [SpaceCam] = spacecam_start,
1534 [SpaceCam2] = spacecam2_start,
1535 [Cvideopro] = cvideopro_start,
1536 [Dlink350c] = dlink_start,
1537 [DS3303u] = ds3303_start,
1538 [Kr651us] = kr651_start_1,
1539 [Kritter] = kritter_start,
1540 [Mustek300] = mustek_start,
1541 [Proscope] = proscope_start_1,
1542 [Twinkle] = twinkle_start,
1543 [DvcV6] = dvcv6_start,
1544 [P35u] = nw801_start_1,
1545 [Generic802] = nw802_start,
1546};
1547
1548/* -- write a register -- */
1549static void reg_w(struct gspca_dev *gspca_dev,
1550 u16 index,
1551 const u8 *data,
1552 int len)
1553{
1554 struct usb_device *dev = gspca_dev->dev;
1555 int ret;
1556
1557 if (gspca_dev->usb_err < 0)
1558 return;
1559 if (len == 1)
1560 PDEBUG(D_USBO, "SET 00 0000 %04x %02x", index, *data);
1561 else
1562 PDEBUG(D_USBO, "SET 00 0000 %04x %02x %02x ...",
1563 index, *data, data[1]);
1564 memcpy(gspca_dev->usb_buf, data, len);
1565 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1566 0x00,
1567 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1568 0x00, /* value */
1569 index,
1570 gspca_dev->usb_buf,
1571 len,
1572 500);
1573 if (ret < 0) {
1574 err("reg_w err %d", ret);
1575 gspca_dev->usb_err = ret;
1576 }
1577}
1578
1579/* -- read registers in usb_buf -- */
1580static void reg_r(struct gspca_dev *gspca_dev,
1581 u16 index,
1582 int len)
1583{
1584 struct usb_device *dev = gspca_dev->dev;
1585 int ret;
1586
1587 if (gspca_dev->usb_err < 0)
1588 return;
1589 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1590 0x00,
1591 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1592 0x00, index,
1593 gspca_dev->usb_buf, len, 500);
1594 if (ret < 0) {
1595 err("reg_r err %d", ret);
1596 gspca_dev->usb_err = ret;
1597 return;
1598 }
1599 if (len == 1)
1600 PDEBUG(D_USBI, "GET 00 0000 %04x %02x",
1601 index, gspca_dev->usb_buf[0]);
1602 else
1603 PDEBUG(D_USBI, "GET 00 0000 %04x %02x %02x ..",
1604 index, gspca_dev->usb_buf[0],
1605 gspca_dev->usb_buf[1]);
1606}
1607
1608static void i2c_w(struct gspca_dev *gspca_dev,
1609 u8 i2c_addr,
1610 const u8 *data,
1611 int len)
1612{
1613 u8 val[2];
1614 int i;
1615
1616 reg_w(gspca_dev, 0x0600, data + 1, len - 1);
1617 reg_w(gspca_dev, 0x0600, data, len);
1618 val[0] = len;
1619 val[1] = i2c_addr;
1620 reg_w(gspca_dev, 0x0502, val, 2);
1621 val[0] = 0x01;
1622 reg_w(gspca_dev, 0x0501, val, 1);
1623 for (i = 5; --i >= 0; ) {
1624 msleep(4);
1625 reg_r(gspca_dev, 0x0505, 1);
1626 if (gspca_dev->usb_err < 0)
1627 return;
1628 if (gspca_dev->usb_buf[0] == 0)
1629 return;
1630 }
1631 gspca_dev->usb_err = -ETIME;
1632}
1633
1634static void reg_w_buf(struct gspca_dev *gspca_dev,
1635 const u8 *cmd)
1636{
1637 u16 reg;
1638 int len;
1639
1640 for (;;) {
1641 reg = *cmd++ << 8;
1642 reg += *cmd++;
1643 len = *cmd++;
1644 if (len == 0)
1645 break;
1646 if (cmd[-3] != I2C0)
1647 reg_w(gspca_dev, reg, cmd, len);
1648 else
1649 i2c_w(gspca_dev, reg, cmd, len);
1650 cmd += len;
1651 }
1652}
1653
1654static int swap_bits(int v)
1655{
1656 int r, i;
1657
1658 r = 0;
1659 for (i = 0; i < 8; i++) {
1660 r <<= 1;
1661 if (v & 1)
1662 r++;
1663 v >>= 1;
1664 }
1665 return r;
1666}
1667
1668static void setgain(struct gspca_dev *gspca_dev)
1669{
1670 struct sd *sd = (struct sd *) gspca_dev;
1671 u8 val, v[2];
1672
1673 val = sd->ctrls[GAIN].val;
1674 switch (sd->webcam) {
1675 case P35u:
1676 /* Note the control goes from 0-255 not 0-127, but anything
1677 above 127 just means amplifying noise */
1678 val >>= 1; /* 0 - 255 -> 0 - 127 */
1679 reg_w(gspca_dev, 0x1026, &val, 1);
1680 break;
1681 case Kr651us:
1682 /* 0 - 253 */
1683 val = swap_bits(val);
1684 v[0] = val << 3;
1685 v[1] = val >> 5;
1686 reg_w(gspca_dev, 0x101d, v, 2); /* SIF reg0/1 (AGC) */
1687 break;
1688 }
1689}
1690
1691static void setexposure(struct gspca_dev *gspca_dev)
1692{
1693 struct sd *sd = (struct sd *) gspca_dev;
1694 s16 val;
1695 u8 v[2];
1696
1697 val = sd->ctrls[EXPOSURE].val;
1698 switch (sd->webcam) {
1699 case P35u:
1700 v[0] = ((9 - val) << 3) | 0x01;
1701 reg_w(gspca_dev, 0x1019, v, 1);
1702 break;
1703 case Cvideopro:
1704 case DvcV6:
1705 case Kritter:
1706 case Kr651us:
1707 v[0] = val;
1708 v[1] = val >> 8;
1709 reg_w(gspca_dev, 0x101b, v, 2);
1710 break;
1711 }
1712}
1713
1714static void setautogain(struct gspca_dev *gspca_dev)
1715{
1716 struct sd *sd = (struct sd *) gspca_dev;
1717 int w, h;
1718
1719 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
1720 return;
1721 if (!sd->ctrls[AUTOGAIN].val) {
1722 sd->ag_cnt = -1;
1723 return;
1724 }
1725 sd->ag_cnt = AG_CNT_START;
1726
1727 reg_r(gspca_dev, 0x1004, 1);
1728 if (gspca_dev->usb_buf[0] & 0x04) { /* if AE_FULL_FRM */
1729 sd->ae_res = gspca_dev->width * gspca_dev->height;
1730 } else { /* get the AE window size */
1731 reg_r(gspca_dev, 0x1011, 8);
1732 w = (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]
1733 - (gspca_dev->usb_buf[3] << 8) - gspca_dev->usb_buf[2];
1734 h = (gspca_dev->usb_buf[5] << 8) + gspca_dev->usb_buf[4]
1735 - (gspca_dev->usb_buf[7] << 8) - gspca_dev->usb_buf[6];
1736 sd->ae_res = h * w;
1737 if (sd->ae_res == 0)
1738 sd->ae_res = gspca_dev->width * gspca_dev->height;
1739 }
1740}
1741
1742static int nw802_test_reg(struct gspca_dev *gspca_dev,
1743 u16 index,
1744 u8 value)
1745{
1746 /* write the value */
1747 reg_w(gspca_dev, index, &value, 1);
1748
1749 /* read it */
1750 reg_r(gspca_dev, index, 1);
1751
1752 return gspca_dev->usb_buf[0] == value;
1753}
1754
1755/* this function is called at probe time */
1756static int sd_config(struct gspca_dev *gspca_dev,
1757 const struct usb_device_id *id)
1758{
1759 struct sd *sd = (struct sd *) gspca_dev;
1760
1761 if ((unsigned) webcam >= NWEBCAMS)
1762 webcam = 0;
1763 sd->webcam = webcam;
1764 gspca_dev->cam.reverse_alts = 1;
1765 gspca_dev->cam.ctrls = sd->ctrls;
1766 sd->ag_cnt = -1;
1767
1768 /*
1769 * Autodetect sequence inspired from some log.
1770 * We try to detect what registers exist or not.
1771 * If 0x0500 does not exist => NW802
1772 * If it does, test 0x109b. If it doesn't exist,
1773 * then it's a NW801. Else, a NW800
1774 * If a et31x110 (nw800 and 06a5:d800)
1775 * get the sensor ID
1776 */
1777 if (!nw802_test_reg(gspca_dev, 0x0500, 0x55)) {
1778 sd->bridge = BRIDGE_NW802;
1779 if (sd->webcam == Generic800)
1780 sd->webcam = Generic802;
1781 } else if (!nw802_test_reg(gspca_dev, 0x109b, 0xaa)) {
1782 sd->bridge = BRIDGE_NW801;
1783 if (sd->webcam == Generic800)
1784 sd->webcam = P35u;
1785 } else if (id->idVendor == 0x06a5 && id->idProduct == 0xd800) {
1786 reg_r(gspca_dev, 0x0403, 1); /* GPIO */
1787 PDEBUG(D_PROBE, "et31x110 sensor type %02x",
1788 gspca_dev->usb_buf[0]);
1789 switch (gspca_dev->usb_buf[0] >> 1) {
1790 case 0x00: /* ?? */
1791 if (sd->webcam == Generic800)
1792 sd->webcam = SpaceCam;
1793 break;
1794 case 0x01: /* Hynix? */
1795 if (sd->webcam == Generic800)
1796 sd->webcam = Twinkle;
1797 break;
1798 case 0x0a: /* Pixart */
1799 if (sd->webcam == Generic800)
1800 sd->webcam = SpaceCam2;
1801 break;
1802 }
1803 }
1804 if (webcam_chip[sd->webcam] != sd->bridge) {
1805 err("Bad webcam type %d for NW80%d", sd->webcam, sd->bridge);
1806 gspca_dev->usb_err = -ENODEV;
1807 return gspca_dev->usb_err;
1808 }
1809 PDEBUG(D_PROBE, "Bridge nw80%d - type: %d", sd->bridge, sd->webcam);
1810
1811 if (sd->bridge == BRIDGE_NW800) {
1812 switch (sd->webcam) {
1813 case DS3303u:
1814 gspca_dev->cam.cam_mode = cif_mode; /* qvga */
1815 break;
1816 default:
1817 gspca_dev->cam.cam_mode = &cif_mode[1]; /* cif */
1818 break;
1819 }
1820 gspca_dev->cam.nmodes = 1;
1821 } else {
1822 gspca_dev->cam.cam_mode = vga_mode;
1823 switch (sd->webcam) {
1824 case Kr651us:
1825 case Proscope:
1826 case P35u:
1827 gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
1828 break;
1829 default:
1830 gspca_dev->cam.nmodes = 1; /* qvga only */
1831 break;
1832 }
1833 }
1834 switch (sd->webcam) {
1835 case P35u:
1836/* sd->ctrls[EXPOSURE].max = 9;
1837 * sd->ctrls[EXPOSURE].def = 9; */
1838 /* coarse expo auto gain function gain minimum, to avoid
1839 * a large settings jump the first auto adjustment */
1840 sd->ctrls[GAIN].def = 255 / 5 * 2;
1841 break;
1842 case Cvideopro:
1843 case DvcV6:
1844 case Kritter:
1845 gspca_dev->ctrl_dis = (1 << GAIN) | (1 << AUTOGAIN);
1846 /* fall thru */
1847 case Kr651us:
1848 sd->ctrls[EXPOSURE].max = 315;
1849 sd->ctrls[EXPOSURE].def = 150;
1850 break;
1851 default:
1852 gspca_dev->ctrl_dis = (1 << GAIN) | (1 << EXPOSURE)
1853 | (1 << AUTOGAIN);
1854 break;
1855 }
1856
1857#if AUTOGAIN_DEF
1858 if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1859 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1860#endif
1861 return gspca_dev->usb_err;
1862}
1863
1864/* this function is called at probe and resume time */
1865static int sd_init(struct gspca_dev *gspca_dev)
1866{
1867 struct sd *sd = (struct sd *) gspca_dev;
1868
1869 switch (sd->bridge) {
1870 case BRIDGE_NW800:
1871 switch (sd->webcam) {
1872 case SpaceCam:
1873 reg_w_buf(gspca_dev, spacecam_init);
1874 break;
1875 default:
1876 reg_w_buf(gspca_dev, nw800_init);
1877 break;
1878 }
1879 break;
1880 default:
1881 switch (sd->webcam) {
1882 case Mustek300:
1883 case P35u:
1884 case Proscope:
1885 reg_w_buf(gspca_dev, proscope_init);
1886 break;
1887 }
1888 break;
1889 }
1890 return gspca_dev->usb_err;
1891}
1892
1893/* -- start the camera -- */
1894static int sd_start(struct gspca_dev *gspca_dev)
1895{
1896 struct sd *sd = (struct sd *) gspca_dev;
1897 const u8 *cmd;
1898
1899 cmd = webcam_start[sd->webcam];
1900 reg_w_buf(gspca_dev, cmd);
1901 switch (sd->webcam) {
1902 case P35u:
1903 if (gspca_dev->width == 320)
1904 reg_w_buf(gspca_dev, nw801_start_qvga);
1905 else
1906 reg_w_buf(gspca_dev, nw801_start_vga);
1907 reg_w_buf(gspca_dev, nw801_start_2);
1908 break;
1909 case Kr651us:
1910 if (gspca_dev->width == 320)
1911 reg_w_buf(gspca_dev, kr651_start_qvga);
1912 else
1913 reg_w_buf(gspca_dev, kr651_start_vga);
1914 reg_w_buf(gspca_dev, kr651_start_2);
1915 break;
1916 case Proscope:
1917 if (gspca_dev->width == 320)
1918 reg_w_buf(gspca_dev, proscope_start_qvga);
1919 else
1920 reg_w_buf(gspca_dev, proscope_start_vga);
1921 reg_w_buf(gspca_dev, proscope_start_2);
1922 break;
1923 }
1924
1925 setgain(gspca_dev);
1926 setexposure(gspca_dev);
1927 setautogain(gspca_dev);
1928 sd->exp_too_high_cnt = 0;
1929 sd->exp_too_low_cnt = 0;
1930 return gspca_dev->usb_err;
1931}
1932
1933static void sd_stopN(struct gspca_dev *gspca_dev)
1934{
1935 struct sd *sd = (struct sd *) gspca_dev;
1936 u8 value;
1937
1938 /* 'go' off */
1939 if (sd->bridge != BRIDGE_NW801) {
1940 value = 0x02;
1941 reg_w(gspca_dev, 0x0406, &value, 1);
1942 }
1943
1944 /* LED off */
1945 switch (sd->webcam) {
1946 case Cvideopro:
1947 case Kr651us:
1948 case DvcV6:
1949 case Kritter:
1950 value = 0xff;
1951 break;
1952 case Dlink350c:
1953 value = 0x21;
1954 break;
1955 case SpaceCam:
1956 case SpaceCam2:
1957 case Proscope:
1958 case Twinkle:
1959 value = 0x01;
1960 break;
1961 default:
1962 return;
1963 }
1964 reg_w(gspca_dev, 0x0404, &value, 1);
1965}
1966
1967static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1968 u8 *data, /* isoc packet */
1969 int len) /* iso packet length */
1970{
1971 /*
1972 * frame header = '00 00 hh ww ss xx ff ff'
1973 * with:
1974 * - 'hh': height / 4
1975 * - 'ww': width / 4
1976 * - 'ss': frame sequence number c0..dd
1977 */
1978 if (data[0] == 0x00 && data[1] == 0x00
1979 && data[6] == 0xff && data[7] == 0xff) {
1980 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1981 gspca_frame_add(gspca_dev, FIRST_PACKET, data + 8, len - 8);
1982 } else {
1983 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1984 }
1985}
1986
1987static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1988{
1989 struct sd *sd = (struct sd *) gspca_dev;
1990
1991 sd->ctrls[AUTOGAIN].val = val;
1992 if (val)
1993 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1994 else
1995 gspca_dev->ctrl_inac = 0;
1996 if (gspca_dev->streaming)
1997 setautogain(gspca_dev);
1998 return gspca_dev->usb_err;
1999}
2000
2001#include "autogain_functions.h"
2002
2003static void do_autogain(struct gspca_dev *gspca_dev)
2004{
2005 struct sd *sd = (struct sd *) gspca_dev;
2006 int luma;
2007
2008 if (sd->ag_cnt < 0)
2009 return;
2010 if (--sd->ag_cnt >= 0)
2011 return;
2012 sd->ag_cnt = AG_CNT_START;
2013
2014 /* get the average luma */
2015 reg_r(gspca_dev, sd->bridge == BRIDGE_NW801 ? 0x080d : 0x080c, 4);
2016 luma = (gspca_dev->usb_buf[3] << 24) + (gspca_dev->usb_buf[2] << 16)
2017 + (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
2018 luma /= sd->ae_res;
2019
2020 switch (sd->webcam) {
2021 case P35u:
2022 coarse_grained_expo_autogain(gspca_dev, luma, 100, 5);
2023 break;
2024 default:
2025 auto_gain_n_exposure(gspca_dev, luma, 100, 5, 230, 0);
2026 break;
2027 }
2028}
2029
2030/* V4L2 controls supported by the driver */
2031static const struct ctrl sd_ctrls[NCTRLS] = {
2032[GAIN] = {
2033 {
2034 .id = V4L2_CID_GAIN,
2035 .type = V4L2_CTRL_TYPE_INTEGER,
2036 .name = "Gain",
2037 .minimum = 0,
2038 .maximum = 253,
2039 .step = 1,
2040 .default_value = 128
2041 },
2042 .set_control = setgain
2043 },
2044[EXPOSURE] = {
2045 {
2046 .id = V4L2_CID_EXPOSURE,
2047 .type = V4L2_CTRL_TYPE_INTEGER,
2048 .name = "Exposure",
2049 .minimum = 0,
2050 .maximum = 9,
2051 .step = 1,
2052 .default_value = 9
2053 },
2054 .set_control = setexposure
2055 },
2056[AUTOGAIN] = {
2057 {
2058 .id = V4L2_CID_AUTOGAIN,
2059 .type = V4L2_CTRL_TYPE_BOOLEAN,
2060 .name = "Auto Gain",
2061 .minimum = 0,
2062 .maximum = 1,
2063 .step = 1,
2064 .default_value = AUTOGAIN_DEF,
2065 .flags = V4L2_CTRL_FLAG_UPDATE
2066 },
2067 .set = sd_setautogain
2068 },
2069};
2070
2071/* sub-driver description */
2072static const struct sd_desc sd_desc = {
2073 .name = MODULE_NAME,
2074 .ctrls = sd_ctrls,
2075 .nctrls = ARRAY_SIZE(sd_ctrls),
2076 .config = sd_config,
2077 .init = sd_init,
2078 .start = sd_start,
2079 .stopN = sd_stopN,
2080 .pkt_scan = sd_pkt_scan,
2081 .dq_callback = do_autogain,
2082};
2083
2084/* -- module initialisation -- */
2085static const struct usb_device_id device_table[] = {
2086 {USB_DEVICE(0x046d, 0xd001)},
2087 {USB_DEVICE(0x0502, 0xd001)},
2088 {USB_DEVICE(0x052b, 0xd001)},
2089 {USB_DEVICE(0x055f, 0xd001)},
2090 {USB_DEVICE(0x06a5, 0x0000)},
2091 {USB_DEVICE(0x06a5, 0xd001)},
2092 {USB_DEVICE(0x06a5, 0xd800)},
2093 {USB_DEVICE(0x06be, 0xd001)},
2094 {USB_DEVICE(0x0728, 0xd001)},
2095 {}
2096};
2097MODULE_DEVICE_TABLE(usb, device_table);
2098
2099/* -- device connect -- */
2100static int sd_probe(struct usb_interface *intf,
2101 const struct usb_device_id *id)
2102{
2103 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2104 THIS_MODULE);
2105}
2106
2107static struct usb_driver sd_driver = {
2108 .name = MODULE_NAME,
2109 .id_table = device_table,
2110 .probe = sd_probe,
2111 .disconnect = gspca_disconnect,
2112#ifdef CONFIG_PM
2113 .suspend = gspca_suspend,
2114 .resume = gspca_resume,
2115#endif
2116};
2117
2118/* -- module insert / remove -- */
2119static int __init sd_mod_init(void)
2120{
2121 return usb_register(&sd_driver);
2122}
2123static void __exit sd_mod_exit(void)
2124{
2125 usb_deregister(&sd_driver);
2126}
2127
2128module_init(sd_mod_init);
2129module_exit(sd_mod_exit);
2130
2131module_param(webcam, int, 0644);
2132MODULE_PARM_DESC(webcam,
2133 "Webcam type\n"
2134 "0: generic\n"
2135 "1: Trust 120 SpaceCam\n"
2136 "2: other Trust 120 SpaceCam\n"
2137 "3: Conceptronic Video Pro\n"
2138 "4: D-link dru-350c\n"
2139 "5: Plustek Opticam 500U\n"
2140 "6: Panasonic GP-KR651US\n"
2141 "7: iRez Kritter\n"
2142 "8: Mustek Wcam 300 mini\n"
2143 "9: Scalar USB Microscope M2 (Proscope)\n"
2144 "10: Divio Chicony TwinkleCam\n"
2145 "11: DVC-V6\n");
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 8ab2c452c25e..fd1b6082c96d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * OV519 driver 2 * OV519 driver
3 * 3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr>
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> 5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
6 * 6 *
7 * This module is adapted from the ov51x-jpeg package, which itself 7 * This module is adapted from the ov51x-jpeg package, which itself
@@ -61,10 +61,12 @@ static int i2c_detect_tries = 10;
61enum e_ctrl { 61enum e_ctrl {
62 BRIGHTNESS, 62 BRIGHTNESS,
63 CONTRAST, 63 CONTRAST,
64 EXPOSURE,
64 COLORS, 65 COLORS,
65 HFLIP, 66 HFLIP,
66 VFLIP, 67 VFLIP,
67 AUTOBRIGHT, 68 AUTOBRIGHT,
69 AUTOGAIN,
68 FREQ, 70 FREQ,
69 NCTRL /* number of controls */ 71 NCTRL /* number of controls */
70}; 72};
@@ -118,6 +120,7 @@ struct sd {
118}; 120};
119enum sensors { 121enum sensors {
120 SEN_OV2610, 122 SEN_OV2610,
123 SEN_OV2610AE,
121 SEN_OV3610, 124 SEN_OV3610,
122 SEN_OV6620, 125 SEN_OV6620,
123 SEN_OV6630, 126 SEN_OV6630,
@@ -141,9 +144,11 @@ enum sensors {
141/* V4L2 controls supported by the driver */ 144/* V4L2 controls supported by the driver */
142static void setbrightness(struct gspca_dev *gspca_dev); 145static void setbrightness(struct gspca_dev *gspca_dev);
143static void setcontrast(struct gspca_dev *gspca_dev); 146static void setcontrast(struct gspca_dev *gspca_dev);
147static void setexposure(struct gspca_dev *gspca_dev);
144static void setcolors(struct gspca_dev *gspca_dev); 148static void setcolors(struct gspca_dev *gspca_dev);
145static void sethvflip(struct gspca_dev *gspca_dev); 149static void sethvflip(struct gspca_dev *gspca_dev);
146static void setautobright(struct gspca_dev *gspca_dev); 150static void setautobright(struct gspca_dev *gspca_dev);
151static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
147static void setfreq(struct gspca_dev *gspca_dev); 152static void setfreq(struct gspca_dev *gspca_dev);
148static void setfreq_i(struct sd *sd); 153static void setfreq_i(struct sd *sd);
149 154
@@ -172,6 +177,18 @@ static const struct ctrl sd_ctrls[] = {
172 }, 177 },
173 .set_control = setcontrast, 178 .set_control = setcontrast,
174 }, 179 },
180[EXPOSURE] = {
181 {
182 .id = V4L2_CID_EXPOSURE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Exposure",
185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
188 .default_value = 127,
189 },
190 .set_control = setexposure,
191 },
175[COLORS] = { 192[COLORS] = {
176 { 193 {
177 .id = V4L2_CID_SATURATION, 194 .id = V4L2_CID_SATURATION,
@@ -221,6 +238,19 @@ static const struct ctrl sd_ctrls[] = {
221 }, 238 },
222 .set_control = setautobright, 239 .set_control = setautobright,
223 }, 240 },
241[AUTOGAIN] = {
242 {
243 .id = V4L2_CID_AUTOGAIN,
244 .type = V4L2_CTRL_TYPE_BOOLEAN,
245 .name = "Auto Gain",
246 .minimum = 0,
247 .maximum = 1,
248 .step = 1,
249 .default_value = 1,
250 .flags = V4L2_CTRL_FLAG_UPDATE
251 },
252 .set = sd_setautogain,
253 },
224[FREQ] = { 254[FREQ] = {
225 { 255 {
226 .id = V4L2_CID_POWER_LINE_FREQUENCY, 256 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -237,48 +267,78 @@ static const struct ctrl sd_ctrls[] = {
237 267
238/* table of the disabled controls */ 268/* table of the disabled controls */
239static const unsigned ctrl_dis[] = { 269static const unsigned ctrl_dis[] = {
240[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ 270[SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */
271 ^ ((1 << EXPOSURE) /* but exposure */
272 | (1 << AUTOGAIN)), /* and autogain */
273
274[SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */
275 ^ ((1 << EXPOSURE) /* but exposure */
276 | (1 << AUTOGAIN)), /* and autogain */
241 277
242[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ 278[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
243 279
244[SEN_OV6620] = (1 << HFLIP) | 280[SEN_OV6620] = (1 << HFLIP) |
245 (1 << VFLIP), 281 (1 << VFLIP) |
282 (1 << EXPOSURE) |
283 (1 << AUTOGAIN),
246 284
247[SEN_OV6630] = (1 << HFLIP) | 285[SEN_OV6630] = (1 << HFLIP) |
248 (1 << VFLIP), 286 (1 << VFLIP) |
287 (1 << EXPOSURE) |
288 (1 << AUTOGAIN),
249 289
250[SEN_OV66308AF] = (1 << HFLIP) | 290[SEN_OV66308AF] = (1 << HFLIP) |
251 (1 << VFLIP), 291 (1 << VFLIP) |
292 (1 << EXPOSURE) |
293 (1 << AUTOGAIN),
252 294
253[SEN_OV7610] = (1 << HFLIP) | 295[SEN_OV7610] = (1 << HFLIP) |
254 (1 << VFLIP), 296 (1 << VFLIP) |
297 (1 << EXPOSURE) |
298 (1 << AUTOGAIN),
255 299
256[SEN_OV7620] = (1 << HFLIP) | 300[SEN_OV7620] = (1 << HFLIP) |
257 (1 << VFLIP), 301 (1 << VFLIP) |
302 (1 << EXPOSURE) |
303 (1 << AUTOGAIN),
258 304
259[SEN_OV7620AE] = (1 << HFLIP) | 305[SEN_OV7620AE] = (1 << HFLIP) |
260 (1 << VFLIP), 306 (1 << VFLIP) |
307 (1 << EXPOSURE) |
308 (1 << AUTOGAIN),
261 309
262[SEN_OV7640] = (1 << HFLIP) | 310[SEN_OV7640] = (1 << HFLIP) |
263 (1 << VFLIP) | 311 (1 << VFLIP) |
264 (1 << AUTOBRIGHT) | 312 (1 << AUTOBRIGHT) |
265 (1 << CONTRAST), 313 (1 << CONTRAST) |
314 (1 << EXPOSURE) |
315 (1 << AUTOGAIN),
266 316
267[SEN_OV7648] = (1 << HFLIP) | 317[SEN_OV7648] = (1 << HFLIP) |
268 (1 << VFLIP) | 318 (1 << VFLIP) |
269 (1 << AUTOBRIGHT) | 319 (1 << AUTOBRIGHT) |
270 (1 << CONTRAST), 320 (1 << CONTRAST) |
321 (1 << EXPOSURE) |
322 (1 << AUTOGAIN),
271 323
272[SEN_OV7660] = (1 << AUTOBRIGHT), 324[SEN_OV7660] = (1 << AUTOBRIGHT) |
325 (1 << EXPOSURE) |
326 (1 << AUTOGAIN),
273 327
274[SEN_OV7670] = (1 << COLORS) | 328[SEN_OV7670] = (1 << COLORS) |
275 (1 << AUTOBRIGHT), 329 (1 << AUTOBRIGHT) |
330 (1 << EXPOSURE) |
331 (1 << AUTOGAIN),
276 332
277[SEN_OV76BE] = (1 << HFLIP) | 333[SEN_OV76BE] = (1 << HFLIP) |
278 (1 << VFLIP), 334 (1 << VFLIP) |
335 (1 << EXPOSURE) |
336 (1 << AUTOGAIN),
279 337
280[SEN_OV8610] = (1 << HFLIP) | 338[SEN_OV8610] = (1 << HFLIP) |
281 (1 << VFLIP) | 339 (1 << VFLIP) |
340 (1 << EXPOSURE) |
341 (1 << AUTOGAIN) |
282 (1 << FREQ), 342 (1 << FREQ),
283}; 343};
284 344
@@ -428,6 +488,11 @@ static const struct v4l2_pix_format ovfx2_cif_mode[] = {
428 .priv = 0}, 488 .priv = 0},
429}; 489};
430static const struct v4l2_pix_format ovfx2_ov2610_mode[] = { 490static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
491 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
492 .bytesperline = 800,
493 .sizeimage = 800 * 600,
494 .colorspace = V4L2_COLORSPACE_SRGB,
495 .priv = 1},
431 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 496 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
432 .bytesperline = 1600, 497 .bytesperline = 1600,
433 .sizeimage = 1600 * 1200, 498 .sizeimage = 1600 * 1200,
@@ -544,6 +609,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
544 * buffers, there are some pretty strict real time constraints for 609 * buffers, there are some pretty strict real time constraints for
545 * isochronous transfer for larger frame sizes). 610 * isochronous transfer for larger frame sizes).
546 */ 611 */
612/*jfm: this value works well for 1600x1200, but not 800x600 - see isoc_init */
547#define OVFX2_BULK_SIZE (13 * 4096) 613#define OVFX2_BULK_SIZE (13 * 4096)
548 614
549/* I2C registers */ 615/* I2C registers */
@@ -656,6 +722,24 @@ static const struct ov_i2c_regvals norm_2610[] = {
656 { 0x12, 0x80 }, /* reset */ 722 { 0x12, 0x80 }, /* reset */
657}; 723};
658 724
725static const struct ov_i2c_regvals norm_2610ae[] = {
726 {0x12, 0x80}, /* reset */
727 {0x13, 0xcd},
728 {0x09, 0x01},
729 {0x0d, 0x00},
730 {0x11, 0x80},
731 {0x12, 0x20}, /* 1600x1200 */
732 {0x33, 0x0c},
733 {0x35, 0x90},
734 {0x36, 0x37},
735/* ms-win traces */
736 {0x11, 0x83}, /* clock / 3 ? */
737 {0x2d, 0x00}, /* 60 Hz filter */
738 {0x24, 0xb0}, /* normal colors */
739 {0x25, 0x90},
740 {0x10, 0x43},
741};
742
659static const struct ov_i2c_regvals norm_3620b[] = { 743static const struct ov_i2c_regvals norm_3620b[] = {
660 /* 744 /*
661 * From the datasheet: "Note that after writing to register COMH 745 * From the datasheet: "Note that after writing to register COMH
@@ -2621,6 +2705,9 @@ static void ov_hires_configure(struct sd *sd)
2621 if (high == 0x96 && low == 0x40) { 2705 if (high == 0x96 && low == 0x40) {
2622 PDEBUG(D_PROBE, "Sensor is an OV2610"); 2706 PDEBUG(D_PROBE, "Sensor is an OV2610");
2623 sd->sensor = SEN_OV2610; 2707 sd->sensor = SEN_OV2610;
2708 } else if (high == 0x96 && low == 0x41) {
2709 PDEBUG(D_PROBE, "Sensor is an OV2610AE");
2710 sd->sensor = SEN_OV2610AE;
2624 } else if (high == 0x36 && (low & 0x0f) == 0x00) { 2711 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2625 PDEBUG(D_PROBE, "Sensor is an OV3610"); 2712 PDEBUG(D_PROBE, "Sensor is an OV3610");
2626 sd->sensor = SEN_OV3610; 2713 sd->sensor = SEN_OV3610;
@@ -3171,6 +3258,13 @@ static void ov519_set_fr(struct sd *sd)
3171 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); 3258 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3172} 3259}
3173 3260
3261static void setautogain(struct gspca_dev *gspca_dev)
3262{
3263 struct sd *sd = (struct sd *) gspca_dev;
3264
3265 i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05);
3266}
3267
3174/* this function is called at probe time */ 3268/* this function is called at probe time */
3175static int sd_config(struct gspca_dev *gspca_dev, 3269static int sd_config(struct gspca_dev *gspca_dev,
3176 const struct usb_device_id *id) 3270 const struct usb_device_id *id)
@@ -3295,15 +3389,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
3295 } 3389 }
3296 break; 3390 break;
3297 case BRIDGE_OVFX2: 3391 case BRIDGE_OVFX2:
3298 if (sd->sensor == SEN_OV2610) { 3392 switch (sd->sensor) {
3393 case SEN_OV2610:
3394 case SEN_OV2610AE:
3299 cam->cam_mode = ovfx2_ov2610_mode; 3395 cam->cam_mode = ovfx2_ov2610_mode;
3300 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode); 3396 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3301 } else if (sd->sensor == SEN_OV3610) { 3397 break;
3398 case SEN_OV3610:
3302 cam->cam_mode = ovfx2_ov3610_mode; 3399 cam->cam_mode = ovfx2_ov3610_mode;
3303 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); 3400 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3304 } else if (sd->sif) { 3401 break;
3305 cam->cam_mode = ov519_sif_mode; 3402 default:
3306 cam->nmodes = ARRAY_SIZE(ov519_sif_mode); 3403 if (sd->sif) {
3404 cam->cam_mode = ov519_sif_mode;
3405 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3406 }
3407 break;
3307 } 3408 }
3308 break; 3409 break;
3309 case BRIDGE_W9968CF: 3410 case BRIDGE_W9968CF:
@@ -3325,6 +3426,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
3325 /* Enable autogain, autoexpo, awb, bandfilter */ 3426 /* Enable autogain, autoexpo, awb, bandfilter */
3326 i2c_w_mask(sd, 0x13, 0x27, 0x27); 3427 i2c_w_mask(sd, 0x13, 0x27, 0x27);
3327 break; 3428 break;
3429 case SEN_OV2610AE:
3430 write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
3431
3432 /* enable autoexpo */
3433 i2c_w_mask(sd, 0x13, 0x05, 0x05);
3434 break;
3328 case SEN_OV3610: 3435 case SEN_OV3610:
3329 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); 3436 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
3330 3437
@@ -3397,6 +3504,22 @@ error:
3397 return -EINVAL; 3504 return -EINVAL;
3398} 3505}
3399 3506
3507/* function called at start time before URB creation */
3508static int sd_isoc_init(struct gspca_dev *gspca_dev)
3509{
3510 struct sd *sd = (struct sd *) gspca_dev;
3511
3512 switch (sd->bridge) {
3513 case BRIDGE_OVFX2:
3514 if (gspca_dev->width == 1600)
3515 gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
3516 else
3517 gspca_dev->cam.bulk_size = 7 * 4096;
3518 break;
3519 }
3520 return 0;
3521}
3522
3400/* Set up the OV511/OV511+ with the given image parameters. 3523/* Set up the OV511/OV511+ with the given image parameters.
3401 * 3524 *
3402 * Do not put any sensor-specific code in here (including I2C I/O functions) 3525 * Do not put any sensor-specific code in here (including I2C I/O functions)
@@ -3827,6 +3950,25 @@ static void mode_init_ov_sensor_regs(struct sd *sd)
3827 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); 3950 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3828 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); 3951 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3829 return; 3952 return;
3953 case SEN_OV2610AE: {
3954 u8 v;
3955
3956 /* frame rates:
3957 * 10fps / 5 fps for 1600x1200
3958 * 40fps / 20fps for 800x600
3959 */
3960 v = 80;
3961 if (qvga) {
3962 if (sd->frame_rate < 25)
3963 v = 0x81;
3964 } else {
3965 if (sd->frame_rate < 10)
3966 v = 0x81;
3967 }
3968 i2c_w(sd, 0x11, v);
3969 i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
3970 return;
3971 }
3830 case SEN_OV3610: 3972 case SEN_OV3610:
3831 if (qvga) { 3973 if (qvga) {
3832 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); 3974 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
@@ -3975,6 +4117,7 @@ static void set_ov_sensor_window(struct sd *sd)
3975 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ 4117 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
3976 switch (sd->sensor) { 4118 switch (sd->sensor) {
3977 case SEN_OV2610: 4119 case SEN_OV2610:
4120 case SEN_OV2610AE:
3978 case SEN_OV3610: 4121 case SEN_OV3610:
3979 case SEN_OV7670: 4122 case SEN_OV7670:
3980 mode_init_ov_sensor_regs(sd); 4123 mode_init_ov_sensor_regs(sd);
@@ -4110,12 +4253,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
4110 setcontrast(gspca_dev); 4253 setcontrast(gspca_dev);
4111 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) 4254 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
4112 setbrightness(gspca_dev); 4255 setbrightness(gspca_dev);
4256 if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE)))
4257 setexposure(gspca_dev);
4113 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) 4258 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
4114 setcolors(gspca_dev); 4259 setcolors(gspca_dev);
4115 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) 4260 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
4116 sethvflip(gspca_dev); 4261 sethvflip(gspca_dev);
4117 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) 4262 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
4118 setautobright(gspca_dev); 4263 setautobright(gspca_dev);
4264 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN)))
4265 setautogain(gspca_dev);
4119 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) 4266 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
4120 setfreq_i(sd); 4267 setfreq_i(sd);
4121 4268
@@ -4529,6 +4676,14 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4529 } 4676 }
4530} 4677}
4531 4678
4679static void setexposure(struct gspca_dev *gspca_dev)
4680{
4681 struct sd *sd = (struct sd *) gspca_dev;
4682
4683 if (!sd->ctrls[AUTOGAIN].val)
4684 i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val);
4685}
4686
4532static void setcolors(struct gspca_dev *gspca_dev) 4687static void setcolors(struct gspca_dev *gspca_dev)
4533{ 4688{
4534 struct sd *sd = (struct sd *) gspca_dev; 4689 struct sd *sd = (struct sd *) gspca_dev;
@@ -4587,6 +4742,22 @@ static void setautobright(struct gspca_dev *gspca_dev)
4587 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); 4742 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
4588} 4743}
4589 4744
4745static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
4746{
4747 struct sd *sd = (struct sd *) gspca_dev;
4748
4749 sd->ctrls[AUTOGAIN].val = val;
4750 if (val) {
4751 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
4752 } else {
4753 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
4754 sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10);
4755 }
4756 if (gspca_dev->streaming)
4757 setautogain(gspca_dev);
4758 return gspca_dev->usb_err;
4759}
4760
4590static void setfreq_i(struct sd *sd) 4761static void setfreq_i(struct sd *sd)
4591{ 4762{
4592 if (sd->sensor == SEN_OV7660 4763 if (sd->sensor == SEN_OV7660
@@ -4731,6 +4902,7 @@ static const struct sd_desc sd_desc = {
4731 .nctrls = ARRAY_SIZE(sd_ctrls), 4902 .nctrls = ARRAY_SIZE(sd_ctrls),
4732 .config = sd_config, 4903 .config = sd_config,
4733 .init = sd_init, 4904 .init = sd_init,
4905 .isoc_init = sd_isoc_init,
4734 .start = sd_start, 4906 .start = sd_start,
4735 .stopN = sd_stopN, 4907 .stopN = sd_stopN,
4736 .stop0 = sd_stop0, 4908 .stop0 = sd_stop0,
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 04da22802736..0c6369b7fe18 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ov534-ov772x gspca driver 2 * ov534-ov7xxx gspca driver
3 * 3 *
4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
@@ -49,54 +49,59 @@ MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
49MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); 49MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51 51
52/* controls */
53enum e_ctrl {
54 BRIGHTNESS,
55 CONTRAST,
56 GAIN,
57 EXPOSURE,
58 AGC,
59 AWB,
60 AEC,
61 SHARPNESS,
62 HFLIP,
63 VFLIP,
64 COLORS,
65 LIGHTFREQ,
66 NCTRLS /* number of controls */
67};
68
52/* specific webcam descriptor */ 69/* specific webcam descriptor */
53struct sd { 70struct sd {
54 struct gspca_dev gspca_dev; /* !! must be the first item */ 71 struct gspca_dev gspca_dev; /* !! must be the first item */
72
73 struct gspca_ctrl ctrls[NCTRLS];
74
55 __u32 last_pts; 75 __u32 last_pts;
56 u16 last_fid; 76 u16 last_fid;
57 u8 frame_rate; 77 u8 frame_rate;
58 78
59 u8 brightness; 79 u8 sensor;
60 u8 contrast; 80};
61 u8 gain; 81enum sensors {
62 u8 exposure; 82 SENSOR_OV767x,
63 u8 agc; 83 SENSOR_OV772x,
64 u8 awb; 84 NSENSORS
65 u8 aec;
66 s8 sharpness;
67 u8 hflip;
68 u8 vflip;
69 u8 freqfltr;
70}; 85};
71 86
72/* V4L2 controls supported by the driver */ 87/* V4L2 controls supported by the driver */
73static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 88static void setbrightness(struct gspca_dev *gspca_dev);
74static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 89static void setcontrast(struct gspca_dev *gspca_dev);
75static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 90static void setgain(struct gspca_dev *gspca_dev);
76static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 91static void setexposure(struct gspca_dev *gspca_dev);
77static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val); 92static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getagc(struct gspca_dev *gspca_dev, __s32 *val); 93static void setawb(struct gspca_dev *gspca_dev);
79static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 94static void setaec(struct gspca_dev *gspca_dev);
80static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 95static void setsharpness(struct gspca_dev *gspca_dev);
81static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 96static void sethvflip(struct gspca_dev *gspca_dev);
82static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 97static void setcolors(struct gspca_dev *gspca_dev);
83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 98static void setlightfreq(struct gspca_dev *gspca_dev);
84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 99
85static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); 100static int sd_start(struct gspca_dev *gspca_dev);
86static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); 101static void sd_stopN(struct gspca_dev *gspca_dev);
87static int sd_setaec(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getaec(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
91static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setfreqfltr(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getfreqfltr(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_querymenu(struct gspca_dev *gspca_dev,
96 struct v4l2_querymenu *menu);
97 102
98static const struct ctrl sd_ctrls[] = { 103static const struct ctrl sd_ctrls[] = {
99 { /* 0 */ 104[BRIGHTNESS] = {
100 { 105 {
101 .id = V4L2_CID_BRIGHTNESS, 106 .id = V4L2_CID_BRIGHTNESS,
102 .type = V4L2_CTRL_TYPE_INTEGER, 107 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -104,13 +109,11 @@ static const struct ctrl sd_ctrls[] = {
104 .minimum = 0, 109 .minimum = 0,
105 .maximum = 255, 110 .maximum = 255,
106 .step = 1, 111 .step = 1,
107#define BRIGHTNESS_DEF 0 112 .default_value = 0,
108 .default_value = BRIGHTNESS_DEF,
109 }, 113 },
110 .set = sd_setbrightness, 114 .set_control = setbrightness
111 .get = sd_getbrightness,
112 }, 115 },
113 { /* 1 */ 116[CONTRAST] = {
114 { 117 {
115 .id = V4L2_CID_CONTRAST, 118 .id = V4L2_CID_CONTRAST,
116 .type = V4L2_CTRL_TYPE_INTEGER, 119 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -118,13 +121,11 @@ static const struct ctrl sd_ctrls[] = {
118 .minimum = 0, 121 .minimum = 0,
119 .maximum = 255, 122 .maximum = 255,
120 .step = 1, 123 .step = 1,
121#define CONTRAST_DEF 32 124 .default_value = 32,
122 .default_value = CONTRAST_DEF,
123 }, 125 },
124 .set = sd_setcontrast, 126 .set_control = setcontrast
125 .get = sd_getcontrast,
126 }, 127 },
127 { /* 2 */ 128[GAIN] = {
128 { 129 {
129 .id = V4L2_CID_GAIN, 130 .id = V4L2_CID_GAIN,
130 .type = V4L2_CTRL_TYPE_INTEGER, 131 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -132,13 +133,11 @@ static const struct ctrl sd_ctrls[] = {
132 .minimum = 0, 133 .minimum = 0,
133 .maximum = 63, 134 .maximum = 63,
134 .step = 1, 135 .step = 1,
135#define GAIN_DEF 20 136 .default_value = 20,
136 .default_value = GAIN_DEF,
137 }, 137 },
138 .set = sd_setgain, 138 .set_control = setgain
139 .get = sd_getgain,
140 }, 139 },
141 { /* 3 */ 140[EXPOSURE] = {
142 { 141 {
143 .id = V4L2_CID_EXPOSURE, 142 .id = V4L2_CID_EXPOSURE,
144 .type = V4L2_CTRL_TYPE_INTEGER, 143 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -146,13 +145,11 @@ static const struct ctrl sd_ctrls[] = {
146 .minimum = 0, 145 .minimum = 0,
147 .maximum = 255, 146 .maximum = 255,
148 .step = 1, 147 .step = 1,
149#define EXPO_DEF 120 148 .default_value = 120,
150 .default_value = EXPO_DEF,
151 }, 149 },
152 .set = sd_setexposure, 150 .set_control = setexposure
153 .get = sd_getexposure,
154 }, 151 },
155 { /* 4 */ 152[AGC] = {
156 { 153 {
157 .id = V4L2_CID_AUTOGAIN, 154 .id = V4L2_CID_AUTOGAIN,
158 .type = V4L2_CTRL_TYPE_BOOLEAN, 155 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -160,14 +157,11 @@ static const struct ctrl sd_ctrls[] = {
160 .minimum = 0, 157 .minimum = 0,
161 .maximum = 1, 158 .maximum = 1,
162 .step = 1, 159 .step = 1,
163#define AGC_DEF 1 160 .default_value = 1,
164 .default_value = AGC_DEF,
165 }, 161 },
166 .set = sd_setagc, 162 .set = sd_setagc
167 .get = sd_getagc,
168 }, 163 },
169#define AWB_IDX 5 164[AWB] = {
170 { /* 5 */
171 { 165 {
172 .id = V4L2_CID_AUTO_WHITE_BALANCE, 166 .id = V4L2_CID_AUTO_WHITE_BALANCE,
173 .type = V4L2_CTRL_TYPE_BOOLEAN, 167 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -175,13 +169,11 @@ static const struct ctrl sd_ctrls[] = {
175 .minimum = 0, 169 .minimum = 0,
176 .maximum = 1, 170 .maximum = 1,
177 .step = 1, 171 .step = 1,
178#define AWB_DEF 1 172 .default_value = 1,
179 .default_value = AWB_DEF,
180 }, 173 },
181 .set = sd_setawb, 174 .set_control = setawb
182 .get = sd_getawb,
183 }, 175 },
184 { /* 6 */ 176[AEC] = {
185 { 177 {
186 .id = V4L2_CID_EXPOSURE_AUTO, 178 .id = V4L2_CID_EXPOSURE_AUTO,
187 .type = V4L2_CTRL_TYPE_BOOLEAN, 179 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -189,13 +181,11 @@ static const struct ctrl sd_ctrls[] = {
189 .minimum = 0, 181 .minimum = 0,
190 .maximum = 1, 182 .maximum = 1,
191 .step = 1, 183 .step = 1,
192#define AEC_DEF 1 184 .default_value = 1,
193 .default_value = AEC_DEF,
194 }, 185 },
195 .set = sd_setaec, 186 .set_control = setaec
196 .get = sd_getaec,
197 }, 187 },
198 { /* 7 */ 188[SHARPNESS] = {
199 { 189 {
200 .id = V4L2_CID_SHARPNESS, 190 .id = V4L2_CID_SHARPNESS,
201 .type = V4L2_CTRL_TYPE_INTEGER, 191 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -203,13 +193,11 @@ static const struct ctrl sd_ctrls[] = {
203 .minimum = 0, 193 .minimum = 0,
204 .maximum = 63, 194 .maximum = 63,
205 .step = 1, 195 .step = 1,
206#define SHARPNESS_DEF 0 196 .default_value = 0,
207 .default_value = SHARPNESS_DEF,
208 }, 197 },
209 .set = sd_setsharpness, 198 .set_control = setsharpness
210 .get = sd_getsharpness,
211 }, 199 },
212 { /* 8 */ 200[HFLIP] = {
213 { 201 {
214 .id = V4L2_CID_HFLIP, 202 .id = V4L2_CID_HFLIP,
215 .type = V4L2_CTRL_TYPE_BOOLEAN, 203 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -217,13 +205,11 @@ static const struct ctrl sd_ctrls[] = {
217 .minimum = 0, 205 .minimum = 0,
218 .maximum = 1, 206 .maximum = 1,
219 .step = 1, 207 .step = 1,
220#define HFLIP_DEF 0 208 .default_value = 0,
221 .default_value = HFLIP_DEF,
222 }, 209 },
223 .set = sd_sethflip, 210 .set_control = sethvflip
224 .get = sd_gethflip,
225 }, 211 },
226 { /* 9 */ 212[VFLIP] = {
227 { 213 {
228 .id = V4L2_CID_VFLIP, 214 .id = V4L2_CID_VFLIP,
229 .type = V4L2_CTRL_TYPE_BOOLEAN, 215 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -231,13 +217,23 @@ static const struct ctrl sd_ctrls[] = {
231 .minimum = 0, 217 .minimum = 0,
232 .maximum = 1, 218 .maximum = 1,
233 .step = 1, 219 .step = 1,
234#define VFLIP_DEF 0 220 .default_value = 0,
235 .default_value = VFLIP_DEF,
236 }, 221 },
237 .set = sd_setvflip, 222 .set_control = sethvflip
238 .get = sd_getvflip,
239 }, 223 },
240 { /* 10 */ 224[COLORS] = {
225 {
226 .id = V4L2_CID_SATURATION,
227 .type = V4L2_CTRL_TYPE_INTEGER,
228 .name = "Saturation",
229 .minimum = 0,
230 .maximum = 6,
231 .step = 1,
232 .default_value = 3,
233 },
234 .set_control = setcolors
235 },
236[LIGHTFREQ] = {
241 { 237 {
242 .id = V4L2_CID_POWER_LINE_FREQUENCY, 238 .id = V4L2_CID_POWER_LINE_FREQUENCY,
243 .type = V4L2_CTRL_TYPE_MENU, 239 .type = V4L2_CTRL_TYPE_MENU,
@@ -245,11 +241,9 @@ static const struct ctrl sd_ctrls[] = {
245 .minimum = 0, 241 .minimum = 0,
246 .maximum = 1, 242 .maximum = 1,
247 .step = 1, 243 .step = 1,
248#define FREQFLTR_DEF 0 244 .default_value = 0,
249 .default_value = FREQFLTR_DEF,
250 }, 245 },
251 .set = sd_setfreqfltr, 246 .set_control = setlightfreq
252 .get = sd_getfreqfltr,
253 }, 247 },
254}; 248};
255 249
@@ -265,6 +259,16 @@ static const struct v4l2_pix_format ov772x_mode[] = {
265 .colorspace = V4L2_COLORSPACE_SRGB, 259 .colorspace = V4L2_COLORSPACE_SRGB,
266 .priv = 0}, 260 .priv = 0},
267}; 261};
262static const struct v4l2_pix_format ov767x_mode[] = {
263 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
264 .bytesperline = 320,
265 .sizeimage = 320 * 240 * 3 / 8 + 590,
266 .colorspace = V4L2_COLORSPACE_JPEG},
267 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
268 .bytesperline = 640,
269 .sizeimage = 640 * 480 * 3 / 8 + 590,
270 .colorspace = V4L2_COLORSPACE_JPEG},
271};
268 272
269static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30}; 273static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30};
270static const u8 vga_rates[] = {60, 50, 40, 30, 15}; 274static const u8 vga_rates[] = {60, 50, 40, 30, 15};
@@ -280,7 +284,288 @@ static const struct framerates ov772x_framerates[] = {
280 }, 284 },
281}; 285};
282 286
283static const u8 bridge_init[][2] = { 287struct reg_array {
288 const u8 (*val)[2];
289 int len;
290};
291
292static const u8 bridge_init_767x[][2] = {
293/* comments from the ms-win file apollo7670.set */
294/* str1 */
295 {0xf1, 0x42},
296 {0x88, 0xf8},
297 {0x89, 0xff},
298 {0x76, 0x03},
299 {0x92, 0x03},
300 {0x95, 0x10},
301 {0xe2, 0x00},
302 {0xe7, 0x3e},
303 {0x8d, 0x1c},
304 {0x8e, 0x00},
305 {0x8f, 0x00},
306 {0x1f, 0x00},
307 {0xc3, 0xf9},
308 {0x89, 0xff},
309 {0x88, 0xf8},
310 {0x76, 0x03},
311 {0x92, 0x01},
312 {0x93, 0x18},
313 {0x1c, 0x00},
314 {0x1d, 0x48},
315 {0x1d, 0x00},
316 {0x1d, 0xff},
317 {0x1d, 0x02},
318 {0x1d, 0x58},
319 {0x1d, 0x00},
320 {0x1c, 0x0a},
321 {0x1d, 0x0a},
322 {0x1d, 0x0e},
323 {0xc0, 0x50}, /* HSize 640 */
324 {0xc1, 0x3c}, /* VSize 480 */
325 {0x34, 0x05}, /* enable Audio Suspend mode */
326 {0xc2, 0x0c}, /* Input YUV */
327 {0xc3, 0xf9}, /* enable PRE */
328 {0x34, 0x05}, /* enable Audio Suspend mode */
329 {0xe7, 0x2e}, /* this solves failure of "SuspendResumeTest" */
330 {0x31, 0xf9}, /* enable 1.8V Suspend */
331 {0x35, 0x02}, /* turn on JPEG */
332 {0xd9, 0x10},
333 {0x25, 0x42}, /* GPIO[8]:Input */
334 {0x94, 0x11}, /* If the default setting is loaded when
335 * system boots up, this flag is closed here */
336};
337static const u8 sensor_init_767x[][2] = {
338 {0x12, 0x80},
339 {0x11, 0x03},
340 {0x3a, 0x04},
341 {0x12, 0x00},
342 {0x17, 0x13},
343 {0x18, 0x01},
344 {0x32, 0xb6},
345 {0x19, 0x02},
346 {0x1a, 0x7a},
347 {0x03, 0x0a},
348 {0x0c, 0x00},
349 {0x3e, 0x00},
350 {0x70, 0x3a},
351 {0x71, 0x35},
352 {0x72, 0x11},
353 {0x73, 0xf0},
354 {0xa2, 0x02},
355 {0x7a, 0x2a}, /* set Gamma=1.6 below */
356 {0x7b, 0x12},
357 {0x7c, 0x1d},
358 {0x7d, 0x2d},
359 {0x7e, 0x45},
360 {0x7f, 0x50},
361 {0x80, 0x59},
362 {0x81, 0x62},
363 {0x82, 0x6b},
364 {0x83, 0x73},
365 {0x84, 0x7b},
366 {0x85, 0x8a},
367 {0x86, 0x98},
368 {0x87, 0xb2},
369 {0x88, 0xca},
370 {0x89, 0xe0},
371 {0x13, 0xe0},
372 {0x00, 0x00},
373 {0x10, 0x00},
374 {0x0d, 0x40},
375 {0x14, 0x38}, /* gain max 16x */
376 {0xa5, 0x05},
377 {0xab, 0x07},
378 {0x24, 0x95},
379 {0x25, 0x33},
380 {0x26, 0xe3},
381 {0x9f, 0x78},
382 {0xa0, 0x68},
383 {0xa1, 0x03},
384 {0xa6, 0xd8},
385 {0xa7, 0xd8},
386 {0xa8, 0xf0},
387 {0xa9, 0x90},
388 {0xaa, 0x94},
389 {0x13, 0xe5},
390 {0x0e, 0x61},
391 {0x0f, 0x4b},
392 {0x16, 0x02},
393 {0x21, 0x02},
394 {0x22, 0x91},
395 {0x29, 0x07},
396 {0x33, 0x0b},
397 {0x35, 0x0b},
398 {0x37, 0x1d},
399 {0x38, 0x71},
400 {0x39, 0x2a},
401 {0x3c, 0x78},
402 {0x4d, 0x40},
403 {0x4e, 0x20},
404 {0x69, 0x00},
405 {0x6b, 0x4a},
406 {0x74, 0x10},
407 {0x8d, 0x4f},
408 {0x8e, 0x00},
409 {0x8f, 0x00},
410 {0x90, 0x00},
411 {0x91, 0x00},
412 {0x96, 0x00},
413 {0x9a, 0x80},
414 {0xb0, 0x84},
415 {0xb1, 0x0c},
416 {0xb2, 0x0e},
417 {0xb3, 0x82},
418 {0xb8, 0x0a},
419 {0x43, 0x0a},
420 {0x44, 0xf0},
421 {0x45, 0x34},
422 {0x46, 0x58},
423 {0x47, 0x28},
424 {0x48, 0x3a},
425 {0x59, 0x88},
426 {0x5a, 0x88},
427 {0x5b, 0x44},
428 {0x5c, 0x67},
429 {0x5d, 0x49},
430 {0x5e, 0x0e},
431 {0x6c, 0x0a},
432 {0x6d, 0x55},
433 {0x6e, 0x11},
434 {0x6f, 0x9f},
435 {0x6a, 0x40},
436 {0x01, 0x40},
437 {0x02, 0x40},
438 {0x13, 0xe7},
439 {0x4f, 0x80},
440 {0x50, 0x80},
441 {0x51, 0x00},
442 {0x52, 0x22},
443 {0x53, 0x5e},
444 {0x54, 0x80},
445 {0x58, 0x9e},
446 {0x41, 0x08},
447 {0x3f, 0x00},
448 {0x75, 0x04},
449 {0x76, 0xe1},
450 {0x4c, 0x00},
451 {0x77, 0x01},
452 {0x3d, 0xc2},
453 {0x4b, 0x09},
454 {0xc9, 0x60},
455 {0x41, 0x38}, /* jfm: auto sharpness + auto de-noise */
456 {0x56, 0x40},
457 {0x34, 0x11},
458 {0x3b, 0xc2},
459 {0xa4, 0x8a}, /* Night mode trigger point */
460 {0x96, 0x00},
461 {0x97, 0x30},
462 {0x98, 0x20},
463 {0x99, 0x20},
464 {0x9a, 0x84},
465 {0x9b, 0x29},
466 {0x9c, 0x03},
467 {0x9d, 0x4c},
468 {0x9e, 0x3f},
469 {0x78, 0x04},
470 {0x79, 0x01},
471 {0xc8, 0xf0},
472 {0x79, 0x0f},
473 {0xc8, 0x00},
474 {0x79, 0x10},
475 {0xc8, 0x7e},
476 {0x79, 0x0a},
477 {0xc8, 0x80},
478 {0x79, 0x0b},
479 {0xc8, 0x01},
480 {0x79, 0x0c},
481 {0xc8, 0x0f},
482 {0x79, 0x0d},
483 {0xc8, 0x20},
484 {0x79, 0x09},
485 {0xc8, 0x80},
486 {0x79, 0x02},
487 {0xc8, 0xc0},
488 {0x79, 0x03},
489 {0xc8, 0x20},
490 {0x79, 0x26},
491};
492static const u8 bridge_start_vga_767x[][2] = {
493/* str59 JPG */
494 {0x94, 0xaa},
495 {0xf1, 0x42},
496 {0xe5, 0x04},
497 {0xc0, 0x50},
498 {0xc1, 0x3c},
499 {0xc2, 0x0c},
500 {0x35, 0x02}, /* turn on JPEG */
501 {0xd9, 0x10},
502 {0xda, 0x00}, /* for higher clock rate(30fps) */
503 {0x34, 0x05}, /* enable Audio Suspend mode */
504 {0xc3, 0xf9}, /* enable PRE */
505 {0x8c, 0x00}, /* CIF VSize LSB[2:0] */
506 {0x8d, 0x1c}, /* output YUV */
507/* {0x34, 0x05}, * enable Audio Suspend mode (?) */
508 {0x50, 0x00}, /* H/V divider=0 */
509 {0x51, 0xa0}, /* input H=640/4 */
510 {0x52, 0x3c}, /* input V=480/4 */
511 {0x53, 0x00}, /* offset X=0 */
512 {0x54, 0x00}, /* offset Y=0 */
513 {0x55, 0x00}, /* H/V size[8]=0 */
514 {0x57, 0x00}, /* H-size[9]=0 */
515 {0x5c, 0x00}, /* output size[9:8]=0 */
516 {0x5a, 0xa0}, /* output H=640/4 */
517 {0x5b, 0x78}, /* output V=480/4 */
518 {0x1c, 0x0a},
519 {0x1d, 0x0a},
520 {0x94, 0x11},
521};
522static const u8 sensor_start_vga_767x[][2] = {
523 {0x11, 0x01},
524 {0x1e, 0x04},
525 {0x19, 0x02},
526 {0x1a, 0x7a},
527};
528static const u8 bridge_start_qvga_767x[][2] = {
529/* str86 JPG */
530 {0x94, 0xaa},
531 {0xf1, 0x42},
532 {0xe5, 0x04},
533 {0xc0, 0x80},
534 {0xc1, 0x60},
535 {0xc2, 0x0c},
536 {0x35, 0x02}, /* turn on JPEG */
537 {0xd9, 0x10},
538 {0xc0, 0x50}, /* CIF HSize 640 */
539 {0xc1, 0x3c}, /* CIF VSize 480 */
540 {0x8c, 0x00}, /* CIF VSize LSB[2:0] */
541 {0x8d, 0x1c}, /* output YUV */
542 {0x34, 0x05}, /* enable Audio Suspend mode */
543 {0xc2, 0x4c}, /* output YUV and Enable DCW */
544 {0xc3, 0xf9}, /* enable PRE */
545 {0x1c, 0x00}, /* indirect addressing */
546 {0x1d, 0x48}, /* output YUV422 */
547 {0x50, 0x89}, /* H/V divider=/2; plus DCW AVG */
548 {0x51, 0xa0}, /* DCW input H=640/4 */
549 {0x52, 0x78}, /* DCW input V=480/4 */
550 {0x53, 0x00}, /* offset X=0 */
551 {0x54, 0x00}, /* offset Y=0 */
552 {0x55, 0x00}, /* H/V size[8]=0 */
553 {0x57, 0x00}, /* H-size[9]=0 */
554 {0x5c, 0x00}, /* DCW output size[9:8]=0 */
555 {0x5a, 0x50}, /* DCW output H=320/4 */
556 {0x5b, 0x3c}, /* DCW output V=240/4 */
557 {0x1c, 0x0a},
558 {0x1d, 0x0a},
559 {0x94, 0x11},
560};
561static const u8 sensor_start_qvga_767x[][2] = {
562 {0x11, 0x01},
563 {0x1e, 0x04},
564 {0x19, 0x02},
565 {0x1a, 0x7a},
566};
567
568static const u8 bridge_init_772x[][2] = {
284 { 0xc2, 0x0c }, 569 { 0xc2, 0x0c },
285 { 0x88, 0xf8 }, 570 { 0x88, 0xf8 },
286 { 0xc3, 0x69 }, 571 { 0xc3, 0x69 },
@@ -338,7 +623,7 @@ static const u8 bridge_init[][2] = {
338 { 0xc1, 0x3c }, 623 { 0xc1, 0x3c },
339 { 0xc2, 0x0c }, 624 { 0xc2, 0x0c },
340}; 625};
341static const u8 sensor_init[][2] = { 626static const u8 sensor_init_772x[][2] = {
342 { 0x12, 0x80 }, 627 { 0x12, 0x80 },
343 { 0x11, 0x01 }, 628 { 0x11, 0x01 },
344/*fixme: better have a delay?*/ 629/*fixme: better have a delay?*/
@@ -431,7 +716,7 @@ static const u8 sensor_init[][2] = {
431 { 0x8e, 0x00 }, /* De-noise threshold */ 716 { 0x8e, 0x00 }, /* De-noise threshold */
432 { 0x0c, 0xd0 } 717 { 0x0c, 0xd0 }
433}; 718};
434static const u8 bridge_start_vga[][2] = { 719static const u8 bridge_start_vga_772x[][2] = {
435 {0x1c, 0x00}, 720 {0x1c, 0x00},
436 {0x1d, 0x40}, 721 {0x1d, 0x40},
437 {0x1d, 0x02}, 722 {0x1d, 0x02},
@@ -442,7 +727,7 @@ static const u8 bridge_start_vga[][2] = {
442 {0xc0, 0x50}, 727 {0xc0, 0x50},
443 {0xc1, 0x3c}, 728 {0xc1, 0x3c},
444}; 729};
445static const u8 sensor_start_vga[][2] = { 730static const u8 sensor_start_vga_772x[][2] = {
446 {0x12, 0x00}, 731 {0x12, 0x00},
447 {0x17, 0x26}, 732 {0x17, 0x26},
448 {0x18, 0xa0}, 733 {0x18, 0xa0},
@@ -452,7 +737,7 @@ static const u8 sensor_start_vga[][2] = {
452 {0x2c, 0xf0}, 737 {0x2c, 0xf0},
453 {0x65, 0x20}, 738 {0x65, 0x20},
454}; 739};
455static const u8 bridge_start_qvga[][2] = { 740static const u8 bridge_start_qvga_772x[][2] = {
456 {0x1c, 0x00}, 741 {0x1c, 0x00},
457 {0x1d, 0x40}, 742 {0x1d, 0x40},
458 {0x1d, 0x02}, 743 {0x1d, 0x02},
@@ -463,7 +748,7 @@ static const u8 bridge_start_qvga[][2] = {
463 {0xc0, 0x28}, 748 {0xc0, 0x28},
464 {0xc1, 0x1e}, 749 {0xc1, 0x1e},
465}; 750};
466static const u8 sensor_start_qvga[][2] = { 751static const u8 sensor_start_qvga_772x[][2] = {
467 {0x12, 0x40}, 752 {0x12, 0x40},
468 {0x17, 0x3f}, 753 {0x17, 0x3f},
469 {0x18, 0x50}, 754 {0x18, 0x50},
@@ -646,6 +931,8 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
646 {30, 0x04, 0x41, 0x04}, 931 {30, 0x04, 0x41, 0x04},
647 }; 932 };
648 933
934 if (sd->sensor != SENSOR_OV772x)
935 return;
649 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) { 936 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
650 r = rate_0; 937 r = rate_0;
651 i = ARRAY_SIZE(rate_0); 938 i = ARRAY_SIZE(rate_0);
@@ -669,15 +956,28 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
669static void setbrightness(struct gspca_dev *gspca_dev) 956static void setbrightness(struct gspca_dev *gspca_dev)
670{ 957{
671 struct sd *sd = (struct sd *) gspca_dev; 958 struct sd *sd = (struct sd *) gspca_dev;
959 int val;
672 960
673 sccb_reg_write(gspca_dev, 0x9b, sd->brightness); 961 val = sd->ctrls[BRIGHTNESS].val;
962 if (sd->sensor == SENSOR_OV767x) {
963 if (val < 0)
964 val = 0x80 - val;
965 sccb_reg_write(gspca_dev, 0x55, val); /* bright */
966 } else {
967 sccb_reg_write(gspca_dev, 0x9b, val);
968 }
674} 969}
675 970
676static void setcontrast(struct gspca_dev *gspca_dev) 971static void setcontrast(struct gspca_dev *gspca_dev)
677{ 972{
678 struct sd *sd = (struct sd *) gspca_dev; 973 struct sd *sd = (struct sd *) gspca_dev;
974 u8 val;
679 975
680 sccb_reg_write(gspca_dev, 0x9c, sd->contrast); 976 val = sd->ctrls[CONTRAST].val;
977 if (sd->sensor == SENSOR_OV767x)
978 sccb_reg_write(gspca_dev, 0x56, val); /* contras */
979 else
980 sccb_reg_write(gspca_dev, 0x9c, val);
681} 981}
682 982
683static void setgain(struct gspca_dev *gspca_dev) 983static void setgain(struct gspca_dev *gspca_dev)
@@ -685,10 +985,10 @@ static void setgain(struct gspca_dev *gspca_dev)
685 struct sd *sd = (struct sd *) gspca_dev; 985 struct sd *sd = (struct sd *) gspca_dev;
686 u8 val; 986 u8 val;
687 987
688 if (sd->agc) 988 if (sd->ctrls[AGC].val)
689 return; 989 return;
690 990
691 val = sd->gain; 991 val = sd->ctrls[GAIN].val;
692 switch (val & 0x30) { 992 switch (val & 0x30) {
693 case 0x00: 993 case 0x00:
694 val &= 0x0f; 994 val &= 0x0f;
@@ -715,25 +1015,32 @@ static void setexposure(struct gspca_dev *gspca_dev)
715 struct sd *sd = (struct sd *) gspca_dev; 1015 struct sd *sd = (struct sd *) gspca_dev;
716 u8 val; 1016 u8 val;
717 1017
718 if (sd->aec) 1018 if (sd->ctrls[AEC].val)
719 return; 1019 return;
720 1020
721 /* 'val' is one byte and represents half of the exposure value we are 1021 val = sd->ctrls[EXPOSURE].val;
722 * going to set into registers, a two bytes value: 1022 if (sd->sensor == SENSOR_OV767x) {
723 * 1023
724 * MSB: ((u16) val << 1) >> 8 == val >> 7 1024 /* set only aec[9:2] */
725 * LSB: ((u16) val << 1) & 0xff == val << 1 1025 sccb_reg_write(gspca_dev, 0x10, val); /* aech */
726 */ 1026 } else {
727 val = sd->exposure; 1027
728 sccb_reg_write(gspca_dev, 0x08, val >> 7); 1028 /* 'val' is one byte and represents half of the exposure value
729 sccb_reg_write(gspca_dev, 0x10, val << 1); 1029 * we are going to set into registers, a two bytes value:
1030 *
1031 * MSB: ((u16) val << 1) >> 8 == val >> 7
1032 * LSB: ((u16) val << 1) & 0xff == val << 1
1033 */
1034 sccb_reg_write(gspca_dev, 0x08, val >> 7);
1035 sccb_reg_write(gspca_dev, 0x10, val << 1);
1036 }
730} 1037}
731 1038
732static void setagc(struct gspca_dev *gspca_dev) 1039static void setagc(struct gspca_dev *gspca_dev)
733{ 1040{
734 struct sd *sd = (struct sd *) gspca_dev; 1041 struct sd *sd = (struct sd *) gspca_dev;
735 1042
736 if (sd->agc) { 1043 if (sd->ctrls[AGC].val) {
737 sccb_reg_write(gspca_dev, 0x13, 1044 sccb_reg_write(gspca_dev, 0x13,
738 sccb_reg_read(gspca_dev, 0x13) | 0x04); 1045 sccb_reg_read(gspca_dev, 0x13) | 0x04);
739 sccb_reg_write(gspca_dev, 0x64, 1046 sccb_reg_write(gspca_dev, 0x64,
@@ -752,15 +1059,17 @@ static void setawb(struct gspca_dev *gspca_dev)
752{ 1059{
753 struct sd *sd = (struct sd *) gspca_dev; 1060 struct sd *sd = (struct sd *) gspca_dev;
754 1061
755 if (sd->awb) { 1062 if (sd->ctrls[AWB].val) {
756 sccb_reg_write(gspca_dev, 0x13, 1063 sccb_reg_write(gspca_dev, 0x13,
757 sccb_reg_read(gspca_dev, 0x13) | 0x02); 1064 sccb_reg_read(gspca_dev, 0x13) | 0x02);
758 sccb_reg_write(gspca_dev, 0x63, 1065 if (sd->sensor == SENSOR_OV772x)
1066 sccb_reg_write(gspca_dev, 0x63,
759 sccb_reg_read(gspca_dev, 0x63) | 0xc0); 1067 sccb_reg_read(gspca_dev, 0x63) | 0xc0);
760 } else { 1068 } else {
761 sccb_reg_write(gspca_dev, 0x13, 1069 sccb_reg_write(gspca_dev, 0x13,
762 sccb_reg_read(gspca_dev, 0x13) & ~0x02); 1070 sccb_reg_read(gspca_dev, 0x13) & ~0x02);
763 sccb_reg_write(gspca_dev, 0x63, 1071 if (sd->sensor == SENSOR_OV772x)
1072 sccb_reg_write(gspca_dev, 0x63,
764 sccb_reg_read(gspca_dev, 0x63) & ~0xc0); 1073 sccb_reg_read(gspca_dev, 0x63) & ~0xc0);
765 } 1074 }
766} 1075}
@@ -768,14 +1077,22 @@ static void setawb(struct gspca_dev *gspca_dev)
768static void setaec(struct gspca_dev *gspca_dev) 1077static void setaec(struct gspca_dev *gspca_dev)
769{ 1078{
770 struct sd *sd = (struct sd *) gspca_dev; 1079 struct sd *sd = (struct sd *) gspca_dev;
1080 u8 data;
771 1081
772 if (sd->aec) 1082 data = sd->sensor == SENSOR_OV767x ?
1083 0x05 : /* agc + aec */
1084 0x01; /* agc */
1085 if (sd->ctrls[AEC].val)
773 sccb_reg_write(gspca_dev, 0x13, 1086 sccb_reg_write(gspca_dev, 0x13,
774 sccb_reg_read(gspca_dev, 0x13) | 0x01); 1087 sccb_reg_read(gspca_dev, 0x13) | data);
775 else { 1088 else {
776 sccb_reg_write(gspca_dev, 0x13, 1089 sccb_reg_write(gspca_dev, 0x13,
777 sccb_reg_read(gspca_dev, 0x13) & ~0x01); 1090 sccb_reg_read(gspca_dev, 0x13) & ~data);
778 setexposure(gspca_dev); 1091 if (sd->sensor == SENSOR_OV767x)
1092 sd->ctrls[EXPOSURE].val =
1093 sccb_reg_read(gspca_dev, 10); /* aech */
1094 else
1095 setexposure(gspca_dev);
779 } 1096 }
780} 1097}
781 1098
@@ -784,43 +1101,67 @@ static void setsharpness(struct gspca_dev *gspca_dev)
784 struct sd *sd = (struct sd *) gspca_dev; 1101 struct sd *sd = (struct sd *) gspca_dev;
785 u8 val; 1102 u8 val;
786 1103
787 val = sd->sharpness; 1104 val = sd->ctrls[SHARPNESS].val;
788 sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */ 1105 sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */
789 sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */ 1106 sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */
790} 1107}
791 1108
792static void sethflip(struct gspca_dev *gspca_dev) 1109static void sethvflip(struct gspca_dev *gspca_dev)
793{ 1110{
794 struct sd *sd = (struct sd *) gspca_dev; 1111 struct sd *sd = (struct sd *) gspca_dev;
1112 u8 val;
795 1113
796 if (sd->hflip == 0) 1114 if (sd->sensor == SENSOR_OV767x) {
797 sccb_reg_write(gspca_dev, 0x0c, 1115 val = sccb_reg_read(gspca_dev, 0x1e); /* mvfp */
798 sccb_reg_read(gspca_dev, 0x0c) | 0x40); 1116 val &= ~0x30;
799 else 1117 if (sd->ctrls[HFLIP].val)
800 sccb_reg_write(gspca_dev, 0x0c, 1118 val |= 0x20;
801 sccb_reg_read(gspca_dev, 0x0c) & ~0x40); 1119 if (sd->ctrls[VFLIP].val)
1120 val |= 0x10;
1121 sccb_reg_write(gspca_dev, 0x1e, val);
1122 } else {
1123 val = sccb_reg_read(gspca_dev, 0x0c);
1124 val &= ~0xc0;
1125 if (sd->ctrls[HFLIP].val == 0)
1126 val |= 0x40;
1127 if (sd->ctrls[VFLIP].val == 0)
1128 val |= 0x80;
1129 sccb_reg_write(gspca_dev, 0x0c, val);
1130 }
802} 1131}
803 1132
804static void setvflip(struct gspca_dev *gspca_dev) 1133static void setcolors(struct gspca_dev *gspca_dev)
805{ 1134{
806 struct sd *sd = (struct sd *) gspca_dev; 1135 struct sd *sd = (struct sd *) gspca_dev;
1136 u8 val;
1137 int i;
1138 static u8 color_tb[][6] = {
1139 {0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
1140 {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
1141 {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
1142 {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
1143 {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
1144 {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
1145 {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
1146 };
807 1147
808 if (sd->vflip == 0) 1148 val = sd->ctrls[COLORS].val;
809 sccb_reg_write(gspca_dev, 0x0c, 1149 for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
810 sccb_reg_read(gspca_dev, 0x0c) | 0x80); 1150 sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
811 else
812 sccb_reg_write(gspca_dev, 0x0c,
813 sccb_reg_read(gspca_dev, 0x0c) & ~0x80);
814} 1151}
815 1152
816static void setfreqfltr(struct gspca_dev *gspca_dev) 1153static void setlightfreq(struct gspca_dev *gspca_dev)
817{ 1154{
818 struct sd *sd = (struct sd *) gspca_dev; 1155 struct sd *sd = (struct sd *) gspca_dev;
1156 u8 val;
819 1157
820 if (sd->freqfltr == 0) 1158 val = sd->ctrls[LIGHTFREQ].val ? 0x9e : 0x00;
821 sccb_reg_write(gspca_dev, 0x2b, 0x00); 1159 if (sd->sensor == SENSOR_OV767x) {
822 else 1160 sccb_reg_write(gspca_dev, 0x2a, 0x00);
823 sccb_reg_write(gspca_dev, 0x2b, 0x9e); 1161 if (val)
1162 val = 0x9d; /* insert dummy to 25fps for 50Hz */
1163 }
1164 sccb_reg_write(gspca_dev, 0x2b, val);
824} 1165}
825 1166
826 1167
@@ -833,39 +1174,33 @@ static int sd_config(struct gspca_dev *gspca_dev,
833 1174
834 cam = &gspca_dev->cam; 1175 cam = &gspca_dev->cam;
835 1176
1177 cam->ctrls = sd->ctrls;
1178
1179 /* the auto white balance control works only when auto gain is set */
1180 if (sd_ctrls[AGC].qctrl.default_value == 0)
1181 gspca_dev->ctrl_inac |= (1 << AWB);
1182
836 cam->cam_mode = ov772x_mode; 1183 cam->cam_mode = ov772x_mode;
837 cam->nmodes = ARRAY_SIZE(ov772x_mode); 1184 cam->nmodes = ARRAY_SIZE(ov772x_mode);
838 cam->mode_framerates = ov772x_framerates;
839
840 cam->bulk = 1;
841 cam->bulk_size = 16384;
842 cam->bulk_nurbs = 2;
843 1185
844 sd->frame_rate = 30; 1186 sd->frame_rate = 30;
845 1187
846 sd->brightness = BRIGHTNESS_DEF;
847 sd->contrast = CONTRAST_DEF;
848 sd->gain = GAIN_DEF;
849 sd->exposure = EXPO_DEF;
850#if AGC_DEF != 0
851 sd->agc = AGC_DEF;
852#else
853 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
854#endif
855 sd->awb = AWB_DEF;
856 sd->aec = AEC_DEF;
857 sd->sharpness = SHARPNESS_DEF;
858 sd->hflip = HFLIP_DEF;
859 sd->vflip = VFLIP_DEF;
860 sd->freqfltr = FREQFLTR_DEF;
861
862 return 0; 1188 return 0;
863} 1189}
864 1190
865/* this function is called at probe and resume time */ 1191/* this function is called at probe and resume time */
866static int sd_init(struct gspca_dev *gspca_dev) 1192static int sd_init(struct gspca_dev *gspca_dev)
867{ 1193{
1194 struct sd *sd = (struct sd *) gspca_dev;
868 u16 sensor_id; 1195 u16 sensor_id;
1196 static const struct reg_array bridge_init[NSENSORS] = {
1197 [SENSOR_OV767x] = {bridge_init_767x, ARRAY_SIZE(bridge_init_767x)},
1198 [SENSOR_OV772x] = {bridge_init_772x, ARRAY_SIZE(bridge_init_772x)},
1199 };
1200 static const struct reg_array sensor_init[NSENSORS] = {
1201 [SENSOR_OV767x] = {sensor_init_767x, ARRAY_SIZE(sensor_init_767x)},
1202 [SENSOR_OV772x] = {sensor_init_772x, ARRAY_SIZE(sensor_init_772x)},
1203 };
869 1204
870 /* reset bridge */ 1205 /* reset bridge */
871 ov534_reg_write(gspca_dev, 0xe7, 0x3a); 1206 ov534_reg_write(gspca_dev, 0xe7, 0x3a);
@@ -886,48 +1221,100 @@ static int sd_init(struct gspca_dev *gspca_dev)
886 sensor_id |= sccb_reg_read(gspca_dev, 0x0b); 1221 sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
887 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); 1222 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
888 1223
1224 if ((sensor_id & 0xfff0) == 0x7670) {
1225 sd->sensor = SENSOR_OV767x;
1226 gspca_dev->ctrl_dis = (1 << GAIN) |
1227 (1 << AGC) |
1228 (1 << SHARPNESS); /* auto */
1229 sd->ctrls[BRIGHTNESS].min = -127;
1230 sd->ctrls[BRIGHTNESS].max = 127;
1231 sd->ctrls[BRIGHTNESS].def = 0;
1232 sd->ctrls[CONTRAST].max = 0x80;
1233 sd->ctrls[CONTRAST].def = 0x40;
1234 sd->ctrls[EXPOSURE].min = 0x08;
1235 sd->ctrls[EXPOSURE].max = 0x60;
1236 sd->ctrls[EXPOSURE].def = 0x13;
1237 sd->ctrls[SHARPNESS].max = 9;
1238 sd->ctrls[SHARPNESS].def = 4;
1239 sd->ctrls[HFLIP].def = 1;
1240 gspca_dev->cam.cam_mode = ov767x_mode;
1241 gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode);
1242 } else {
1243 sd->sensor = SENSOR_OV772x;
1244 gspca_dev->ctrl_dis = (1 << COLORS);
1245 gspca_dev->cam.bulk = 1;
1246 gspca_dev->cam.bulk_size = 16384;
1247 gspca_dev->cam.bulk_nurbs = 2;
1248 gspca_dev->cam.mode_framerates = ov772x_framerates;
1249 }
1250
889 /* initialize */ 1251 /* initialize */
890 reg_w_array(gspca_dev, bridge_init, 1252 reg_w_array(gspca_dev, bridge_init[sd->sensor].val,
891 ARRAY_SIZE(bridge_init)); 1253 bridge_init[sd->sensor].len);
892 ov534_set_led(gspca_dev, 1); 1254 ov534_set_led(gspca_dev, 1);
893 sccb_w_array(gspca_dev, sensor_init, 1255 sccb_w_array(gspca_dev, sensor_init[sd->sensor].val,
894 ARRAY_SIZE(sensor_init)); 1256 sensor_init[sd->sensor].len);
895 ov534_reg_write(gspca_dev, 0xe0, 0x09); 1257 if (sd->sensor == SENSOR_OV767x)
896 ov534_set_led(gspca_dev, 0); 1258 sd_start(gspca_dev);
897 set_frame_rate(gspca_dev); 1259 sd_stopN(gspca_dev);
1260/* set_frame_rate(gspca_dev); */
898 1261
899 return gspca_dev->usb_err; 1262 return gspca_dev->usb_err;
900} 1263}
901 1264
902static int sd_start(struct gspca_dev *gspca_dev) 1265static int sd_start(struct gspca_dev *gspca_dev)
903{ 1266{
1267 struct sd *sd = (struct sd *) gspca_dev;
904 int mode; 1268 int mode;
1269 static const struct reg_array bridge_start[NSENSORS][2] = {
1270 [SENSOR_OV767x] = {{bridge_start_qvga_767x,
1271 ARRAY_SIZE(bridge_start_qvga_767x)},
1272 {bridge_start_vga_767x,
1273 ARRAY_SIZE(bridge_start_vga_767x)}},
1274 [SENSOR_OV772x] = {{bridge_start_qvga_772x,
1275 ARRAY_SIZE(bridge_start_qvga_772x)},
1276 {bridge_start_vga_772x,
1277 ARRAY_SIZE(bridge_start_vga_772x)}},
1278 };
1279 static const struct reg_array sensor_start[NSENSORS][2] = {
1280 [SENSOR_OV767x] = {{sensor_start_qvga_767x,
1281 ARRAY_SIZE(sensor_start_qvga_767x)},
1282 {sensor_start_vga_767x,
1283 ARRAY_SIZE(sensor_start_vga_767x)}},
1284 [SENSOR_OV772x] = {{sensor_start_qvga_772x,
1285 ARRAY_SIZE(sensor_start_qvga_772x)},
1286 {sensor_start_vga_772x,
1287 ARRAY_SIZE(sensor_start_vga_772x)}},
1288 };
1289
1290 /* (from ms-win trace) */
1291 if (sd->sensor == SENSOR_OV767x)
1292 sccb_reg_write(gspca_dev, 0x1e, 0x04);
1293 /* black sun enable ? */
1294
1295 mode = gspca_dev->curr_mode; /* 0: 320x240, 1: 640x480 */
1296 reg_w_array(gspca_dev, bridge_start[sd->sensor][mode].val,
1297 bridge_start[sd->sensor][mode].len);
1298 sccb_w_array(gspca_dev, sensor_start[sd->sensor][mode].val,
1299 sensor_start[sd->sensor][mode].len);
905 1300
906 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
907 if (mode != 0) { /* 320x240 */
908 reg_w_array(gspca_dev, bridge_start_qvga,
909 ARRAY_SIZE(bridge_start_qvga));
910 sccb_w_array(gspca_dev, sensor_start_qvga,
911 ARRAY_SIZE(sensor_start_qvga));
912 } else { /* 640x480 */
913 reg_w_array(gspca_dev, bridge_start_vga,
914 ARRAY_SIZE(bridge_start_vga));
915 sccb_w_array(gspca_dev, sensor_start_vga,
916 ARRAY_SIZE(sensor_start_vga));
917 }
918 set_frame_rate(gspca_dev); 1301 set_frame_rate(gspca_dev);
919 1302
920 setagc(gspca_dev); 1303 if (!(gspca_dev->ctrl_dis & (1 << AGC)))
1304 setagc(gspca_dev);
921 setawb(gspca_dev); 1305 setawb(gspca_dev);
922 setaec(gspca_dev); 1306 setaec(gspca_dev);
923 setgain(gspca_dev); 1307 if (!(gspca_dev->ctrl_dis & (1 << GAIN)))
1308 setgain(gspca_dev);
924 setexposure(gspca_dev); 1309 setexposure(gspca_dev);
925 setbrightness(gspca_dev); 1310 setbrightness(gspca_dev);
926 setcontrast(gspca_dev); 1311 setcontrast(gspca_dev);
927 setsharpness(gspca_dev); 1312 if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS)))
928 setvflip(gspca_dev); 1313 setsharpness(gspca_dev);
929 sethflip(gspca_dev); 1314 sethvflip(gspca_dev);
930 setfreqfltr(gspca_dev); 1315 if (!(gspca_dev->ctrl_dis & (1 << COLORS)))
1316 setcolors(gspca_dev);
1317 setlightfreq(gspca_dev);
931 1318
932 ov534_set_led(gspca_dev, 1); 1319 ov534_set_led(gspca_dev, 1);
933 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1320 ov534_reg_write(gspca_dev, 0xe0, 0x00);
@@ -957,9 +1344,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
957 __u32 this_pts; 1344 __u32 this_pts;
958 u16 this_fid; 1345 u16 this_fid;
959 int remaining_len = len; 1346 int remaining_len = len;
1347 int payload_len;
960 1348
1349 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
961 do { 1350 do {
962 len = min(remaining_len, 2048); 1351 len = min(remaining_len, payload_len);
963 1352
964 /* Payloads are prefixed with a UVC-style header. We 1353 /* Payloads are prefixed with a UVC-style header. We
965 consider a frame to start when the FID toggles, or the PTS 1354 consider a frame to start when the FID toggles, or the PTS
@@ -999,8 +1388,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
999 /* If this packet is marked as EOF, end the frame */ 1388 /* If this packet is marked as EOF, end the frame */
1000 } else if (data[1] & UVC_STREAM_EOF) { 1389 } else if (data[1] & UVC_STREAM_EOF) {
1001 sd->last_pts = 0; 1390 sd->last_pts = 0;
1002 if (gspca_dev->image_len + len - 12 != 1391 if (gspca_dev->pixfmt == V4L2_PIX_FMT_YUYV
1003 gspca_dev->width * gspca_dev->height * 2) { 1392 && gspca_dev->image_len + len - 12 !=
1393 gspca_dev->width * gspca_dev->height * 2) {
1004 PDEBUG(D_PACK, "wrong sized frame"); 1394 PDEBUG(D_PACK, "wrong sized frame");
1005 goto discard; 1395 goto discard;
1006 } 1396 }
@@ -1026,212 +1416,27 @@ scan_next:
1026 } while (remaining_len > 0); 1416 } while (remaining_len > 0);
1027} 1417}
1028 1418
1029/* controls */
1030static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1031{
1032 struct sd *sd = (struct sd *) gspca_dev;
1033
1034 sd->gain = val;
1035 if (gspca_dev->streaming)
1036 setgain(gspca_dev);
1037 return 0;
1038}
1039
1040static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1041{
1042 struct sd *sd = (struct sd *) gspca_dev;
1043
1044 *val = sd->gain;
1045 return 0;
1046}
1047
1048static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1049{
1050 struct sd *sd = (struct sd *) gspca_dev;
1051
1052 sd->exposure = val;
1053 if (gspca_dev->streaming)
1054 setexposure(gspca_dev);
1055 return 0;
1056}
1057
1058static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1059{
1060 struct sd *sd = (struct sd *) gspca_dev;
1061
1062 *val = sd->exposure;
1063 return 0;
1064}
1065
1066static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1067{
1068 struct sd *sd = (struct sd *) gspca_dev;
1069
1070 sd->brightness = val;
1071 if (gspca_dev->streaming)
1072 setbrightness(gspca_dev);
1073 return 0;
1074}
1075
1076static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1077{
1078 struct sd *sd = (struct sd *) gspca_dev;
1079
1080 *val = sd->brightness;
1081 return 0;
1082}
1083
1084static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1085{
1086 struct sd *sd = (struct sd *) gspca_dev;
1087
1088 sd->contrast = val;
1089 if (gspca_dev->streaming)
1090 setcontrast(gspca_dev);
1091 return 0;
1092}
1093
1094static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1095{
1096 struct sd *sd = (struct sd *) gspca_dev;
1097
1098 *val = sd->contrast;
1099 return 0;
1100}
1101
1102static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val) 1419static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val)
1103{ 1420{
1104 struct sd *sd = (struct sd *) gspca_dev; 1421 struct sd *sd = (struct sd *) gspca_dev;
1105 1422
1106 sd->agc = val; 1423 sd->ctrls[AGC].val = val;
1107
1108 if (gspca_dev->streaming) {
1109 1424
1110 /* the auto white balance control works only 1425 /* the auto white balance control works only
1111 * when auto gain is set */ 1426 * when auto gain is set */
1112 if (val) 1427 if (val) {
1113 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX); 1428 gspca_dev->ctrl_inac &= ~(1 << AWB);
1114 else 1429 } else {
1115 gspca_dev->ctrl_inac |= (1 << AWB_IDX); 1430 gspca_dev->ctrl_inac |= (1 << AWB);
1116 setagc(gspca_dev); 1431 if (sd->ctrls[AWB].val) {
1432 sd->ctrls[AWB].val = 0;
1433 if (gspca_dev->streaming)
1434 setawb(gspca_dev);
1435 }
1117 } 1436 }
1118 return 0;
1119}
1120
1121static int sd_getagc(struct gspca_dev *gspca_dev, __s32 *val)
1122{
1123 struct sd *sd = (struct sd *) gspca_dev;
1124
1125 *val = sd->agc;
1126 return 0;
1127}
1128
1129static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
1130{
1131 struct sd *sd = (struct sd *) gspca_dev;
1132
1133 sd->awb = val;
1134 if (gspca_dev->streaming)
1135 setawb(gspca_dev);
1136 return 0;
1137}
1138
1139static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
1140{
1141 struct sd *sd = (struct sd *) gspca_dev;
1142
1143 *val = sd->awb;
1144 return 0;
1145}
1146
1147static int sd_setaec(struct gspca_dev *gspca_dev, __s32 val)
1148{
1149 struct sd *sd = (struct sd *) gspca_dev;
1150
1151 sd->aec = val;
1152 if (gspca_dev->streaming)
1153 setaec(gspca_dev);
1154 return 0;
1155}
1156
1157static int sd_getaec(struct gspca_dev *gspca_dev, __s32 *val)
1158{
1159 struct sd *sd = (struct sd *) gspca_dev;
1160
1161 *val = sd->aec;
1162 return 0;
1163}
1164
1165static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1166{
1167 struct sd *sd = (struct sd *) gspca_dev;
1168
1169 sd->sharpness = val;
1170 if (gspca_dev->streaming)
1171 setsharpness(gspca_dev);
1172 return 0;
1173}
1174
1175static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1176{
1177 struct sd *sd = (struct sd *) gspca_dev;
1178
1179 *val = sd->sharpness;
1180 return 0;
1181}
1182
1183static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1184{
1185 struct sd *sd = (struct sd *) gspca_dev;
1186
1187 sd->hflip = val;
1188 if (gspca_dev->streaming)
1189 sethflip(gspca_dev);
1190 return 0;
1191}
1192
1193static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1194{
1195 struct sd *sd = (struct sd *) gspca_dev;
1196
1197 *val = sd->hflip;
1198 return 0;
1199}
1200
1201static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1202{
1203 struct sd *sd = (struct sd *) gspca_dev;
1204
1205 sd->vflip = val;
1206 if (gspca_dev->streaming)
1207 setvflip(gspca_dev);
1208 return 0;
1209}
1210
1211static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1212{
1213 struct sd *sd = (struct sd *) gspca_dev;
1214
1215 *val = sd->vflip;
1216 return 0;
1217}
1218
1219static int sd_setfreqfltr(struct gspca_dev *gspca_dev, __s32 val)
1220{
1221 struct sd *sd = (struct sd *) gspca_dev;
1222
1223 sd->freqfltr = val;
1224 if (gspca_dev->streaming) 1437 if (gspca_dev->streaming)
1225 setfreqfltr(gspca_dev); 1438 setagc(gspca_dev);
1226 return 0; 1439 return gspca_dev->usb_err;
1227}
1228
1229static int sd_getfreqfltr(struct gspca_dev *gspca_dev, __s32 *val)
1230{
1231 struct sd *sd = (struct sd *) gspca_dev;
1232
1233 *val = sd->freqfltr;
1234 return 0;
1235} 1440}
1236 1441
1237static int sd_querymenu(struct gspca_dev *gspca_dev, 1442static int sd_querymenu(struct gspca_dev *gspca_dev,
@@ -1302,6 +1507,7 @@ static const struct sd_desc sd_desc = {
1302/* -- module initialisation -- */ 1507/* -- module initialisation -- */
1303static const struct usb_device_id device_table[] = { 1508static const struct usb_device_id device_table[] = {
1304 {USB_DEVICE(0x1415, 0x2000)}, 1509 {USB_DEVICE(0x1415, 0x2000)},
1510 {USB_DEVICE(0x06f8, 0x3002)},
1305 {} 1511 {}
1306}; 1512};
1307 1513
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index fcf29897b713..c431900cd292 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -152,6 +152,13 @@ static const struct dmi_system_id flip_dmi_table[] = {
152 } 152 }
153 }, 153 },
154 { 154 {
155 .ident = "MSI MS-1633X",
156 .matches = {
157 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
158 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
159 }
160 },
161 {
155 .ident = "MSI MS-1635X", 162 .ident = "MSI MS-1635X",
156 .matches = { 163 .matches = {
157 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 164 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
@@ -369,7 +376,7 @@ static const struct v4l2_pix_format vga_mode[] = {
369 .priv = SCALE_160x120}, 376 .priv = SCALE_160x120},
370 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 377 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
371 .bytesperline = 320, 378 .bytesperline = 320,
372 .sizeimage = 320 * 240 * 3 / 8 + 590, 379 .sizeimage = 320 * 240 * 4 / 8 + 590,
373 .colorspace = V4L2_COLORSPACE_JPEG, 380 .colorspace = V4L2_COLORSPACE_JPEG,
374 .priv = SCALE_320x240 | MODE_JPEG}, 381 .priv = SCALE_320x240 | MODE_JPEG},
375 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 382 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -384,7 +391,7 @@ static const struct v4l2_pix_format vga_mode[] = {
384 .priv = SCALE_320x240}, 391 .priv = SCALE_320x240},
385 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 392 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
386 .bytesperline = 640, 393 .bytesperline = 640,
387 .sizeimage = 640 * 480 * 3 / 8 + 590, 394 .sizeimage = 640 * 480 * 4 / 8 + 590,
388 .colorspace = V4L2_COLORSPACE_JPEG, 395 .colorspace = V4L2_COLORSPACE_JPEG,
389 .priv = SCALE_640x480 | MODE_JPEG}, 396 .priv = SCALE_640x480 | MODE_JPEG},
390 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 397 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -417,7 +424,7 @@ static const struct v4l2_pix_format sxga_mode[] = {
417 .priv = SCALE_160x120}, 424 .priv = SCALE_160x120},
418 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 425 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
419 .bytesperline = 320, 426 .bytesperline = 320,
420 .sizeimage = 320 * 240 * 3 / 8 + 590, 427 .sizeimage = 320 * 240 * 4 / 8 + 590,
421 .colorspace = V4L2_COLORSPACE_JPEG, 428 .colorspace = V4L2_COLORSPACE_JPEG,
422 .priv = SCALE_320x240 | MODE_JPEG}, 429 .priv = SCALE_320x240 | MODE_JPEG},
423 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 430 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -432,7 +439,7 @@ static const struct v4l2_pix_format sxga_mode[] = {
432 .priv = SCALE_320x240}, 439 .priv = SCALE_320x240},
433 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 440 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
434 .bytesperline = 640, 441 .bytesperline = 640,
435 .sizeimage = 640 * 480 * 3 / 8 + 590, 442 .sizeimage = 640 * 480 * 4 / 8 + 590,
436 .colorspace = V4L2_COLORSPACE_JPEG, 443 .colorspace = V4L2_COLORSPACE_JPEG,
437 .priv = SCALE_640x480 | MODE_JPEG}, 444 .priv = SCALE_640x480 | MODE_JPEG},
438 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 445 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -884,6 +891,9 @@ static struct i2c_reg_u8 ov7660_init[] = {
884 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, 891 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
885 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, 892 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
886 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, 893 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
894 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
895 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
896 {0x17, 0x10}, {0x18, 0x61},
887 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, 897 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
888 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6}, 898 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
889 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50}, 899 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
@@ -1332,10 +1342,8 @@ static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1332 return -ENODEV; 1342 return -ENODEV;
1333 } 1343 }
1334 } 1344 }
1335 /* disable hflip and vflip */ 1345 sd->hstart = 3;
1336 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1346 sd->vstart = 3;
1337 sd->hstart = 1;
1338 sd->vstart = 1;
1339 return 0; 1347 return 0;
1340} 1348}
1341 1349
@@ -1608,6 +1616,18 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1608 } 1616 }
1609 1617
1610 switch (sd->sensor) { 1618 switch (sd->sensor) {
1619 case SENSOR_OV7660:
1620 value = 0x01;
1621 if (hflip)
1622 value |= 0x20;
1623 if (vflip) {
1624 value |= 0x10;
1625 sd->vstart = 2;
1626 } else
1627 sd->vstart = 3;
1628 reg_w1(gspca_dev, 0x1182, sd->vstart);
1629 i2c_w1(gspca_dev, 0x1e, value);
1630 break;
1611 case SENSOR_OV9650: 1631 case SENSOR_OV9650:
1612 i2c_r1(gspca_dev, 0x1e, &value); 1632 i2c_r1(gspca_dev, 0x1e, &value);
1613 value &= ~0x30; 1633 value &= ~0x30;
@@ -2482,7 +2502,7 @@ static const struct usb_device_id device_table[] = {
2482 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2502 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2483 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, 2503 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2484 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)}, 2504 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2485 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)}, 2505 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2486 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)}, 2506 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2487 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, 2507 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2488 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, 2508 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
@@ -2494,7 +2514,7 @@ static const struct usb_device_id device_table[] = {
2494 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, 2514 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2495 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, 2515 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2496 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)}, 2516 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2497 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)}, 2517 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2498 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, 2518 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2499 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, 2519 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2500 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, 2520 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index c6cd68d66b53..5a08738fba30 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * sonix sn9c102 (bayer) library 2 * sonix sn9c102 (bayer) library
3 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
4 * Add Pas106 Stefano Mozzi (C) 2004
5 * 3 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
5 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
6 * Add Pas106 Stefano Mozzi (C) 2004
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -52,13 +52,26 @@ all:
52#include <linux/input.h> 52#include <linux/input.h>
53#include "gspca.h" 53#include "gspca.h"
54 54
55MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 55MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); 56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
57MODULE_LICENSE("GPL"); 57MODULE_LICENSE("GPL");
58 58
59/* controls */
60enum e_ctrl {
61 BRIGHTNESS,
62 GAIN,
63 EXPOSURE,
64 AUTOGAIN,
65 FREQ,
66 NCTRLS /* number of controls */
67};
68
59/* specific webcam descriptor */ 69/* specific webcam descriptor */
60struct sd { 70struct sd {
61 struct gspca_dev gspca_dev; /* !! must be the first item */ 71 struct gspca_dev gspca_dev; /* !! must be the first item */
72
73 struct gspca_ctrl ctrls[NCTRLS];
74
62 atomic_t avg_lum; 75 atomic_t avg_lum;
63 int prev_avg_lum; 76 int prev_avg_lum;
64 int exp_too_low_cnt; 77 int exp_too_low_cnt;
@@ -66,13 +79,8 @@ struct sd {
66 int header_read; 79 int header_read;
67 u8 header[12]; /* Header without sof marker */ 80 u8 header[12]; /* Header without sof marker */
68 81
69 unsigned short exposure;
70 unsigned char gain;
71 unsigned char brightness;
72 unsigned char autogain;
73 unsigned char autogain_ignore_frames; 82 unsigned char autogain_ignore_frames;
74 unsigned char frames_to_drop; 83 unsigned char frames_to_drop;
75 unsigned char freq; /* light freq filter setting */
76 84
77 __u8 bridge; /* Type of bridge */ 85 __u8 bridge; /* Type of bridge */
78#define BRIDGE_101 0 86#define BRIDGE_101 0
@@ -113,10 +121,9 @@ struct sensor_data {
113#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ 121#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
114 122
115/* ctrl_dis helper macros */ 123/* ctrl_dis helper macros */
116#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \ 124#define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN))
117 (1 << AUTOGAIN_IDX)) 125#define NO_FREQ (1 << FREQ)
118#define NO_FREQ (1 << FREQ_IDX) 126#define NO_BRIGHTNESS (1 << BRIGHTNESS)
119#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
120 127
121#define COMP 0xc7 /* 0x87 //0x07 */ 128#define COMP 0xc7 /* 0x87 //0x07 */
122#define COMP1 0xc9 /* 0x89 //0x09 */ 129#define COMP1 0xc9 /* 0x89 //0x09 */
@@ -141,20 +148,14 @@ struct sensor_data {
141#define AUTOGAIN_IGNORE_FRAMES 1 148#define AUTOGAIN_IGNORE_FRAMES 1
142 149
143/* V4L2 controls supported by the driver */ 150/* V4L2 controls supported by the driver */
144static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 151static void setbrightness(struct gspca_dev *gspca_dev);
145static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 152static void setgain(struct gspca_dev *gspca_dev);
146static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 153static void setexposure(struct gspca_dev *gspca_dev);
147static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
148static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
149static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
150static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 154static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
151static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 155static void setfreq(struct gspca_dev *gspca_dev);
152static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
153static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
154 156
155static const struct ctrl sd_ctrls[] = { 157static const struct ctrl sd_ctrls[NCTRLS] = {
156#define BRIGHTNESS_IDX 0 158[BRIGHTNESS] = {
157 {
158 { 159 {
159 .id = V4L2_CID_BRIGHTNESS, 160 .id = V4L2_CID_BRIGHTNESS,
160 .type = V4L2_CTRL_TYPE_INTEGER, 161 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -162,14 +163,11 @@ static const struct ctrl sd_ctrls[] = {
162 .minimum = 0, 163 .minimum = 0,
163 .maximum = 255, 164 .maximum = 255,
164 .step = 1, 165 .step = 1,
165#define BRIGHTNESS_DEF 127 166 .default_value = 127,
166 .default_value = BRIGHTNESS_DEF,
167 }, 167 },
168 .set = sd_setbrightness, 168 .set_control = setbrightness
169 .get = sd_getbrightness,
170 }, 169 },
171#define GAIN_IDX 1 170[GAIN] = {
172 {
173 { 171 {
174 .id = V4L2_CID_GAIN, 172 .id = V4L2_CID_GAIN,
175 .type = V4L2_CTRL_TYPE_INTEGER, 173 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -177,48 +175,31 @@ static const struct ctrl sd_ctrls[] = {
177 .minimum = 0, 175 .minimum = 0,
178 .maximum = 255, 176 .maximum = 255,
179 .step = 1, 177 .step = 1,
180#define GAIN_DEF 127
181#define GAIN_KNEE 230 178#define GAIN_KNEE 230
182 .default_value = GAIN_DEF, 179 .default_value = 127,
183 }, 180 },
184 .set = sd_setgain, 181 .set_control = setgain
185 .get = sd_getgain,
186 }, 182 },
187#define EXPOSURE_IDX 2 183[EXPOSURE] = {
188 {
189 { 184 {
190 .id = V4L2_CID_EXPOSURE, 185 .id = V4L2_CID_EXPOSURE,
191 .type = V4L2_CTRL_TYPE_INTEGER, 186 .type = V4L2_CTRL_TYPE_INTEGER,
192 .name = "Exposure", 187 .name = "Exposure",
193#define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */
194#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
195 .minimum = 0, 188 .minimum = 0,
196 .maximum = 1023, 189 .maximum = 1023,
197 .step = 1, 190 .step = 1,
198 .default_value = EXPOSURE_DEF, 191 .default_value = 66,
192 /* 33 ms / 30 fps (except on PASXXX) */
193#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
199 .flags = 0, 194 .flags = 0,
200 }, 195 },
201 .set = sd_setexposure, 196 .set_control = setexposure
202 .get = sd_getexposure,
203 }, 197 },
204#define COARSE_EXPOSURE_IDX 3 198/* for coarse exposure */
205 { 199#define COARSE_EXPOSURE_MIN 2
206 { 200#define COARSE_EXPOSURE_MAX 15
207 .id = V4L2_CID_EXPOSURE,
208 .type = V4L2_CTRL_TYPE_INTEGER,
209 .name = "Exposure",
210#define COARSE_EXPOSURE_DEF 2 /* 30 fps */ 201#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
211 .minimum = 2, 202[AUTOGAIN] = {
212 .maximum = 15,
213 .step = 1,
214 .default_value = COARSE_EXPOSURE_DEF,
215 .flags = 0,
216 },
217 .set = sd_setexposure,
218 .get = sd_getexposure,
219 },
220#define AUTOGAIN_IDX 4
221 {
222 { 203 {
223 .id = V4L2_CID_AUTOGAIN, 204 .id = V4L2_CID_AUTOGAIN,
224 .type = V4L2_CTRL_TYPE_BOOLEAN, 205 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -228,13 +209,11 @@ static const struct ctrl sd_ctrls[] = {
228 .step = 1, 209 .step = 1,
229#define AUTOGAIN_DEF 1 210#define AUTOGAIN_DEF 1
230 .default_value = AUTOGAIN_DEF, 211 .default_value = AUTOGAIN_DEF,
231 .flags = 0, 212 .flags = V4L2_CTRL_FLAG_UPDATE
232 }, 213 },
233 .set = sd_setautogain, 214 .set = sd_setautogain,
234 .get = sd_getautogain,
235 }, 215 },
236#define FREQ_IDX 5 216[FREQ] = {
237 {
238 { 217 {
239 .id = V4L2_CID_POWER_LINE_FREQUENCY, 218 .id = V4L2_CID_POWER_LINE_FREQUENCY,
240 .type = V4L2_CTRL_TYPE_MENU, 219 .type = V4L2_CTRL_TYPE_MENU,
@@ -245,8 +224,7 @@ static const struct ctrl sd_ctrls[] = {
245#define FREQ_DEF 0 224#define FREQ_DEF 0
246 .default_value = FREQ_DEF, 225 .default_value = FREQ_DEF,
247 }, 226 },
248 .set = sd_setfreq, 227 .set_control = setfreq
249 .get = sd_getfreq,
250 }, 228 },
251}; 229};
252 230
@@ -553,7 +531,7 @@ static const __u8 tas5130_sensor_init[][8] = {
553 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, 531 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
554}; 532};
555 533
556static struct sensor_data sensor_data[] = { 534static const struct sensor_data sensor_data[] = {
557SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), 535SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
558SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), 536SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
559SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60), 537SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60),
@@ -646,7 +624,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
646 624
647 /* change reg 0x06 */ 625 /* change reg 0x06 */
648 i2cOV[1] = sensor_data[sd->sensor].sensor_addr; 626 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
649 i2cOV[3] = sd->brightness; 627 i2cOV[3] = sd->ctrls[BRIGHTNESS].val;
650 if (i2c_w(gspca_dev, i2cOV) < 0) 628 if (i2c_w(gspca_dev, i2cOV) < 0)
651 goto err; 629 goto err;
652 break; 630 break;
@@ -664,13 +642,13 @@ static void setbrightness(struct gspca_dev *gspca_dev)
664 i2cpdoit[2] = 0x13; 642 i2cpdoit[2] = 0x13;
665 } 643 }
666 644
667 if (sd->brightness < 127) { 645 if (sd->ctrls[BRIGHTNESS].val < 127) {
668 /* change reg 0x0b, signreg */ 646 /* change reg 0x0b, signreg */
669 i2cpbright[3] = 0x01; 647 i2cpbright[3] = 0x01;
670 /* set reg 0x0c, offset */ 648 /* set reg 0x0c, offset */
671 i2cpbright[4] = 127 - sd->brightness; 649 i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val;
672 } else 650 } else
673 i2cpbright[4] = sd->brightness - 127; 651 i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127;
674 652
675 if (i2c_w(gspca_dev, i2cpbright) < 0) 653 if (i2c_w(gspca_dev, i2cpbright) < 0)
676 goto err; 654 goto err;
@@ -687,16 +665,16 @@ err:
687static void setsensorgain(struct gspca_dev *gspca_dev) 665static void setsensorgain(struct gspca_dev *gspca_dev)
688{ 666{
689 struct sd *sd = (struct sd *) gspca_dev; 667 struct sd *sd = (struct sd *) gspca_dev;
690 unsigned char gain = sd->gain; 668 u8 gain = sd->ctrls[GAIN].val;
691 669
692 switch (sd->sensor) { 670 switch (sd->sensor) {
693 case SENSOR_HV7131D: { 671 case SENSOR_HV7131D: {
694 __u8 i2c[] = 672 __u8 i2c[] =
695 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; 673 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
696 674
697 i2c[3] = 0x3f - (sd->gain / 4); 675 i2c[3] = 0x3f - (gain / 4);
698 i2c[4] = 0x3f - (sd->gain / 4); 676 i2c[4] = 0x3f - (gain / 4);
699 i2c[5] = 0x3f - (sd->gain / 4); 677 i2c[5] = 0x3f - (gain / 4);
700 678
701 if (i2c_w(gspca_dev, i2c) < 0) 679 if (i2c_w(gspca_dev, i2c) < 0)
702 goto err; 680 goto err;
@@ -759,11 +737,11 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
759 i2cpdoit[2] = 0x13; 737 i2cpdoit[2] = 0x13;
760 } 738 }
761 739
762 i2cpgain[3] = sd->gain >> 3; 740 i2cpgain[3] = gain >> 3;
763 i2cpcolorgain[3] = sd->gain >> 4; 741 i2cpcolorgain[3] = gain >> 4;
764 i2cpcolorgain[4] = sd->gain >> 4; 742 i2cpcolorgain[4] = gain >> 4;
765 i2cpcolorgain[5] = sd->gain >> 4; 743 i2cpcolorgain[5] = gain >> 4;
766 i2cpcolorgain[6] = sd->gain >> 4; 744 i2cpcolorgain[6] = gain >> 4;
767 745
768 if (i2c_w(gspca_dev, i2cpgain) < 0) 746 if (i2c_w(gspca_dev, i2cpgain) < 0)
769 goto err; 747 goto err;
@@ -792,13 +770,13 @@ static void setgain(struct gspca_dev *gspca_dev)
792 } 770 }
793 771
794 if (sd->bridge == BRIDGE_103) { 772 if (sd->bridge == BRIDGE_103) {
795 gain = sd->gain >> 1; 773 gain = sd->ctrls[GAIN].val >> 1;
796 buf[0] = gain; /* Red */ 774 buf[0] = gain; /* Red */
797 buf[1] = gain; /* Green */ 775 buf[1] = gain; /* Green */
798 buf[2] = gain; /* Blue */ 776 buf[2] = gain; /* Blue */
799 reg_w(gspca_dev, 0x05, buf, 3); 777 reg_w(gspca_dev, 0x05, buf, 3);
800 } else { 778 } else {
801 gain = sd->gain >> 4; 779 gain = sd->ctrls[GAIN].val >> 4;
802 buf[0] = gain << 4 | gain; /* Red and blue */ 780 buf[0] = gain << 4 | gain; /* Red and blue */
803 buf[1] = gain; /* Green */ 781 buf[1] = gain; /* Green */
804 reg_w(gspca_dev, 0x10, buf, 2); 782 reg_w(gspca_dev, 0x10, buf, 2);
@@ -820,7 +798,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
820 where the framerate starts dropping 798 where the framerate starts dropping
821 2) At 6138 the framerate has already dropped to 2 fps, 799 2) At 6138 the framerate has already dropped to 2 fps,
822 going any lower makes little sense */ 800 going any lower makes little sense */
823 __u16 reg = sd->exposure * 6; 801 u16 reg = sd->ctrls[EXPOSURE].val * 6;
802
824 i2c[3] = reg >> 8; 803 i2c[3] = reg >> 8;
825 i2c[4] = reg & 0xff; 804 i2c[4] = reg & 0xff;
826 if (i2c_w(gspca_dev, i2c) != 0) 805 if (i2c_w(gspca_dev, i2c) != 0)
@@ -832,7 +811,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
832 /* register 19's high nibble contains the sn9c10x clock divider 811 /* register 19's high nibble contains the sn9c10x clock divider
833 The high nibble configures the no fps according to the 812 The high nibble configures the no fps according to the
834 formula: 60 / high_nibble. With a maximum of 30 fps */ 813 formula: 60 / high_nibble. With a maximum of 30 fps */
835 __u8 reg = sd->exposure; 814 u8 reg = sd->ctrls[EXPOSURE].val;
815
836 reg = (reg << 4) | 0x0b; 816 reg = (reg << 4) | 0x0b;
837 reg_w(gspca_dev, 0x19, &reg, 1); 817 reg_w(gspca_dev, 0x19, &reg, 1);
838 break; 818 break;
@@ -868,7 +848,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
868 } else 848 } else
869 reg10_max = 0x41; 849 reg10_max = 0x41;
870 850
871 reg11 = (15 * sd->exposure + 999) / 1000; 851 reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000;
872 if (reg11 < 1) 852 if (reg11 < 1)
873 reg11 = 1; 853 reg11 = 1;
874 else if (reg11 > 16) 854 else if (reg11 > 16)
@@ -881,14 +861,16 @@ static void setexposure(struct gspca_dev *gspca_dev)
881 reg11 = 4; 861 reg11 = 4;
882 862
883 /* frame exposure time in ms = 1000 * reg11 / 30 -> 863 /* frame exposure time in ms = 1000 * reg11 / 30 ->
884 reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */ 864 reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max
885 reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11); 865 / (1000 * reg11 / 30) */
866 reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max)
867 / (1000 * reg11);
886 868
887 /* Don't allow this to get below 10 when using autogain, the 869 /* Don't allow this to get below 10 when using autogain, the
888 steps become very large (relatively) when below 10 causing 870 steps become very large (relatively) when below 10 causing
889 the image to oscilate from much too dark, to much too bright 871 the image to oscilate from much too dark, to much too bright
890 and back again. */ 872 and back again. */
891 if (sd->autogain && reg10 < 10) 873 if (sd->ctrls[AUTOGAIN].val && reg10 < 10)
892 reg10 = 10; 874 reg10 = 10;
893 else if (reg10 > reg10_max) 875 else if (reg10 > reg10_max)
894 reg10 = reg10_max; 876 reg10 = reg10_max;
@@ -927,15 +909,16 @@ static void setexposure(struct gspca_dev *gspca_dev)
927 frame exposure times (like we are doing with the ov chips), 909 frame exposure times (like we are doing with the ov chips),
928 as that sometimes leads to jumps in the exposure control, 910 as that sometimes leads to jumps in the exposure control,
929 which are bad for auto exposure. */ 911 which are bad for auto exposure. */
930 if (sd->exposure < 200) { 912 if (sd->ctrls[EXPOSURE].val < 200) {
931 i2cpexpo[3] = 255 - (sd->exposure * 255) / 200; 913 i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255)
914 / 200;
932 framerate_ctrl = 500; 915 framerate_ctrl = 500;
933 } else { 916 } else {
934 /* The PAS202's exposure control goes from 0 - 4095, 917 /* The PAS202's exposure control goes from 0 - 4095,
935 but anything below 500 causes vsync issues, so scale 918 but anything below 500 causes vsync issues, so scale
936 our 200-1023 to 500-4095 */ 919 our 200-1023 to 500-4095 */
937 framerate_ctrl = (sd->exposure - 200) * 1000 / 229 + 920 framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200)
938 500; 921 * 1000 / 229 + 500;
939 } 922 }
940 923
941 i2cpframerate[3] = framerate_ctrl >> 6; 924 i2cpframerate[3] = framerate_ctrl >> 6;
@@ -959,15 +942,15 @@ static void setexposure(struct gspca_dev *gspca_dev)
959 942
960 /* For values below 150 use partial frame exposure, above 943 /* For values below 150 use partial frame exposure, above
961 that use framerate ctrl */ 944 that use framerate ctrl */
962 if (sd->exposure < 150) { 945 if (sd->ctrls[EXPOSURE].val < 150) {
963 i2cpexpo[3] = 150 - sd->exposure; 946 i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val;
964 framerate_ctrl = 300; 947 framerate_ctrl = 300;
965 } else { 948 } else {
966 /* The PAS106's exposure control goes from 0 - 4095, 949 /* The PAS106's exposure control goes from 0 - 4095,
967 but anything below 300 causes vsync issues, so scale 950 but anything below 300 causes vsync issues, so scale
968 our 150-1023 to 300-4095 */ 951 our 150-1023 to 300-4095 */
969 framerate_ctrl = (sd->exposure - 150) * 1000 / 230 + 952 framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150)
970 300; 953 * 1000 / 230 + 300;
971 } 954 }
972 955
973 i2cpframerate[3] = framerate_ctrl >> 4; 956 i2cpframerate[3] = framerate_ctrl >> 4;
@@ -998,7 +981,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
998 0x2b register, see ov6630 datasheet. 981 0x2b register, see ov6630 datasheet.
999 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ 982 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
1000 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; 983 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
1001 switch (sd->freq) { 984 switch (sd->ctrls[FREQ].val) {
1002 default: 985 default:
1003/* case 0: * no filter*/ 986/* case 0: * no filter*/
1004/* case 2: * 60 hz */ 987/* case 2: * 60 hz */
@@ -1017,7 +1000,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
1017 } 1000 }
1018} 1001}
1019 1002
1020#include "coarse_expo_autogain.h" 1003#include "autogain_functions.h"
1021 1004
1022static void do_autogain(struct gspca_dev *gspca_dev) 1005static void do_autogain(struct gspca_dev *gspca_dev)
1023{ 1006{
@@ -1025,7 +1008,8 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1025 struct sd *sd = (struct sd *) gspca_dev; 1008 struct sd *sd = (struct sd *) gspca_dev;
1026 int avg_lum = atomic_read(&sd->avg_lum); 1009 int avg_lum = atomic_read(&sd->avg_lum);
1027 1010
1028 if (avg_lum == -1 || !sd->autogain) 1011 if ((gspca_dev->ctrl_dis & (1 << AUTOGAIN)) ||
1012 avg_lum == -1 || !sd->ctrls[AUTOGAIN].val)
1029 return; 1013 return;
1030 1014
1031 if (sd->autogain_ignore_frames > 0) { 1015 if (sd->autogain_ignore_frames > 0) {
@@ -1045,17 +1029,20 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1045 } 1029 }
1046 1030
1047 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) 1031 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
1048 result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, 1032 result = coarse_grained_expo_autogain(gspca_dev, avg_lum,
1049 sd->brightness * desired_avg_lum / 127, 1033 sd->ctrls[BRIGHTNESS].val
1034 * desired_avg_lum / 127,
1050 deadzone); 1035 deadzone);
1051 else 1036 else
1052 result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 1037 result = auto_gain_n_exposure(gspca_dev, avg_lum,
1053 sd->brightness * desired_avg_lum / 127, 1038 sd->ctrls[BRIGHTNESS].val
1039 * desired_avg_lum / 127,
1054 deadzone, GAIN_KNEE, EXPOSURE_KNEE); 1040 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1055 1041
1056 if (result) { 1042 if (result) {
1057 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", 1043 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
1058 (int)sd->gain, (int)sd->exposure); 1044 (int) sd->ctrls[GAIN].val,
1045 (int) sd->ctrls[EXPOSURE].val);
1059 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1046 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1060 } 1047 }
1061} 1048}
@@ -1074,9 +1061,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
1074 /* copy the webcam info from the device id */ 1061 /* copy the webcam info from the device id */
1075 sd->sensor = id->driver_info >> 8; 1062 sd->sensor = id->driver_info >> 8;
1076 sd->bridge = id->driver_info & 0xff; 1063 sd->bridge = id->driver_info & 0xff;
1064
1077 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; 1065 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
1066#if AUTOGAIN_DEF
1067 if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1068 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1069#endif
1078 1070
1079 cam = &gspca_dev->cam; 1071 cam = &gspca_dev->cam;
1072 cam->ctrls = sd->ctrls;
1080 if (!(sensor_data[sd->sensor].flags & F_SIF)) { 1073 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
1081 cam->cam_mode = vga_mode; 1074 cam->cam_mode = vga_mode;
1082 cam->nmodes = ARRAY_SIZE(vga_mode); 1075 cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1086,20 +1079,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
1086 } 1079 }
1087 cam->npkt = 36; /* 36 packets per ISOC message */ 1080 cam->npkt = 36; /* 36 packets per ISOC message */
1088 1081
1089 sd->brightness = BRIGHTNESS_DEF;
1090 sd->gain = GAIN_DEF;
1091 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { 1082 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1092 sd->exposure = COARSE_EXPOSURE_DEF; 1083 sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN;
1093 gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX); 1084 sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX;
1094 } else { 1085 sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF;
1095 sd->exposure = EXPOSURE_DEF;
1096 gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
1097 } 1086 }
1098 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1099 sd->autogain = 0; /* Disable do_autogain callback */
1100 else
1101 sd->autogain = AUTOGAIN_DEF;
1102 sd->freq = FREQ_DEF;
1103 1087
1104 return 0; 1088 return 0;
1105} 1089}
@@ -1398,65 +1382,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1398 } 1382 }
1399} 1383}
1400 1384
1401static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1402{
1403 struct sd *sd = (struct sd *) gspca_dev;
1404
1405 sd->brightness = val;
1406 if (gspca_dev->streaming)
1407 setbrightness(gspca_dev);
1408 return 0;
1409}
1410
1411static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1412{
1413 struct sd *sd = (struct sd *) gspca_dev;
1414
1415 *val = sd->brightness;
1416 return 0;
1417}
1418
1419static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1420{
1421 struct sd *sd = (struct sd *) gspca_dev;
1422
1423 sd->gain = val;
1424 if (gspca_dev->streaming)
1425 setgain(gspca_dev);
1426 return 0;
1427}
1428
1429static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1430{
1431 struct sd *sd = (struct sd *) gspca_dev;
1432
1433 *val = sd->gain;
1434 return 0;
1435}
1436
1437static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1438{
1439 struct sd *sd = (struct sd *) gspca_dev;
1440
1441 sd->exposure = val;
1442 if (gspca_dev->streaming)
1443 setexposure(gspca_dev);
1444 return 0;
1445}
1446
1447static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1448{
1449 struct sd *sd = (struct sd *) gspca_dev;
1450
1451 *val = sd->exposure;
1452 return 0;
1453}
1454
1455static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 1385static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1456{ 1386{
1457 struct sd *sd = (struct sd *) gspca_dev; 1387 struct sd *sd = (struct sd *) gspca_dev;
1458 1388
1459 sd->autogain = val; 1389 sd->ctrls[AUTOGAIN].val = val;
1460 sd->exp_too_high_cnt = 0; 1390 sd->exp_too_high_cnt = 0;
1461 sd->exp_too_low_cnt = 0; 1391 sd->exp_too_low_cnt = 0;
1462 1392
@@ -1464,9 +1394,10 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1464 we are on a valid point of the autogain gain / 1394 we are on a valid point of the autogain gain /
1465 exposure knee graph, and give this change time to 1395 exposure knee graph, and give this change time to
1466 take effect before doing autogain. */ 1396 take effect before doing autogain. */
1467 if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) { 1397 if (sd->ctrls[AUTOGAIN].val
1468 sd->exposure = EXPOSURE_DEF; 1398 && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1469 sd->gain = GAIN_DEF; 1399 sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def;
1400 sd->ctrls[GAIN].val = sd->ctrls[GAIN].def;
1470 if (gspca_dev->streaming) { 1401 if (gspca_dev->streaming) {
1471 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1402 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1472 setexposure(gspca_dev); 1403 setexposure(gspca_dev);
@@ -1474,32 +1405,11 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1474 } 1405 }
1475 } 1406 }
1476 1407
1477 return 0; 1408 if (sd->ctrls[AUTOGAIN].val)
1478} 1409 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1479 1410 else
1480static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1411 gspca_dev->ctrl_inac = 0;
1481{
1482 struct sd *sd = (struct sd *) gspca_dev;
1483
1484 *val = sd->autogain;
1485 return 0;
1486}
1487
1488static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1489{
1490 struct sd *sd = (struct sd *) gspca_dev;
1491
1492 sd->freq = val;
1493 if (gspca_dev->streaming)
1494 setfreq(gspca_dev);
1495 return 0;
1496}
1497
1498static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1499{
1500 struct sd *sd = (struct sd *) gspca_dev;
1501 1412
1502 *val = sd->freq;
1503 return 0; 1413 return 0;
1504} 1414}
1505 1415
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index d6f39ce1b7e1..6415aff5cbd1 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -29,8 +29,6 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
29MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); 29MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31 31
32static int starcam;
33
34/* controls */ 32/* controls */
35enum e_ctrl { 33enum e_ctrl {
36 BRIGHTNESS, 34 BRIGHTNESS,
@@ -57,11 +55,18 @@ struct sd {
57 atomic_t avg_lum; 55 atomic_t avg_lum;
58 u32 exposure; 56 u32 exposure;
59 57
58 struct work_struct work;
59 struct workqueue_struct *work_thread;
60
61 u32 pktsz; /* (used by pkt_scan) */
62 u16 npkt;
63 u8 nchg;
64 s8 short_mark;
65
60 u8 quality; /* image quality */ 66 u8 quality; /* image quality */
61#define QUALITY_MIN 60 67#define QUALITY_MIN 25
62#define QUALITY_MAX 95 68#define QUALITY_MAX 90
63#define QUALITY_DEF 80 69#define QUALITY_DEF 70
64 u8 jpegqual; /* webcam quality */
65 70
66 u8 reg01; 71 u8 reg01;
67 u8 reg17; 72 u8 reg17;
@@ -99,6 +104,8 @@ enum sensors {
99 SENSOR_SP80708, 104 SENSOR_SP80708,
100}; 105};
101 106
107static void qual_upd(struct work_struct *work);
108
102/* device flags */ 109/* device flags */
103#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */ 110#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
104#define F_ILLUM 0x02 /* presence of illuminator */ 111#define F_ILLUM 0x02 /* presence of illuminator */
@@ -401,7 +408,7 @@ static const u8 sn_hv7131[0x1c] = {
401 408
402static const u8 sn_mi0360[0x1c] = { 409static const u8 sn_mi0360[0x1c] = {
403/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 410/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
404 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 411 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
405/* reg8 reg9 rega regb regc regd rege regf */ 412/* reg8 reg9 rega regb regc regd rege regf */
406 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 413 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 414/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
@@ -847,18 +854,8 @@ static const u8 mt9v111_sensor_init[][8] = {
847 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ 854 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
848 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ 855 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
849 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ 856 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
850 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
851 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
852 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
853 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
854 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ 857 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
855 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
856 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
857 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
858 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
859 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
860 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ 858 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
861 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
862 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ 859 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
863 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ 860 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
864 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ 861 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
@@ -872,15 +869,10 @@ static const u8 mt9v111_sensor_init[][8] = {
872 {} 869 {}
873}; 870};
874static const u8 mt9v111_sensor_param1[][8] = { 871static const u8 mt9v111_sensor_param1[][8] = {
875 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 872 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
876 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 873 {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
877 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, 874 {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
878 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */ 875 {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
879 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
880 /*******/
881 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
882 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
883 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
884 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ 876 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
885 {} 877 {}
886}; 878};
@@ -1784,7 +1776,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
1784 1776
1785 sd->ag_cnt = -1; 1777 sd->ag_cnt = -1;
1786 sd->quality = QUALITY_DEF; 1778 sd->quality = QUALITY_DEF;
1787 sd->jpegqual = 80; 1779
1780 /* if USB 1.1, let some bandwidth for the audio device */
1781 if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
1782 gspca_dev->nbalt--;
1783
1784 INIT_WORK(&sd->work, qual_upd);
1788 1785
1789 return 0; 1786 return 0;
1790} 1787}
@@ -1794,7 +1791,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1794{ 1791{
1795 struct sd *sd = (struct sd *) gspca_dev; 1792 struct sd *sd = (struct sd *) gspca_dev;
1796 const u8 *sn9c1xx; 1793 const u8 *sn9c1xx;
1797 u8 regGpio[] = { 0x29, 0x74 }; /* with audio */ 1794 u8 regGpio[] = { 0x29, 0x70 }; /* no audio */
1798 u8 regF1; 1795 u8 regF1;
1799 1796
1800 /* setup a selector by bridge */ 1797 /* setup a selector by bridge */
@@ -1806,6 +1803,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
1806 if (gspca_dev->usb_err < 0) 1803 if (gspca_dev->usb_err < 0)
1807 return gspca_dev->usb_err; 1804 return gspca_dev->usb_err;
1808 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); 1805 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1806 if (gspca_dev->audio)
1807 regGpio[1] |= 0x04; /* with audio */
1809 switch (sd->bridge) { 1808 switch (sd->bridge) {
1810 case BRIDGE_SN9C102P: 1809 case BRIDGE_SN9C102P:
1811 case BRIDGE_SN9C105: 1810 case BRIDGE_SN9C105:
@@ -1838,14 +1837,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1838 case BRIDGE_SN9C102P: 1837 case BRIDGE_SN9C102P:
1839 reg_w1(gspca_dev, 0x02, regGpio[1]); 1838 reg_w1(gspca_dev, 0x02, regGpio[1]);
1840 break; 1839 break;
1841 case BRIDGE_SN9C105: 1840 default:
1842 reg_w(gspca_dev, 0x01, regGpio, 2);
1843 break;
1844 case BRIDGE_SN9C110:
1845 reg_w1(gspca_dev, 0x02, 0x62);
1846 break;
1847 case BRIDGE_SN9C120:
1848 regGpio[1] = 0x70; /* no audio */
1849 reg_w(gspca_dev, 0x01, regGpio, 2); 1841 reg_w(gspca_dev, 0x01, regGpio, 2);
1850 break; 1842 break;
1851 } 1843 }
@@ -1944,10 +1936,10 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1944 u8 expo_c1[] = 1936 u8 expo_c1[] =
1945 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 }; 1937 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1946 1938
1947 if (expo > 0x0280) 1939 if (expo > 0x0390)
1948 expo = 0x0280; 1940 expo = 0x0390;
1949 else if (expo < 0x0040) 1941 else if (expo < 0x0060)
1950 expo = 0x0040; 1942 expo = 0x0060;
1951 expo_c1[3] = expo >> 8; 1943 expo_c1[3] = expo >> 8;
1952 expo_c1[4] = expo; 1944 expo_c1[4] = expo;
1953 i2c_w8(gspca_dev, expo_c1); 1945 i2c_w8(gspca_dev, expo_c1);
@@ -2004,10 +1996,13 @@ static void setbrightness(struct gspca_dev *gspca_dev)
2004 sd->exposure = setexposure(gspca_dev, expo); 1996 sd->exposure = setexposure(gspca_dev, expo);
2005 break; 1997 break;
2006 case SENSOR_GC0307: 1998 case SENSOR_GC0307:
2007 case SENSOR_MT9V111:
2008 expo = brightness; 1999 expo = brightness;
2009 sd->exposure = setexposure(gspca_dev, expo); 2000 sd->exposure = setexposure(gspca_dev, expo);
2010 return; /* don't set the Y offset */ 2001 return; /* don't set the Y offset */
2002 case SENSOR_MT9V111:
2003 expo = brightness << 2;
2004 sd->exposure = setexposure(gspca_dev, expo);
2005 return; /* don't set the Y offset */
2011 case SENSOR_OM6802: 2006 case SENSOR_OM6802:
2012 expo = brightness << 2; 2007 expo = brightness << 2;
2013 sd->exposure = setexposure(gspca_dev, expo); 2008 sd->exposure = setexposure(gspca_dev, expo);
@@ -2199,14 +2194,11 @@ static void setillum(struct gspca_dev *gspca_dev)
2199 sd->ctrls[ILLUM].val ? 0x64 : 0x60); 2194 sd->ctrls[ILLUM].val ? 0x64 : 0x60);
2200 break; 2195 break;
2201 case SENSOR_MT9V111: 2196 case SENSOR_MT9V111:
2202 if (starcam) 2197 reg_w1(gspca_dev, 0x02,
2203 reg_w1(gspca_dev, 0x02, 2198 sd->ctrls[ILLUM].val ? 0x77 : 0x74);
2204 sd->ctrls[ILLUM].val ? 2199/* should have been: */
2205 0x55 : 0x54); /* 370i */ 2200/* 0x55 : 0x54); * 370i */
2206 else 2201/* 0x66 : 0x64); * Clip */
2207 reg_w1(gspca_dev, 0x02,
2208 sd->ctrls[ILLUM].val ?
2209 0x66 : 0x64); /* Clip */
2210 break; 2202 break;
2211 } 2203 }
2212} 2204}
@@ -2271,18 +2263,12 @@ static void setfreq(struct gspca_dev *gspca_dev)
2271static void setjpegqual(struct gspca_dev *gspca_dev) 2263static void setjpegqual(struct gspca_dev *gspca_dev)
2272{ 2264{
2273 struct sd *sd = (struct sd *) gspca_dev; 2265 struct sd *sd = (struct sd *) gspca_dev;
2274 int i, sc;
2275 2266
2276 if (sd->jpegqual < 50) 2267 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2277 sc = 5000 / sd->jpegqual;
2278 else
2279 sc = 200 - sd->jpegqual * 2;
2280#if USB_BUF_SZ < 64 2268#if USB_BUF_SZ < 64
2281#error "No room enough in usb_buf for quantization table" 2269#error "No room enough in usb_buf for quantization table"
2282#endif 2270#endif
2283 for (i = 0; i < 64; i++) 2271 memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2284 gspca_dev->usb_buf[i] =
2285 (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
2286 usb_control_msg(gspca_dev->dev, 2272 usb_control_msg(gspca_dev->dev,
2287 usb_sndctrlpipe(gspca_dev->dev, 0), 2273 usb_sndctrlpipe(gspca_dev->dev, 0),
2288 0x08, 2274 0x08,
@@ -2290,9 +2276,7 @@ static void setjpegqual(struct gspca_dev *gspca_dev)
2290 0x0100, 0, 2276 0x0100, 0,
2291 gspca_dev->usb_buf, 64, 2277 gspca_dev->usb_buf, 64,
2292 500); 2278 500);
2293 for (i = 0; i < 64; i++) 2279 memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2294 gspca_dev->usb_buf[i] =
2295 (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
2296 usb_control_msg(gspca_dev->dev, 2280 usb_control_msg(gspca_dev->dev,
2297 usb_sndctrlpipe(gspca_dev->dev, 0), 2281 usb_sndctrlpipe(gspca_dev->dev, 0),
2298 0x08, 2282 0x08,
@@ -2305,6 +2289,19 @@ static void setjpegqual(struct gspca_dev *gspca_dev)
2305 reg_w1(gspca_dev, 0x18, sd->reg18); 2289 reg_w1(gspca_dev, 0x18, sd->reg18);
2306} 2290}
2307 2291
2292/* JPEG quality update */
2293/* This function is executed from a work queue. */
2294static void qual_upd(struct work_struct *work)
2295{
2296 struct sd *sd = container_of(work, struct sd, work);
2297 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2298
2299 mutex_lock(&gspca_dev->usb_lock);
2300 PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
2301 setjpegqual(gspca_dev);
2302 mutex_unlock(&gspca_dev->usb_lock);
2303}
2304
2308/* -- start the camera -- */ 2305/* -- start the camera -- */
2309static int sd_start(struct gspca_dev *gspca_dev) 2306static int sd_start(struct gspca_dev *gspca_dev)
2310{ 2307{
@@ -2338,7 +2335,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
2338 /* create the JPEG header */ 2335 /* create the JPEG header */
2339 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 2336 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2340 0x21); /* JPEG 422 */ 2337 0x21); /* JPEG 422 */
2341 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2342 2338
2343 /* initialize the bridge */ 2339 /* initialize the bridge */
2344 sn9c1xx = sn_tb[sd->sensor]; 2340 sn9c1xx = sn_tb[sd->sensor];
@@ -2619,6 +2615,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
2619 setcolors(gspca_dev); 2615 setcolors(gspca_dev);
2620 setautogain(gspca_dev); 2616 setautogain(gspca_dev);
2621 setfreq(gspca_dev); 2617 setfreq(gspca_dev);
2618
2619 sd->pktsz = sd->npkt = 0;
2620 sd->nchg = sd->short_mark = 0;
2621 sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
2622
2622 return gspca_dev->usb_err; 2623 return gspca_dev->usb_err;
2623} 2624}
2624 2625
@@ -2695,6 +2696,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2695 /* reg_w1(gspca_dev, 0xf1, 0x01); */ 2696 /* reg_w1(gspca_dev, 0xf1, 0x01); */
2696} 2697}
2697 2698
2699/* called on streamoff with alt==0 and on disconnect */
2700/* the usb_lock is held at entry - restore on exit */
2701static void sd_stop0(struct gspca_dev *gspca_dev)
2702{
2703 struct sd *sd = (struct sd *) gspca_dev;
2704
2705 if (sd->work_thread != NULL) {
2706 mutex_unlock(&gspca_dev->usb_lock);
2707 destroy_workqueue(sd->work_thread);
2708 mutex_lock(&gspca_dev->usb_lock);
2709 sd->work_thread = NULL;
2710 }
2711}
2712
2698static void do_autogain(struct gspca_dev *gspca_dev) 2713static void do_autogain(struct gspca_dev *gspca_dev)
2699{ 2714{
2700 struct sd *sd = (struct sd *) gspca_dev; 2715 struct sd *sd = (struct sd *) gspca_dev;
@@ -2732,6 +2747,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2732 (unsigned int) (expotimes << 8)); 2747 (unsigned int) (expotimes << 8));
2733 break; 2748 break;
2734 case SENSOR_OM6802: 2749 case SENSOR_OM6802:
2750 case SENSOR_MT9V111:
2735 expotimes = sd->exposure; 2751 expotimes = sd->exposure;
2736 expotimes += (luma_mean - delta) >> 2; 2752 expotimes += (luma_mean - delta) >> 2;
2737 if (expotimes < 0) 2753 if (expotimes < 0)
@@ -2744,7 +2760,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2744/* case SENSOR_MO4000: */ 2760/* case SENSOR_MO4000: */
2745/* case SENSOR_MI0360: */ 2761/* case SENSOR_MI0360: */
2746/* case SENSOR_MI0360B: */ 2762/* case SENSOR_MI0360B: */
2747/* case SENSOR_MT9V111: */
2748 expotimes = sd->exposure; 2763 expotimes = sd->exposure;
2749 expotimes += (luma_mean - delta) >> 6; 2764 expotimes += (luma_mean - delta) >> 6;
2750 if (expotimes < 0) 2765 if (expotimes < 0)
@@ -2757,6 +2772,29 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2757 } 2772 }
2758} 2773}
2759 2774
2775/* set the average luminosity from an isoc marker */
2776static void set_lum(struct sd *sd,
2777 u8 *data)
2778{
2779 int avg_lum;
2780
2781 /* w0 w1 w2
2782 * w3 w4 w5
2783 * w6 w7 w8
2784 */
2785 avg_lum = (data[27] << 8) + data[28] /* w3 */
2786
2787 + (data[31] << 8) + data[32] /* w5 */
2788
2789 + (data[23] << 8) + data[24] /* w1 */
2790
2791 + (data[35] << 8) + data[36] /* w7 */
2792
2793 + (data[29] << 10) + (data[30] << 2); /* w4 * 4 */
2794 avg_lum >>= 10;
2795 atomic_set(&sd->avg_lum, avg_lum);
2796}
2797
2760/* scan the URB packets */ 2798/* scan the URB packets */
2761/* This function is run at interrupt level. */ 2799/* This function is run at interrupt level. */
2762static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2800static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -2764,70 +2802,141 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2764 int len) /* iso packet length */ 2802 int len) /* iso packet length */
2765{ 2803{
2766 struct sd *sd = (struct sd *) gspca_dev; 2804 struct sd *sd = (struct sd *) gspca_dev;
2767 int sof, avg_lum; 2805 int i, new_qual;
2768 2806
2769 /* the image ends on a 64 bytes block starting with 2807 /*
2770 * ff d9 ff ff 00 c4 c4 96 2808 * A frame ends on the marker
2771 * and followed by various information including luminosity */ 2809 * ff ff 00 c4 c4 96 ..
2772 /* this block may be splitted between two packets */ 2810 * which is 62 bytes long and is followed by various information
2773 /* a new image always starts in a new packet */ 2811 * including statuses and luminosity.
2774 switch (gspca_dev->last_packet_type) { 2812 *
2775 case DISCARD_PACKET: /* restart image building */ 2813 * A marker may be splitted on two packets.
2776 sof = len - 64; 2814 *
2777 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) 2815 * The 6th byte of a marker contains the bits:
2778 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2816 * 0x08: USB full
2779 return; 2817 * 0xc0: frame sequence
2780 case LAST_PACKET: /* put the JPEG 422 header */ 2818 * When the bit 'USB full' is set, the frame must be discarded;
2819 * this is also the case when the 2 bytes before the marker are
2820 * not the JPEG end of frame ('ff d9').
2821 */
2822
2823/*fixme: assumption about the following code:
2824 * - there can be only one marker in a packet
2825 */
2826
2827 /* skip the remaining bytes of a short marker */
2828 i = sd->short_mark;
2829 if (i != 0) {
2830 sd->short_mark = 0;
2831 if (i < 0 /* if 'ff' at end of previous packet */
2832 && data[0] == 0xff
2833 && data[1] == 0x00)
2834 goto marker_found;
2835 if (data[0] == 0xff && data[1] == 0xff) {
2836 i = 0;
2837 goto marker_found;
2838 }
2839 len -= i;
2840 if (len <= 0)
2841 return;
2842 data += i;
2843 }
2844
2845 /* count the packets and their size */
2846 sd->npkt++;
2847 sd->pktsz += len;
2848
2849 /* search backwards if there is a marker in the packet */
2850 for (i = len - 1; --i >= 0; ) {
2851 if (data[i] != 0xff) {
2852 i--;
2853 continue;
2854 }
2855 if (data[i + 1] == 0xff) {
2856
2857 /* (there may be 'ff ff' inside a marker) */
2858 if (i + 2 >= len || data[i + 2] == 0x00)
2859 goto marker_found;
2860 }
2861 }
2862
2863 /* no marker found */
2864 /* add the JPEG header if first fragment */
2865 if (data[len - 1] == 0xff)
2866 sd->short_mark = -1;
2867 if (gspca_dev->last_packet_type == LAST_PACKET)
2781 gspca_frame_add(gspca_dev, FIRST_PACKET, 2868 gspca_frame_add(gspca_dev, FIRST_PACKET,
2782 sd->jpeg_hdr, JPEG_HDR_SZ); 2869 sd->jpeg_hdr, JPEG_HDR_SZ);
2783 break;
2784 }
2785 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 2870 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2871 return;
2872
2873 /* marker found */
2874 /* if some error, discard the frame and decrease the quality */
2875marker_found:
2876 new_qual = 0;
2877 if (i > 2) {
2878 if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
2879 gspca_dev->last_packet_type = DISCARD_PACKET;
2880 new_qual = -3;
2881 }
2882 } else if (i + 6 < len) {
2883 if (data[i + 6] & 0x08) {
2884 gspca_dev->last_packet_type = DISCARD_PACKET;
2885 new_qual = -5;
2886 }
2887 }
2786 2888
2787 data = gspca_dev->image; 2889 gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
2788 if (data == NULL)
2789 return;
2790 sof = gspca_dev->image_len - 64;
2791 if (data[sof] != 0xff
2792 || data[sof + 1] != 0xd9)
2793 return;
2794 2890
2795 /* end of image found - remove the trailing data */ 2891 /* compute the filling rate and a new JPEG quality */
2796 gspca_dev->image_len = sof + 2; 2892 if (new_qual == 0) {
2797 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2893 int r;
2798 if (sd->ag_cnt < 0)
2799 return;
2800/* w1 w2 w3 */
2801/* w4 w5 w6 */
2802/* w7 w8 */
2803/* w4 */
2804 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2805/* w6 */
2806 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2807/* w2 */
2808 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2809/* w8 */
2810 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2811/* w5 */
2812 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2813 avg_lum >>= 4;
2814 atomic_set(&sd->avg_lum, avg_lum);
2815}
2816 2894
2817static int sd_set_jcomp(struct gspca_dev *gspca_dev, 2895 r = (sd->pktsz * 100) /
2818 struct v4l2_jpegcompression *jcomp) 2896 (sd->npkt *
2819{ 2897 gspca_dev->urb[0]->iso_frame_desc[0].length);
2820 struct sd *sd = (struct sd *) gspca_dev; 2898 if (r >= 85)
2899 new_qual = -3;
2900 else if (r < 75)
2901 new_qual = 2;
2902 }
2903 if (new_qual != 0) {
2904 sd->nchg += new_qual;
2905 if (sd->nchg < -6 || sd->nchg >= 12) {
2906 sd->nchg = 0;
2907 new_qual += sd->quality;
2908 if (new_qual < QUALITY_MIN)
2909 new_qual = QUALITY_MIN;
2910 else if (new_qual > QUALITY_MAX)
2911 new_qual = QUALITY_MAX;
2912 if (new_qual != sd->quality) {
2913 sd->quality = new_qual;
2914 queue_work(sd->work_thread, &sd->work);
2915 }
2916 }
2917 } else {
2918 sd->nchg = 0;
2919 }
2920 sd->pktsz = sd->npkt = 0;
2821 2921
2822 if (jcomp->quality < QUALITY_MIN) 2922 /* if the marker is smaller than 62 bytes,
2823 sd->quality = QUALITY_MIN; 2923 * memorize the number of bytes to skip in the next packet */
2824 else if (jcomp->quality > QUALITY_MAX) 2924 if (i + 62 > len) { /* no more usable data */
2825 sd->quality = QUALITY_MAX; 2925 sd->short_mark = i + 62 - len;
2826 else 2926 return;
2827 sd->quality = jcomp->quality; 2927 }
2828 if (gspca_dev->streaming) 2928 if (sd->ag_cnt >= 0)
2829 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 2929 set_lum(sd, data + i);
2830 return 0; 2930
2931 /* if more data, start a new frame */
2932 i += 62;
2933 if (i < len) {
2934 data += i;
2935 len -= i;
2936 gspca_frame_add(gspca_dev, FIRST_PACKET,
2937 sd->jpeg_hdr, JPEG_HDR_SZ);
2938 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2939 }
2831} 2940}
2832 2941
2833static int sd_get_jcomp(struct gspca_dev *gspca_dev, 2942static int sd_get_jcomp(struct gspca_dev *gspca_dev,
@@ -2891,10 +3000,10 @@ static const struct sd_desc sd_desc = {
2891 .init = sd_init, 3000 .init = sd_init,
2892 .start = sd_start, 3001 .start = sd_start,
2893 .stopN = sd_stopN, 3002 .stopN = sd_stopN,
3003 .stop0 = sd_stop0,
2894 .pkt_scan = sd_pkt_scan, 3004 .pkt_scan = sd_pkt_scan,
2895 .dq_callback = do_autogain, 3005 .dq_callback = do_autogain,
2896 .get_jcomp = sd_get_jcomp, 3006 .get_jcomp = sd_get_jcomp,
2897 .set_jcomp = sd_set_jcomp,
2898 .querymenu = sd_querymenu, 3007 .querymenu = sd_querymenu,
2899#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 3008#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2900 .int_pkt_scan = sd_int_pkt_scan, 3009 .int_pkt_scan = sd_int_pkt_scan,
@@ -3004,7 +3113,3 @@ static void __exit sd_mod_exit(void)
3004 3113
3005module_init(sd_mod_init); 3114module_init(sd_mod_init);
3006module_exit(sd_mod_exit); 3115module_exit(sd_mod_exit);
3007
3008module_param(starcam, int, 0644);
3009MODULE_PARM_DESC(starcam,
3010 "StarCam model. 0: Clip, 1: 370i");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 7e0661429293..abf1658fa33e 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -525,11 +525,9 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
525 const struct usb_device_id *id) 525 const struct usb_device_id *id)
526{ 526{
527 struct sd *sd = (struct sd *) gspca_dev; 527 struct sd *sd = (struct sd *) gspca_dev;
528 struct cam *cam;
529 528
530 PDEBUG(D_PROBE, "Configuring camera"); 529 PDEBUG(D_PROBE, "Configuring camera");
531 530
532 cam = &gspca_dev->cam;
533 sd->desc = sd_desc; 531 sd->desc = sd_desc;
534 sd->bridge = id->driver_info; 532 sd->bridge = id->driver_info;
535 gspca_dev->sd_desc = &sd->desc; 533 gspca_dev->sd_desc = &sd->desc;
diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/video/gspca/vicam.c
new file mode 100644
index 000000000000..84dfbab923b5
--- /dev/null
+++ b/drivers/media/video/gspca/vicam.c
@@ -0,0 +1,381 @@
1/*
2 * gspca ViCam subdriver
3 *
4 * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
5 *
6 * Based on the usbvideo vicam driver, which is:
7 *
8 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
9 * Christopher L Cheney (ccheney@cheney.cx),
10 * Pavel Machek (pavel@ucw.cz),
11 * John Tyner (jtyner@cs.ucr.edu),
12 * Monroe Williams (monroe@pobox.com)
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */
28
29#define MODULE_NAME "vicam"
30#define HEADER_SIZE 64
31
32#include <linux/workqueue.h>
33#include <linux/slab.h>
34#include <linux/firmware.h>
35#include <linux/ihex.h>
36#include "gspca.h"
37
38MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
39MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver");
40MODULE_LICENSE("GPL");
41
42enum e_ctrl {
43 GAIN,
44 EXPOSURE,
45 NCTRL /* number of controls */
46};
47
48struct sd {
49 struct gspca_dev gspca_dev; /* !! must be the first item */
50 struct work_struct work_struct;
51 struct workqueue_struct *work_thread;
52 struct gspca_ctrl ctrls[NCTRL];
53};
54
55/* The vicam sensor has a resolution of 512 x 244, with I believe square
56 pixels, but this is forced to a 4:3 ratio by optics. So it has
57 non square pixels :( */
58static struct v4l2_pix_format vicam_mode[] = {
59 { 256, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
60 .bytesperline = 256,
61 .sizeimage = 256 * 122,
62 .colorspace = V4L2_COLORSPACE_SRGB,},
63 /* 2 modes with somewhat more square pixels */
64 { 256, 200, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
65 .bytesperline = 256,
66 .sizeimage = 256 * 200,
67 .colorspace = V4L2_COLORSPACE_SRGB,},
68 { 256, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
69 .bytesperline = 256,
70 .sizeimage = 256 * 240,
71 .colorspace = V4L2_COLORSPACE_SRGB,},
72#if 0 /* This mode has extremely non square pixels, testing use only */
73 { 512, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
74 .bytesperline = 512,
75 .sizeimage = 512 * 122,
76 .colorspace = V4L2_COLORSPACE_SRGB,},
77#endif
78 { 512, 244, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
79 .bytesperline = 512,
80 .sizeimage = 512 * 244,
81 .colorspace = V4L2_COLORSPACE_SRGB,},
82};
83
84static const struct ctrl sd_ctrls[] = {
85[GAIN] = {
86 {
87 .id = V4L2_CID_GAIN,
88 .type = V4L2_CTRL_TYPE_INTEGER,
89 .name = "Gain",
90 .minimum = 0,
91 .maximum = 255,
92 .step = 1,
93 .default_value = 200,
94 },
95 },
96[EXPOSURE] = {
97 {
98 .id = V4L2_CID_EXPOSURE,
99 .type = V4L2_CTRL_TYPE_INTEGER,
100 .name = "Exposure",
101 .minimum = 0,
102 .maximum = 2047,
103 .step = 1,
104 .default_value = 256,
105 },
106 },
107};
108
109static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request,
110 u16 value, u16 index, u8 *data, u16 len)
111{
112 int ret;
113
114 ret = usb_control_msg(gspca_dev->dev,
115 usb_sndctrlpipe(gspca_dev->dev, 0),
116 request,
117 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
118 value, index, data, len, 1000);
119 if (ret < 0)
120 err("control msg req %02X error %d", request, ret);
121
122 return ret;
123}
124
125static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state)
126{
127 int ret;
128
129 ret = vicam_control_msg(gspca_dev, 0x50, state, 0, NULL, 0);
130 if (ret < 0)
131 return ret;
132
133 if (state)
134 ret = vicam_control_msg(gspca_dev, 0x55, 1, 0, NULL, 0);
135
136 return ret;
137}
138
139/*
140 * request and read a block of data - see warning on vicam_command.
141 */
142static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size)
143{
144 struct sd *sd = (struct sd *)gspca_dev;
145 int ret, unscaled_height, act_len = 0;
146 u8 *req_data = gspca_dev->usb_buf;
147
148 memset(req_data, 0, 16);
149 req_data[0] = sd->ctrls[GAIN].val;
150 if (gspca_dev->width == 256)
151 req_data[1] |= 0x01; /* low nibble x-scale */
152 if (gspca_dev->height <= 122) {
153 req_data[1] |= 0x10; /* high nibble y-scale */
154 unscaled_height = gspca_dev->height * 2;
155 } else
156 unscaled_height = gspca_dev->height;
157 req_data[2] = 0x90; /* unknown, does not seem to do anything */
158 if (unscaled_height <= 200)
159 req_data[3] = 0x06; /* vend? */
160 else if (unscaled_height <= 242) /* Yes 242 not 240 */
161 req_data[3] = 0x07; /* vend? */
162 else /* Up to 244 lines with req_data[3] == 0x08 */
163 req_data[3] = 0x08; /* vend? */
164
165 if (sd->ctrls[EXPOSURE].val < 256) {
166 /* Frame rate maxed out, use partial frame expo time */
167 req_data[4] = 255 - sd->ctrls[EXPOSURE].val;
168 req_data[5] = 0x00;
169 req_data[6] = 0x00;
170 req_data[7] = 0x01;
171 } else {
172 /* Modify frame rate */
173 req_data[4] = 0x00;
174 req_data[5] = 0x00;
175 req_data[6] = sd->ctrls[EXPOSURE].val & 0xFF;
176 req_data[7] = sd->ctrls[EXPOSURE].val >> 8;
177 }
178 req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */
179 /* bytes 9-15 do not seem to affect exposure or image quality */
180
181 mutex_lock(&gspca_dev->usb_lock);
182 ret = vicam_control_msg(gspca_dev, 0x51, 0x80, 0, req_data, 16);
183 mutex_unlock(&gspca_dev->usb_lock);
184 if (ret < 0)
185 return ret;
186
187 ret = usb_bulk_msg(gspca_dev->dev,
188 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
189 data, size, &act_len, 10000);
190 /* successful, it returns 0, otherwise negative */
191 if (ret < 0 || act_len != size) {
192 err("bulk read fail (%d) len %d/%d",
193 ret, act_len, size);
194 return -EIO;
195 }
196 return 0;
197}
198
199/* This function is called as a workqueue function and runs whenever the camera
200 * is streaming data. Because it is a workqueue function it is allowed to sleep
201 * so we can use synchronous USB calls. To avoid possible collisions with other
202 * threads attempting to use the camera's USB interface we take the gspca
203 * usb_lock when performing USB operations. In practice the only thing we need
204 * to protect against is the usb_set_interface call that gspca makes during
205 * stream_off as the camera doesn't provide any controls that the user could try
206 * to change.
207 */
208static void vicam_dostream(struct work_struct *work)
209{
210 struct sd *sd = container_of(work, struct sd, work_struct);
211 struct gspca_dev *gspca_dev = &sd->gspca_dev;
212 int ret, frame_sz;
213 u8 *buffer;
214
215 frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage +
216 HEADER_SIZE;
217 buffer = kmalloc(frame_sz, GFP_KERNEL | GFP_DMA);
218 if (!buffer) {
219 err("Couldn't allocate USB buffer");
220 goto exit;
221 }
222
223 while (gspca_dev->present && gspca_dev->streaming) {
224 ret = vicam_read_frame(gspca_dev, buffer, frame_sz);
225 if (ret < 0)
226 break;
227
228 /* Note the frame header contents seem to be completely
229 constant, they do not change with either image, or
230 settings. So we simply discard it. The frames have
231 a very similar 64 byte footer, which we don't even
232 bother reading from the cam */
233 gspca_frame_add(gspca_dev, FIRST_PACKET,
234 buffer + HEADER_SIZE,
235 frame_sz - HEADER_SIZE);
236 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
237 }
238exit:
239 kfree(buffer);
240}
241
242/* This function is called at probe time just before sd_init */
243static int sd_config(struct gspca_dev *gspca_dev,
244 const struct usb_device_id *id)
245{
246 struct cam *cam = &gspca_dev->cam;
247 struct sd *sd = (struct sd *)gspca_dev;
248
249 /* We don't use the buffer gspca allocates so make it small. */
250 cam->bulk = 1;
251 cam->bulk_size = 64;
252 cam->cam_mode = vicam_mode;
253 cam->nmodes = ARRAY_SIZE(vicam_mode);
254 cam->ctrls = sd->ctrls;
255
256 INIT_WORK(&sd->work_struct, vicam_dostream);
257
258 return 0;
259}
260
261/* this function is called at probe and resume time */
262static int sd_init(struct gspca_dev *gspca_dev)
263{
264 int ret;
265 const struct ihex_binrec *rec;
266 const struct firmware *uninitialized_var(fw);
267 u8 *firmware_buf;
268
269 ret = request_ihex_firmware(&fw, "vicam/firmware.fw",
270 &gspca_dev->dev->dev);
271 if (ret) {
272 err("Failed to load \"vicam/firmware.fw\": %d\n", ret);
273 return ret;
274 }
275
276 firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
277 if (!firmware_buf) {
278 ret = -ENOMEM;
279 goto exit;
280 }
281 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
282 memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len));
283 ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,
284 be16_to_cpu(rec->len));
285 if (ret < 0)
286 break;
287 }
288
289 kfree(firmware_buf);
290exit:
291 release_firmware(fw);
292 return ret;
293}
294
295/* Set up for getting frames. */
296static int sd_start(struct gspca_dev *gspca_dev)
297{
298 struct sd *sd = (struct sd *)gspca_dev;
299 int ret;
300
301 ret = vicam_set_camera_power(gspca_dev, 1);
302 if (ret < 0)
303 return ret;
304
305 /* Start the workqueue function to do the streaming */
306 sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
307 queue_work(sd->work_thread, &sd->work_struct);
308
309 return 0;
310}
311
312/* called on streamoff with alt==0 and on disconnect */
313/* the usb_lock is held at entry - restore on exit */
314static void sd_stop0(struct gspca_dev *gspca_dev)
315{
316 struct sd *dev = (struct sd *)gspca_dev;
317
318 /* wait for the work queue to terminate */
319 mutex_unlock(&gspca_dev->usb_lock);
320 /* This waits for vicam_dostream to finish */
321 destroy_workqueue(dev->work_thread);
322 dev->work_thread = NULL;
323 mutex_lock(&gspca_dev->usb_lock);
324
325 vicam_set_camera_power(gspca_dev, 0);
326}
327
328/* Table of supported USB devices */
329static const struct usb_device_id device_table[] = {
330 {USB_DEVICE(0x04c1, 0x009d)},
331 {USB_DEVICE(0x0602, 0x1001)},
332 {}
333};
334
335MODULE_DEVICE_TABLE(usb, device_table);
336
337/* sub-driver description */
338static const struct sd_desc sd_desc = {
339 .name = MODULE_NAME,
340 .ctrls = sd_ctrls,
341 .nctrls = ARRAY_SIZE(sd_ctrls),
342 .config = sd_config,
343 .init = sd_init,
344 .start = sd_start,
345 .stop0 = sd_stop0,
346};
347
348/* -- device connect -- */
349static int sd_probe(struct usb_interface *intf,
350 const struct usb_device_id *id)
351{
352 return gspca_dev_probe(intf, id,
353 &sd_desc,
354 sizeof(struct sd),
355 THIS_MODULE);
356}
357
358static struct usb_driver sd_driver = {
359 .name = MODULE_NAME,
360 .id_table = device_table,
361 .probe = sd_probe,
362 .disconnect = gspca_disconnect,
363#ifdef CONFIG_PM
364 .suspend = gspca_suspend,
365 .resume = gspca_resume,
366#endif
367};
368
369/* -- module insert / remove -- */
370static int __init sd_mod_init(void)
371{
372 return usb_register(&sd_driver);
373}
374
375static void __exit sd_mod_exit(void)
376{
377 usb_deregister(&sd_driver);
378}
379
380module_init(sd_mod_init);
381module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h
index bfb559c3b713..a1bd94e8ce52 100644
--- a/drivers/media/video/gspca/zc3xx-reg.h
+++ b/drivers/media/video/gspca/zc3xx-reg.h
@@ -160,8 +160,6 @@
160#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6 160#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6
161#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7 161#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7
162 162
163#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2
164
165/* Matrixes */ 163/* Matrixes */
166 164
167/* Color matrix is like : 165/* Color matrix is like :
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 47236a58bf33..fa164e861cde 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Z-Star/Vimicro zc301/zc302p/vc30x library 2 * Z-Star/Vimicro zc301/zc302p/vc30x library
3 * 3 *
4 * Copyright (C) 2009-2010 Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2011 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr 5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -39,6 +39,7 @@ static int force_sensor = -1;
39enum e_ctrl { 39enum e_ctrl {
40 BRIGHTNESS, 40 BRIGHTNESS,
41 CONTRAST, 41 CONTRAST,
42 EXPOSURE,
42 GAMMA, 43 GAMMA,
43 AUTOGAIN, 44 AUTOGAIN,
44 LIGHTFREQ, 45 LIGHTFREQ,
@@ -46,6 +47,8 @@ enum e_ctrl {
46 NCTRLS /* number of controls */ 47 NCTRLS /* number of controls */
47}; 48};
48 49
50#define AUTOGAIN_DEF 1
51
49/* specific webcam descriptor */ 52/* specific webcam descriptor */
50struct sd { 53struct sd {
51 struct gspca_dev gspca_dev; /* !! must be the first item */ 54 struct gspca_dev gspca_dev; /* !! must be the first item */
@@ -73,7 +76,7 @@ enum sensors {
73 SENSOR_CS2102K, 76 SENSOR_CS2102K,
74 SENSOR_GC0303, 77 SENSOR_GC0303,
75 SENSOR_GC0305, 78 SENSOR_GC0305,
76 SENSOR_HDCS2020b, 79 SENSOR_HDCS2020,
77 SENSOR_HV7131B, 80 SENSOR_HV7131B,
78 SENSOR_HV7131R, 81 SENSOR_HV7131R,
79 SENSOR_ICM105A, 82 SENSOR_ICM105A,
@@ -92,7 +95,8 @@ enum sensors {
92 95
93/* V4L2 controls supported by the driver */ 96/* V4L2 controls supported by the driver */
94static void setcontrast(struct gspca_dev *gspca_dev); 97static void setcontrast(struct gspca_dev *gspca_dev);
95static void setautogain(struct gspca_dev *gspca_dev); 98static void setexposure(struct gspca_dev *gspca_dev);
99static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
96static void setlightfreq(struct gspca_dev *gspca_dev); 100static void setlightfreq(struct gspca_dev *gspca_dev);
97static void setsharpness(struct gspca_dev *gspca_dev); 101static void setsharpness(struct gspca_dev *gspca_dev);
98 102
@@ -121,6 +125,18 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
121 }, 125 },
122 .set_control = setcontrast 126 .set_control = setcontrast
123 }, 127 },
128[EXPOSURE] = {
129 {
130 .id = V4L2_CID_EXPOSURE,
131 .type = V4L2_CTRL_TYPE_INTEGER,
132 .name = "Exposure",
133 .minimum = 0x30d,
134 .maximum = 0x493e,
135 .step = 1,
136 .default_value = 0x927
137 },
138 .set_control = setexposure
139 },
124[GAMMA] = { 140[GAMMA] = {
125 { 141 {
126 .id = V4L2_CID_GAMMA, 142 .id = V4L2_CID_GAMMA,
@@ -141,9 +157,10 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
141 .minimum = 0, 157 .minimum = 0,
142 .maximum = 1, 158 .maximum = 1,
143 .step = 1, 159 .step = 1,
144 .default_value = 1, 160 .default_value = AUTOGAIN_DEF,
161 .flags = V4L2_CTRL_FLAG_UPDATE
145 }, 162 },
146 .set_control = setautogain 163 .set = sd_setautogain
147 }, 164 },
148[LIGHTFREQ] = { 165[LIGHTFREQ] = {
149 { 166 {
@@ -1498,7 +1515,7 @@ static const struct usb_action gc0305_NoFliker[] = {
1498 {} 1515 {}
1499}; 1516};
1500 1517
1501static const struct usb_action hdcs2020b_InitialScale[] = { 1518static const struct usb_action hdcs2020_InitialScale[] = {
1502 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1519 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1503 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 1520 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
1504 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */ 1521 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */
@@ -1630,7 +1647,7 @@ static const struct usb_action hdcs2020b_InitialScale[] = {
1630 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 1647 {0xa0, 0x40, ZC3XX_R118_BGAIN},
1631 {} 1648 {}
1632}; 1649};
1633static const struct usb_action hdcs2020b_Initial[] = { 1650static const struct usb_action hdcs2020_Initial[] = {
1634 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1651 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1635 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 1652 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1636 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 1653 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1758,7 +1775,7 @@ static const struct usb_action hdcs2020b_Initial[] = {
1758 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 1775 {0xa0, 0x40, ZC3XX_R118_BGAIN},
1759 {} 1776 {}
1760}; 1777};
1761static const struct usb_action hdcs2020b_50HZ[] = { 1778static const struct usb_action hdcs2020_50HZ[] = {
1762 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 1779 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
1763 {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ 1780 {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */
1764 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ 1781 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
@@ -1779,7 +1796,7 @@ static const struct usb_action hdcs2020b_50HZ[] = {
1779 {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */ 1796 {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */
1780 {} 1797 {}
1781}; 1798};
1782static const struct usb_action hdcs2020b_60HZ[] = { 1799static const struct usb_action hdcs2020_60HZ[] = {
1783 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 1800 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
1784 {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ 1801 {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */
1785 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ 1802 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
@@ -1800,7 +1817,7 @@ static const struct usb_action hdcs2020b_60HZ[] = {
1800 {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */ 1817 {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */
1801 {} 1818 {}
1802}; 1819};
1803static const struct usb_action hdcs2020b_NoFliker[] = { 1820static const struct usb_action hdcs2020_NoFliker[] = {
1804 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 1821 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
1805 {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ 1822 {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
1806 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ 1823 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
@@ -2126,7 +2143,6 @@ static const struct usb_action hv7131r_Initial[] = {
2126 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 2143 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
2127 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 2144 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
2128 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, 2145 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
2129
2130 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, 2146 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
2131 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 2147 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
2132 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, 2148 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
@@ -2878,7 +2894,7 @@ static const struct usb_action mc501cb_Initial[] = {
2878 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ 2894 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
2879 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ 2895 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
2880 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ 2896 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
2881 {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ 2897 {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */
2882 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ 2898 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
2883 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ 2899 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
2884 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ 2900 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
@@ -2998,7 +3014,7 @@ static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */
2998 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ 3014 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
2999 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ 3015 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
3000 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ 3016 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
3001 {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ 3017 {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */
3002 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ 3018 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
3003 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ 3019 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
3004 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ 3020 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
@@ -3310,7 +3326,7 @@ static const struct usb_action ov7620_50HZ[] = {
3310 {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ 3326 {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */
3311 {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ 3327 {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */
3312/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc 3328/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc
3313 if mode0 (640x480) */ 3329 * if mode0 (640x480) */
3314 {} 3330 {}
3315}; 3331};
3316static const struct usb_action ov7620_60HZ[] = { 3332static const struct usb_action ov7620_60HZ[] = {
@@ -5828,7 +5844,7 @@ static void setmatrix(struct gspca_dev *gspca_dev)
5828 [SENSOR_CS2102K] = NULL, 5844 [SENSOR_CS2102K] = NULL,
5829 [SENSOR_GC0303] = gc0303_matrix, 5845 [SENSOR_GC0303] = gc0303_matrix,
5830 [SENSOR_GC0305] = gc0305_matrix, 5846 [SENSOR_GC0305] = gc0305_matrix,
5831 [SENSOR_HDCS2020b] = NULL, 5847 [SENSOR_HDCS2020] = NULL,
5832 [SENSOR_HV7131B] = NULL, 5848 [SENSOR_HV7131B] = NULL,
5833 [SENSOR_HV7131R] = po2030_matrix, 5849 [SENSOR_HV7131R] = po2030_matrix,
5834 [SENSOR_ICM105A] = po2030_matrix, 5850 [SENSOR_ICM105A] = po2030_matrix,
@@ -5927,6 +5943,26 @@ static void setcontrast(struct gspca_dev *gspca_dev)
5927 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */ 5943 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */
5928} 5944}
5929 5945
5946static void getexposure(struct gspca_dev *gspca_dev)
5947{
5948 struct sd *sd = (struct sd *) gspca_dev;
5949
5950 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9)
5951 | (i2c_read(gspca_dev, 0x26) << 1)
5952 | (i2c_read(gspca_dev, 0x27) >> 7);
5953}
5954
5955static void setexposure(struct gspca_dev *gspca_dev)
5956{
5957 struct sd *sd = (struct sd *) gspca_dev;
5958 int val;
5959
5960 val = sd->ctrls[EXPOSURE].val;
5961 i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
5962 i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
5963 i2c_write(gspca_dev, 0x27, val << 7, 0x00);
5964}
5965
5930static void setquality(struct gspca_dev *gspca_dev) 5966static void setquality(struct gspca_dev *gspca_dev)
5931{ 5967{
5932 struct sd *sd = (struct sd *) gspca_dev; 5968 struct sd *sd = (struct sd *) gspca_dev;
@@ -5990,10 +6026,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
5990 {gc0305_NoFliker, gc0305_NoFliker, 6026 {gc0305_NoFliker, gc0305_NoFliker,
5991 gc0305_50HZ, gc0305_50HZ, 6027 gc0305_50HZ, gc0305_50HZ,
5992 gc0305_60HZ, gc0305_60HZ}, 6028 gc0305_60HZ, gc0305_60HZ},
5993 [SENSOR_HDCS2020b] = 6029 [SENSOR_HDCS2020] =
5994 {hdcs2020b_NoFliker, hdcs2020b_NoFliker, 6030 {hdcs2020_NoFliker, hdcs2020_NoFliker,
5995 hdcs2020b_50HZ, hdcs2020b_50HZ, 6031 hdcs2020_50HZ, hdcs2020_50HZ,
5996 hdcs2020b_60HZ, hdcs2020b_60HZ}, 6032 hdcs2020_60HZ, hdcs2020_60HZ},
5997 [SENSOR_HV7131B] = 6033 [SENSOR_HV7131B] =
5998 {hv7131b_NoFliker, hv7131b_NoFlikerScale, 6034 {hv7131b_NoFliker, hv7131b_NoFlikerScale,
5999 hv7131b_50HZ, hv7131b_50HZScale, 6035 hv7131b_50HZ, hv7131b_50HZScale,
@@ -6091,7 +6127,7 @@ static void setautogain(struct gspca_dev *gspca_dev)
6091 6127
6092static void send_unknown(struct gspca_dev *gspca_dev, int sensor) 6128static void send_unknown(struct gspca_dev *gspca_dev, int sensor)
6093{ 6129{
6094 reg_w(gspca_dev, 0x01, 0x0000); /* led off */ 6130 reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */
6095 switch (sensor) { 6131 switch (sensor) {
6096 case SENSOR_PAS106: 6132 case SENSOR_PAS106:
6097 reg_w(gspca_dev, 0x03, 0x003a); 6133 reg_w(gspca_dev, 0x03, 0x003a);
@@ -6310,6 +6346,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6310 return 0x0a; /* PB0330 */ 6346 return 0x0a; /* PB0330 */
6311 } 6347 }
6312 6348
6349 /* probe gc0303 / gc0305 */
6313 reg_w(gspca_dev, 0x01, 0x0000); 6350 reg_w(gspca_dev, 0x01, 0x0000);
6314 reg_w(gspca_dev, 0x01, 0x0001); 6351 reg_w(gspca_dev, 0x01, 0x0001);
6315 reg_w(gspca_dev, 0x98, 0x008b); 6352 reg_w(gspca_dev, 0x98, 0x008b);
@@ -6414,6 +6451,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
6414 gspca_dev->cam.ctrls = sd->ctrls; 6451 gspca_dev->cam.ctrls = sd->ctrls;
6415 sd->quality = QUALITY_DEF; 6452 sd->quality = QUALITY_DEF;
6416 6453
6454 /* if USB 1.1, let some bandwidth for the audio device */
6455 if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
6456 gspca_dev->nbalt--;
6457
6417 return 0; 6458 return 0;
6418} 6459}
6419 6460
@@ -6429,7 +6470,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
6429 [SENSOR_CS2102K] = 5, 6470 [SENSOR_CS2102K] = 5,
6430 [SENSOR_GC0303] = 3, 6471 [SENSOR_GC0303] = 3,
6431 [SENSOR_GC0305] = 4, 6472 [SENSOR_GC0305] = 4,
6432 [SENSOR_HDCS2020b] = 4, 6473 [SENSOR_HDCS2020] = 4,
6433 [SENSOR_HV7131B] = 4, 6474 [SENSOR_HV7131B] = 4,
6434 [SENSOR_HV7131R] = 4, 6475 [SENSOR_HV7131R] = 4,
6435 [SENSOR_ICM105A] = 4, 6476 [SENSOR_ICM105A] = 4,
@@ -6450,7 +6491,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
6450 [SENSOR_CS2102K] = 1, 6491 [SENSOR_CS2102K] = 1,
6451 [SENSOR_GC0303] = 1, 6492 [SENSOR_GC0303] = 1,
6452 [SENSOR_GC0305] = 1, 6493 [SENSOR_GC0305] = 1,
6453 [SENSOR_HDCS2020b] = 1, 6494 [SENSOR_HDCS2020] = 1,
6454 [SENSOR_HV7131B] = 1, 6495 [SENSOR_HV7131B] = 1,
6455 [SENSOR_HV7131R] = 1, 6496 [SENSOR_HV7131R] = 1,
6456 [SENSOR_ICM105A] = 1, 6497 [SENSOR_ICM105A] = 1,
@@ -6513,8 +6554,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
6513 sd->sensor = SENSOR_CS2102; 6554 sd->sensor = SENSOR_CS2102;
6514 break; 6555 break;
6515 case 0x08: 6556 case 0x08:
6516 PDEBUG(D_PROBE, "Find Sensor HDCS2020(b)"); 6557 PDEBUG(D_PROBE, "Find Sensor HDCS2020");
6517 sd->sensor = SENSOR_HDCS2020b; 6558 sd->sensor = SENSOR_HDCS2020;
6518 break; 6559 break;
6519 case 0x0a: 6560 case 0x0a:
6520 PDEBUG(D_PROBE, 6561 PDEBUG(D_PROBE,
@@ -6619,10 +6660,19 @@ static int sd_init(struct gspca_dev *gspca_dev)
6619 sd->ctrls[GAMMA].def = gamma[sd->sensor]; 6660 sd->ctrls[GAMMA].def = gamma[sd->sensor];
6620 6661
6621 switch (sd->sensor) { 6662 switch (sd->sensor) {
6663 case SENSOR_HV7131R:
6664 break;
6622 case SENSOR_OV7630C: 6665 case SENSOR_OV7630C:
6623 gspca_dev->ctrl_dis = (1 << LIGHTFREQ); 6666 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
6667 break;
6668 default:
6669 gspca_dev->ctrl_dis = (1 << EXPOSURE);
6624 break; 6670 break;
6625 } 6671 }
6672#if AUTOGAIN_DEF
6673 if (sd->ctrls[AUTOGAIN].val)
6674 gspca_dev->ctrl_inac = (1 << EXPOSURE);
6675#endif
6626 6676
6627 /* switch off the led */ 6677 /* switch off the led */
6628 reg_w(gspca_dev, 0x01, 0x0000); 6678 reg_w(gspca_dev, 0x01, 0x0000);
@@ -6644,8 +6694,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
6644 {gc0303_Initial, gc0303_InitialScale}, 6694 {gc0303_Initial, gc0303_InitialScale},
6645 [SENSOR_GC0305] = 6695 [SENSOR_GC0305] =
6646 {gc0305_Initial, gc0305_InitialScale}, 6696 {gc0305_Initial, gc0305_InitialScale},
6647 [SENSOR_HDCS2020b] = 6697 [SENSOR_HDCS2020] =
6648 {hdcs2020b_Initial, hdcs2020b_InitialScale}, 6698 {hdcs2020_Initial, hdcs2020_InitialScale},
6649 [SENSOR_HV7131B] = 6699 [SENSOR_HV7131B] =
6650 {hv7131b_Initial, hv7131b_InitialScale}, 6700 {hv7131b_Initial, hv7131b_InitialScale},
6651 [SENSOR_HV7131R] = 6701 [SENSOR_HV7131R] =
@@ -6739,7 +6789,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6739 /* set the gamma tables when not set */ 6789 /* set the gamma tables when not set */
6740 switch (sd->sensor) { 6790 switch (sd->sensor) {
6741 case SENSOR_CS2102K: /* gamma set in xxx_Initial */ 6791 case SENSOR_CS2102K: /* gamma set in xxx_Initial */
6742 case SENSOR_HDCS2020b: 6792 case SENSOR_HDCS2020:
6743 case SENSOR_OV7630C: 6793 case SENSOR_OV7630C:
6744 break; 6794 break;
6745 default: 6795 default:
@@ -6768,9 +6818,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
6768 reg_w(gspca_dev, 0x40, 0x0117); 6818 reg_w(gspca_dev, 0x40, 0x0117);
6769 break; 6819 break;
6770 case SENSOR_HV7131R: 6820 case SENSOR_HV7131R:
6771 i2c_write(gspca_dev, 0x25, 0x04, 0x00); /* exposure */ 6821 if (!sd->ctrls[AUTOGAIN].val)
6772 i2c_write(gspca_dev, 0x26, 0x93, 0x00); 6822 setexposure(gspca_dev);
6773 i2c_write(gspca_dev, 0x27, 0xe0, 0x00);
6774 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); 6823 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
6775 break; 6824 break;
6776 case SENSOR_GC0305: 6825 case SENSOR_GC0305:
@@ -6848,6 +6897,23 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
6848 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 6897 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
6849} 6898}
6850 6899
6900static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
6901{
6902 struct sd *sd = (struct sd *) gspca_dev;
6903
6904 sd->ctrls[AUTOGAIN].val = val;
6905 if (val) {
6906 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
6907 } else {
6908 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
6909 if (gspca_dev->streaming)
6910 getexposure(gspca_dev);
6911 }
6912 if (gspca_dev->streaming)
6913 setautogain(gspca_dev);
6914 return gspca_dev->usb_err;
6915}
6916
6851static int sd_querymenu(struct gspca_dev *gspca_dev, 6917static int sd_querymenu(struct gspca_dev *gspca_dev,
6852 struct v4l2_querymenu *menu) 6918 struct v4l2_querymenu *menu)
6853{ 6919{
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index e53fa55d56a1..2a1ac287591d 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -52,25 +52,36 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
52 }; 52 };
53 53
54 /* Our default information for ir-kbd-i2c.c to use */ 54 /* Our default information for ir-kbd-i2c.c to use */
55 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 55 init_data->ir_codes = RC_MAP_HAUPPAUGE;
56 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 56 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
57 init_data->type = RC_TYPE_RC5; 57 init_data->type = RC_TYPE_RC5;
58 init_data->name = "HD-PVR"; 58 init_data->name = "HD-PVR";
59 init_data->polling_interval = 405; /* ms, duplicated from Windows */
59 hdpvr_ir_rx_i2c_board_info.platform_data = init_data; 60 hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
60 61
61 return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info); 62 return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
62} 63}
63 64
64static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus, 65static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
65 unsigned char addr, char *data, int len) 66 unsigned char addr, char *wdata, int wlen,
67 char *data, int len)
66{ 68{
67 int ret; 69 int ret;
68 70
69 if (len > sizeof(dev->i2c_buf)) 71 if ((len > sizeof(dev->i2c_buf)) || (wlen > sizeof(dev->i2c_buf)))
70 return -EINVAL; 72 return -EINVAL;
71 73
72 ret = usb_control_msg(dev->udev, 74 if (wlen) {
73 usb_rcvctrlpipe(dev->udev, 0), 75 memcpy(&dev->i2c_buf, wdata, wlen);
76 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
77 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
78 (bus << 8) | addr, 0, &dev->i2c_buf,
79 wlen, 1000);
80 if (ret < 0)
81 return ret;
82 }
83
84 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
74 REQTYPE_I2C_READ, CTRL_READ_REQUEST, 85 REQTYPE_I2C_READ, CTRL_READ_REQUEST,
75 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); 86 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
76 87
@@ -92,16 +103,14 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
92 return -EINVAL; 103 return -EINVAL;
93 104
94 memcpy(&dev->i2c_buf, data, len); 105 memcpy(&dev->i2c_buf, data, len);
95 ret = usb_control_msg(dev->udev, 106 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
96 usb_sndctrlpipe(dev->udev, 0),
97 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, 107 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
98 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); 108 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
99 109
100 if (ret < 0) 110 if (ret < 0)
101 return ret; 111 return ret;
102 112
103 ret = usb_control_msg(dev->udev, 113 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
104 usb_rcvctrlpipe(dev->udev, 0),
105 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, 114 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
106 0, 0, &dev->i2c_buf, 2, 1000); 115 0, 0, &dev->i2c_buf, 2, 1000);
107 116
@@ -117,24 +126,49 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
117 int num) 126 int num)
118{ 127{
119 struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter); 128 struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
120 int retval = 0, i, addr; 129 int retval = 0, addr;
121 130
122 if (num <= 0) 131 if (num <= 0)
123 return 0; 132 return 0;
124 133
125 mutex_lock(&dev->i2c_mutex); 134 mutex_lock(&dev->i2c_mutex);
126 135
127 for (i = 0; i < num && !retval; i++) { 136 addr = msgs[0].addr << 1;
128 addr = msgs[i].addr << 1;
129 137
130 if (msgs[i].flags & I2C_M_RD) 138 if (num == 1) {
131 retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf, 139 if (msgs[0].flags & I2C_M_RD)
132 msgs[i].len); 140 retval = hdpvr_i2c_read(dev, 1, addr, NULL, 0,
141 msgs[0].buf, msgs[0].len);
133 else 142 else
134 retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf, 143 retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf,
135 msgs[i].len); 144 msgs[0].len);
145 } else if (num == 2) {
146 if (msgs[0].addr != msgs[1].addr) {
147 v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer "
148 "with conflicting target addresses\n");
149 retval = -EINVAL;
150 goto out;
151 }
152
153 if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) {
154 v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with "
155 "r0=%d, r1=%d\n", msgs[0].flags & I2C_M_RD,
156 msgs[1].flags & I2C_M_RD);
157 retval = -EINVAL;
158 goto out;
159 }
160
161 /*
162 * Write followed by atomic read is the only complex xfer that
163 * we actually support here.
164 */
165 retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len,
166 msgs[1].buf, msgs[1].len);
167 } else {
168 v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num);
136 } 169 }
137 170
171out:
138 mutex_unlock(&dev->i2c_mutex); 172 mutex_unlock(&dev->i2c_mutex);
139 173
140 return retval ? retval : num; 174 return retval ? retval : num;
@@ -158,11 +192,11 @@ static struct i2c_adapter hdpvr_i2c_adapter_template = {
158 192
159static int hdpvr_activate_ir(struct hdpvr_device *dev) 193static int hdpvr_activate_ir(struct hdpvr_device *dev)
160{ 194{
161 char buffer[8]; 195 char buffer[2];
162 196
163 mutex_lock(&dev->i2c_mutex); 197 mutex_lock(&dev->i2c_mutex);
164 198
165 hdpvr_i2c_read(dev, 0, 0x54, buffer, 1); 199 hdpvr_i2c_read(dev, 0, 0x54, NULL, 0, buffer, 1);
166 200
167 buffer[0] = 0; 201 buffer[0] = 0;
168 buffer[1] = 0x8; 202 buffer[1] = 0x8;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index a221ad68b330..3ab875d036e1 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -55,10 +55,6 @@
55static int debug; 55static int debug;
56module_param(debug, int, 0644); /* debug level (0,1,2) */ 56module_param(debug, int, 0644); /* debug level (0,1,2) */
57 57
58static int hauppauge;
59module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */
60MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)");
61
62 58
63#define MODULE_NAME "ir-kbd-i2c" 59#define MODULE_NAME "ir-kbd-i2c"
64#define dprintk(level, fmt, arg...) if (debug >= level) \ 60#define dprintk(level, fmt, arg...) if (debug >= level) \
@@ -105,10 +101,6 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
105 /* invalid key press */ 101 /* invalid key press */
106 return 0; 102 return 0;
107 103
108 if (dev!=0x1e && dev!=0x1f)
109 /* not a hauppauge remote */
110 return 0;
111
112 if (!range) 104 if (!range)
113 code += 64; 105 code += 64;
114 106
@@ -116,7 +108,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
116 start, range, toggle, dev, code); 108 start, range, toggle, dev, code);
117 109
118 /* return key */ 110 /* return key */
119 *ir_key = code; 111 *ir_key = (dev << 8) | code;
120 *ir_raw = ircode; 112 *ir_raw = ircode;
121 return 1; 113 return 1;
122} 114}
@@ -312,11 +304,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
312 name = "Hauppauge"; 304 name = "Hauppauge";
313 ir->get_key = get_key_haup; 305 ir->get_key = get_key_haup;
314 rc_type = RC_TYPE_RC5; 306 rc_type = RC_TYPE_RC5;
315 if (hauppauge == 1) { 307 ir_codes = RC_MAP_HAUPPAUGE;
316 ir_codes = RC_MAP_HAUPPAUGE_NEW;
317 } else {
318 ir_codes = RC_MAP_RC5_TV;
319 }
320 break; 308 break;
321 case 0x30: 309 case 0x30:
322 name = "KNC One"; 310 name = "KNC One";
@@ -340,7 +328,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
340 name = "Hauppauge/Zilog Z8"; 328 name = "Hauppauge/Zilog Z8";
341 ir->get_key = get_key_haup_xvr; 329 ir->get_key = get_key_haup_xvr;
342 rc_type = RC_TYPE_RC5; 330 rc_type = RC_TYPE_RC5;
343 ir_codes = hauppauge ? RC_MAP_HAUPPAUGE_NEW : RC_MAP_RC5_TV; 331 ir_codes = RC_MAP_HAUPPAUGE;
344 break; 332 break;
345 } 333 }
346 334
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 04bacdbd10bb..84bdf0f42a8e 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -383,7 +383,6 @@ struct ivtv_open_id {
383 u32 open_id; /* unique ID for this file descriptor */ 383 u32 open_id; /* unique ID for this file descriptor */
384 int type; /* stream type */ 384 int type; /* stream type */
385 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ 385 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
386 enum v4l2_priority prio; /* priority */
387 struct ivtv *itv; 386 struct ivtv *itv;
388}; 387};
389 388
@@ -710,7 +709,6 @@ struct ivtv {
710 709
711 /* Miscellaneous */ 710 /* Miscellaneous */
712 u32 open_id; /* incremented each time an open occurs, is >= 1 */ 711 u32 open_id; /* incremented each time an open occurs, is >= 1 */
713 struct v4l2_prio_state prio; /* priority state */
714 int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */ 712 int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */
715 int speed; /* current playback speed setting */ 713 int speed; /* current playback speed setting */
716 u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */ 714 u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index c57a58523ca8..a7f54b010a5c 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -856,7 +856,6 @@ int ivtv_v4l2_close(struct file *filp)
856 856
857 IVTV_DEBUG_FILE("close %s\n", s->name); 857 IVTV_DEBUG_FILE("close %s\n", s->name);
858 858
859 v4l2_prio_close(&itv->prio, id->prio);
860 v4l2_fh_del(fh); 859 v4l2_fh_del(fh);
861 v4l2_fh_exit(fh); 860 v4l2_fh_exit(fh);
862 861
@@ -973,7 +972,6 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
973 } 972 }
974 item->itv = itv; 973 item->itv = itv;
975 item->type = s->type; 974 item->type = s->type;
976 v4l2_prio_open(&itv->prio, &item->prio);
977 975
978 item->open_id = itv->open_id++; 976 item->open_id = itv->open_id++;
979 filp->private_data = &item->fh; 977 filp->private_data = &item->fh;
@@ -982,6 +980,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
982 /* Try to claim this stream */ 980 /* Try to claim this stream */
983 if (ivtv_claim_stream(item, item->type)) { 981 if (ivtv_claim_stream(item, item->type)) {
984 /* No, it's already in use */ 982 /* No, it's already in use */
983 v4l2_fh_exit(&item->fh);
985 kfree(item); 984 kfree(item);
986 return -EBUSY; 985 return -EBUSY;
987 } 986 }
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9fb86a081c0f..d47f41a0ef66 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -205,15 +205,14 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
205 break; 205 break;
206 case IVTV_HW_I2C_IR_RX_HAUP_EXT: 206 case IVTV_HW_I2C_IR_RX_HAUP_EXT:
207 case IVTV_HW_I2C_IR_RX_HAUP_INT: 207 case IVTV_HW_I2C_IR_RX_HAUP_INT:
208 /* Default to old black remote */ 208 init_data->ir_codes = RC_MAP_HAUPPAUGE;
209 init_data->ir_codes = RC_MAP_RC5_TV;
210 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; 209 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
211 init_data->type = RC_TYPE_RC5; 210 init_data->type = RC_TYPE_RC5;
212 init_data->name = itv->card_name; 211 init_data->name = itv->card_name;
213 break; 212 break;
214 case IVTV_HW_Z8F0811_IR_RX_HAUP: 213 case IVTV_HW_Z8F0811_IR_RX_HAUP:
215 /* Default to grey remote */ 214 /* Default to grey remote */
216 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 215 init_data->ir_codes = RC_MAP_HAUPPAUGE;
217 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 216 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
218 init_data->type = RC_TYPE_RC5; 217 init_data->type = RC_TYPE_RC5;
219 init_data->name = itv->card_name; 218 init_data->name = itv->card_name;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index b686da5e4326..1689783cd19a 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -313,7 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
313 313
314static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) 314static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
315{ 315{
316 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 316 struct ivtv *itv = fh2id(fh)->itv;
317 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 317 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
318 318
319 vbifmt->reserved[0] = 0; 319 vbifmt->reserved[0] = 0;
@@ -334,7 +334,7 @@ static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo
334 334
335static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 335static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
336{ 336{
337 struct ivtv_open_id *id = fh; 337 struct ivtv_open_id *id = fh2id(fh);
338 struct ivtv *itv = id->itv; 338 struct ivtv *itv = id->itv;
339 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 339 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
340 340
@@ -358,7 +358,7 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
358 358
359static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 359static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
360{ 360{
361 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 361 struct ivtv *itv = fh2id(fh)->itv;
362 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; 362 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
363 363
364 vbifmt->sampling_rate = 27000000; 364 vbifmt->sampling_rate = 27000000;
@@ -377,7 +377,7 @@ static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
377static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 377static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
378{ 378{
379 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 379 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
380 struct ivtv_open_id *id = fh; 380 struct ivtv_open_id *id = fh2id(fh);
381 struct ivtv *itv = id->itv; 381 struct ivtv *itv = id->itv;
382 382
383 vbifmt->reserved[0] = 0; 383 vbifmt->reserved[0] = 0;
@@ -398,7 +398,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
398 398
399static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) 399static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
400{ 400{
401 struct ivtv_open_id *id = fh; 401 struct ivtv_open_id *id = fh2id(fh);
402 struct ivtv *itv = id->itv; 402 struct ivtv *itv = id->itv;
403 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 403 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
404 404
@@ -439,7 +439,7 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
439 439
440static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 440static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
441{ 441{
442 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 442 struct ivtv *itv = fh2id(fh)->itv;
443 struct v4l2_window *winfmt = &fmt->fmt.win; 443 struct v4l2_window *winfmt = &fmt->fmt.win;
444 444
445 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 445 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
@@ -463,7 +463,7 @@ static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_
463 463
464static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 464static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
465{ 465{
466 struct ivtv_open_id *id = fh; 466 struct ivtv_open_id *id = fh2id(fh);
467 struct ivtv *itv = id->itv; 467 struct ivtv *itv = id->itv;
468 int w = fmt->fmt.pix.width; 468 int w = fmt->fmt.pix.width;
469 int h = fmt->fmt.pix.height; 469 int h = fmt->fmt.pix.height;
@@ -492,7 +492,7 @@ static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format
492static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 492static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
493{ 493{
494 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 494 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
495 struct ivtv_open_id *id = fh; 495 struct ivtv_open_id *id = fh2id(fh);
496 struct ivtv *itv = id->itv; 496 struct ivtv *itv = id->itv;
497 497
498 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) 498 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
@@ -512,7 +512,7 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
512 512
513static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) 513static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
514{ 514{
515 struct ivtv_open_id *id = fh; 515 struct ivtv_open_id *id = fh2id(fh);
516 s32 w = fmt->fmt.pix.width; 516 s32 w = fmt->fmt.pix.width;
517 s32 h = fmt->fmt.pix.height; 517 s32 h = fmt->fmt.pix.height;
518 int field = fmt->fmt.pix.field; 518 int field = fmt->fmt.pix.field;
@@ -546,7 +546,7 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format
546 546
547static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 547static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
548{ 548{
549 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 549 struct ivtv *itv = fh2id(fh)->itv;
550 u32 chromakey = fmt->fmt.win.chromakey; 550 u32 chromakey = fmt->fmt.win.chromakey;
551 u8 global_alpha = fmt->fmt.win.global_alpha; 551 u8 global_alpha = fmt->fmt.win.global_alpha;
552 552
@@ -565,7 +565,7 @@ static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo
565 565
566static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 566static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
567{ 567{
568 struct ivtv_open_id *id = fh; 568 struct ivtv_open_id *id = fh2id(fh);
569 struct ivtv *itv = id->itv; 569 struct ivtv *itv = id->itv;
570 struct v4l2_mbus_framefmt mbus_fmt; 570 struct v4l2_mbus_framefmt mbus_fmt;
571 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); 571 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
@@ -594,7 +594,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
594 594
595static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 595static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
596{ 596{
597 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 597 struct ivtv *itv = fh2id(fh)->itv;
598 598
599 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) 599 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
600 return -EBUSY; 600 return -EBUSY;
@@ -607,7 +607,7 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
607static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 607static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
608{ 608{
609 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 609 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
610 struct ivtv_open_id *id = fh; 610 struct ivtv_open_id *id = fh2id(fh);
611 struct ivtv *itv = id->itv; 611 struct ivtv *itv = id->itv;
612 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt); 612 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
613 613
@@ -625,7 +625,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
625 625
626static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) 626static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
627{ 627{
628 struct ivtv_open_id *id = fh; 628 struct ivtv_open_id *id = fh2id(fh);
629 struct ivtv *itv = id->itv; 629 struct ivtv *itv = id->itv;
630 struct yuv_playback_info *yi = &itv->yuv_info; 630 struct yuv_playback_info *yi = &itv->yuv_info;
631 int ret = ivtv_try_fmt_vid_out(file, fh, fmt); 631 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
@@ -670,7 +670,7 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
670 670
671static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 671static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
672{ 672{
673 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 673 struct ivtv *itv = fh2id(fh)->itv;
674 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt); 674 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
675 675
676 if (ret == 0) { 676 if (ret == 0) {
@@ -683,7 +683,7 @@ static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_f
683 683
684static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip) 684static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
685{ 685{
686 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 686 struct ivtv *itv = fh2id(fh)->itv;
687 687
688 chip->ident = V4L2_IDENT_NONE; 688 chip->ident = V4L2_IDENT_NONE;
689 chip->revision = 0; 689 chip->revision = 0;
@@ -727,7 +727,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
727 727
728static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) 728static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
729{ 729{
730 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 730 struct ivtv *itv = fh2id(fh)->itv;
731 731
732 if (v4l2_chip_match_host(&reg->match)) 732 if (v4l2_chip_match_host(&reg->match))
733 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); 733 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
@@ -739,7 +739,7 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register
739 739
740static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) 740static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
741{ 741{
742 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 742 struct ivtv *itv = fh2id(fh)->itv;
743 743
744 if (v4l2_chip_match_host(&reg->match)) 744 if (v4l2_chip_match_host(&reg->match))
745 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); 745 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
@@ -750,26 +750,9 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register
750} 750}
751#endif 751#endif
752 752
753static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
754{
755 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
756
757 *p = v4l2_prio_max(&itv->prio);
758
759 return 0;
760}
761
762static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
763{
764 struct ivtv_open_id *id = fh;
765 struct ivtv *itv = id->itv;
766
767 return v4l2_prio_change(&itv->prio, &id->prio, prio);
768}
769
770static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) 753static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
771{ 754{
772 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 755 struct ivtv *itv = fh2id(fh)->itv;
773 756
774 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); 757 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
775 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); 758 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
@@ -781,14 +764,14 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
781 764
782static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) 765static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
783{ 766{
784 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 767 struct ivtv *itv = fh2id(fh)->itv;
785 768
786 return ivtv_get_audio_input(itv, vin->index, vin); 769 return ivtv_get_audio_input(itv, vin->index, vin);
787} 770}
788 771
789static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) 772static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
790{ 773{
791 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 774 struct ivtv *itv = fh2id(fh)->itv;
792 775
793 vin->index = itv->audio_input; 776 vin->index = itv->audio_input;
794 return ivtv_get_audio_input(itv, vin->index, vin); 777 return ivtv_get_audio_input(itv, vin->index, vin);
@@ -796,7 +779,7 @@ static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
796 779
797static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) 780static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
798{ 781{
799 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 782 struct ivtv *itv = fh2id(fh)->itv;
800 783
801 if (vout->index >= itv->nof_audio_inputs) 784 if (vout->index >= itv->nof_audio_inputs)
802 return -EINVAL; 785 return -EINVAL;
@@ -809,7 +792,7 @@ static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
809 792
810static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin) 793static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
811{ 794{
812 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 795 struct ivtv *itv = fh2id(fh)->itv;
813 796
814 /* set it to defaults from our table */ 797 /* set it to defaults from our table */
815 return ivtv_get_audio_output(itv, vin->index, vin); 798 return ivtv_get_audio_output(itv, vin->index, vin);
@@ -817,7 +800,7 @@ static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vi
817 800
818static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin) 801static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
819{ 802{
820 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 803 struct ivtv *itv = fh2id(fh)->itv;
821 804
822 vin->index = 0; 805 vin->index = 0;
823 return ivtv_get_audio_output(itv, vin->index, vin); 806 return ivtv_get_audio_output(itv, vin->index, vin);
@@ -825,14 +808,14 @@ static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
825 808
826static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout) 809static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
827{ 810{
828 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 811 struct ivtv *itv = fh2id(fh)->itv;
829 812
830 return ivtv_get_audio_output(itv, vout->index, vout); 813 return ivtv_get_audio_output(itv, vout->index, vout);
831} 814}
832 815
833static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin) 816static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
834{ 817{
835 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 818 struct ivtv *itv = fh2id(fh)->itv;
836 819
837 /* set it to defaults from our table */ 820 /* set it to defaults from our table */
838 return ivtv_get_input(itv, vin->index, vin); 821 return ivtv_get_input(itv, vin->index, vin);
@@ -840,14 +823,14 @@ static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
840 823
841static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout) 824static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
842{ 825{
843 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 826 struct ivtv *itv = fh2id(fh)->itv;
844 827
845 return ivtv_get_output(itv, vout->index, vout); 828 return ivtv_get_output(itv, vout->index, vout);
846} 829}
847 830
848static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap) 831static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
849{ 832{
850 struct ivtv_open_id *id = fh; 833 struct ivtv_open_id *id = fh2id(fh);
851 struct ivtv *itv = id->itv; 834 struct ivtv *itv = id->itv;
852 struct yuv_playback_info *yi = &itv->yuv_info; 835 struct yuv_playback_info *yi = &itv->yuv_info;
853 int streamtype; 836 int streamtype;
@@ -884,7 +867,7 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca
884 867
885static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) 868static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
886{ 869{
887 struct ivtv_open_id *id = fh; 870 struct ivtv_open_id *id = fh2id(fh);
888 struct ivtv *itv = id->itv; 871 struct ivtv *itv = id->itv;
889 struct yuv_playback_info *yi = &itv->yuv_info; 872 struct yuv_playback_info *yi = &itv->yuv_info;
890 int streamtype; 873 int streamtype;
@@ -910,7 +893,7 @@ static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
910 893
911static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) 894static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
912{ 895{
913 struct ivtv_open_id *id = fh; 896 struct ivtv_open_id *id = fh2id(fh);
914 struct ivtv *itv = id->itv; 897 struct ivtv *itv = id->itv;
915 struct yuv_playback_info *yi = &itv->yuv_info; 898 struct yuv_playback_info *yi = &itv->yuv_info;
916 int streamtype; 899 int streamtype;
@@ -952,7 +935,7 @@ static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes
952 935
953static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) 936static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
954{ 937{
955 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 938 struct ivtv *itv = fh2id(fh)->itv;
956 939
957 static struct v4l2_fmtdesc formats[] = { 940 static struct v4l2_fmtdesc formats[] = {
958 { 0, 0, 0, 941 { 0, 0, 0,
@@ -980,7 +963,7 @@ static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdes
980 963
981static int ivtv_g_input(struct file *file, void *fh, unsigned int *i) 964static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
982{ 965{
983 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 966 struct ivtv *itv = fh2id(fh)->itv;
984 967
985 *i = itv->active_input; 968 *i = itv->active_input;
986 969
@@ -989,7 +972,7 @@ static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
989 972
990int ivtv_s_input(struct file *file, void *fh, unsigned int inp) 973int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
991{ 974{
992 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 975 struct ivtv *itv = fh2id(fh)->itv;
993 976
994 if (inp < 0 || inp >= itv->nof_inputs) 977 if (inp < 0 || inp >= itv->nof_inputs)
995 return -EINVAL; 978 return -EINVAL;
@@ -1023,7 +1006,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
1023 1006
1024static int ivtv_g_output(struct file *file, void *fh, unsigned int *i) 1007static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1025{ 1008{
1026 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1009 struct ivtv *itv = fh2id(fh)->itv;
1027 1010
1028 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1011 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1029 return -EINVAL; 1012 return -EINVAL;
@@ -1035,7 +1018,7 @@ static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1035 1018
1036static int ivtv_s_output(struct file *file, void *fh, unsigned int outp) 1019static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1037{ 1020{
1038 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1021 struct ivtv *itv = fh2id(fh)->itv;
1039 1022
1040 if (outp >= itv->card->nof_outputs) 1023 if (outp >= itv->card->nof_outputs)
1041 return -EINVAL; 1024 return -EINVAL;
@@ -1057,7 +1040,7 @@ static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1057 1040
1058static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 1041static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1059{ 1042{
1060 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1043 struct ivtv *itv = fh2id(fh)->itv;
1061 1044
1062 if (vf->tuner != 0) 1045 if (vf->tuner != 0)
1063 return -EINVAL; 1046 return -EINVAL;
@@ -1068,7 +1051,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
1068 1051
1069int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 1052int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1070{ 1053{
1071 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1054 struct ivtv *itv = fh2id(fh)->itv;
1072 1055
1073 if (vf->tuner != 0) 1056 if (vf->tuner != 0)
1074 return -EINVAL; 1057 return -EINVAL;
@@ -1082,7 +1065,7 @@ int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1082 1065
1083static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) 1066static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1084{ 1067{
1085 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1068 struct ivtv *itv = fh2id(fh)->itv;
1086 1069
1087 *std = itv->std; 1070 *std = itv->std;
1088 return 0; 1071 return 0;
@@ -1091,7 +1074,7 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1091int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) 1074int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1092{ 1075{
1093 DEFINE_WAIT(wait); 1076 DEFINE_WAIT(wait);
1094 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1077 struct ivtv *itv = fh2id(fh)->itv;
1095 struct yuv_playback_info *yi = &itv->yuv_info; 1078 struct yuv_playback_info *yi = &itv->yuv_info;
1096 int f; 1079 int f;
1097 1080
@@ -1170,7 +1153,7 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1170 1153
1171static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 1154static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1172{ 1155{
1173 struct ivtv_open_id *id = fh; 1156 struct ivtv_open_id *id = fh2id(fh);
1174 struct ivtv *itv = id->itv; 1157 struct ivtv *itv = id->itv;
1175 1158
1176 if (vt->index != 0) 1159 if (vt->index != 0)
@@ -1183,7 +1166,7 @@ static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1183 1166
1184static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 1167static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1185{ 1168{
1186 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1169 struct ivtv *itv = fh2id(fh)->itv;
1187 1170
1188 if (vt->index != 0) 1171 if (vt->index != 0)
1189 return -EINVAL; 1172 return -EINVAL;
@@ -1203,7 +1186,7 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1203 1186
1204static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) 1187static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1205{ 1188{
1206 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1189 struct ivtv *itv = fh2id(fh)->itv;
1207 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; 1190 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1208 int f, l; 1191 int f, l;
1209 1192
@@ -1233,7 +1216,7 @@ static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced
1233 1216
1234static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx) 1217static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1235{ 1218{
1236 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1219 struct ivtv *itv = fh2id(fh)->itv;
1237 struct v4l2_enc_idx_entry *e = idx->entry; 1220 struct v4l2_enc_idx_entry *e = idx->entry;
1238 int entries; 1221 int entries;
1239 int i; 1222 int i;
@@ -1256,7 +1239,7 @@ static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *id
1256 1239
1257static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) 1240static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1258{ 1241{
1259 struct ivtv_open_id *id = fh; 1242 struct ivtv_open_id *id = fh2id(fh);
1260 struct ivtv *itv = id->itv; 1243 struct ivtv *itv = id->itv;
1261 1244
1262 1245
@@ -1308,7 +1291,7 @@ static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd
1308 1291
1309static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) 1292static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1310{ 1293{
1311 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1294 struct ivtv *itv = fh2id(fh)->itv;
1312 1295
1313 switch (enc->cmd) { 1296 switch (enc->cmd) {
1314 case V4L2_ENC_CMD_START: 1297 case V4L2_ENC_CMD_START:
@@ -1338,7 +1321,7 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder
1338 1321
1339static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 1322static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1340{ 1323{
1341 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1324 struct ivtv *itv = fh2id(fh)->itv;
1342 u32 data[CX2341X_MBOX_MAX_DATA]; 1325 u32 data[CX2341X_MBOX_MAX_DATA];
1343 struct yuv_playback_info *yi = &itv->yuv_info; 1326 struct yuv_playback_info *yi = &itv->yuv_info;
1344 1327
@@ -1425,7 +1408,7 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1425 1408
1426static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 1409static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1427{ 1410{
1428 struct ivtv_open_id *id = fh; 1411 struct ivtv_open_id *id = fh2id(fh);
1429 struct ivtv *itv = id->itv; 1412 struct ivtv *itv = id->itv;
1430 struct yuv_playback_info *yi = &itv->yuv_info; 1413 struct yuv_playback_info *yi = &itv->yuv_info;
1431 1414
@@ -1445,7 +1428,7 @@ static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1445 1428
1446static int ivtv_overlay(struct file *file, void *fh, unsigned int on) 1429static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1447{ 1430{
1448 struct ivtv_open_id *id = fh; 1431 struct ivtv_open_id *id = fh2id(fh);
1449 struct ivtv *itv = id->itv; 1432 struct ivtv *itv = id->itv;
1450 1433
1451 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1434 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
@@ -1470,7 +1453,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscripti
1470 1453
1471static int ivtv_log_status(struct file *file, void *fh) 1454static int ivtv_log_status(struct file *file, void *fh)
1472{ 1455{
1473 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1456 struct ivtv *itv = fh2id(fh)->itv;
1474 u32 data[CX2341X_MBOX_MAX_DATA]; 1457 u32 data[CX2341X_MBOX_MAX_DATA];
1475 1458
1476 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; 1459 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
@@ -1795,9 +1778,25 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1795 return 0; 1778 return 0;
1796} 1779}
1797 1780
1798static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) 1781static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1782 int cmd, void *arg)
1799{ 1783{
1800 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1784 struct ivtv *itv = fh2id(fh)->itv;
1785
1786 if (!valid_prio) {
1787 switch (cmd) {
1788 case VIDEO_PLAY:
1789 case VIDEO_STOP:
1790 case VIDEO_FREEZE:
1791 case VIDEO_CONTINUE:
1792 case VIDEO_COMMAND:
1793 case VIDEO_SELECT_SOURCE:
1794 case AUDIO_SET_MUTE:
1795 case AUDIO_CHANNEL_SELECT:
1796 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1797 return -EBUSY;
1798 }
1799 }
1801 1800
1802 switch (cmd) { 1801 switch (cmd) {
1803 case VIDIOC_INT_RESET: { 1802 case VIDIOC_INT_RESET: {
@@ -1836,30 +1835,8 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1836 unsigned int cmd, unsigned long arg) 1835 unsigned int cmd, unsigned long arg)
1837{ 1836{
1838 struct video_device *vfd = video_devdata(filp); 1837 struct video_device *vfd = video_devdata(filp);
1839 struct ivtv_open_id *id = fh2id(filp->private_data);
1840 long ret; 1838 long ret;
1841 1839
1842 /* check priority */
1843 switch (cmd) {
1844 case VIDIOC_S_CTRL:
1845 case VIDIOC_S_STD:
1846 case VIDIOC_S_INPUT:
1847 case VIDIOC_S_OUTPUT:
1848 case VIDIOC_S_TUNER:
1849 case VIDIOC_S_FREQUENCY:
1850 case VIDIOC_S_FMT:
1851 case VIDIOC_S_CROP:
1852 case VIDIOC_S_AUDIO:
1853 case VIDIOC_S_AUDOUT:
1854 case VIDIOC_S_EXT_CTRLS:
1855 case VIDIOC_S_FBUF:
1856 case VIDIOC_S_PRIORITY:
1857 case VIDIOC_OVERLAY:
1858 ret = v4l2_prio_check(&itv->prio, id->prio);
1859 if (ret)
1860 return ret;
1861 }
1862
1863 if (ivtv_debug & IVTV_DBGFLG_IOCTL) 1840 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1864 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; 1841 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1865 ret = video_ioctl2(filp, cmd, arg); 1842 ret = video_ioctl2(filp, cmd, arg);
@@ -1884,8 +1861,6 @@ long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1884 1861
1885static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { 1862static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1886 .vidioc_querycap = ivtv_querycap, 1863 .vidioc_querycap = ivtv_querycap,
1887 .vidioc_g_priority = ivtv_g_priority,
1888 .vidioc_s_priority = ivtv_s_priority,
1889 .vidioc_s_audio = ivtv_s_audio, 1864 .vidioc_s_audio = ivtv_s_audio,
1890 .vidioc_g_audio = ivtv_g_audio, 1865 .vidioc_g_audio = ivtv_g_audio,
1891 .vidioc_enumaudio = ivtv_enumaudio, 1866 .vidioc_enumaudio = ivtv_enumaudio,
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 512607e0cda3..942683336555 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -214,6 +214,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
214 s->vdev->fops = ivtv_stream_info[type].fops; 214 s->vdev->fops = ivtv_stream_info[type].fops;
215 s->vdev->release = video_device_release; 215 s->vdev->release = video_device_release;
216 s->vdev->tvnorms = V4L2_STD_ALL; 216 s->vdev->tvnorms = V4L2_STD_ALL;
217 set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
217 ivtv_set_funcs(s->vdev); 218 ivtv_set_funcs(s->vdev);
218 return 0; 219 return 0;
219} 220}
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index 1daf1dd65bf7..69cc8166b20b 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -132,7 +132,12 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
132 if (user_dma.page_count != err) { 132 if (user_dma.page_count != err) {
133 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n", 133 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
134 err, user_dma.page_count); 134 err, user_dma.page_count);
135 return -EINVAL; 135 if (err >= 0) {
136 for (i = 0; i < err; i++)
137 put_page(dma->map[i]);
138 return -EINVAL;
139 }
140 return err;
136 } 141 }
137 142
138 dma->page_count = user_dma.page_count; 143 dma->page_count = user_dma.page_count;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 2dfa957b0fd5..b6eb51ce7735 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -174,7 +174,7 @@ ivtv_write_vbi_from_user(struct ivtv *itv,
174 ret = -EFAULT; 174 ret = -EFAULT;
175 break; 175 break;
176 } 176 }
177 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); 177 ivtv_write_vbi_line(itv, &d, &cc, &found_cc);
178 } 178 }
179 179
180 if (found_cc) 180 if (found_cc)
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index c0875378acc2..dcbab6ad4c26 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -77,23 +77,51 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
77 /* Get user pages for DMA Xfer */ 77 /* Get user pages for DMA Xfer */
78 down_read(&current->mm->mmap_sem); 78 down_read(&current->mm->mmap_sem);
79 y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL); 79 y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
80 uv_pages = get_user_pages(current, current->mm, uv_dma.uaddr, uv_dma.page_count, 0, 1, &dma->map[y_pages], NULL); 80 uv_pages = 0; /* silence gcc. value is set and consumed only if: */
81 if (y_pages == y_dma.page_count) {
82 uv_pages = get_user_pages(current, current->mm,
83 uv_dma.uaddr, uv_dma.page_count, 0, 1,
84 &dma->map[y_pages], NULL);
85 }
81 up_read(&current->mm->mmap_sem); 86 up_read(&current->mm->mmap_sem);
82 87
83 dma->page_count = y_dma.page_count + uv_dma.page_count; 88 if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
84 89 int rc = -EFAULT;
85 if (y_pages + uv_pages != dma->page_count) { 90
86 IVTV_DEBUG_WARN 91 if (y_pages == y_dma.page_count) {
87 ("failed to map user pages, returned %d instead of %d\n", 92 IVTV_DEBUG_WARN
88 y_pages + uv_pages, dma->page_count); 93 ("failed to map uv user pages, returned %d "
89 94 "expecting %d\n", uv_pages, uv_dma.page_count);
90 for (i = 0; i < dma->page_count; i++) { 95
91 put_page(dma->map[i]); 96 if (uv_pages >= 0) {
97 for (i = 0; i < uv_pages; i++)
98 put_page(dma->map[y_pages + i]);
99 rc = -EFAULT;
100 } else {
101 rc = uv_pages;
102 }
103 } else {
104 IVTV_DEBUG_WARN
105 ("failed to map y user pages, returned %d "
106 "expecting %d\n", y_pages, y_dma.page_count);
92 } 107 }
93 dma->page_count = 0; 108 if (y_pages >= 0) {
94 return -EINVAL; 109 for (i = 0; i < y_pages; i++)
110 put_page(dma->map[i]);
111 /*
112 * Inherit the -EFAULT from rc's
113 * initialization, but allow it to be
114 * overriden by uv_pages above if it was an
115 * actual errno.
116 */
117 } else {
118 rc = y_pages;
119 }
120 return rc;
95 } 121 }
96 122
123 dma->page_count = y_pages + uv_pages;
124
97 /* Fill & map SG List */ 125 /* Fill & map SG List */
98 if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) { 126 if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
99 IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n"); 127 IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index e7e717800ee2..b03d74e09a3c 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -8,7 +8,7 @@
8 * operation (via the mem2mem framework). 8 * operation (via the mem2mem framework).
9 * 9 *
10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. 10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
11 * Pawel Osciak, <p.osciak@samsung.com> 11 * Pawel Osciak, <pawel@osciak.com>
12 * Marek Szyprowski, <m.szyprowski@samsung.com> 12 * Marek Szyprowski, <m.szyprowski@samsung.com>
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
@@ -28,12 +28,12 @@
28#include <media/v4l2-mem2mem.h> 28#include <media/v4l2-mem2mem.h>
29#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-ioctl.h> 30#include <media/v4l2-ioctl.h>
31#include <media/videobuf-vmalloc.h> 31#include <media/videobuf2-vmalloc.h>
32 32
33#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev" 33#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev"
34 34
35MODULE_DESCRIPTION("Virtual device for mem2mem framework testing"); 35MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
36MODULE_AUTHOR("Pawel Osciak, <p.osciak@samsung.com>"); 36MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39 39
@@ -201,11 +201,6 @@ struct m2mtest_ctx {
201 struct v4l2_m2m_ctx *m2m_ctx; 201 struct v4l2_m2m_ctx *m2m_ctx;
202}; 202};
203 203
204struct m2mtest_buffer {
205 /* vb must be first! */
206 struct videobuf_buffer vb;
207};
208
209static struct v4l2_queryctrl *get_ctrl(int id) 204static struct v4l2_queryctrl *get_ctrl(int id)
210{ 205{
211 int i; 206 int i;
@@ -219,37 +214,41 @@ static struct v4l2_queryctrl *get_ctrl(int id)
219} 214}
220 215
221static int device_process(struct m2mtest_ctx *ctx, 216static int device_process(struct m2mtest_ctx *ctx,
222 struct m2mtest_buffer *in_buf, 217 struct vb2_buffer *in_vb,
223 struct m2mtest_buffer *out_buf) 218 struct vb2_buffer *out_vb)
224{ 219{
225 struct m2mtest_dev *dev = ctx->dev; 220 struct m2mtest_dev *dev = ctx->dev;
221 struct m2mtest_q_data *q_data;
226 u8 *p_in, *p_out; 222 u8 *p_in, *p_out;
227 int x, y, t, w; 223 int x, y, t, w;
228 int tile_w, bytes_left; 224 int tile_w, bytes_left;
229 struct videobuf_queue *src_q; 225 int width, height, bytesperline;
230 struct videobuf_queue *dst_q;
231 226
232 src_q = v4l2_m2m_get_src_vq(ctx->m2m_ctx); 227 q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
233 dst_q = v4l2_m2m_get_dst_vq(ctx->m2m_ctx); 228
234 p_in = videobuf_queue_to_vaddr(src_q, &in_buf->vb); 229 width = q_data->width;
235 p_out = videobuf_queue_to_vaddr(dst_q, &out_buf->vb); 230 height = q_data->height;
231 bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
232
233 p_in = vb2_plane_vaddr(in_vb, 0);
234 p_out = vb2_plane_vaddr(out_vb, 0);
236 if (!p_in || !p_out) { 235 if (!p_in || !p_out) {
237 v4l2_err(&dev->v4l2_dev, 236 v4l2_err(&dev->v4l2_dev,
238 "Acquiring kernel pointers to buffers failed\n"); 237 "Acquiring kernel pointers to buffers failed\n");
239 return -EFAULT; 238 return -EFAULT;
240 } 239 }
241 240
242 if (in_buf->vb.size > out_buf->vb.size) { 241 if (vb2_plane_size(in_vb, 0) > vb2_plane_size(out_vb, 0)) {
243 v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n"); 242 v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
244 return -EINVAL; 243 return -EINVAL;
245 } 244 }
246 245
247 tile_w = (in_buf->vb.width * (q_data[V4L2_M2M_DST].fmt->depth >> 3)) 246 tile_w = (width * (q_data[V4L2_M2M_DST].fmt->depth >> 3))
248 / MEM2MEM_NUM_TILES; 247 / MEM2MEM_NUM_TILES;
249 bytes_left = in_buf->vb.bytesperline - tile_w * MEM2MEM_NUM_TILES; 248 bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES;
250 w = 0; 249 w = 0;
251 250
252 for (y = 0; y < in_buf->vb.height; ++y) { 251 for (y = 0; y < height; ++y) {
253 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) { 252 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
254 if (w & 0x1) { 253 if (w & 0x1) {
255 for (x = 0; x < tile_w; ++x) 254 for (x = 0; x < tile_w; ++x)
@@ -301,6 +300,21 @@ static void job_abort(void *priv)
301 ctx->aborting = 1; 300 ctx->aborting = 1;
302} 301}
303 302
303static void m2mtest_lock(void *priv)
304{
305 struct m2mtest_ctx *ctx = priv;
306 struct m2mtest_dev *dev = ctx->dev;
307 mutex_lock(&dev->dev_mutex);
308}
309
310static void m2mtest_unlock(void *priv)
311{
312 struct m2mtest_ctx *ctx = priv;
313 struct m2mtest_dev *dev = ctx->dev;
314 mutex_unlock(&dev->dev_mutex);
315}
316
317
304/* device_run() - prepares and starts the device 318/* device_run() - prepares and starts the device
305 * 319 *
306 * This simulates all the immediate preparations required before starting 320 * This simulates all the immediate preparations required before starting
@@ -311,7 +325,7 @@ static void device_run(void *priv)
311{ 325{
312 struct m2mtest_ctx *ctx = priv; 326 struct m2mtest_ctx *ctx = priv;
313 struct m2mtest_dev *dev = ctx->dev; 327 struct m2mtest_dev *dev = ctx->dev;
314 struct m2mtest_buffer *src_buf, *dst_buf; 328 struct vb2_buffer *src_buf, *dst_buf;
315 329
316 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 330 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
317 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 331 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
@@ -322,12 +336,11 @@ static void device_run(void *priv)
322 schedule_irq(dev, ctx->transtime); 336 schedule_irq(dev, ctx->transtime);
323} 337}
324 338
325
326static void device_isr(unsigned long priv) 339static void device_isr(unsigned long priv)
327{ 340{
328 struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv; 341 struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv;
329 struct m2mtest_ctx *curr_ctx; 342 struct m2mtest_ctx *curr_ctx;
330 struct m2mtest_buffer *src_buf, *dst_buf; 343 struct vb2_buffer *src_vb, *dst_vb;
331 unsigned long flags; 344 unsigned long flags;
332 345
333 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev); 346 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);
@@ -338,31 +351,26 @@ static void device_isr(unsigned long priv)
338 return; 351 return;
339 } 352 }
340 353
341 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); 354 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
342 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx); 355 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
356
343 curr_ctx->num_processed++; 357 curr_ctx->num_processed++;
344 358
359 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
360 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
361 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
362 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
363
345 if (curr_ctx->num_processed == curr_ctx->translen 364 if (curr_ctx->num_processed == curr_ctx->translen
346 || curr_ctx->aborting) { 365 || curr_ctx->aborting) {
347 dprintk(curr_ctx->dev, "Finishing transaction\n"); 366 dprintk(curr_ctx->dev, "Finishing transaction\n");
348 curr_ctx->num_processed = 0; 367 curr_ctx->num_processed = 0;
349 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
350 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
351 wake_up(&src_buf->vb.done);
352 wake_up(&dst_buf->vb.done);
353 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
354 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx); 368 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx);
355 } else { 369 } else {
356 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
357 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
358 wake_up(&src_buf->vb.done);
359 wake_up(&dst_buf->vb.done);
360 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
361 device_run(curr_ctx); 370 device_run(curr_ctx);
362 } 371 }
363} 372}
364 373
365
366/* 374/*
367 * video ioctls 375 * video ioctls
368 */ 376 */
@@ -423,7 +431,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
423 431
424static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) 432static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
425{ 433{
426 struct videobuf_queue *vq; 434 struct vb2_queue *vq;
427 struct m2mtest_q_data *q_data; 435 struct m2mtest_q_data *q_data;
428 436
429 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 437 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
@@ -434,7 +442,7 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
434 442
435 f->fmt.pix.width = q_data->width; 443 f->fmt.pix.width = q_data->width;
436 f->fmt.pix.height = q_data->height; 444 f->fmt.pix.height = q_data->height;
437 f->fmt.pix.field = vq->field; 445 f->fmt.pix.field = V4L2_FIELD_NONE;
438 f->fmt.pix.pixelformat = q_data->fmt->fourcc; 446 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
439 f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3; 447 f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
440 f->fmt.pix.sizeimage = q_data->sizeimage; 448 f->fmt.pix.sizeimage = q_data->sizeimage;
@@ -523,7 +531,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
523static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) 531static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
524{ 532{
525 struct m2mtest_q_data *q_data; 533 struct m2mtest_q_data *q_data;
526 struct videobuf_queue *vq; 534 struct vb2_queue *vq;
527 535
528 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 536 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
529 if (!vq) 537 if (!vq)
@@ -533,7 +541,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
533 if (!q_data) 541 if (!q_data)
534 return -EINVAL; 542 return -EINVAL;
535 543
536 if (videobuf_queue_is_busy(vq)) { 544 if (vb2_is_busy(vq)) {
537 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); 545 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
538 return -EBUSY; 546 return -EBUSY;
539 } 547 }
@@ -543,7 +551,6 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
543 q_data->height = f->fmt.pix.height; 551 q_data->height = f->fmt.pix.height;
544 q_data->sizeimage = q_data->width * q_data->height 552 q_data->sizeimage = q_data->width * q_data->height
545 * q_data->fmt->depth >> 3; 553 * q_data->fmt->depth >> 3;
546 vq->field = f->fmt.pix.field;
547 554
548 dprintk(ctx->dev, 555 dprintk(ctx->dev,
549 "Setting format for type %d, wxh: %dx%d, fmt: %d\n", 556 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
@@ -733,120 +740,94 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
733 * Queue operations 740 * Queue operations
734 */ 741 */
735 742
736static void m2mtest_buf_release(struct videobuf_queue *vq, 743static int m2mtest_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
737 struct videobuf_buffer *vb) 744 unsigned int *nplanes, unsigned long sizes[],
738{ 745 void *alloc_ctxs[])
739 struct m2mtest_ctx *ctx = vq->priv_data;
740
741 dprintk(ctx->dev, "type: %d, index: %d, state: %d\n",
742 vq->type, vb->i, vb->state);
743
744 videobuf_vmalloc_free(vb);
745 vb->state = VIDEOBUF_NEEDS_INIT;
746}
747
748static int m2mtest_buf_setup(struct videobuf_queue *vq, unsigned int *count,
749 unsigned int *size)
750{ 746{
751 struct m2mtest_ctx *ctx = vq->priv_data; 747 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
752 struct m2mtest_q_data *q_data; 748 struct m2mtest_q_data *q_data;
749 unsigned int size, count = *nbuffers;
753 750
754 q_data = get_q_data(vq->type); 751 q_data = get_q_data(vq->type);
755 752
756 *size = q_data->width * q_data->height * q_data->fmt->depth >> 3; 753 size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
757 dprintk(ctx->dev, "size:%d, w/h %d/%d, depth: %d\n",
758 *size, q_data->width, q_data->height, q_data->fmt->depth);
759 754
760 if (0 == *count) 755 while (size * count > MEM2MEM_VID_MEM_LIMIT)
761 *count = MEM2MEM_DEF_NUM_BUFS; 756 (count)--;
762 757
763 while (*size * *count > MEM2MEM_VID_MEM_LIMIT) 758 *nplanes = 1;
764 (*count)--; 759 *nbuffers = count;
760 sizes[0] = size;
765 761
766 v4l2_info(&ctx->dev->v4l2_dev, 762 /*
767 "%d buffers of size %d set up.\n", *count, *size); 763 * videobuf2-vmalloc allocator is context-less so no need to set
764 * alloc_ctxs array.
765 */
766
767 dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
768 768
769 return 0; 769 return 0;
770} 770}
771 771
772static int m2mtest_buf_prepare(struct videobuf_queue *vq, 772static int m2mtest_buf_prepare(struct vb2_buffer *vb)
773 struct videobuf_buffer *vb,
774 enum v4l2_field field)
775{ 773{
776 struct m2mtest_ctx *ctx = vq->priv_data; 774 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
777 struct m2mtest_q_data *q_data; 775 struct m2mtest_q_data *q_data;
778 int ret;
779 776
780 dprintk(ctx->dev, "type: %d, index: %d, state: %d\n", 777 dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
781 vq->type, vb->i, vb->state);
782 778
783 q_data = get_q_data(vq->type); 779 q_data = get_q_data(vb->vb2_queue->type);
784 780
785 if (vb->baddr) { 781 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
786 /* User-provided buffer */ 782 dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
787 if (vb->bsize < q_data->sizeimage) { 783 __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
788 /* Buffer too small to fit a frame */
789 v4l2_err(&ctx->dev->v4l2_dev,
790 "User-provided buffer too small\n");
791 return -EINVAL;
792 }
793 } else if (vb->state != VIDEOBUF_NEEDS_INIT
794 && vb->bsize < q_data->sizeimage) {
795 /* We provide the buffer, but it's already been initialized
796 * and is too small */
797 return -EINVAL; 784 return -EINVAL;
798 } 785 }
799 786
800 vb->width = q_data->width; 787 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
801 vb->height = q_data->height;
802 vb->bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
803 vb->size = q_data->sizeimage;
804 vb->field = field;
805
806 if (VIDEOBUF_NEEDS_INIT == vb->state) {
807 ret = videobuf_iolock(vq, vb, NULL);
808 if (ret) {
809 v4l2_err(&ctx->dev->v4l2_dev,
810 "Iolock failed\n");
811 goto fail;
812 }
813 }
814
815 vb->state = VIDEOBUF_PREPARED;
816 788
817 return 0; 789 return 0;
818fail:
819 m2mtest_buf_release(vq, vb);
820 return ret;
821} 790}
822 791
823static void m2mtest_buf_queue(struct videobuf_queue *vq, 792static void m2mtest_buf_queue(struct vb2_buffer *vb)
824 struct videobuf_buffer *vb)
825{ 793{
826 struct m2mtest_ctx *ctx = vq->priv_data; 794 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
827 795 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
828 v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb);
829} 796}
830 797
831static struct videobuf_queue_ops m2mtest_qops = { 798static struct vb2_ops m2mtest_qops = {
832 .buf_setup = m2mtest_buf_setup, 799 .queue_setup = m2mtest_queue_setup,
833 .buf_prepare = m2mtest_buf_prepare, 800 .buf_prepare = m2mtest_buf_prepare,
834 .buf_queue = m2mtest_buf_queue, 801 .buf_queue = m2mtest_buf_queue,
835 .buf_release = m2mtest_buf_release,
836}; 802};
837 803
838static void queue_init(void *priv, struct videobuf_queue *vq, 804static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
839 enum v4l2_buf_type type)
840{ 805{
841 struct m2mtest_ctx *ctx = priv; 806 struct m2mtest_ctx *ctx = priv;
842 struct m2mtest_dev *dev = ctx->dev; 807 int ret;
843 808
844 videobuf_queue_vmalloc_init(vq, &m2mtest_qops, dev->v4l2_dev.dev, 809 memset(src_vq, 0, sizeof(*src_vq));
845 &dev->irqlock, type, V4L2_FIELD_NONE, 810 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
846 sizeof(struct m2mtest_buffer), priv, 811 src_vq->io_modes = VB2_MMAP;
847 &dev->dev_mutex); 812 src_vq->drv_priv = ctx;
848} 813 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
814 src_vq->ops = &m2mtest_qops;
815 src_vq->mem_ops = &vb2_vmalloc_memops;
849 816
817 ret = vb2_queue_init(src_vq);
818 if (ret)
819 return ret;
820
821 memset(dst_vq, 0, sizeof(*dst_vq));
822 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
823 dst_vq->io_modes = VB2_MMAP;
824 dst_vq->drv_priv = ctx;
825 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
826 dst_vq->ops = &m2mtest_qops;
827 dst_vq->mem_ops = &vb2_vmalloc_memops;
828
829 return vb2_queue_init(dst_vq);
830}
850 831
851/* 832/*
852 * File operations 833 * File operations
@@ -866,7 +847,8 @@ static int m2mtest_open(struct file *file)
866 ctx->transtime = MEM2MEM_DEF_TRANSTIME; 847 ctx->transtime = MEM2MEM_DEF_TRANSTIME;
867 ctx->num_processed = 0; 848 ctx->num_processed = 0;
868 849
869 ctx->m2m_ctx = v4l2_m2m_ctx_init(ctx, dev->m2m_dev, queue_init); 850 ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
851
870 if (IS_ERR(ctx->m2m_ctx)) { 852 if (IS_ERR(ctx->m2m_ctx)) {
871 int ret = PTR_ERR(ctx->m2m_ctx); 853 int ret = PTR_ERR(ctx->m2m_ctx);
872 854
@@ -932,6 +914,8 @@ static struct v4l2_m2m_ops m2m_ops = {
932 .device_run = device_run, 914 .device_run = device_run,
933 .job_ready = job_ready, 915 .job_ready = job_ready,
934 .job_abort = job_abort, 916 .job_abort = job_abort,
917 .lock = m2mtest_lock,
918 .unlock = m2mtest_unlock,
935}; 919};
936 920
937static int m2mtest_probe(struct platform_device *pdev) 921static int m2mtest_probe(struct platform_device *pdev)
@@ -990,6 +974,7 @@ static int m2mtest_probe(struct platform_device *pdev)
990 974
991 return 0; 975 return 0;
992 976
977 v4l2_m2m_release(dev->m2m_dev);
993err_m2m: 978err_m2m:
994 video_unregister_device(dev->vfd); 979 video_unregister_device(dev->vfd);
995rel_vdev: 980rel_vdev:
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 48d2c2419c13..b09a3c80a15e 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1547,7 +1547,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1547 return 0; 1547 return 0;
1548} 1548}
1549 1549
1550static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) 1550static long vidioc_default(struct file *file, void *fh, bool valid_prio,
1551 int cmd, void *arg)
1551{ 1552{
1552 switch (cmd) { 1553 switch (cmd) {
1553 case MEYEIOC_G_PARAMS: 1554 case MEYEIOC_G_PARAMS:
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index f7fc88d240e6..e2bbd8c35c98 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -79,7 +79,7 @@ static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
79static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { 79static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
80 /* Order important - see above */ 80 /* Order important - see above */
81 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, 81 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
82 {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, 82 {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
83}; 83};
84 84
85struct mt9m001 { 85struct mt9m001 {
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 6a784c87e5ff..e313d8390092 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -95,7 +95,7 @@ static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
95static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { 95static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
96 /* Order important - see above */ 96 /* Order important - see above */
97 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, 97 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
98 {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, 98 {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
99}; 99};
100 100
101struct mt9v022 { 101struct mt9v022 {
@@ -392,7 +392,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
392 * icd->try_fmt(), datawidth is from our supported format list 392 * icd->try_fmt(), datawidth is from our supported format list
393 */ 393 */
394 switch (mf->code) { 394 switch (mf->code) {
395 case V4L2_MBUS_FMT_GREY8_1X8: 395 case V4L2_MBUS_FMT_Y8_1X8:
396 case V4L2_MBUS_FMT_Y10_1X10: 396 case V4L2_MBUS_FMT_Y10_1X10:
397 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) 397 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
398 return -EINVAL; 398 return -EINVAL;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index b9cb4a436959..502e2a40964c 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -21,7 +21,7 @@
21 21
22#include <media/v4l2-common.h> 22#include <media/v4l2-common.h>
23#include <media/v4l2-dev.h> 23#include <media/v4l2-dev.h>
24#include <media/videobuf-dma-contig.h> 24#include <media/videobuf2-dma-contig.h>
25#include <media/soc_camera.h> 25#include <media/soc_camera.h>
26#include <media/soc_mediabus.h> 26#include <media/soc_mediabus.h>
27 27
@@ -62,10 +62,16 @@
62 62
63#define MAX_VIDEO_MEM 16 63#define MAX_VIDEO_MEM 16
64 64
65enum csi_buffer_state {
66 CSI_BUF_NEEDS_INIT,
67 CSI_BUF_PREPARED,
68};
69
65struct mx3_camera_buffer { 70struct mx3_camera_buffer {
66 /* common v4l buffer stuff -- must be first */ 71 /* common v4l buffer stuff -- must be first */
67 struct videobuf_buffer vb; 72 struct vb2_buffer vb;
68 enum v4l2_mbus_pixelcode code; 73 enum csi_buffer_state state;
74 struct list_head queue;
69 75
70 /* One descriptot per scatterlist (per frame) */ 76 /* One descriptot per scatterlist (per frame) */
71 struct dma_async_tx_descriptor *txd; 77 struct dma_async_tx_descriptor *txd;
@@ -108,6 +114,9 @@ struct mx3_camera_dev {
108 struct list_head capture; 114 struct list_head capture;
109 spinlock_t lock; /* Protects video buffer lists */ 115 spinlock_t lock; /* Protects video buffer lists */
110 struct mx3_camera_buffer *active; 116 struct mx3_camera_buffer *active;
117 struct vb2_alloc_ctx *alloc_ctx;
118 enum v4l2_field field;
119 int sequence;
111 120
112 /* IDMAC / dmaengine interface */ 121 /* IDMAC / dmaengine interface */
113 struct idmac_channel *idmac_channel[1]; /* We need one channel */ 122 struct idmac_channel *idmac_channel[1]; /* We need one channel */
@@ -130,6 +139,11 @@ static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
130 __raw_writel(value, mx3->base + reg); 139 __raw_writel(value, mx3->base + reg);
131} 140}
132 141
142static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
143{
144 return container_of(vb, struct mx3_camera_buffer, vb);
145}
146
133/* Called from the IPU IDMAC ISR */ 147/* Called from the IPU IDMAC ISR */
134static void mx3_cam_dma_done(void *arg) 148static void mx3_cam_dma_done(void *arg)
135{ 149{
@@ -137,20 +151,20 @@ static void mx3_cam_dma_done(void *arg)
137 struct dma_chan *chan = desc->txd.chan; 151 struct dma_chan *chan = desc->txd.chan;
138 struct idmac_channel *ichannel = to_idmac_chan(chan); 152 struct idmac_channel *ichannel = to_idmac_chan(chan);
139 struct mx3_camera_dev *mx3_cam = ichannel->client; 153 struct mx3_camera_dev *mx3_cam = ichannel->client;
140 struct videobuf_buffer *vb;
141 154
142 dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n", 155 dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
143 desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0); 156 desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
144 157
145 spin_lock(&mx3_cam->lock); 158 spin_lock(&mx3_cam->lock);
146 if (mx3_cam->active) { 159 if (mx3_cam->active) {
147 vb = &mx3_cam->active->vb; 160 struct vb2_buffer *vb = &mx3_cam->active->vb;
148 161 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
149 list_del_init(&vb->queue); 162
150 vb->state = VIDEOBUF_DONE; 163 list_del_init(&buf->queue);
151 do_gettimeofday(&vb->ts); 164 do_gettimeofday(&vb->v4l2_buf.timestamp);
152 vb->field_count++; 165 vb->v4l2_buf.field = mx3_cam->field;
153 wake_up(&vb->done); 166 vb->v4l2_buf.sequence = mx3_cam->sequence++;
167 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
154 } 168 }
155 169
156 if (list_empty(&mx3_cam->capture)) { 170 if (list_empty(&mx3_cam->capture)) {
@@ -165,50 +179,22 @@ static void mx3_cam_dma_done(void *arg)
165 } 179 }
166 180
167 mx3_cam->active = list_entry(mx3_cam->capture.next, 181 mx3_cam->active = list_entry(mx3_cam->capture.next,
168 struct mx3_camera_buffer, vb.queue); 182 struct mx3_camera_buffer, queue);
169 mx3_cam->active->vb.state = VIDEOBUF_ACTIVE;
170 spin_unlock(&mx3_cam->lock); 183 spin_unlock(&mx3_cam->lock);
171} 184}
172 185
173static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf)
174{
175 struct soc_camera_device *icd = vq->priv_data;
176 struct videobuf_buffer *vb = &buf->vb;
177 struct dma_async_tx_descriptor *txd = buf->txd;
178 struct idmac_channel *ichan;
179
180 BUG_ON(in_interrupt());
181
182 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
183 vb, vb->baddr, vb->bsize);
184
185 /*
186 * This waits until this buffer is out of danger, i.e., until it is no
187 * longer in STATE_QUEUED or STATE_ACTIVE
188 */
189 videobuf_waiton(vq, vb, 0, 0);
190 if (txd) {
191 ichan = to_idmac_chan(txd->chan);
192 async_tx_ack(txd);
193 }
194 videobuf_dma_contig_free(vq, vb);
195 buf->txd = NULL;
196
197 vb->state = VIDEOBUF_NEEDS_INIT;
198}
199
200/* 186/*
201 * Videobuf operations 187 * Videobuf operations
202 */ 188 */
203 189
204/* 190/*
205 * Calculate the __buffer__ (not data) size and number of buffers. 191 * Calculate the __buffer__ (not data) size and number of buffers.
206 * Called with .vb_lock held
207 */ 192 */
208static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, 193static int mx3_videobuf_setup(struct vb2_queue *vq,
209 unsigned int *size) 194 unsigned int *count, unsigned int *num_planes,
195 unsigned long sizes[], void *alloc_ctxs[])
210{ 196{
211 struct soc_camera_device *icd = vq->priv_data; 197 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
212 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 198 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
213 struct mx3_camera_dev *mx3_cam = ici->priv; 199 struct mx3_camera_dev *mx3_cam = ici->priv;
214 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 200 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
@@ -220,162 +206,133 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
220 if (!mx3_cam->idmac_channel[0]) 206 if (!mx3_cam->idmac_channel[0])
221 return -EINVAL; 207 return -EINVAL;
222 208
223 *size = bytes_per_line * icd->user_height; 209 *num_planes = 1;
210
211 mx3_cam->sequence = 0;
212 sizes[0] = bytes_per_line * icd->user_height;
213 alloc_ctxs[0] = mx3_cam->alloc_ctx;
224 214
225 if (!*count) 215 if (!*count)
226 *count = 32; 216 *count = 32;
227 217
228 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) 218 if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
229 *count = MAX_VIDEO_MEM * 1024 * 1024 / *size; 219 *count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0];
230 220
231 return 0; 221 return 0;
232} 222}
233 223
234/* Called with .vb_lock held */ 224static int mx3_videobuf_prepare(struct vb2_buffer *vb)
235static int mx3_videobuf_prepare(struct videobuf_queue *vq,
236 struct videobuf_buffer *vb, enum v4l2_field field)
237{ 225{
238 struct soc_camera_device *icd = vq->priv_data; 226 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
239 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 227 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
240 struct mx3_camera_dev *mx3_cam = ici->priv; 228 struct mx3_camera_dev *mx3_cam = ici->priv;
241 struct mx3_camera_buffer *buf = 229 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
242 container_of(vb, struct mx3_camera_buffer, vb); 230 struct scatterlist *sg;
231 struct mx3_camera_buffer *buf;
243 size_t new_size; 232 size_t new_size;
244 int ret;
245 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 233 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
246 icd->current_fmt->host_fmt); 234 icd->current_fmt->host_fmt);
247 235
248 if (bytes_per_line < 0) 236 if (bytes_per_line < 0)
249 return bytes_per_line; 237 return bytes_per_line;
250 238
251 new_size = bytes_per_line * icd->user_height; 239 buf = to_mx3_vb(vb);
240 sg = &buf->sg;
252 241
253 /* 242 new_size = bytes_per_line * icd->user_height;
254 * I think, in buf_prepare you only have to protect global data,
255 * the actual buffer is yours
256 */
257
258 if (buf->code != icd->current_fmt->code ||
259 vb->width != icd->user_width ||
260 vb->height != icd->user_height ||
261 vb->field != field) {
262 buf->code = icd->current_fmt->code;
263 vb->width = icd->user_width;
264 vb->height = icd->user_height;
265 vb->field = field;
266 if (vb->state != VIDEOBUF_NEEDS_INIT)
267 free_buffer(vq, buf);
268 }
269 243
270 if (vb->baddr && vb->bsize < new_size) { 244 if (vb2_plane_size(vb, 0) < new_size) {
271 /* User provided buffer, but it is too small */ 245 dev_err(icd->dev.parent, "Buffer too small (%lu < %zu)\n",
272 ret = -ENOMEM; 246 vb2_plane_size(vb, 0), new_size);
273 goto out; 247 return -ENOBUFS;
274 } 248 }
275 249
276 if (vb->state == VIDEOBUF_NEEDS_INIT) { 250 if (buf->state == CSI_BUF_NEEDS_INIT) {
277 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 251 sg_dma_address(sg) = vb2_dma_contig_plane_paddr(vb, 0);
278 struct scatterlist *sg = &buf->sg; 252 sg_dma_len(sg) = new_size;
279
280 /*
281 * The total size of video-buffers that will be allocated / mapped.
282 * *size that we calculated in videobuf_setup gets assigned to
283 * vb->bsize, and now we use the same calculation to get vb->size.
284 */
285 vb->size = new_size;
286
287 /* This actually (allocates and) maps buffers */
288 ret = videobuf_iolock(vq, vb, NULL);
289 if (ret)
290 goto fail;
291
292 /*
293 * We will have to configure the IDMAC channel. It has two slots
294 * for DMA buffers, we shall enter the first two buffers there,
295 * and then submit new buffers in DMA-ready interrupts
296 */
297 sg_init_table(sg, 1);
298 sg_dma_address(sg) = videobuf_to_dma_contig(vb);
299 sg_dma_len(sg) = vb->size;
300 253
301 buf->txd = ichan->dma_chan.device->device_prep_slave_sg( 254 buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
302 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE, 255 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
303 DMA_PREP_INTERRUPT); 256 DMA_PREP_INTERRUPT);
304 if (!buf->txd) { 257 if (!buf->txd)
305 ret = -EIO; 258 return -EIO;
306 goto fail;
307 }
308 259
309 buf->txd->callback_param = buf->txd; 260 buf->txd->callback_param = buf->txd;
310 buf->txd->callback = mx3_cam_dma_done; 261 buf->txd->callback = mx3_cam_dma_done;
311 262
312 vb->state = VIDEOBUF_PREPARED; 263 buf->state = CSI_BUF_PREPARED;
313 } 264 }
314 265
315 return 0; 266 vb2_set_plane_payload(vb, 0, new_size);
316 267
317fail: 268 return 0;
318 free_buffer(vq, buf);
319out:
320 return ret;
321} 269}
322 270
323static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc) 271static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
324{ 272{
325 /* Add more formats as need arises and test possibilities appear... */ 273 /* Add more formats as need arises and test possibilities appear... */
326 switch (fourcc) { 274 switch (fourcc) {
327 case V4L2_PIX_FMT_RGB565:
328 return IPU_PIX_FMT_RGB565;
329 case V4L2_PIX_FMT_RGB24: 275 case V4L2_PIX_FMT_RGB24:
330 return IPU_PIX_FMT_RGB24; 276 return IPU_PIX_FMT_RGB24;
331 case V4L2_PIX_FMT_RGB332: 277 case V4L2_PIX_FMT_UYVY:
332 return IPU_PIX_FMT_RGB332; 278 case V4L2_PIX_FMT_RGB565:
333 case V4L2_PIX_FMT_YUV422P:
334 return IPU_PIX_FMT_YVU422P;
335 default: 279 default:
336 return IPU_PIX_FMT_GENERIC; 280 return IPU_PIX_FMT_GENERIC;
337 } 281 }
338} 282}
339 283
340/* 284static void mx3_videobuf_queue(struct vb2_buffer *vb)
341 * Called with .vb_lock mutex held and
342 * under spinlock_irqsave(&mx3_cam->lock, ...)
343 */
344static void mx3_videobuf_queue(struct videobuf_queue *vq,
345 struct videobuf_buffer *vb)
346{ 285{
347 struct soc_camera_device *icd = vq->priv_data; 286 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
348 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 287 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
349 struct mx3_camera_dev *mx3_cam = ici->priv; 288 struct mx3_camera_dev *mx3_cam = ici->priv;
350 struct mx3_camera_buffer *buf = 289 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
351 container_of(vb, struct mx3_camera_buffer, vb);
352 struct dma_async_tx_descriptor *txd = buf->txd; 290 struct dma_async_tx_descriptor *txd = buf->txd;
353 struct idmac_channel *ichan = to_idmac_chan(txd->chan); 291 struct idmac_channel *ichan = to_idmac_chan(txd->chan);
354 struct idmac_video_param *video = &ichan->params.video; 292 struct idmac_video_param *video = &ichan->params.video;
355 dma_cookie_t cookie; 293 dma_cookie_t cookie;
356 u32 fourcc = icd->current_fmt->host_fmt->fourcc; 294 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
357 295 unsigned long flags;
358 BUG_ON(!irqs_disabled());
359 296
360 /* This is the configuration of one sg-element */ 297 /* This is the configuration of one sg-element */
361 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); 298 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc);
362 video->out_width = icd->user_width; 299
363 video->out_height = icd->user_height; 300 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
364 video->out_stride = icd->user_width; 301 /*
302 * If the IPU DMA channel is configured to transport
303 * generic 8-bit data, we have to set up correctly the
304 * geometry parameters upon the current pixel format.
305 * So, since the DMA horizontal parameters are expressed
306 * in bytes not pixels, convert these in the right unit.
307 */
308 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
309 icd->current_fmt->host_fmt);
310 BUG_ON(bytes_per_line <= 0);
311
312 video->out_width = bytes_per_line;
313 video->out_height = icd->user_height;
314 video->out_stride = bytes_per_line;
315 } else {
316 /*
317 * For IPU known formats the pixel unit will be managed
318 * successfully by the IPU code
319 */
320 video->out_width = icd->user_width;
321 video->out_height = icd->user_height;
322 video->out_stride = icd->user_width;
323 }
365 324
366#ifdef DEBUG 325#ifdef DEBUG
367 /* helps to see what DMA actually has written */ 326 /* helps to see what DMA actually has written */
368 memset((void *)vb->baddr, 0xaa, vb->bsize); 327 if (vb2_plane_vaddr(vb, 0))
328 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
369#endif 329#endif
370 330
371 list_add_tail(&vb->queue, &mx3_cam->capture); 331 spin_lock_irqsave(&mx3_cam->lock, flags);
332 list_add_tail(&buf->queue, &mx3_cam->capture);
372 333
373 if (!mx3_cam->active) { 334 if (!mx3_cam->active)
374 mx3_cam->active = buf; 335 mx3_cam->active = buf;
375 vb->state = VIDEOBUF_ACTIVE;
376 } else {
377 vb->state = VIDEOBUF_QUEUED;
378 }
379 336
380 spin_unlock_irq(&mx3_cam->lock); 337 spin_unlock_irq(&mx3_cam->lock);
381 338
@@ -383,67 +340,87 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
383 dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n", 340 dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n",
384 cookie, sg_dma_address(&buf->sg)); 341 cookie, sg_dma_address(&buf->sg));
385 342
386 spin_lock_irq(&mx3_cam->lock);
387
388 if (cookie >= 0) 343 if (cookie >= 0)
389 return; 344 return;
390 345
391 /* Submit error */ 346 spin_lock_irq(&mx3_cam->lock);
392 vb->state = VIDEOBUF_PREPARED;
393 347
394 list_del_init(&vb->queue); 348 /* Submit error */
349 list_del_init(&buf->queue);
395 350
396 if (mx3_cam->active == buf) 351 if (mx3_cam->active == buf)
397 mx3_cam->active = NULL; 352 mx3_cam->active = NULL;
353
354 spin_unlock_irqrestore(&mx3_cam->lock, flags);
355 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
398} 356}
399 357
400/* Called with .vb_lock held */ 358static void mx3_videobuf_release(struct vb2_buffer *vb)
401static void mx3_videobuf_release(struct videobuf_queue *vq,
402 struct videobuf_buffer *vb)
403{ 359{
404 struct soc_camera_device *icd = vq->priv_data; 360 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
405 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 361 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
406 struct mx3_camera_dev *mx3_cam = ici->priv; 362 struct mx3_camera_dev *mx3_cam = ici->priv;
407 struct mx3_camera_buffer *buf = 363 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
408 container_of(vb, struct mx3_camera_buffer, vb); 364 struct dma_async_tx_descriptor *txd = buf->txd;
409 unsigned long flags; 365 unsigned long flags;
410 366
411 dev_dbg(icd->dev.parent, 367 dev_dbg(icd->dev.parent,
412 "Release%s DMA 0x%08x (state %d), queue %sempty\n", 368 "Release%s DMA 0x%08x, queue %sempty\n",
413 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg), 369 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
414 vb->state, list_empty(&vb->queue) ? "" : "not "); 370 list_empty(&buf->queue) ? "" : "not ");
371
415 spin_lock_irqsave(&mx3_cam->lock, flags); 372 spin_lock_irqsave(&mx3_cam->lock, flags);
416 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
417 !list_empty(&vb->queue)) {
418 vb->state = VIDEOBUF_ERROR;
419 373
420 list_del_init(&vb->queue); 374 if (mx3_cam->active == buf)
421 if (mx3_cam->active == buf) 375 mx3_cam->active = NULL;
422 mx3_cam->active = NULL; 376
377 /* Doesn't hurt also if the list is empty */
378 list_del_init(&buf->queue);
379 buf->state = CSI_BUF_NEEDS_INIT;
380
381 if (txd) {
382 buf->txd = NULL;
383 if (mx3_cam->idmac_channel[0])
384 async_tx_ack(txd);
423 } 385 }
386
424 spin_unlock_irqrestore(&mx3_cam->lock, flags); 387 spin_unlock_irqrestore(&mx3_cam->lock, flags);
425 free_buffer(vq, buf);
426} 388}
427 389
428static struct videobuf_queue_ops mx3_videobuf_ops = { 390static int mx3_videobuf_init(struct vb2_buffer *vb)
429 .buf_setup = mx3_videobuf_setup, 391{
430 .buf_prepare = mx3_videobuf_prepare, 392 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
431 .buf_queue = mx3_videobuf_queue, 393 /* This is for locking debugging only */
432 .buf_release = mx3_videobuf_release, 394 INIT_LIST_HEAD(&buf->queue);
395 sg_init_table(&buf->sg, 1);
396
397 buf->state = CSI_BUF_NEEDS_INIT;
398 buf->txd = NULL;
399
400 return 0;
401}
402
403static struct vb2_ops mx3_videobuf_ops = {
404 .queue_setup = mx3_videobuf_setup,
405 .buf_prepare = mx3_videobuf_prepare,
406 .buf_queue = mx3_videobuf_queue,
407 .buf_cleanup = mx3_videobuf_release,
408 .buf_init = mx3_videobuf_init,
409 .wait_prepare = soc_camera_unlock,
410 .wait_finish = soc_camera_lock,
433}; 411};
434 412
435static void mx3_camera_init_videobuf(struct videobuf_queue *q, 413static int mx3_camera_init_videobuf(struct vb2_queue *q,
436 struct soc_camera_device *icd) 414 struct soc_camera_device *icd)
437{ 415{
438 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 416 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
439 struct mx3_camera_dev *mx3_cam = ici->priv; 417 q->io_modes = VB2_MMAP | VB2_USERPTR;
440 418 q->drv_priv = icd;
441 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, icd->dev.parent, 419 q->ops = &mx3_videobuf_ops;
442 &mx3_cam->lock, 420 q->mem_ops = &vb2_dma_contig_memops;
443 V4L2_BUF_TYPE_VIDEO_CAPTURE, 421 q->buf_struct_size = sizeof(struct mx3_camera_buffer);
444 V4L2_FIELD_NONE, 422
445 sizeof(struct mx3_camera_buffer), icd, 423 return vb2_queue_init(q);
446 &icd->video_lock);
447} 424}
448 425
449/* First part of ipu_csi_init_interface() */ 426/* First part of ipu_csi_init_interface() */
@@ -538,18 +515,6 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
538 icd->devnum); 515 icd->devnum);
539} 516}
540 517
541static bool channel_change_requested(struct soc_camera_device *icd,
542 struct v4l2_rect *rect)
543{
544 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
545 struct mx3_camera_dev *mx3_cam = ici->priv;
546 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
547
548 /* Do buffers have to be re-allocated or channel re-configured? */
549 return ichan && rect->width * rect->height >
550 icd->user_width * icd->user_height;
551}
552
553static int test_platform_param(struct mx3_camera_dev *mx3_cam, 518static int test_platform_param(struct mx3_camera_dev *mx3_cam,
554 unsigned char buswidth, unsigned long *flags) 519 unsigned char buswidth, unsigned long *flags)
555{ 520{
@@ -734,18 +699,36 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id
734 if (xlate) { 699 if (xlate) {
735 xlate->host_fmt = fmt; 700 xlate->host_fmt = fmt;
736 xlate->code = code; 701 xlate->code = code;
702 dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n",
703 (fmt->fourcc >> (0*8)) & 0xFF,
704 (fmt->fourcc >> (1*8)) & 0xFF,
705 (fmt->fourcc >> (2*8)) & 0xFF,
706 (fmt->fourcc >> (3*8)) & 0xFF);
737 xlate++; 707 xlate++;
738 dev_dbg(dev, "Providing format %x in pass-through mode\n",
739 xlate->host_fmt->fourcc);
740 } 708 }
741 709
742 return formats; 710 return formats;
743} 711}
744 712
745static void configure_geometry(struct mx3_camera_dev *mx3_cam, 713static void configure_geometry(struct mx3_camera_dev *mx3_cam,
746 unsigned int width, unsigned int height) 714 unsigned int width, unsigned int height,
715 enum v4l2_mbus_pixelcode code)
747{ 716{
748 u32 ctrl, width_field, height_field; 717 u32 ctrl, width_field, height_field;
718 const struct soc_mbus_pixelfmt *fmt;
719
720 fmt = soc_mbus_get_fmtdesc(code);
721 BUG_ON(!fmt);
722
723 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
724 /*
725 * As the CSI will be configured to output BAYER, here
726 * the width parameter count the number of samples to
727 * capture to complete the whole image width.
728 */
729 width *= soc_mbus_samples_per_pixel(fmt);
730 BUG_ON(width < 0);
731 }
749 732
750 /* Setup frame size - this cannot be changed on-the-fly... */ 733 /* Setup frame size - this cannot be changed on-the-fly... */
751 width_field = width - 1; 734 width_field = width - 1;
@@ -772,18 +755,6 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
772 struct dma_chan_request rq = {.mx3_cam = mx3_cam, 755 struct dma_chan_request rq = {.mx3_cam = mx3_cam,
773 .id = IDMAC_IC_7}; 756 .id = IDMAC_IC_7};
774 757
775 if (*ichan) {
776 struct videobuf_buffer *vb, *_vb;
777 dma_release_channel(&(*ichan)->dma_chan);
778 *ichan = NULL;
779 mx3_cam->active = NULL;
780 list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) {
781 list_del_init(&vb->queue);
782 vb->state = VIDEOBUF_ERROR;
783 wake_up(&vb->done);
784 }
785 }
786
787 dma_cap_zero(mask); 758 dma_cap_zero(mask);
788 dma_cap_set(DMA_SLAVE, mask); 759 dma_cap_set(DMA_SLAVE, mask);
789 dma_cap_set(DMA_PRIVATE, mask); 760 dma_cap_set(DMA_PRIVATE, mask);
@@ -843,19 +814,8 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
843 return ret; 814 return ret;
844 } 815 }
845 816
846 if (mf.width != icd->user_width || mf.height != icd->user_height) { 817 if (mf.width != icd->user_width || mf.height != icd->user_height)
847 /* 818 configure_geometry(mx3_cam, mf.width, mf.height, mf.code);
848 * We now know pixel formats and can decide upon DMA-channel(s)
849 * So far only direct camera-to-memory is supported
850 */
851 if (channel_change_requested(icd, rect)) {
852 ret = acquire_dma_channel(mx3_cam);
853 if (ret < 0)
854 return ret;
855 }
856
857 configure_geometry(mx3_cam, mf.width, mf.height);
858 }
859 819
860 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", 820 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
861 mf.width, mf.height); 821 mf.width, mf.height);
@@ -887,17 +847,13 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
887 stride_align(&pix->width); 847 stride_align(&pix->width);
888 dev_dbg(icd->dev.parent, "Set format %dx%d\n", pix->width, pix->height); 848 dev_dbg(icd->dev.parent, "Set format %dx%d\n", pix->width, pix->height);
889 849
890 ret = acquire_dma_channel(mx3_cam);
891 if (ret < 0)
892 return ret;
893
894 /* 850 /*
895 * Might have to perform a complete interface initialisation like in 851 * Might have to perform a complete interface initialisation like in
896 * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider 852 * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
897 * mxc_v4l2_s_fmt() 853 * mxc_v4l2_s_fmt()
898 */ 854 */
899 855
900 configure_geometry(mx3_cam, pix->width, pix->height); 856 configure_geometry(mx3_cam, pix->width, pix->height, xlate->code);
901 857
902 mf.width = pix->width; 858 mf.width = pix->width;
903 mf.height = pix->height; 859 mf.height = pix->height;
@@ -912,12 +868,25 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
912 if (mf.code != xlate->code) 868 if (mf.code != xlate->code)
913 return -EINVAL; 869 return -EINVAL;
914 870
871 if (!mx3_cam->idmac_channel[0]) {
872 ret = acquire_dma_channel(mx3_cam);
873 if (ret < 0)
874 return ret;
875 }
876
915 pix->width = mf.width; 877 pix->width = mf.width;
916 pix->height = mf.height; 878 pix->height = mf.height;
917 pix->field = mf.field; 879 pix->field = mf.field;
880 mx3_cam->field = mf.field;
918 pix->colorspace = mf.colorspace; 881 pix->colorspace = mf.colorspace;
919 icd->current_fmt = xlate; 882 icd->current_fmt = xlate;
920 883
884 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
885 xlate->host_fmt);
886 if (pix->bytesperline < 0)
887 return pix->bytesperline;
888 pix->sizeimage = pix->height * pix->bytesperline;
889
921 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height); 890 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
922 891
923 return ret; 892 return ret;
@@ -991,7 +960,7 @@ static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
991{ 960{
992 struct soc_camera_device *icd = file->private_data; 961 struct soc_camera_device *icd = file->private_data;
993 962
994 return videobuf_poll_stream(file, &icd->vb_vidq, pt); 963 return vb2_poll(&icd->vb2_vidq, file, pt);
995} 964}
996 965
997static int mx3_camera_querycap(struct soc_camera_host *ici, 966static int mx3_camera_querycap(struct soc_camera_host *ici,
@@ -1165,7 +1134,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
1165 .set_fmt = mx3_camera_set_fmt, 1134 .set_fmt = mx3_camera_set_fmt,
1166 .try_fmt = mx3_camera_try_fmt, 1135 .try_fmt = mx3_camera_try_fmt,
1167 .get_formats = mx3_camera_get_formats, 1136 .get_formats = mx3_camera_get_formats,
1168 .init_videobuf = mx3_camera_init_videobuf, 1137 .init_videobuf2 = mx3_camera_init_videobuf,
1169 .reqbufs = mx3_camera_reqbufs, 1138 .reqbufs = mx3_camera_reqbufs,
1170 .poll = mx3_camera_poll, 1139 .poll = mx3_camera_poll,
1171 .querycap = mx3_camera_querycap, 1140 .querycap = mx3_camera_querycap,
@@ -1241,6 +1210,12 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1241 soc_host->v4l2_dev.dev = &pdev->dev; 1210 soc_host->v4l2_dev.dev = &pdev->dev;
1242 soc_host->nr = pdev->id; 1211 soc_host->nr = pdev->id;
1243 1212
1213 mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1214 if (IS_ERR(mx3_cam->alloc_ctx)) {
1215 err = PTR_ERR(mx3_cam->alloc_ctx);
1216 goto eallocctx;
1217 }
1218
1244 err = soc_camera_host_register(soc_host); 1219 err = soc_camera_host_register(soc_host);
1245 if (err) 1220 if (err)
1246 goto ecamhostreg; 1221 goto ecamhostreg;
@@ -1251,6 +1226,8 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1251 return 0; 1226 return 0;
1252 1227
1253ecamhostreg: 1228ecamhostreg:
1229 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1230eallocctx:
1254 iounmap(base); 1231 iounmap(base);
1255eioremap: 1232eioremap:
1256 clk_put(mx3_cam->clk); 1233 clk_put(mx3_cam->clk);
@@ -1280,6 +1257,8 @@ static int __devexit mx3_camera_remove(struct platform_device *pdev)
1280 if (WARN_ON(mx3_cam->idmac_channel[0])) 1257 if (WARN_ON(mx3_cam->idmac_channel[0]))
1281 dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan); 1258 dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
1282 1259
1260 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1261
1283 vfree(mx3_cam); 1262 vfree(mx3_cam);
1284 1263
1285 dmaengine_put(); 1264 dmaengine_put();
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index e8846a09b026..0b3850023505 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -643,7 +643,8 @@ static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_regist
643} 643}
644#endif 644#endif
645 645
646static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) 646static long vidioc_default(struct file *file, void *fh, bool valid_prio,
647 int cmd, void *arg)
647{ 648{
648 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 649 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
649 struct mxb *mxb = (struct mxb *)dev->ext_priv; 650 struct mxb *mxb = (struct mxb *)dev->ext_priv;
diff --git a/drivers/media/video/noon010pc30.c b/drivers/media/video/noon010pc30.c
new file mode 100644
index 000000000000..35f722a88f76
--- /dev/null
+++ b/drivers/media/video/noon010pc30.c
@@ -0,0 +1,792 @@
1/*
2 * Driver for SiliconFile NOON010PC30 CIF (1/11") Image Sensor with ISP
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * Initial register configuration based on a driver authored by
8 * HeungJun Kim <riverful.kim@samsung.com>.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later vergsion.
14 */
15
16#include <linux/delay.h>
17#include <linux/gpio.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20#include <linux/regulator/consumer.h>
21#include <media/noon010pc30.h>
22#include <media/v4l2-chip-ident.h>
23#include <linux/videodev2.h>
24#include <media/v4l2-ctrls.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-mediabus.h>
27#include <media/v4l2-subdev.h>
28
29static int debug;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "Enable module debug trace. Set to 1 to enable.");
32
33#define MODULE_NAME "NOON010PC30"
34
35/*
36 * Register offsets within a page
37 * b15..b8 - page id, b7..b0 - register address
38 */
39#define POWER_CTRL_REG 0x0001
40#define PAGEMODE_REG 0x03
41#define DEVICE_ID_REG 0x0004
42#define NOON010PC30_ID 0x86
43#define VDO_CTL_REG(n) (0x0010 + (n))
44#define SYNC_CTL_REG 0x0012
45/* Window size and position */
46#define WIN_ROWH_REG 0x0013
47#define WIN_ROWL_REG 0x0014
48#define WIN_COLH_REG 0x0015
49#define WIN_COLL_REG 0x0016
50#define WIN_HEIGHTH_REG 0x0017
51#define WIN_HEIGHTL_REG 0x0018
52#define WIN_WIDTHH_REG 0x0019
53#define WIN_WIDTHL_REG 0x001A
54#define HBLANKH_REG 0x001B
55#define HBLANKL_REG 0x001C
56#define VSYNCH_REG 0x001D
57#define VSYNCL_REG 0x001E
58/* VSYNC control */
59#define VS_CTL_REG(n) (0x00A1 + (n))
60/* page 1 */
61#define ISP_CTL_REG(n) (0x0110 + (n))
62#define YOFS_REG 0x0119
63#define DARK_YOFS_REG 0x011A
64#define SAT_CTL_REG 0x0120
65#define BSAT_REG 0x0121
66#define RSAT_REG 0x0122
67/* Color correction */
68#define CMC_CTL_REG 0x0130
69#define CMC_OFSGH_REG 0x0133
70#define CMC_OFSGL_REG 0x0135
71#define CMC_SIGN_REG 0x0136
72#define CMC_GOFS_REG 0x0137
73#define CMC_COEF_REG(n) (0x0138 + (n))
74#define CMC_OFS_REG(n) (0x0141 + (n))
75/* Gamma correction */
76#define GMA_CTL_REG 0x0160
77#define GMA_COEF_REG(n) (0x0161 + (n))
78/* Lens Shading */
79#define LENS_CTRL_REG 0x01D0
80#define LENS_XCEN_REG 0x01D1
81#define LENS_YCEN_REG 0x01D2
82#define LENS_RC_REG 0x01D3
83#define LENS_GC_REG 0x01D4
84#define LENS_BC_REG 0x01D5
85#define L_AGON_REG 0x01D6
86#define L_AGOFF_REG 0x01D7
87/* Page 3 - Auto Exposure */
88#define AE_CTL_REG(n) (0x0310 + (n))
89#define AE_CTL9_REG 0x032C
90#define AE_CTL10_REG 0x032D
91#define AE_YLVL_REG 0x031C
92#define AE_YTH_REG(n) (0x031D + (n))
93#define AE_WGT_REG 0x0326
94#define EXP_TIMEH_REG 0x0333
95#define EXP_TIMEM_REG 0x0334
96#define EXP_TIMEL_REG 0x0335
97#define EXP_MMINH_REG 0x0336
98#define EXP_MMINL_REG 0x0337
99#define EXP_MMAXH_REG 0x0338
100#define EXP_MMAXM_REG 0x0339
101#define EXP_MMAXL_REG 0x033A
102/* Page 4 - Auto White Balance */
103#define AWB_CTL_REG(n) (0x0410 + (n))
104#define AWB_ENABE 0x80
105#define AWB_WGHT_REG 0x0419
106#define BGAIN_PAR_REG(n) (0x044F + (n))
107/* Manual white balance, when AWB_CTL2[0]=1 */
108#define MWB_RGAIN_REG 0x0466
109#define MWB_BGAIN_REG 0x0467
110
111/* The token to mark an array end */
112#define REG_TERM 0xFFFF
113
114struct noon010_format {
115 enum v4l2_mbus_pixelcode code;
116 enum v4l2_colorspace colorspace;
117 u16 ispctl1_reg;
118};
119
120struct noon010_frmsize {
121 u16 width;
122 u16 height;
123 int vid_ctl1;
124};
125
126static const char * const noon010_supply_name[] = {
127 "vdd_core", "vddio", "vdda"
128};
129
130#define NOON010_NUM_SUPPLIES ARRAY_SIZE(noon010_supply_name)
131
132struct noon010_info {
133 struct v4l2_subdev sd;
134 struct v4l2_ctrl_handler hdl;
135 const struct noon010pc30_platform_data *pdata;
136 const struct noon010_format *curr_fmt;
137 const struct noon010_frmsize *curr_win;
138 unsigned int hflip:1;
139 unsigned int vflip:1;
140 unsigned int power:1;
141 u8 i2c_reg_page;
142 struct regulator_bulk_data supply[NOON010_NUM_SUPPLIES];
143 u32 gpio_nreset;
144 u32 gpio_nstby;
145};
146
147struct i2c_regval {
148 u16 addr;
149 u16 val;
150};
151
152/* Supported resolutions. */
153static const struct noon010_frmsize noon010_sizes[] = {
154 {
155 .width = 352,
156 .height = 288,
157 .vid_ctl1 = 0,
158 }, {
159 .width = 176,
160 .height = 144,
161 .vid_ctl1 = 0x10,
162 }, {
163 .width = 88,
164 .height = 72,
165 .vid_ctl1 = 0x20,
166 },
167};
168
169/* Supported pixel formats. */
170static const struct noon010_format noon010_formats[] = {
171 {
172 .code = V4L2_MBUS_FMT_YUYV8_2X8,
173 .colorspace = V4L2_COLORSPACE_JPEG,
174 .ispctl1_reg = 0x03,
175 }, {
176 .code = V4L2_MBUS_FMT_YVYU8_2X8,
177 .colorspace = V4L2_COLORSPACE_JPEG,
178 .ispctl1_reg = 0x02,
179 }, {
180 .code = V4L2_MBUS_FMT_VYUY8_2X8,
181 .colorspace = V4L2_COLORSPACE_JPEG,
182 .ispctl1_reg = 0,
183 }, {
184 .code = V4L2_MBUS_FMT_UYVY8_2X8,
185 .colorspace = V4L2_COLORSPACE_JPEG,
186 .ispctl1_reg = 0x01,
187 }, {
188 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
189 .colorspace = V4L2_COLORSPACE_JPEG,
190 .ispctl1_reg = 0x40,
191 },
192};
193
194static const struct i2c_regval noon010_base_regs[] = {
195 { WIN_COLL_REG, 0x06 }, { HBLANKL_REG, 0x7C },
196 /* Color corection and saturation */
197 { ISP_CTL_REG(0), 0x30 }, { ISP_CTL_REG(2), 0x30 },
198 { YOFS_REG, 0x80 }, { DARK_YOFS_REG, 0x04 },
199 { SAT_CTL_REG, 0x1F }, { BSAT_REG, 0x90 },
200 { CMC_CTL_REG, 0x0F }, { CMC_OFSGH_REG, 0x3C },
201 { CMC_OFSGL_REG, 0x2C }, { CMC_SIGN_REG, 0x3F },
202 { CMC_COEF_REG(0), 0x79 }, { CMC_OFS_REG(0), 0x00 },
203 { CMC_COEF_REG(1), 0x39 }, { CMC_OFS_REG(1), 0x00 },
204 { CMC_COEF_REG(2), 0x00 }, { CMC_OFS_REG(2), 0x00 },
205 { CMC_COEF_REG(3), 0x11 }, { CMC_OFS_REG(3), 0x8B },
206 { CMC_COEF_REG(4), 0x65 }, { CMC_OFS_REG(4), 0x07 },
207 { CMC_COEF_REG(5), 0x14 }, { CMC_OFS_REG(5), 0x04 },
208 { CMC_COEF_REG(6), 0x01 }, { CMC_OFS_REG(6), 0x9C },
209 { CMC_COEF_REG(7), 0x33 }, { CMC_OFS_REG(7), 0x89 },
210 { CMC_COEF_REG(8), 0x74 }, { CMC_OFS_REG(8), 0x25 },
211 /* Automatic white balance */
212 { AWB_CTL_REG(0), 0x78 }, { AWB_CTL_REG(1), 0x2E },
213 { AWB_CTL_REG(2), 0x20 }, { AWB_CTL_REG(3), 0x85 },
214 /* Auto exposure */
215 { AE_CTL_REG(0), 0xDC }, { AE_CTL_REG(1), 0x81 },
216 { AE_CTL_REG(2), 0x30 }, { AE_CTL_REG(3), 0xA5 },
217 { AE_CTL_REG(4), 0x40 }, { AE_CTL_REG(5), 0x51 },
218 { AE_CTL_REG(6), 0x33 }, { AE_CTL_REG(7), 0x7E },
219 { AE_CTL9_REG, 0x00 }, { AE_CTL10_REG, 0x02 },
220 { AE_YLVL_REG, 0x44 }, { AE_YTH_REG(0), 0x34 },
221 { AE_YTH_REG(1), 0x30 }, { AE_WGT_REG, 0xD5 },
222 /* Lens shading compensation */
223 { LENS_CTRL_REG, 0x01 }, { LENS_XCEN_REG, 0x80 },
224 { LENS_YCEN_REG, 0x70 }, { LENS_RC_REG, 0x53 },
225 { LENS_GC_REG, 0x40 }, { LENS_BC_REG, 0x3E },
226 { REG_TERM, 0 },
227};
228
229static inline struct noon010_info *to_noon010(struct v4l2_subdev *sd)
230{
231 return container_of(sd, struct noon010_info, sd);
232}
233
234static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
235{
236 return &container_of(ctrl->handler, struct noon010_info, hdl)->sd;
237}
238
239static inline int set_i2c_page(struct noon010_info *info,
240 struct i2c_client *client, unsigned int reg)
241{
242 u32 page = reg >> 8 & 0xFF;
243 int ret = 0;
244
245 if (info->i2c_reg_page != page && (reg & 0xFF) != 0x03) {
246 ret = i2c_smbus_write_byte_data(client, PAGEMODE_REG, page);
247 if (!ret)
248 info->i2c_reg_page = page;
249 }
250 return ret;
251}
252
253static int cam_i2c_read(struct v4l2_subdev *sd, u32 reg_addr)
254{
255 struct i2c_client *client = v4l2_get_subdevdata(sd);
256 struct noon010_info *info = to_noon010(sd);
257 int ret = set_i2c_page(info, client, reg_addr);
258
259 if (ret)
260 return ret;
261 return i2c_smbus_read_byte_data(client, reg_addr & 0xFF);
262}
263
264static int cam_i2c_write(struct v4l2_subdev *sd, u32 reg_addr, u32 val)
265{
266 struct i2c_client *client = v4l2_get_subdevdata(sd);
267 struct noon010_info *info = to_noon010(sd);
268 int ret = set_i2c_page(info, client, reg_addr);
269
270 if (ret)
271 return ret;
272 return i2c_smbus_write_byte_data(client, reg_addr & 0xFF, val);
273}
274
275static inline int noon010_bulk_write_reg(struct v4l2_subdev *sd,
276 const struct i2c_regval *msg)
277{
278 while (msg->addr != REG_TERM) {
279 int ret = cam_i2c_write(sd, msg->addr, msg->val);
280
281 if (ret)
282 return ret;
283 msg++;
284 }
285 return 0;
286}
287
288/* Device reset and sleep mode control */
289static int noon010_power_ctrl(struct v4l2_subdev *sd, bool reset, bool sleep)
290{
291 struct noon010_info *info = to_noon010(sd);
292 u8 reg = sleep ? 0xF1 : 0xF0;
293 int ret = 0;
294
295 if (reset)
296 ret = cam_i2c_write(sd, POWER_CTRL_REG, reg | 0x02);
297 if (!ret) {
298 ret = cam_i2c_write(sd, POWER_CTRL_REG, reg);
299 if (reset && !ret)
300 info->i2c_reg_page = -1;
301 }
302 return ret;
303}
304
305/* Automatic white balance control */
306static int noon010_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
307{
308 int ret;
309
310 ret = cam_i2c_write(sd, AWB_CTL_REG(1), on ? 0x2E : 0x2F);
311 if (!ret)
312 ret = cam_i2c_write(sd, AWB_CTL_REG(0), on ? 0xFB : 0x7B);
313 return ret;
314}
315
316static int noon010_set_flip(struct v4l2_subdev *sd, int hflip, int vflip)
317{
318 struct noon010_info *info = to_noon010(sd);
319 int reg, ret;
320
321 reg = cam_i2c_read(sd, VDO_CTL_REG(1));
322 if (reg < 0)
323 return reg;
324
325 reg &= 0x7C;
326 if (hflip)
327 reg |= 0x01;
328 if (vflip)
329 reg |= 0x02;
330
331 ret = cam_i2c_write(sd, VDO_CTL_REG(1), reg | 0x80);
332 if (!ret) {
333 info->hflip = hflip;
334 info->vflip = vflip;
335 }
336 return ret;
337}
338
339/* Configure resolution and color format */
340static int noon010_set_params(struct v4l2_subdev *sd)
341{
342 struct noon010_info *info = to_noon010(sd);
343 int ret;
344
345 if (!info->curr_win)
346 return -EINVAL;
347
348 ret = cam_i2c_write(sd, VDO_CTL_REG(0), info->curr_win->vid_ctl1);
349
350 if (!ret && info->curr_fmt)
351 ret = cam_i2c_write(sd, ISP_CTL_REG(0),
352 info->curr_fmt->ispctl1_reg);
353 return ret;
354}
355
356/* Find nearest matching image pixel size. */
357static int noon010_try_frame_size(struct v4l2_mbus_framefmt *mf)
358{
359 unsigned int min_err = ~0;
360 int i = ARRAY_SIZE(noon010_sizes);
361 const struct noon010_frmsize *fsize = &noon010_sizes[0],
362 *match = NULL;
363
364 while (i--) {
365 int err = abs(fsize->width - mf->width)
366 + abs(fsize->height - mf->height);
367
368 if (err < min_err) {
369 min_err = err;
370 match = fsize;
371 }
372 fsize++;
373 }
374 if (match) {
375 mf->width = match->width;
376 mf->height = match->height;
377 return 0;
378 }
379 return -EINVAL;
380}
381
382static int power_enable(struct noon010_info *info)
383{
384 int ret;
385
386 if (info->power) {
387 v4l2_info(&info->sd, "%s: sensor is already on\n", __func__);
388 return 0;
389 }
390
391 if (gpio_is_valid(info->gpio_nstby))
392 gpio_set_value(info->gpio_nstby, 0);
393
394 if (gpio_is_valid(info->gpio_nreset))
395 gpio_set_value(info->gpio_nreset, 0);
396
397 ret = regulator_bulk_enable(NOON010_NUM_SUPPLIES, info->supply);
398 if (ret)
399 return ret;
400
401 if (gpio_is_valid(info->gpio_nreset)) {
402 msleep(50);
403 gpio_set_value(info->gpio_nreset, 1);
404 }
405 if (gpio_is_valid(info->gpio_nstby)) {
406 udelay(1000);
407 gpio_set_value(info->gpio_nstby, 1);
408 }
409 if (gpio_is_valid(info->gpio_nreset)) {
410 udelay(1000);
411 gpio_set_value(info->gpio_nreset, 0);
412 msleep(100);
413 gpio_set_value(info->gpio_nreset, 1);
414 msleep(20);
415 }
416 info->power = 1;
417
418 v4l2_dbg(1, debug, &info->sd, "%s: sensor is on\n", __func__);
419 return 0;
420}
421
422static int power_disable(struct noon010_info *info)
423{
424 int ret;
425
426 if (!info->power) {
427 v4l2_info(&info->sd, "%s: sensor is already off\n", __func__);
428 return 0;
429 }
430
431 ret = regulator_bulk_disable(NOON010_NUM_SUPPLIES, info->supply);
432 if (ret)
433 return ret;
434
435 if (gpio_is_valid(info->gpio_nstby))
436 gpio_set_value(info->gpio_nstby, 0);
437
438 if (gpio_is_valid(info->gpio_nreset))
439 gpio_set_value(info->gpio_nreset, 0);
440
441 info->power = 0;
442
443 v4l2_dbg(1, debug, &info->sd, "%s: sensor is off\n", __func__);
444
445 return 0;
446}
447
448static int noon010_s_ctrl(struct v4l2_ctrl *ctrl)
449{
450 struct v4l2_subdev *sd = to_sd(ctrl);
451
452 v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
453 __func__, ctrl->id, ctrl->val);
454
455 switch (ctrl->id) {
456 case V4L2_CID_AUTO_WHITE_BALANCE:
457 return noon010_enable_autowhitebalance(sd, ctrl->val);
458 case V4L2_CID_BLUE_BALANCE:
459 return cam_i2c_write(sd, MWB_BGAIN_REG, ctrl->val);
460 case V4L2_CID_RED_BALANCE:
461 return cam_i2c_write(sd, MWB_RGAIN_REG, ctrl->val);
462 default:
463 return -EINVAL;
464 }
465}
466
467static int noon010_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
468 enum v4l2_mbus_pixelcode *code)
469{
470 if (!code || index >= ARRAY_SIZE(noon010_formats))
471 return -EINVAL;
472
473 *code = noon010_formats[index].code;
474 return 0;
475}
476
477static int noon010_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
478{
479 struct noon010_info *info = to_noon010(sd);
480 int ret;
481
482 if (!mf)
483 return -EINVAL;
484
485 if (!info->curr_win || !info->curr_fmt) {
486 ret = noon010_set_params(sd);
487 if (ret)
488 return ret;
489 }
490
491 mf->width = info->curr_win->width;
492 mf->height = info->curr_win->height;
493 mf->code = info->curr_fmt->code;
494 mf->colorspace = info->curr_fmt->colorspace;
495 mf->field = V4L2_FIELD_NONE;
496
497 return 0;
498}
499
500/* Return nearest media bus frame format. */
501static const struct noon010_format *try_fmt(struct v4l2_subdev *sd,
502 struct v4l2_mbus_framefmt *mf)
503{
504 int i = ARRAY_SIZE(noon010_formats);
505
506 noon010_try_frame_size(mf);
507
508 while (i--)
509 if (mf->code == noon010_formats[i].code)
510 break;
511
512 mf->code = noon010_formats[i].code;
513
514 return &noon010_formats[i];
515}
516
517static int noon010_try_fmt(struct v4l2_subdev *sd,
518 struct v4l2_mbus_framefmt *mf)
519{
520 if (!sd || !mf)
521 return -EINVAL;
522
523 try_fmt(sd, mf);
524 return 0;
525}
526
527static int noon010_s_fmt(struct v4l2_subdev *sd,
528 struct v4l2_mbus_framefmt *mf)
529{
530 struct noon010_info *info = to_noon010(sd);
531
532 if (!sd || !mf)
533 return -EINVAL;
534
535 info->curr_fmt = try_fmt(sd, mf);
536
537 return noon010_set_params(sd);
538}
539
540static int noon010_base_config(struct v4l2_subdev *sd)
541{
542 struct noon010_info *info = to_noon010(sd);
543 int ret;
544
545 ret = noon010_bulk_write_reg(sd, noon010_base_regs);
546 if (!ret) {
547 info->curr_fmt = &noon010_formats[0];
548 info->curr_win = &noon010_sizes[0];
549 ret = noon010_set_params(sd);
550 }
551 if (!ret)
552 ret = noon010_set_flip(sd, 1, 0);
553 if (!ret)
554 ret = noon010_power_ctrl(sd, false, false);
555
556 /* sync the handler and the registers state */
557 v4l2_ctrl_handler_setup(&to_noon010(sd)->hdl);
558 return ret;
559}
560
561static int noon010_s_power(struct v4l2_subdev *sd, int on)
562{
563 struct noon010_info *info = to_noon010(sd);
564 const struct noon010pc30_platform_data *pdata = info->pdata;
565 int ret = 0;
566
567 if (WARN(pdata == NULL, "No platform data!\n"))
568 return -ENOMEM;
569
570 if (on) {
571 ret = power_enable(info);
572 if (ret)
573 return ret;
574 ret = noon010_base_config(sd);
575 } else {
576 noon010_power_ctrl(sd, false, true);
577 ret = power_disable(info);
578 info->curr_win = NULL;
579 info->curr_fmt = NULL;
580 }
581
582 return ret;
583}
584
585static int noon010_g_chip_ident(struct v4l2_subdev *sd,
586 struct v4l2_dbg_chip_ident *chip)
587{
588 struct i2c_client *client = v4l2_get_subdevdata(sd);
589
590 return v4l2_chip_ident_i2c_client(client, chip,
591 V4L2_IDENT_NOON010PC30, 0);
592}
593
594static int noon010_log_status(struct v4l2_subdev *sd)
595{
596 struct noon010_info *info = to_noon010(sd);
597
598 v4l2_ctrl_handler_log_status(&info->hdl, sd->name);
599 return 0;
600}
601
602static const struct v4l2_ctrl_ops noon010_ctrl_ops = {
603 .s_ctrl = noon010_s_ctrl,
604};
605
606static const struct v4l2_subdev_core_ops noon010_core_ops = {
607 .g_chip_ident = noon010_g_chip_ident,
608 .s_power = noon010_s_power,
609 .g_ctrl = v4l2_subdev_g_ctrl,
610 .s_ctrl = v4l2_subdev_s_ctrl,
611 .queryctrl = v4l2_subdev_queryctrl,
612 .querymenu = v4l2_subdev_querymenu,
613 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
614 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
615 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
616 .log_status = noon010_log_status,
617};
618
619static const struct v4l2_subdev_video_ops noon010_video_ops = {
620 .g_mbus_fmt = noon010_g_fmt,
621 .s_mbus_fmt = noon010_s_fmt,
622 .try_mbus_fmt = noon010_try_fmt,
623 .enum_mbus_fmt = noon010_enum_fmt,
624};
625
626static const struct v4l2_subdev_ops noon010_ops = {
627 .core = &noon010_core_ops,
628 .video = &noon010_video_ops,
629};
630
631/* Return 0 if NOON010PC30L sensor type was detected or -ENODEV otherwise. */
632static int noon010_detect(struct i2c_client *client, struct noon010_info *info)
633{
634 int ret;
635
636 ret = power_enable(info);
637 if (ret)
638 return ret;
639
640 ret = i2c_smbus_read_byte_data(client, DEVICE_ID_REG);
641 if (ret < 0)
642 dev_err(&client->dev, "I2C read failed: 0x%X\n", ret);
643
644 power_disable(info);
645
646 return ret == NOON010PC30_ID ? 0 : -ENODEV;
647}
648
649static int noon010_probe(struct i2c_client *client,
650 const struct i2c_device_id *id)
651{
652 struct noon010_info *info;
653 struct v4l2_subdev *sd;
654 const struct noon010pc30_platform_data *pdata
655 = client->dev.platform_data;
656 int ret;
657 int i;
658
659 if (!pdata) {
660 dev_err(&client->dev, "No platform data!\n");
661 return -EIO;
662 }
663
664 info = kzalloc(sizeof(*info), GFP_KERNEL);
665 if (!info)
666 return -ENOMEM;
667
668 sd = &info->sd;
669 strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
670 v4l2_i2c_subdev_init(sd, client, &noon010_ops);
671
672 v4l2_ctrl_handler_init(&info->hdl, 3);
673
674 v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
675 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
676 v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
677 V4L2_CID_RED_BALANCE, 0, 127, 1, 64);
678 v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
679 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 64);
680
681 sd->ctrl_handler = &info->hdl;
682
683 ret = info->hdl.error;
684 if (ret)
685 goto np_err;
686
687 info->pdata = client->dev.platform_data;
688 info->i2c_reg_page = -1;
689 info->gpio_nreset = -EINVAL;
690 info->gpio_nstby = -EINVAL;
691
692 if (gpio_is_valid(pdata->gpio_nreset)) {
693 ret = gpio_request(pdata->gpio_nreset, "NOON010PC30 NRST");
694 if (ret) {
695 dev_err(&client->dev, "GPIO request error: %d\n", ret);
696 goto np_err;
697 }
698 info->gpio_nreset = pdata->gpio_nreset;
699 gpio_direction_output(info->gpio_nreset, 0);
700 gpio_export(info->gpio_nreset, 0);
701 }
702
703 if (gpio_is_valid(pdata->gpio_nstby)) {
704 ret = gpio_request(pdata->gpio_nstby, "NOON010PC30 NSTBY");
705 if (ret) {
706 dev_err(&client->dev, "GPIO request error: %d\n", ret);
707 goto np_gpio_err;
708 }
709 info->gpio_nstby = pdata->gpio_nstby;
710 gpio_direction_output(info->gpio_nstby, 0);
711 gpio_export(info->gpio_nstby, 0);
712 }
713
714 for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
715 info->supply[i].supply = noon010_supply_name[i];
716
717 ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
718 info->supply);
719 if (ret)
720 goto np_reg_err;
721
722 ret = noon010_detect(client, info);
723 if (!ret)
724 return 0;
725
726 /* the sensor detection failed */
727 regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
728np_reg_err:
729 if (gpio_is_valid(info->gpio_nstby))
730 gpio_free(info->gpio_nstby);
731np_gpio_err:
732 if (gpio_is_valid(info->gpio_nreset))
733 gpio_free(info->gpio_nreset);
734np_err:
735 v4l2_ctrl_handler_free(&info->hdl);
736 v4l2_device_unregister_subdev(sd);
737 kfree(info);
738 return ret;
739}
740
741static int noon010_remove(struct i2c_client *client)
742{
743 struct v4l2_subdev *sd = i2c_get_clientdata(client);
744 struct noon010_info *info = to_noon010(sd);
745
746 v4l2_device_unregister_subdev(sd);
747 v4l2_ctrl_handler_free(&info->hdl);
748
749 regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
750
751 if (gpio_is_valid(info->gpio_nreset))
752 gpio_free(info->gpio_nreset);
753
754 if (gpio_is_valid(info->gpio_nstby))
755 gpio_free(info->gpio_nstby);
756
757 kfree(info);
758 return 0;
759}
760
761static const struct i2c_device_id noon010_id[] = {
762 { MODULE_NAME, 0 },
763 { },
764};
765MODULE_DEVICE_TABLE(i2c, noon010_id);
766
767
768static struct i2c_driver noon010_i2c_driver = {
769 .driver = {
770 .name = MODULE_NAME
771 },
772 .probe = noon010_probe,
773 .remove = noon010_remove,
774 .id_table = noon010_id,
775};
776
777static int __init noon010_init(void)
778{
779 return i2c_add_driver(&noon010_i2c_driver);
780}
781
782static void __exit noon010_exit(void)
783{
784 i2c_del_driver(&noon010_i2c_driver);
785}
786
787module_init(noon010_init);
788module_exit(noon010_exit);
789
790MODULE_DESCRIPTION("Siliconfile NOON010PC30 camera driver");
791MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
792MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index 0a2fb2bfdbfb..eab31cbd68eb 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -811,8 +811,8 @@ static irqreturn_t cam_isr(int irq, void *data)
811 spin_lock_irqsave(&pcdev->lock, flags); 811 spin_lock_irqsave(&pcdev->lock, flags);
812 812
813 if (WARN_ON(!buf)) { 813 if (WARN_ON(!buf)) {
814 dev_warn(dev, "%s: unhandled camera interrupt, status == " 814 dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
815 "%#x\n", __func__, it_status); 815 __func__, it_status);
816 suspend_capture(pcdev); 816 suspend_capture(pcdev);
817 disable_capture(pcdev); 817 disable_capture(pcdev);
818 goto out; 818 goto out;
@@ -1088,15 +1088,15 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1088 xlate->host_fmt = &omap1_cam_formats[code]; 1088 xlate->host_fmt = &omap1_cam_formats[code];
1089 xlate->code = code; 1089 xlate->code = code;
1090 xlate++; 1090 xlate++;
1091 dev_dbg(dev, "%s: providing format %s " 1091 dev_dbg(dev,
1092 "as byte swapped code #%d\n", __func__, 1092 "%s: providing format %s as byte swapped code #%d\n",
1093 omap1_cam_formats[code].name, code); 1093 __func__, omap1_cam_formats[code].name, code);
1094 } 1094 }
1095 default: 1095 default:
1096 if (xlate) 1096 if (xlate)
1097 dev_dbg(dev, "%s: providing format %s " 1097 dev_dbg(dev,
1098 "in pass-through mode\n", __func__, 1098 "%s: providing format %s in pass-through mode\n",
1099 fmt->name); 1099 __func__, fmt->name);
1100 } 1100 }
1101 formats++; 1101 formats++;
1102 if (xlate) { 1102 if (xlate) {
@@ -1139,29 +1139,29 @@ static int dma_align(int *width, int *height,
1139 return 1; 1139 return 1;
1140} 1140}
1141 1141
1142#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \ 1142#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \
1143({ \ 1143({ \
1144 struct soc_camera_sense sense = { \ 1144 struct soc_camera_sense sense = { \
1145 .master_clock = pcdev->camexclk, \ 1145 .master_clock = pcdev->camexclk, \
1146 .pixel_clock_max = 0, \ 1146 .pixel_clock_max = 0, \
1147 }; \ 1147 }; \
1148 int __ret; \ 1148 int __ret; \
1149 \ 1149 \
1150 if (pcdev->pdata) \ 1150 if (pcdev->pdata) \
1151 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \ 1151 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \
1152 icd->sense = &sense; \ 1152 icd->sense = &sense; \
1153 __ret = v4l2_subdev_call(sd, video, function, ##args); \ 1153 __ret = v4l2_subdev_call(sd, video, function, ##args); \
1154 icd->sense = NULL; \ 1154 icd->sense = NULL; \
1155 \ 1155 \
1156 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \ 1156 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \
1157 if (sense.pixel_clock > sense.pixel_clock_max) { \ 1157 if (sense.pixel_clock > sense.pixel_clock_max) { \
1158 dev_err(dev, "%s: pixel clock %lu " \ 1158 dev_err(dev, \
1159 "set by the camera too high!\n", \ 1159 "%s: pixel clock %lu set by the camera too high!\n", \
1160 __func__, sense.pixel_clock); \ 1160 __func__, sense.pixel_clock); \
1161 __ret = -EINVAL; \ 1161 __ret = -EINVAL; \
1162 } \ 1162 } \
1163 } \ 1163 } \
1164 __ret; \ 1164 __ret; \
1165}) 1165})
1166 1166
1167static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, 1167static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
@@ -1664,10 +1664,10 @@ static int __exit omap1_cam_remove(struct platform_device *pdev)
1664 res = pcdev->res; 1664 res = pcdev->res;
1665 release_mem_region(res->start, resource_size(res)); 1665 release_mem_region(res->start, resource_size(res));
1666 1666
1667 kfree(pcdev);
1668
1669 clk_put(pcdev->clk); 1667 clk_put(pcdev->clk);
1670 1668
1669 kfree(pcdev);
1670
1671 dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n"); 1671 dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n");
1672 1672
1673 return 0; 1673 return 0;
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index 017552762902..f6626e87dbc5 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -36,6 +36,7 @@
36#include <linux/clk.h> 36#include <linux/clk.h>
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/sched.h>
39 40
40#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
41#include <media/v4l2-ioctl.h> 42#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/omap3isp/Makefile b/drivers/media/video/omap3isp/Makefile
new file mode 100644
index 000000000000..b1b344774ae7
--- /dev/null
+++ b/drivers/media/video/omap3isp/Makefile
@@ -0,0 +1,13 @@
1# Makefile for OMAP3 ISP driver
2
3ifdef CONFIG_VIDEO_OMAP3_DEBUG
4EXTRA_CFLAGS += -DDEBUG
5endif
6
7omap3-isp-objs += \
8 isp.o ispqueue.o ispvideo.o \
9 ispcsiphy.o ispccp2.o ispcsi2.o \
10 ispccdc.o isppreview.o ispresizer.o \
11 ispstat.o isph3a_aewb.o isph3a_af.o isphist.o
12
13obj-$(CONFIG_VIDEO_OMAP3) += omap3-isp.o
diff --git a/drivers/media/video/omap3isp/cfa_coef_table.h b/drivers/media/video/omap3isp/cfa_coef_table.h
new file mode 100644
index 000000000000..c60df0ed075a
--- /dev/null
+++ b/drivers/media/video/omap3isp/cfa_coef_table.h
@@ -0,0 +1,61 @@
1/*
2 * cfa_coef_table.h
3 *
4 * TI OMAP3 ISP - CFA coefficients table
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
27248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
28247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
29244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
30248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
31247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
32244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
33248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
34247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
35 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
36 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
37 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
38 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
39 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
40 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
41 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
42 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
43 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
44 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
45 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
46 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
47 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
48 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
49 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
50 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
51 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
52 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
53244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
54248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
55250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
56244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
57248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
58250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
59244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
60248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
61250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248
diff --git a/drivers/media/video/omap3isp/gamma_table.h b/drivers/media/video/omap3isp/gamma_table.h
new file mode 100644
index 000000000000..78deebf7d965
--- /dev/null
+++ b/drivers/media/video/omap3isp/gamma_table.h
@@ -0,0 +1,90 @@
1/*
2 * gamma_table.h
3 *
4 * TI OMAP3 ISP - Default gamma table for all components
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27 0, 0, 1, 2, 3, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20,
28 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 36, 37, 39, 40, 41, 42,
29 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 54, 55, 56, 57,
30 58, 59, 60, 61, 62, 63, 63, 64, 65, 66, 66, 67, 68, 69, 69, 70,
31 71, 72, 72, 73, 74, 75, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82,
32 83, 84, 84, 85, 86, 87, 88, 88, 89, 90, 91, 91, 92, 93, 94, 94,
33 95, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 103, 104, 104,
34105, 106, 107, 108, 108, 109, 110, 111, 111, 112, 113, 114, 114, 115, 116, 117,
35117, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125,
36126, 126, 127, 127, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133,
37134, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141,
38142, 142, 143, 143, 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149,
39150, 150, 151, 151, 152, 152, 153, 153, 153, 153, 154, 154, 154, 154, 155, 155,
40156, 156, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 162,
41162, 163, 163, 164, 164, 164, 164, 165, 165, 165, 165, 166, 166, 167, 167, 168,
42168, 169, 169, 170, 170, 170, 170, 171, 171, 171, 171, 172, 172, 173, 173, 174,
43174, 175, 175, 176, 176, 176, 176, 177, 177, 177, 177, 178, 178, 178, 178, 179,
44179, 179, 179, 180, 180, 180, 180, 181, 181, 181, 181, 182, 182, 182, 182, 183,
45183, 183, 183, 184, 184, 184, 184, 185, 185, 185, 185, 186, 186, 186, 186, 187,
46187, 187, 187, 188, 188, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191,
47191, 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, 194, 194, 194, 194, 195,
48195, 195, 195, 196, 196, 196, 196, 197, 197, 197, 197, 198, 198, 198, 198, 199,
49199, 199, 199, 200, 200, 200, 200, 201, 201, 201, 201, 202, 202, 202, 203, 203,
50203, 203, 204, 204, 204, 204, 205, 205, 205, 205, 206, 206, 206, 206, 207, 207,
51207, 207, 208, 208, 208, 208, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210,
52210, 210, 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
53211, 212, 212, 212, 212, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213,
54213, 214, 214, 214, 214, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
55216, 216, 216, 216, 217, 217, 217, 217, 218, 218, 218, 218, 219, 219, 219, 219,
56219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 221, 221, 221, 221,
57221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 223,
58223, 223, 223, 223, 223, 223, 223, 224, 224, 224, 224, 225, 225, 225, 225, 225,
59225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 226,
60226, 226, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 228, 228,
61228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, 230,
62230, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 232, 232, 232,
63232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
64233, 233, 233, 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 235,
65235, 235, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
66236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238,
67238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
68238, 238, 238, 238, 238, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240,
69240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
70240, 240, 240, 240, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242,
71242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
72242, 242, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
73244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
74244, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
75246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
76246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 248, 248, 248, 248, 248,
77248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
78248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 250, 250, 250, 250, 250, 250,
79250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
80250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
81250, 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252,
82252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
83252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
84252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
85252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 253,
86253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
87253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
88253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
89253, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
new file mode 100644
index 000000000000..1a9963bd6d40
--- /dev/null
+++ b/drivers/media/video/omap3isp/isp.c
@@ -0,0 +1,2220 @@
1/*
2 * isp.c
3 *
4 * TI OMAP3 ISP - Core
5 *
6 * Copyright (C) 2006-2010 Nokia Corporation
7 * Copyright (C) 2007-2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * Contributors:
13 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
14 * Sakari Ailus <sakari.ailus@iki.fi>
15 * David Cohen <dacohen@gmail.com>
16 * Stanimir Varbanov <svarbanov@mm-sol.com>
17 * Vimarsh Zutshi <vimarsh.zutshi@gmail.com>
18 * Tuukka Toivonen <tuukkat76@gmail.com>
19 * Sergio Aguirre <saaguirre@ti.com>
20 * Antti Koskipaa <akoskipa@gmail.com>
21 * Ivan T. Ivanov <iivanov@mm-sol.com>
22 * RaniSuneela <r-m@ti.com>
23 * Atanas Filipov <afilipov@mm-sol.com>
24 * Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
25 * Hiroshi DOYU <hiroshi.doyu@nokia.com>
26 * Nayden Kanchev <nkanchev@mm-sol.com>
27 * Phil Carmody <ext-phil.2.carmody@nokia.com>
28 * Artem Bityutskiy <artem.bityutskiy@nokia.com>
29 * Dominic Curran <dcurran@ti.com>
30 * Ilkka Myllyperkio <ilkka.myllyperkio@sofica.fi>
31 * Pallavi Kulkarni <p-kulkarni@ti.com>
32 * Vaibhav Hiremath <hvaibhav@ti.com>
33 * Mohit Jalori <mjalori@ti.com>
34 * Sameer Venkatraman <sameerv@ti.com>
35 * Senthilvadivu Guruswamy <svadivu@ti.com>
36 * Thara Gopinath <thara@ti.com>
37 * Toni Leinonen <toni.leinonen@nokia.com>
38 * Troy Laramy <t-laramy@ti.com>
39 *
40 * This program is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License version 2 as
42 * published by the Free Software Foundation.
43 *
44 * This program is distributed in the hope that it will be useful, but
45 * WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47 * General Public License for more details.
48 *
49 * You should have received a copy of the GNU General Public License
50 * along with this program; if not, write to the Free Software
51 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
52 * 02110-1301 USA
53 */
54
55#include <asm/cacheflush.h>
56
57#include <linux/clk.h>
58#include <linux/delay.h>
59#include <linux/device.h>
60#include <linux/dma-mapping.h>
61#include <linux/i2c.h>
62#include <linux/interrupt.h>
63#include <linux/module.h>
64#include <linux/platform_device.h>
65#include <linux/regulator/consumer.h>
66#include <linux/slab.h>
67#include <linux/sched.h>
68#include <linux/vmalloc.h>
69
70#include <media/v4l2-common.h>
71#include <media/v4l2-device.h>
72
73#include "isp.h"
74#include "ispreg.h"
75#include "ispccdc.h"
76#include "isppreview.h"
77#include "ispresizer.h"
78#include "ispcsi2.h"
79#include "ispccp2.h"
80#include "isph3a.h"
81#include "isphist.h"
82
83static unsigned int autoidle;
84module_param(autoidle, int, 0444);
85MODULE_PARM_DESC(autoidle, "Enable OMAP3ISP AUTOIDLE support");
86
87static void isp_save_ctx(struct isp_device *isp);
88
89static void isp_restore_ctx(struct isp_device *isp);
90
91static const struct isp_res_mapping isp_res_maps[] = {
92 {
93 .isp_rev = ISP_REVISION_2_0,
94 .map = 1 << OMAP3_ISP_IOMEM_MAIN |
95 1 << OMAP3_ISP_IOMEM_CCP2 |
96 1 << OMAP3_ISP_IOMEM_CCDC |
97 1 << OMAP3_ISP_IOMEM_HIST |
98 1 << OMAP3_ISP_IOMEM_H3A |
99 1 << OMAP3_ISP_IOMEM_PREV |
100 1 << OMAP3_ISP_IOMEM_RESZ |
101 1 << OMAP3_ISP_IOMEM_SBL |
102 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
103 1 << OMAP3_ISP_IOMEM_CSIPHY2,
104 },
105 {
106 .isp_rev = ISP_REVISION_15_0,
107 .map = 1 << OMAP3_ISP_IOMEM_MAIN |
108 1 << OMAP3_ISP_IOMEM_CCP2 |
109 1 << OMAP3_ISP_IOMEM_CCDC |
110 1 << OMAP3_ISP_IOMEM_HIST |
111 1 << OMAP3_ISP_IOMEM_H3A |
112 1 << OMAP3_ISP_IOMEM_PREV |
113 1 << OMAP3_ISP_IOMEM_RESZ |
114 1 << OMAP3_ISP_IOMEM_SBL |
115 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
116 1 << OMAP3_ISP_IOMEM_CSIPHY2 |
117 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 |
118 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 |
119 1 << OMAP3_ISP_IOMEM_CSIPHY1 |
120 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2,
121 },
122};
123
124/* Structure for saving/restoring ISP module registers */
125static struct isp_reg isp_reg_list[] = {
126 {OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG, 0},
127 {OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, 0},
128 {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, 0},
129 {0, ISP_TOK_TERM, 0}
130};
131
132/*
133 * omap3isp_flush - Post pending L3 bus writes by doing a register readback
134 * @isp: OMAP3 ISP device
135 *
136 * In order to force posting of pending writes, we need to write and
137 * readback the same register, in this case the revision register.
138 *
139 * See this link for reference:
140 * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
141 */
142void omap3isp_flush(struct isp_device *isp)
143{
144 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
145 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
146}
147
148/*
149 * isp_enable_interrupts - Enable ISP interrupts.
150 * @isp: OMAP3 ISP device
151 */
152static void isp_enable_interrupts(struct isp_device *isp)
153{
154 static const u32 irq = IRQ0ENABLE_CSIA_IRQ
155 | IRQ0ENABLE_CSIB_IRQ
156 | IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ
157 | IRQ0ENABLE_CCDC_LSC_DONE_IRQ
158 | IRQ0ENABLE_CCDC_VD0_IRQ
159 | IRQ0ENABLE_CCDC_VD1_IRQ
160 | IRQ0ENABLE_HS_VS_IRQ
161 | IRQ0ENABLE_HIST_DONE_IRQ
162 | IRQ0ENABLE_H3A_AWB_DONE_IRQ
163 | IRQ0ENABLE_H3A_AF_DONE_IRQ
164 | IRQ0ENABLE_PRV_DONE_IRQ
165 | IRQ0ENABLE_RSZ_DONE_IRQ;
166
167 isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
168 isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
169}
170
171/*
172 * isp_disable_interrupts - Disable ISP interrupts.
173 * @isp: OMAP3 ISP device
174 */
175static void isp_disable_interrupts(struct isp_device *isp)
176{
177 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
178}
179
180/**
181 * isp_set_xclk - Configures the specified cam_xclk to the desired frequency.
182 * @isp: OMAP3 ISP device
183 * @xclk: Desired frequency of the clock in Hz. 0 = stable low, 1 is stable high
184 * @xclksel: XCLK to configure (0 = A, 1 = B).
185 *
186 * Configures the specified MCLK divisor in the ISP timing control register
187 * (TCTRL_CTRL) to generate the desired xclk clock value.
188 *
189 * Divisor = cam_mclk_hz / xclk
190 *
191 * Returns the final frequency that is actually being generated
192 **/
193static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
194{
195 u32 divisor;
196 u32 currentxclk;
197 unsigned long mclk_hz;
198
199 if (!omap3isp_get(isp))
200 return 0;
201
202 mclk_hz = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
203
204 if (xclk >= mclk_hz) {
205 divisor = ISPTCTRL_CTRL_DIV_BYPASS;
206 currentxclk = mclk_hz;
207 } else if (xclk >= 2) {
208 divisor = mclk_hz / xclk;
209 if (divisor >= ISPTCTRL_CTRL_DIV_BYPASS)
210 divisor = ISPTCTRL_CTRL_DIV_BYPASS - 1;
211 currentxclk = mclk_hz / divisor;
212 } else {
213 divisor = xclk;
214 currentxclk = 0;
215 }
216
217 switch (xclksel) {
218 case 0:
219 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
220 ISPTCTRL_CTRL_DIVA_MASK,
221 divisor << ISPTCTRL_CTRL_DIVA_SHIFT);
222 dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n",
223 currentxclk);
224 break;
225 case 1:
226 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
227 ISPTCTRL_CTRL_DIVB_MASK,
228 divisor << ISPTCTRL_CTRL_DIVB_SHIFT);
229 dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n",
230 currentxclk);
231 break;
232 default:
233 omap3isp_put(isp);
234 dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested "
235 "xclk. Must be 0 (A) or 1 (B).\n");
236 return -EINVAL;
237 }
238
239 /* Do we go from stable whatever to clock? */
240 if (divisor >= 2 && isp->xclk_divisor[xclksel] < 2)
241 omap3isp_get(isp);
242 /* Stopping the clock. */
243 else if (divisor < 2 && isp->xclk_divisor[xclksel] >= 2)
244 omap3isp_put(isp);
245
246 isp->xclk_divisor[xclksel] = divisor;
247
248 omap3isp_put(isp);
249
250 return currentxclk;
251}
252
253/*
254 * isp_power_settings - Sysconfig settings, for Power Management.
255 * @isp: OMAP3 ISP device
256 * @idle: Consider idle state.
257 *
258 * Sets the power settings for the ISP, and SBL bus.
259 */
260static void isp_power_settings(struct isp_device *isp, int idle)
261{
262 isp_reg_writel(isp,
263 ((idle ? ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY :
264 ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY) <<
265 ISP_SYSCONFIG_MIDLEMODE_SHIFT) |
266 ((isp->revision == ISP_REVISION_15_0) ?
267 ISP_SYSCONFIG_AUTOIDLE : 0),
268 OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
269
270 if (isp->autoidle)
271 isp_reg_writel(isp, ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN,
272 ISP_CTRL);
273}
274
275/*
276 * Configure the bridge and lane shifter. Valid inputs are
277 *
278 * CCDC_INPUT_PARALLEL: Parallel interface
279 * CCDC_INPUT_CSI2A: CSI2a receiver
280 * CCDC_INPUT_CCP2B: CCP2b receiver
281 * CCDC_INPUT_CSI2C: CSI2c receiver
282 *
283 * The bridge and lane shifter are configured according to the selected input
284 * and the ISP platform data.
285 */
286void omap3isp_configure_bridge(struct isp_device *isp,
287 enum ccdc_input_entity input,
288 const struct isp_parallel_platform_data *pdata)
289{
290 u32 ispctrl_val;
291
292 ispctrl_val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
293 ispctrl_val &= ~ISPCTRL_SHIFT_MASK;
294 ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV;
295 ispctrl_val &= ~ISPCTRL_PAR_SER_CLK_SEL_MASK;
296 ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_MASK;
297
298 switch (input) {
299 case CCDC_INPUT_PARALLEL:
300 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
301 ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT;
302 ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
303 ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT;
304 break;
305
306 case CCDC_INPUT_CSI2A:
307 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIA;
308 break;
309
310 case CCDC_INPUT_CCP2B:
311 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIB;
312 break;
313
314 case CCDC_INPUT_CSI2C:
315 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIC;
316 break;
317
318 default:
319 return;
320 }
321
322 ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK;
323 ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE;
324
325 isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
326}
327
328/**
329 * isp_set_pixel_clock - Configures the ISP pixel clock
330 * @isp: OMAP3 ISP device
331 * @pixelclk: Average pixel clock in Hz
332 *
333 * Set the average pixel clock required by the sensor. The ISP will use the
334 * lowest possible memory bandwidth settings compatible with the clock.
335 **/
336static void isp_set_pixel_clock(struct isp_device *isp, unsigned int pixelclk)
337{
338 isp->isp_ccdc.vpcfg.pixelclk = pixelclk;
339}
340
341void omap3isp_hist_dma_done(struct isp_device *isp)
342{
343 if (omap3isp_ccdc_busy(&isp->isp_ccdc) ||
344 omap3isp_stat_pcr_busy(&isp->isp_hist)) {
345 /* Histogram cannot be enabled in this frame anymore */
346 atomic_set(&isp->isp_hist.buf_err, 1);
347 dev_dbg(isp->dev, "hist: Out of synchronization with "
348 "CCDC. Ignoring next buffer.\n");
349 }
350}
351
352static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus)
353{
354 static const char *name[] = {
355 "CSIA_IRQ",
356 "res1",
357 "res2",
358 "CSIB_LCM_IRQ",
359 "CSIB_IRQ",
360 "res5",
361 "res6",
362 "res7",
363 "CCDC_VD0_IRQ",
364 "CCDC_VD1_IRQ",
365 "CCDC_VD2_IRQ",
366 "CCDC_ERR_IRQ",
367 "H3A_AF_DONE_IRQ",
368 "H3A_AWB_DONE_IRQ",
369 "res14",
370 "res15",
371 "HIST_DONE_IRQ",
372 "CCDC_LSC_DONE",
373 "CCDC_LSC_PREFETCH_COMPLETED",
374 "CCDC_LSC_PREFETCH_ERROR",
375 "PRV_DONE_IRQ",
376 "CBUFF_IRQ",
377 "res22",
378 "res23",
379 "RSZ_DONE_IRQ",
380 "OVF_IRQ",
381 "res26",
382 "res27",
383 "MMU_ERR_IRQ",
384 "OCP_ERR_IRQ",
385 "SEC_ERR_IRQ",
386 "HS_VS_IRQ",
387 };
388 int i;
389
390 dev_dbg(isp->dev, "");
391
392 for (i = 0; i < ARRAY_SIZE(name); i++) {
393 if ((1 << i) & irqstatus)
394 printk(KERN_CONT "%s ", name[i]);
395 }
396 printk(KERN_CONT "\n");
397}
398
399static void isp_isr_sbl(struct isp_device *isp)
400{
401 struct device *dev = isp->dev;
402 u32 sbl_pcr;
403
404 /*
405 * Handle shared buffer logic overflows for video buffers.
406 * ISPSBL_PCR_CCDCPRV_2_RSZ_OVF can be safely ignored.
407 */
408 sbl_pcr = isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
409 isp_reg_writel(isp, sbl_pcr, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
410 sbl_pcr &= ~ISPSBL_PCR_CCDCPRV_2_RSZ_OVF;
411
412 if (sbl_pcr)
413 dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr);
414
415 if (sbl_pcr & (ISPSBL_PCR_CCDC_WBL_OVF | ISPSBL_PCR_CSIA_WBL_OVF
416 | ISPSBL_PCR_CSIB_WBL_OVF)) {
417 isp->isp_ccdc.error = 1;
418 if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
419 isp->isp_prev.error = 1;
420 if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)
421 isp->isp_res.error = 1;
422 }
423
424 if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) {
425 isp->isp_prev.error = 1;
426 if (isp->isp_res.input == RESIZER_INPUT_VP &&
427 !(isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER))
428 isp->isp_res.error = 1;
429 }
430
431 if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF
432 | ISPSBL_PCR_RSZ2_WBL_OVF
433 | ISPSBL_PCR_RSZ3_WBL_OVF
434 | ISPSBL_PCR_RSZ4_WBL_OVF))
435 isp->isp_res.error = 1;
436
437 if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF)
438 omap3isp_stat_sbl_overflow(&isp->isp_af);
439
440 if (sbl_pcr & ISPSBL_PCR_H3A_AEAWB_WBL_OVF)
441 omap3isp_stat_sbl_overflow(&isp->isp_aewb);
442}
443
444/*
445 * isp_isr - Interrupt Service Routine for Camera ISP module.
446 * @irq: Not used currently.
447 * @_isp: Pointer to the OMAP3 ISP device
448 *
449 * Handles the corresponding callback if plugged in.
450 *
451 * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
452 * IRQ wasn't handled.
453 */
454static irqreturn_t isp_isr(int irq, void *_isp)
455{
456 static const u32 ccdc_events = IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ |
457 IRQ0STATUS_CCDC_LSC_DONE_IRQ |
458 IRQ0STATUS_CCDC_VD0_IRQ |
459 IRQ0STATUS_CCDC_VD1_IRQ |
460 IRQ0STATUS_HS_VS_IRQ;
461 struct isp_device *isp = _isp;
462 u32 irqstatus;
463 int ret;
464
465 irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
466 isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
467
468 isp_isr_sbl(isp);
469
470 if (irqstatus & IRQ0STATUS_CSIA_IRQ) {
471 ret = omap3isp_csi2_isr(&isp->isp_csi2a);
472 if (ret)
473 isp->isp_ccdc.error = 1;
474 }
475
476 if (irqstatus & IRQ0STATUS_CSIB_IRQ) {
477 ret = omap3isp_ccp2_isr(&isp->isp_ccp2);
478 if (ret)
479 isp->isp_ccdc.error = 1;
480 }
481
482 if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) {
483 if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
484 omap3isp_preview_isr_frame_sync(&isp->isp_prev);
485 if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)
486 omap3isp_resizer_isr_frame_sync(&isp->isp_res);
487 omap3isp_stat_isr_frame_sync(&isp->isp_aewb);
488 omap3isp_stat_isr_frame_sync(&isp->isp_af);
489 omap3isp_stat_isr_frame_sync(&isp->isp_hist);
490 }
491
492 if (irqstatus & ccdc_events)
493 omap3isp_ccdc_isr(&isp->isp_ccdc, irqstatus & ccdc_events);
494
495 if (irqstatus & IRQ0STATUS_PRV_DONE_IRQ) {
496 if (isp->isp_prev.output & PREVIEW_OUTPUT_RESIZER)
497 omap3isp_resizer_isr_frame_sync(&isp->isp_res);
498 omap3isp_preview_isr(&isp->isp_prev);
499 }
500
501 if (irqstatus & IRQ0STATUS_RSZ_DONE_IRQ)
502 omap3isp_resizer_isr(&isp->isp_res);
503
504 if (irqstatus & IRQ0STATUS_H3A_AWB_DONE_IRQ)
505 omap3isp_stat_isr(&isp->isp_aewb);
506
507 if (irqstatus & IRQ0STATUS_H3A_AF_DONE_IRQ)
508 omap3isp_stat_isr(&isp->isp_af);
509
510 if (irqstatus & IRQ0STATUS_HIST_DONE_IRQ)
511 omap3isp_stat_isr(&isp->isp_hist);
512
513 omap3isp_flush(isp);
514
515#if defined(DEBUG) && defined(ISP_ISR_DEBUG)
516 isp_isr_dbg(isp, irqstatus);
517#endif
518
519 return IRQ_HANDLED;
520}
521
522/* -----------------------------------------------------------------------------
523 * Pipeline power management
524 *
525 * Entities must be powered up when part of a pipeline that contains at least
526 * one open video device node.
527 *
528 * To achieve this use the entity use_count field to track the number of users.
529 * For entities corresponding to video device nodes the use_count field stores
530 * the users count of the node. For entities corresponding to subdevs the
531 * use_count field stores the total number of users of all video device nodes
532 * in the pipeline.
533 *
534 * The omap3isp_pipeline_pm_use() function must be called in the open() and
535 * close() handlers of video device nodes. It increments or decrements the use
536 * count of all subdev entities in the pipeline.
537 *
538 * To react to link management on powered pipelines, the link setup notification
539 * callback updates the use count of all entities in the source and sink sides
540 * of the link.
541 */
542
543/*
544 * isp_pipeline_pm_use_count - Count the number of users of a pipeline
545 * @entity: The entity
546 *
547 * Return the total number of users of all video device nodes in the pipeline.
548 */
549static int isp_pipeline_pm_use_count(struct media_entity *entity)
550{
551 struct media_entity_graph graph;
552 int use = 0;
553
554 media_entity_graph_walk_start(&graph, entity);
555
556 while ((entity = media_entity_graph_walk_next(&graph))) {
557 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
558 use += entity->use_count;
559 }
560
561 return use;
562}
563
564/*
565 * isp_pipeline_pm_power_one - Apply power change to an entity
566 * @entity: The entity
567 * @change: Use count change
568 *
569 * Change the entity use count by @change. If the entity is a subdev update its
570 * power state by calling the core::s_power operation when the use count goes
571 * from 0 to != 0 or from != 0 to 0.
572 *
573 * Return 0 on success or a negative error code on failure.
574 */
575static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
576{
577 struct v4l2_subdev *subdev;
578 int ret;
579
580 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
581 ? media_entity_to_v4l2_subdev(entity) : NULL;
582
583 if (entity->use_count == 0 && change > 0 && subdev != NULL) {
584 ret = v4l2_subdev_call(subdev, core, s_power, 1);
585 if (ret < 0 && ret != -ENOIOCTLCMD)
586 return ret;
587 }
588
589 entity->use_count += change;
590 WARN_ON(entity->use_count < 0);
591
592 if (entity->use_count == 0 && change < 0 && subdev != NULL)
593 v4l2_subdev_call(subdev, core, s_power, 0);
594
595 return 0;
596}
597
598/*
599 * isp_pipeline_pm_power - Apply power change to all entities in a pipeline
600 * @entity: The entity
601 * @change: Use count change
602 *
603 * Walk the pipeline to update the use count and the power state of all non-node
604 * entities.
605 *
606 * Return 0 on success or a negative error code on failure.
607 */
608static int isp_pipeline_pm_power(struct media_entity *entity, int change)
609{
610 struct media_entity_graph graph;
611 struct media_entity *first = entity;
612 int ret = 0;
613
614 if (!change)
615 return 0;
616
617 media_entity_graph_walk_start(&graph, entity);
618
619 while (!ret && (entity = media_entity_graph_walk_next(&graph)))
620 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
621 ret = isp_pipeline_pm_power_one(entity, change);
622
623 if (!ret)
624 return 0;
625
626 media_entity_graph_walk_start(&graph, first);
627
628 while ((first = media_entity_graph_walk_next(&graph))
629 && first != entity)
630 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
631 isp_pipeline_pm_power_one(first, -change);
632
633 return ret;
634}
635
636/*
637 * omap3isp_pipeline_pm_use - Update the use count of an entity
638 * @entity: The entity
639 * @use: Use (1) or stop using (0) the entity
640 *
641 * Update the use count of all entities in the pipeline and power entities on or
642 * off accordingly.
643 *
644 * Return 0 on success or a negative error code on failure. Powering entities
645 * off is assumed to never fail. No failure can occur when the use parameter is
646 * set to 0.
647 */
648int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
649{
650 int change = use ? 1 : -1;
651 int ret;
652
653 mutex_lock(&entity->parent->graph_mutex);
654
655 /* Apply use count to node. */
656 entity->use_count += change;
657 WARN_ON(entity->use_count < 0);
658
659 /* Apply power change to connected non-nodes. */
660 ret = isp_pipeline_pm_power(entity, change);
661
662 mutex_unlock(&entity->parent->graph_mutex);
663
664 return ret;
665}
666
667/*
668 * isp_pipeline_link_notify - Link management notification callback
669 * @source: Pad at the start of the link
670 * @sink: Pad at the end of the link
671 * @flags: New link flags that will be applied
672 *
673 * React to link management on powered pipelines by updating the use count of
674 * all entities in the source and sink sides of the link. Entities are powered
675 * on or off accordingly.
676 *
677 * Return 0 on success or a negative error code on failure. Powering entities
678 * off is assumed to never fail. This function will not fail for disconnection
679 * events.
680 */
681static int isp_pipeline_link_notify(struct media_pad *source,
682 struct media_pad *sink, u32 flags)
683{
684 int source_use = isp_pipeline_pm_use_count(source->entity);
685 int sink_use = isp_pipeline_pm_use_count(sink->entity);
686 int ret;
687
688 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
689 /* Powering off entities is assumed to never fail. */
690 isp_pipeline_pm_power(source->entity, -sink_use);
691 isp_pipeline_pm_power(sink->entity, -source_use);
692 return 0;
693 }
694
695 ret = isp_pipeline_pm_power(source->entity, sink_use);
696 if (ret < 0)
697 return ret;
698
699 ret = isp_pipeline_pm_power(sink->entity, source_use);
700 if (ret < 0)
701 isp_pipeline_pm_power(source->entity, -sink_use);
702
703 return ret;
704}
705
706/* -----------------------------------------------------------------------------
707 * Pipeline stream management
708 */
709
710/*
711 * isp_pipeline_enable - Enable streaming on a pipeline
712 * @pipe: ISP pipeline
713 * @mode: Stream mode (single shot or continuous)
714 *
715 * Walk the entities chain starting at the pipeline output video node and start
716 * all modules in the chain in the given mode.
717 *
718 * Return 0 if successfull, or the return value of the failed video::s_stream
719 * operation otherwise.
720 */
721static int isp_pipeline_enable(struct isp_pipeline *pipe,
722 enum isp_pipeline_stream_state mode)
723{
724 struct isp_device *isp = pipe->output->isp;
725 struct media_entity *entity;
726 struct media_pad *pad;
727 struct v4l2_subdev *subdev;
728 unsigned long flags;
729 int ret = 0;
730
731 spin_lock_irqsave(&pipe->lock, flags);
732 pipe->state &= ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT);
733 spin_unlock_irqrestore(&pipe->lock, flags);
734
735 pipe->do_propagation = false;
736
737 entity = &pipe->output->video.entity;
738 while (1) {
739 pad = &entity->pads[0];
740 if (!(pad->flags & MEDIA_PAD_FL_SINK))
741 break;
742
743 pad = media_entity_remote_source(pad);
744 if (pad == NULL ||
745 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
746 break;
747
748 entity = pad->entity;
749 subdev = media_entity_to_v4l2_subdev(entity);
750
751 ret = v4l2_subdev_call(subdev, video, s_stream, mode);
752 if (ret < 0 && ret != -ENOIOCTLCMD)
753 break;
754
755 if (subdev == &isp->isp_ccdc.subdev) {
756 v4l2_subdev_call(&isp->isp_aewb.subdev, video,
757 s_stream, mode);
758 v4l2_subdev_call(&isp->isp_af.subdev, video,
759 s_stream, mode);
760 v4l2_subdev_call(&isp->isp_hist.subdev, video,
761 s_stream, mode);
762 pipe->do_propagation = true;
763 }
764 }
765
766 /* Frame number propagation. In continuous streaming mode the number
767 * is incremented in the frame start ISR. In mem-to-mem mode
768 * singleshot is used and frame start IRQs are not available.
769 * Thus we have to increment the number here.
770 */
771 if (pipe->do_propagation && mode == ISP_PIPELINE_STREAM_SINGLESHOT)
772 atomic_inc(&pipe->frame_number);
773
774 return ret;
775}
776
777static int isp_pipeline_wait_resizer(struct isp_device *isp)
778{
779 return omap3isp_resizer_busy(&isp->isp_res);
780}
781
782static int isp_pipeline_wait_preview(struct isp_device *isp)
783{
784 return omap3isp_preview_busy(&isp->isp_prev);
785}
786
787static int isp_pipeline_wait_ccdc(struct isp_device *isp)
788{
789 return omap3isp_stat_busy(&isp->isp_af)
790 || omap3isp_stat_busy(&isp->isp_aewb)
791 || omap3isp_stat_busy(&isp->isp_hist)
792 || omap3isp_ccdc_busy(&isp->isp_ccdc);
793}
794
795#define ISP_STOP_TIMEOUT msecs_to_jiffies(1000)
796
797static int isp_pipeline_wait(struct isp_device *isp,
798 int(*busy)(struct isp_device *isp))
799{
800 unsigned long timeout = jiffies + ISP_STOP_TIMEOUT;
801
802 while (!time_after(jiffies, timeout)) {
803 if (!busy(isp))
804 return 0;
805 }
806
807 return 1;
808}
809
810/*
811 * isp_pipeline_disable - Disable streaming on a pipeline
812 * @pipe: ISP pipeline
813 *
814 * Walk the entities chain starting at the pipeline output video node and stop
815 * all modules in the chain. Wait synchronously for the modules to be stopped if
816 * necessary.
817 *
818 * Return 0 if all modules have been properly stopped, or -ETIMEDOUT if a module
819 * can't be stopped (in which case a software reset of the ISP is probably
820 * necessary).
821 */
822static int isp_pipeline_disable(struct isp_pipeline *pipe)
823{
824 struct isp_device *isp = pipe->output->isp;
825 struct media_entity *entity;
826 struct media_pad *pad;
827 struct v4l2_subdev *subdev;
828 int failure = 0;
829 int ret;
830
831 /*
832 * We need to stop all the modules after CCDC first or they'll
833 * never stop since they may not get a full frame from CCDC.
834 */
835 entity = &pipe->output->video.entity;
836 while (1) {
837 pad = &entity->pads[0];
838 if (!(pad->flags & MEDIA_PAD_FL_SINK))
839 break;
840
841 pad = media_entity_remote_source(pad);
842 if (pad == NULL ||
843 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
844 break;
845
846 entity = pad->entity;
847 subdev = media_entity_to_v4l2_subdev(entity);
848
849 if (subdev == &isp->isp_ccdc.subdev) {
850 v4l2_subdev_call(&isp->isp_aewb.subdev,
851 video, s_stream, 0);
852 v4l2_subdev_call(&isp->isp_af.subdev,
853 video, s_stream, 0);
854 v4l2_subdev_call(&isp->isp_hist.subdev,
855 video, s_stream, 0);
856 }
857
858 v4l2_subdev_call(subdev, video, s_stream, 0);
859
860 if (subdev == &isp->isp_res.subdev)
861 ret = isp_pipeline_wait(isp, isp_pipeline_wait_resizer);
862 else if (subdev == &isp->isp_prev.subdev)
863 ret = isp_pipeline_wait(isp, isp_pipeline_wait_preview);
864 else if (subdev == &isp->isp_ccdc.subdev)
865 ret = isp_pipeline_wait(isp, isp_pipeline_wait_ccdc);
866 else
867 ret = 0;
868
869 if (ret) {
870 dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
871 failure = -ETIMEDOUT;
872 }
873 }
874
875 return failure;
876}
877
878/*
879 * omap3isp_pipeline_set_stream - Enable/disable streaming on a pipeline
880 * @pipe: ISP pipeline
881 * @state: Stream state (stopped, single shot or continuous)
882 *
883 * Set the pipeline to the given stream state. Pipelines can be started in
884 * single-shot or continuous mode.
885 *
886 * Return 0 if successfull, or the return value of the failed video::s_stream
887 * operation otherwise.
888 */
889int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
890 enum isp_pipeline_stream_state state)
891{
892 int ret;
893
894 if (state == ISP_PIPELINE_STREAM_STOPPED)
895 ret = isp_pipeline_disable(pipe);
896 else
897 ret = isp_pipeline_enable(pipe, state);
898 pipe->stream_state = state;
899
900 return ret;
901}
902
903/*
904 * isp_pipeline_resume - Resume streaming on a pipeline
905 * @pipe: ISP pipeline
906 *
907 * Resume video output and input and re-enable pipeline.
908 */
909static void isp_pipeline_resume(struct isp_pipeline *pipe)
910{
911 int singleshot = pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT;
912
913 omap3isp_video_resume(pipe->output, !singleshot);
914 if (singleshot)
915 omap3isp_video_resume(pipe->input, 0);
916 isp_pipeline_enable(pipe, pipe->stream_state);
917}
918
919/*
920 * isp_pipeline_suspend - Suspend streaming on a pipeline
921 * @pipe: ISP pipeline
922 *
923 * Suspend pipeline.
924 */
925static void isp_pipeline_suspend(struct isp_pipeline *pipe)
926{
927 isp_pipeline_disable(pipe);
928}
929
930/*
931 * isp_pipeline_is_last - Verify if entity has an enabled link to the output
932 * video node
933 * @me: ISP module's media entity
934 *
935 * Returns 1 if the entity has an enabled link to the output video node or 0
936 * otherwise. It's true only while pipeline can have no more than one output
937 * node.
938 */
939static int isp_pipeline_is_last(struct media_entity *me)
940{
941 struct isp_pipeline *pipe;
942 struct media_pad *pad;
943
944 if (!me->pipe)
945 return 0;
946 pipe = to_isp_pipeline(me);
947 if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
948 return 0;
949 pad = media_entity_remote_source(&pipe->output->pad);
950 return pad->entity == me;
951}
952
953/*
954 * isp_suspend_module_pipeline - Suspend pipeline to which belongs the module
955 * @me: ISP module's media entity
956 *
957 * Suspend the whole pipeline if module's entity has an enabled link to the
958 * output video node. It works only while pipeline can have no more than one
959 * output node.
960 */
961static void isp_suspend_module_pipeline(struct media_entity *me)
962{
963 if (isp_pipeline_is_last(me))
964 isp_pipeline_suspend(to_isp_pipeline(me));
965}
966
967/*
968 * isp_resume_module_pipeline - Resume pipeline to which belongs the module
969 * @me: ISP module's media entity
970 *
971 * Resume the whole pipeline if module's entity has an enabled link to the
972 * output video node. It works only while pipeline can have no more than one
973 * output node.
974 */
975static void isp_resume_module_pipeline(struct media_entity *me)
976{
977 if (isp_pipeline_is_last(me))
978 isp_pipeline_resume(to_isp_pipeline(me));
979}
980
981/*
982 * isp_suspend_modules - Suspend ISP submodules.
983 * @isp: OMAP3 ISP device
984 *
985 * Returns 0 if suspend left in idle state all the submodules properly,
986 * or returns 1 if a general Reset is required to suspend the submodules.
987 */
988static int isp_suspend_modules(struct isp_device *isp)
989{
990 unsigned long timeout;
991
992 omap3isp_stat_suspend(&isp->isp_aewb);
993 omap3isp_stat_suspend(&isp->isp_af);
994 omap3isp_stat_suspend(&isp->isp_hist);
995 isp_suspend_module_pipeline(&isp->isp_res.subdev.entity);
996 isp_suspend_module_pipeline(&isp->isp_prev.subdev.entity);
997 isp_suspend_module_pipeline(&isp->isp_ccdc.subdev.entity);
998 isp_suspend_module_pipeline(&isp->isp_csi2a.subdev.entity);
999 isp_suspend_module_pipeline(&isp->isp_ccp2.subdev.entity);
1000
1001 timeout = jiffies + ISP_STOP_TIMEOUT;
1002 while (omap3isp_stat_busy(&isp->isp_af)
1003 || omap3isp_stat_busy(&isp->isp_aewb)
1004 || omap3isp_stat_busy(&isp->isp_hist)
1005 || omap3isp_preview_busy(&isp->isp_prev)
1006 || omap3isp_resizer_busy(&isp->isp_res)
1007 || omap3isp_ccdc_busy(&isp->isp_ccdc)) {
1008 if (time_after(jiffies, timeout)) {
1009 dev_info(isp->dev, "can't stop modules.\n");
1010 return 1;
1011 }
1012 msleep(1);
1013 }
1014
1015 return 0;
1016}
1017
1018/*
1019 * isp_resume_modules - Resume ISP submodules.
1020 * @isp: OMAP3 ISP device
1021 */
1022static void isp_resume_modules(struct isp_device *isp)
1023{
1024 omap3isp_stat_resume(&isp->isp_aewb);
1025 omap3isp_stat_resume(&isp->isp_af);
1026 omap3isp_stat_resume(&isp->isp_hist);
1027 isp_resume_module_pipeline(&isp->isp_res.subdev.entity);
1028 isp_resume_module_pipeline(&isp->isp_prev.subdev.entity);
1029 isp_resume_module_pipeline(&isp->isp_ccdc.subdev.entity);
1030 isp_resume_module_pipeline(&isp->isp_csi2a.subdev.entity);
1031 isp_resume_module_pipeline(&isp->isp_ccp2.subdev.entity);
1032}
1033
1034/*
1035 * isp_reset - Reset ISP with a timeout wait for idle.
1036 * @isp: OMAP3 ISP device
1037 */
1038static int isp_reset(struct isp_device *isp)
1039{
1040 unsigned long timeout = 0;
1041
1042 isp_reg_writel(isp,
1043 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG)
1044 | ISP_SYSCONFIG_SOFTRESET,
1045 OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
1046 while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN,
1047 ISP_SYSSTATUS) & 0x1)) {
1048 if (timeout++ > 10000) {
1049 dev_alert(isp->dev, "cannot reset ISP\n");
1050 return -ETIMEDOUT;
1051 }
1052 udelay(1);
1053 }
1054
1055 return 0;
1056}
1057
1058/*
1059 * isp_save_context - Saves the values of the ISP module registers.
1060 * @isp: OMAP3 ISP device
1061 * @reg_list: Structure containing pairs of register address and value to
1062 * modify on OMAP.
1063 */
1064static void
1065isp_save_context(struct isp_device *isp, struct isp_reg *reg_list)
1066{
1067 struct isp_reg *next = reg_list;
1068
1069 for (; next->reg != ISP_TOK_TERM; next++)
1070 next->val = isp_reg_readl(isp, next->mmio_range, next->reg);
1071}
1072
1073/*
1074 * isp_restore_context - Restores the values of the ISP module registers.
1075 * @isp: OMAP3 ISP device
1076 * @reg_list: Structure containing pairs of register address and value to
1077 * modify on OMAP.
1078 */
1079static void
1080isp_restore_context(struct isp_device *isp, struct isp_reg *reg_list)
1081{
1082 struct isp_reg *next = reg_list;
1083
1084 for (; next->reg != ISP_TOK_TERM; next++)
1085 isp_reg_writel(isp, next->val, next->mmio_range, next->reg);
1086}
1087
1088/*
1089 * isp_save_ctx - Saves ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
1090 * @isp: OMAP3 ISP device
1091 *
1092 * Routine for saving the context of each module in the ISP.
1093 * CCDC, HIST, H3A, PREV, RESZ and MMU.
1094 */
1095static void isp_save_ctx(struct isp_device *isp)
1096{
1097 isp_save_context(isp, isp_reg_list);
1098 if (isp->iommu)
1099 iommu_save_ctx(isp->iommu);
1100}
1101
1102/*
1103 * isp_restore_ctx - Restores ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
1104 * @isp: OMAP3 ISP device
1105 *
1106 * Routine for restoring the context of each module in the ISP.
1107 * CCDC, HIST, H3A, PREV, RESZ and MMU.
1108 */
1109static void isp_restore_ctx(struct isp_device *isp)
1110{
1111 isp_restore_context(isp, isp_reg_list);
1112 if (isp->iommu)
1113 iommu_restore_ctx(isp->iommu);
1114 omap3isp_ccdc_restore_context(isp);
1115 omap3isp_preview_restore_context(isp);
1116}
1117
1118/* -----------------------------------------------------------------------------
1119 * SBL resources management
1120 */
1121#define OMAP3_ISP_SBL_READ (OMAP3_ISP_SBL_CSI1_READ | \
1122 OMAP3_ISP_SBL_CCDC_LSC_READ | \
1123 OMAP3_ISP_SBL_PREVIEW_READ | \
1124 OMAP3_ISP_SBL_RESIZER_READ)
1125#define OMAP3_ISP_SBL_WRITE (OMAP3_ISP_SBL_CSI1_WRITE | \
1126 OMAP3_ISP_SBL_CSI2A_WRITE | \
1127 OMAP3_ISP_SBL_CSI2C_WRITE | \
1128 OMAP3_ISP_SBL_CCDC_WRITE | \
1129 OMAP3_ISP_SBL_PREVIEW_WRITE)
1130
1131void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res)
1132{
1133 u32 sbl = 0;
1134
1135 isp->sbl_resources |= res;
1136
1137 if (isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ)
1138 sbl |= ISPCTRL_SBL_SHARED_RPORTA;
1139
1140 if (isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ)
1141 sbl |= ISPCTRL_SBL_SHARED_RPORTB;
1142
1143 if (isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE)
1144 sbl |= ISPCTRL_SBL_SHARED_WPORTC;
1145
1146 if (isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE)
1147 sbl |= ISPCTRL_SBL_WR0_RAM_EN;
1148
1149 if (isp->sbl_resources & OMAP3_ISP_SBL_WRITE)
1150 sbl |= ISPCTRL_SBL_WR1_RAM_EN;
1151
1152 if (isp->sbl_resources & OMAP3_ISP_SBL_READ)
1153 sbl |= ISPCTRL_SBL_RD_RAM_EN;
1154
1155 isp_reg_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
1156}
1157
1158void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res)
1159{
1160 u32 sbl = 0;
1161
1162 isp->sbl_resources &= ~res;
1163
1164 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ))
1165 sbl |= ISPCTRL_SBL_SHARED_RPORTA;
1166
1167 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ))
1168 sbl |= ISPCTRL_SBL_SHARED_RPORTB;
1169
1170 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE))
1171 sbl |= ISPCTRL_SBL_SHARED_WPORTC;
1172
1173 if (!(isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE))
1174 sbl |= ISPCTRL_SBL_WR0_RAM_EN;
1175
1176 if (!(isp->sbl_resources & OMAP3_ISP_SBL_WRITE))
1177 sbl |= ISPCTRL_SBL_WR1_RAM_EN;
1178
1179 if (!(isp->sbl_resources & OMAP3_ISP_SBL_READ))
1180 sbl |= ISPCTRL_SBL_RD_RAM_EN;
1181
1182 isp_reg_clr(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
1183}
1184
1185/*
1186 * isp_module_sync_idle - Helper to sync module with its idle state
1187 * @me: ISP submodule's media entity
1188 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
1189 * @stopping: flag which tells module wants to stop
1190 *
1191 * This function checks if ISP submodule needs to wait for next interrupt. If
1192 * yes, makes the caller to sleep while waiting for such event.
1193 */
1194int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
1195 atomic_t *stopping)
1196{
1197 struct isp_pipeline *pipe = to_isp_pipeline(me);
1198
1199 if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED ||
1200 (pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT &&
1201 !isp_pipeline_ready(pipe)))
1202 return 0;
1203
1204 /*
1205 * atomic_set() doesn't include memory barrier on ARM platform for SMP
1206 * scenario. We'll call it here to avoid race conditions.
1207 */
1208 atomic_set(stopping, 1);
1209 smp_mb();
1210
1211 /*
1212 * If module is the last one, it's writing to memory. In this case,
1213 * it's necessary to check if the module is already paused due to
1214 * DMA queue underrun or if it has to wait for next interrupt to be
1215 * idle.
1216 * If it isn't the last one, the function won't sleep but *stopping
1217 * will still be set to warn next submodule caller's interrupt the
1218 * module wants to be idle.
1219 */
1220 if (isp_pipeline_is_last(me)) {
1221 struct isp_video *video = pipe->output;
1222 unsigned long flags;
1223 spin_lock_irqsave(&video->queue->irqlock, flags);
1224 if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
1225 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1226 atomic_set(stopping, 0);
1227 smp_mb();
1228 return 0;
1229 }
1230 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1231 if (!wait_event_timeout(*wait, !atomic_read(stopping),
1232 msecs_to_jiffies(1000))) {
1233 atomic_set(stopping, 0);
1234 smp_mb();
1235 return -ETIMEDOUT;
1236 }
1237 }
1238
1239 return 0;
1240}
1241
1242/*
1243 * omap3isp_module_sync_is_stopped - Helper to verify if module was stopping
1244 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
1245 * @stopping: flag which tells module wants to stop
1246 *
1247 * This function checks if ISP submodule was stopping. In case of yes, it
1248 * notices the caller by setting stopping to 0 and waking up the wait queue.
1249 * Returns 1 if it was stopping or 0 otherwise.
1250 */
1251int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
1252 atomic_t *stopping)
1253{
1254 if (atomic_cmpxchg(stopping, 1, 0)) {
1255 wake_up(wait);
1256 return 1;
1257 }
1258
1259 return 0;
1260}
1261
1262/* --------------------------------------------------------------------------
1263 * Clock management
1264 */
1265
1266#define ISPCTRL_CLKS_MASK (ISPCTRL_H3A_CLK_EN | \
1267 ISPCTRL_HIST_CLK_EN | \
1268 ISPCTRL_RSZ_CLK_EN | \
1269 (ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN) | \
1270 (ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN))
1271
1272static void __isp_subclk_update(struct isp_device *isp)
1273{
1274 u32 clk = 0;
1275
1276 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_H3A)
1277 clk |= ISPCTRL_H3A_CLK_EN;
1278
1279 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_HIST)
1280 clk |= ISPCTRL_HIST_CLK_EN;
1281
1282 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_RESIZER)
1283 clk |= ISPCTRL_RSZ_CLK_EN;
1284
1285 /* NOTE: For CCDC & Preview submodules, we need to affect internal
1286 * RAM aswell.
1287 */
1288 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_CCDC)
1289 clk |= ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN;
1290
1291 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_PREVIEW)
1292 clk |= ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN;
1293
1294 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
1295 ISPCTRL_CLKS_MASK, clk);
1296}
1297
1298void omap3isp_subclk_enable(struct isp_device *isp,
1299 enum isp_subclk_resource res)
1300{
1301 isp->subclk_resources |= res;
1302
1303 __isp_subclk_update(isp);
1304}
1305
1306void omap3isp_subclk_disable(struct isp_device *isp,
1307 enum isp_subclk_resource res)
1308{
1309 isp->subclk_resources &= ~res;
1310
1311 __isp_subclk_update(isp);
1312}
1313
1314/*
1315 * isp_enable_clocks - Enable ISP clocks
1316 * @isp: OMAP3 ISP device
1317 *
1318 * Return 0 if successful, or clk_enable return value if any of tthem fails.
1319 */
1320static int isp_enable_clocks(struct isp_device *isp)
1321{
1322 int r;
1323 unsigned long rate;
1324 int divisor;
1325
1326 /*
1327 * cam_mclk clock chain:
1328 * dpll4 -> dpll4_m5 -> dpll4_m5x2 -> cam_mclk
1329 *
1330 * In OMAP3630 dpll4_m5x2 != 2 x dpll4_m5 but both are
1331 * set to the same value. Hence the rate set for dpll4_m5
1332 * has to be twice of what is set on OMAP3430 to get
1333 * the required value for cam_mclk
1334 */
1335 if (cpu_is_omap3630())
1336 divisor = 1;
1337 else
1338 divisor = 2;
1339
1340 r = clk_enable(isp->clock[ISP_CLK_CAM_ICK]);
1341 if (r) {
1342 dev_err(isp->dev, "clk_enable cam_ick failed\n");
1343 goto out_clk_enable_ick;
1344 }
1345 r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK],
1346 CM_CAM_MCLK_HZ/divisor);
1347 if (r) {
1348 dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n");
1349 goto out_clk_enable_mclk;
1350 }
1351 r = clk_enable(isp->clock[ISP_CLK_CAM_MCLK]);
1352 if (r) {
1353 dev_err(isp->dev, "clk_enable cam_mclk failed\n");
1354 goto out_clk_enable_mclk;
1355 }
1356 rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
1357 if (rate != CM_CAM_MCLK_HZ)
1358 dev_warn(isp->dev, "unexpected cam_mclk rate:\n"
1359 " expected : %d\n"
1360 " actual : %ld\n", CM_CAM_MCLK_HZ, rate);
1361 r = clk_enable(isp->clock[ISP_CLK_CSI2_FCK]);
1362 if (r) {
1363 dev_err(isp->dev, "clk_enable csi2_fck failed\n");
1364 goto out_clk_enable_csi2_fclk;
1365 }
1366 return 0;
1367
1368out_clk_enable_csi2_fclk:
1369 clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
1370out_clk_enable_mclk:
1371 clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
1372out_clk_enable_ick:
1373 return r;
1374}
1375
1376/*
1377 * isp_disable_clocks - Disable ISP clocks
1378 * @isp: OMAP3 ISP device
1379 */
1380static void isp_disable_clocks(struct isp_device *isp)
1381{
1382 clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
1383 clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
1384 clk_disable(isp->clock[ISP_CLK_CSI2_FCK]);
1385}
1386
1387static const char *isp_clocks[] = {
1388 "cam_ick",
1389 "cam_mclk",
1390 "dpll4_m5_ck",
1391 "csi2_96m_fck",
1392 "l3_ick",
1393};
1394
1395static void isp_put_clocks(struct isp_device *isp)
1396{
1397 unsigned int i;
1398
1399 for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
1400 if (isp->clock[i]) {
1401 clk_put(isp->clock[i]);
1402 isp->clock[i] = NULL;
1403 }
1404 }
1405}
1406
1407static int isp_get_clocks(struct isp_device *isp)
1408{
1409 struct clk *clk;
1410 unsigned int i;
1411
1412 for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
1413 clk = clk_get(isp->dev, isp_clocks[i]);
1414 if (IS_ERR(clk)) {
1415 dev_err(isp->dev, "clk_get %s failed\n", isp_clocks[i]);
1416 isp_put_clocks(isp);
1417 return PTR_ERR(clk);
1418 }
1419
1420 isp->clock[i] = clk;
1421 }
1422
1423 return 0;
1424}
1425
1426/*
1427 * omap3isp_get - Acquire the ISP resource.
1428 *
1429 * Initializes the clocks for the first acquire.
1430 *
1431 * Increment the reference count on the ISP. If the first reference is taken,
1432 * enable clocks and power-up all submodules.
1433 *
1434 * Return a pointer to the ISP device structure, or NULL if an error occured.
1435 */
1436struct isp_device *omap3isp_get(struct isp_device *isp)
1437{
1438 struct isp_device *__isp = isp;
1439
1440 if (isp == NULL)
1441 return NULL;
1442
1443 mutex_lock(&isp->isp_mutex);
1444 if (isp->ref_count > 0)
1445 goto out;
1446
1447 if (isp_enable_clocks(isp) < 0) {
1448 __isp = NULL;
1449 goto out;
1450 }
1451
1452 /* We don't want to restore context before saving it! */
1453 if (isp->has_context)
1454 isp_restore_ctx(isp);
1455 else
1456 isp->has_context = 1;
1457
1458 isp_enable_interrupts(isp);
1459
1460out:
1461 if (__isp != NULL)
1462 isp->ref_count++;
1463 mutex_unlock(&isp->isp_mutex);
1464
1465 return __isp;
1466}
1467
1468/*
1469 * omap3isp_put - Release the ISP
1470 *
1471 * Decrement the reference count on the ISP. If the last reference is released,
1472 * power-down all submodules, disable clocks and free temporary buffers.
1473 */
1474void omap3isp_put(struct isp_device *isp)
1475{
1476 if (isp == NULL)
1477 return;
1478
1479 mutex_lock(&isp->isp_mutex);
1480 BUG_ON(isp->ref_count == 0);
1481 if (--isp->ref_count == 0) {
1482 isp_disable_interrupts(isp);
1483 isp_save_ctx(isp);
1484 isp_disable_clocks(isp);
1485 }
1486 mutex_unlock(&isp->isp_mutex);
1487}
1488
1489/* --------------------------------------------------------------------------
1490 * Platform device driver
1491 */
1492
1493/*
1494 * omap3isp_print_status - Prints the values of the ISP Control Module registers
1495 * @isp: OMAP3 ISP device
1496 */
1497#define ISP_PRINT_REGISTER(isp, name)\
1498 dev_dbg(isp->dev, "###ISP " #name "=0x%08x\n", \
1499 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_##name))
1500#define SBL_PRINT_REGISTER(isp, name)\
1501 dev_dbg(isp->dev, "###SBL " #name "=0x%08x\n", \
1502 isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_##name))
1503
1504void omap3isp_print_status(struct isp_device *isp)
1505{
1506 dev_dbg(isp->dev, "-------------ISP Register dump--------------\n");
1507
1508 ISP_PRINT_REGISTER(isp, SYSCONFIG);
1509 ISP_PRINT_REGISTER(isp, SYSSTATUS);
1510 ISP_PRINT_REGISTER(isp, IRQ0ENABLE);
1511 ISP_PRINT_REGISTER(isp, IRQ0STATUS);
1512 ISP_PRINT_REGISTER(isp, TCTRL_GRESET_LENGTH);
1513 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_REPLAY);
1514 ISP_PRINT_REGISTER(isp, CTRL);
1515 ISP_PRINT_REGISTER(isp, TCTRL_CTRL);
1516 ISP_PRINT_REGISTER(isp, TCTRL_FRAME);
1517 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_DELAY);
1518 ISP_PRINT_REGISTER(isp, TCTRL_STRB_DELAY);
1519 ISP_PRINT_REGISTER(isp, TCTRL_SHUT_DELAY);
1520 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_LENGTH);
1521 ISP_PRINT_REGISTER(isp, TCTRL_STRB_LENGTH);
1522 ISP_PRINT_REGISTER(isp, TCTRL_SHUT_LENGTH);
1523
1524 SBL_PRINT_REGISTER(isp, PCR);
1525 SBL_PRINT_REGISTER(isp, SDR_REQ_EXP);
1526
1527 dev_dbg(isp->dev, "--------------------------------------------\n");
1528}
1529
1530#ifdef CONFIG_PM
1531
1532/*
1533 * Power management support.
1534 *
1535 * As the ISP can't properly handle an input video stream interruption on a non
1536 * frame boundary, the ISP pipelines need to be stopped before sensors get
1537 * suspended. However, as suspending the sensors can require a running clock,
1538 * which can be provided by the ISP, the ISP can't be completely suspended
1539 * before the sensor.
1540 *
1541 * To solve this problem power management support is split into prepare/complete
1542 * and suspend/resume operations. The pipelines are stopped in prepare() and the
1543 * ISP clocks get disabled in suspend(). Similarly, the clocks are reenabled in
1544 * resume(), and the the pipelines are restarted in complete().
1545 *
1546 * TODO: PM dependencies between the ISP and sensors are not modeled explicitly
1547 * yet.
1548 */
1549static int isp_pm_prepare(struct device *dev)
1550{
1551 struct isp_device *isp = dev_get_drvdata(dev);
1552 int reset;
1553
1554 WARN_ON(mutex_is_locked(&isp->isp_mutex));
1555
1556 if (isp->ref_count == 0)
1557 return 0;
1558
1559 reset = isp_suspend_modules(isp);
1560 isp_disable_interrupts(isp);
1561 isp_save_ctx(isp);
1562 if (reset)
1563 isp_reset(isp);
1564
1565 return 0;
1566}
1567
1568static int isp_pm_suspend(struct device *dev)
1569{
1570 struct isp_device *isp = dev_get_drvdata(dev);
1571
1572 WARN_ON(mutex_is_locked(&isp->isp_mutex));
1573
1574 if (isp->ref_count)
1575 isp_disable_clocks(isp);
1576
1577 return 0;
1578}
1579
1580static int isp_pm_resume(struct device *dev)
1581{
1582 struct isp_device *isp = dev_get_drvdata(dev);
1583
1584 if (isp->ref_count == 0)
1585 return 0;
1586
1587 return isp_enable_clocks(isp);
1588}
1589
1590static void isp_pm_complete(struct device *dev)
1591{
1592 struct isp_device *isp = dev_get_drvdata(dev);
1593
1594 if (isp->ref_count == 0)
1595 return;
1596
1597 isp_restore_ctx(isp);
1598 isp_enable_interrupts(isp);
1599 isp_resume_modules(isp);
1600}
1601
1602#else
1603
1604#define isp_pm_prepare NULL
1605#define isp_pm_suspend NULL
1606#define isp_pm_resume NULL
1607#define isp_pm_complete NULL
1608
1609#endif /* CONFIG_PM */
1610
1611static void isp_unregister_entities(struct isp_device *isp)
1612{
1613 omap3isp_csi2_unregister_entities(&isp->isp_csi2a);
1614 omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);
1615 omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);
1616 omap3isp_preview_unregister_entities(&isp->isp_prev);
1617 omap3isp_resizer_unregister_entities(&isp->isp_res);
1618 omap3isp_stat_unregister_entities(&isp->isp_aewb);
1619 omap3isp_stat_unregister_entities(&isp->isp_af);
1620 omap3isp_stat_unregister_entities(&isp->isp_hist);
1621
1622 v4l2_device_unregister(&isp->v4l2_dev);
1623 media_device_unregister(&isp->media_dev);
1624}
1625
1626/*
1627 * isp_register_subdev_group - Register a group of subdevices
1628 * @isp: OMAP3 ISP device
1629 * @board_info: I2C subdevs board information array
1630 *
1631 * Register all I2C subdevices in the board_info array. The array must be
1632 * terminated by a NULL entry, and the first entry must be the sensor.
1633 *
1634 * Return a pointer to the sensor media entity if it has been successfully
1635 * registered, or NULL otherwise.
1636 */
1637static struct v4l2_subdev *
1638isp_register_subdev_group(struct isp_device *isp,
1639 struct isp_subdev_i2c_board_info *board_info)
1640{
1641 struct v4l2_subdev *sensor = NULL;
1642 unsigned int first;
1643
1644 if (board_info->board_info == NULL)
1645 return NULL;
1646
1647 for (first = 1; board_info->board_info; ++board_info, first = 0) {
1648 struct v4l2_subdev *subdev;
1649 struct i2c_adapter *adapter;
1650
1651 adapter = i2c_get_adapter(board_info->i2c_adapter_id);
1652 if (adapter == NULL) {
1653 printk(KERN_ERR "%s: Unable to get I2C adapter %d for "
1654 "device %s\n", __func__,
1655 board_info->i2c_adapter_id,
1656 board_info->board_info->type);
1657 continue;
1658 }
1659
1660 subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
1661 board_info->board_info, NULL);
1662 if (subdev == NULL) {
1663 printk(KERN_ERR "%s: Unable to register subdev %s\n",
1664 __func__, board_info->board_info->type);
1665 continue;
1666 }
1667
1668 if (first)
1669 sensor = subdev;
1670 }
1671
1672 return sensor;
1673}
1674
1675static int isp_register_entities(struct isp_device *isp)
1676{
1677 struct isp_platform_data *pdata = isp->pdata;
1678 struct isp_v4l2_subdevs_group *subdevs;
1679 int ret;
1680
1681 isp->media_dev.dev = isp->dev;
1682 strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
1683 sizeof(isp->media_dev.model));
1684 isp->media_dev.link_notify = isp_pipeline_link_notify;
1685 ret = media_device_register(&isp->media_dev);
1686 if (ret < 0) {
1687 printk(KERN_ERR "%s: Media device registration failed (%d)\n",
1688 __func__, ret);
1689 return ret;
1690 }
1691
1692 isp->v4l2_dev.mdev = &isp->media_dev;
1693 ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
1694 if (ret < 0) {
1695 printk(KERN_ERR "%s: V4L2 device registration failed (%d)\n",
1696 __func__, ret);
1697 goto done;
1698 }
1699
1700 /* Register internal entities */
1701 ret = omap3isp_ccp2_register_entities(&isp->isp_ccp2, &isp->v4l2_dev);
1702 if (ret < 0)
1703 goto done;
1704
1705 ret = omap3isp_csi2_register_entities(&isp->isp_csi2a, &isp->v4l2_dev);
1706 if (ret < 0)
1707 goto done;
1708
1709 ret = omap3isp_ccdc_register_entities(&isp->isp_ccdc, &isp->v4l2_dev);
1710 if (ret < 0)
1711 goto done;
1712
1713 ret = omap3isp_preview_register_entities(&isp->isp_prev,
1714 &isp->v4l2_dev);
1715 if (ret < 0)
1716 goto done;
1717
1718 ret = omap3isp_resizer_register_entities(&isp->isp_res, &isp->v4l2_dev);
1719 if (ret < 0)
1720 goto done;
1721
1722 ret = omap3isp_stat_register_entities(&isp->isp_aewb, &isp->v4l2_dev);
1723 if (ret < 0)
1724 goto done;
1725
1726 ret = omap3isp_stat_register_entities(&isp->isp_af, &isp->v4l2_dev);
1727 if (ret < 0)
1728 goto done;
1729
1730 ret = omap3isp_stat_register_entities(&isp->isp_hist, &isp->v4l2_dev);
1731 if (ret < 0)
1732 goto done;
1733
1734 /* Register external entities */
1735 for (subdevs = pdata->subdevs; subdevs->subdevs; ++subdevs) {
1736 struct v4l2_subdev *sensor;
1737 struct media_entity *input;
1738 unsigned int flags;
1739 unsigned int pad;
1740
1741 sensor = isp_register_subdev_group(isp, subdevs->subdevs);
1742 if (sensor == NULL)
1743 continue;
1744
1745 sensor->host_priv = subdevs;
1746
1747 /* Connect the sensor to the correct interface module. Parallel
1748 * sensors are connected directly to the CCDC, while serial
1749 * sensors are connected to the CSI2a, CCP2b or CSI2c receiver
1750 * through CSIPHY1 or CSIPHY2.
1751 */
1752 switch (subdevs->interface) {
1753 case ISP_INTERFACE_PARALLEL:
1754 input = &isp->isp_ccdc.subdev.entity;
1755 pad = CCDC_PAD_SINK;
1756 flags = 0;
1757 break;
1758
1759 case ISP_INTERFACE_CSI2A_PHY2:
1760 input = &isp->isp_csi2a.subdev.entity;
1761 pad = CSI2_PAD_SINK;
1762 flags = MEDIA_LNK_FL_IMMUTABLE
1763 | MEDIA_LNK_FL_ENABLED;
1764 break;
1765
1766 case ISP_INTERFACE_CCP2B_PHY1:
1767 case ISP_INTERFACE_CCP2B_PHY2:
1768 input = &isp->isp_ccp2.subdev.entity;
1769 pad = CCP2_PAD_SINK;
1770 flags = 0;
1771 break;
1772
1773 case ISP_INTERFACE_CSI2C_PHY1:
1774 input = &isp->isp_csi2c.subdev.entity;
1775 pad = CSI2_PAD_SINK;
1776 flags = MEDIA_LNK_FL_IMMUTABLE
1777 | MEDIA_LNK_FL_ENABLED;
1778 break;
1779
1780 default:
1781 printk(KERN_ERR "%s: invalid interface type %u\n",
1782 __func__, subdevs->interface);
1783 ret = -EINVAL;
1784 goto done;
1785 }
1786
1787 ret = media_entity_create_link(&sensor->entity, 0, input, pad,
1788 flags);
1789 if (ret < 0)
1790 goto done;
1791 }
1792
1793 ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
1794
1795done:
1796 if (ret < 0)
1797 isp_unregister_entities(isp);
1798
1799 return ret;
1800}
1801
1802static void isp_cleanup_modules(struct isp_device *isp)
1803{
1804 omap3isp_h3a_aewb_cleanup(isp);
1805 omap3isp_h3a_af_cleanup(isp);
1806 omap3isp_hist_cleanup(isp);
1807 omap3isp_resizer_cleanup(isp);
1808 omap3isp_preview_cleanup(isp);
1809 omap3isp_ccdc_cleanup(isp);
1810 omap3isp_ccp2_cleanup(isp);
1811 omap3isp_csi2_cleanup(isp);
1812}
1813
1814static int isp_initialize_modules(struct isp_device *isp)
1815{
1816 int ret;
1817
1818 ret = omap3isp_csiphy_init(isp);
1819 if (ret < 0) {
1820 dev_err(isp->dev, "CSI PHY initialization failed\n");
1821 goto error_csiphy;
1822 }
1823
1824 ret = omap3isp_csi2_init(isp);
1825 if (ret < 0) {
1826 dev_err(isp->dev, "CSI2 initialization failed\n");
1827 goto error_csi2;
1828 }
1829
1830 ret = omap3isp_ccp2_init(isp);
1831 if (ret < 0) {
1832 dev_err(isp->dev, "CCP2 initialization failed\n");
1833 goto error_ccp2;
1834 }
1835
1836 ret = omap3isp_ccdc_init(isp);
1837 if (ret < 0) {
1838 dev_err(isp->dev, "CCDC initialization failed\n");
1839 goto error_ccdc;
1840 }
1841
1842 ret = omap3isp_preview_init(isp);
1843 if (ret < 0) {
1844 dev_err(isp->dev, "Preview initialization failed\n");
1845 goto error_preview;
1846 }
1847
1848 ret = omap3isp_resizer_init(isp);
1849 if (ret < 0) {
1850 dev_err(isp->dev, "Resizer initialization failed\n");
1851 goto error_resizer;
1852 }
1853
1854 ret = omap3isp_hist_init(isp);
1855 if (ret < 0) {
1856 dev_err(isp->dev, "Histogram initialization failed\n");
1857 goto error_hist;
1858 }
1859
1860 ret = omap3isp_h3a_aewb_init(isp);
1861 if (ret < 0) {
1862 dev_err(isp->dev, "H3A AEWB initialization failed\n");
1863 goto error_h3a_aewb;
1864 }
1865
1866 ret = omap3isp_h3a_af_init(isp);
1867 if (ret < 0) {
1868 dev_err(isp->dev, "H3A AF initialization failed\n");
1869 goto error_h3a_af;
1870 }
1871
1872 /* Connect the submodules. */
1873 ret = media_entity_create_link(
1874 &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
1875 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
1876 if (ret < 0)
1877 goto error_link;
1878
1879 ret = media_entity_create_link(
1880 &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
1881 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
1882 if (ret < 0)
1883 goto error_link;
1884
1885 ret = media_entity_create_link(
1886 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1887 &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
1888 if (ret < 0)
1889 goto error_link;
1890
1891 ret = media_entity_create_link(
1892 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
1893 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
1894 if (ret < 0)
1895 goto error_link;
1896
1897 ret = media_entity_create_link(
1898 &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
1899 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
1900 if (ret < 0)
1901 goto error_link;
1902
1903 ret = media_entity_create_link(
1904 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1905 &isp->isp_aewb.subdev.entity, 0,
1906 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1907 if (ret < 0)
1908 goto error_link;
1909
1910 ret = media_entity_create_link(
1911 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1912 &isp->isp_af.subdev.entity, 0,
1913 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1914 if (ret < 0)
1915 goto error_link;
1916
1917 ret = media_entity_create_link(
1918 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1919 &isp->isp_hist.subdev.entity, 0,
1920 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1921 if (ret < 0)
1922 goto error_link;
1923
1924 return 0;
1925
1926error_link:
1927 omap3isp_h3a_af_cleanup(isp);
1928error_h3a_af:
1929 omap3isp_h3a_aewb_cleanup(isp);
1930error_h3a_aewb:
1931 omap3isp_hist_cleanup(isp);
1932error_hist:
1933 omap3isp_resizer_cleanup(isp);
1934error_resizer:
1935 omap3isp_preview_cleanup(isp);
1936error_preview:
1937 omap3isp_ccdc_cleanup(isp);
1938error_ccdc:
1939 omap3isp_ccp2_cleanup(isp);
1940error_ccp2:
1941 omap3isp_csi2_cleanup(isp);
1942error_csi2:
1943error_csiphy:
1944 return ret;
1945}
1946
1947/*
1948 * isp_remove - Remove ISP platform device
1949 * @pdev: Pointer to ISP platform device
1950 *
1951 * Always returns 0.
1952 */
1953static int isp_remove(struct platform_device *pdev)
1954{
1955 struct isp_device *isp = platform_get_drvdata(pdev);
1956 int i;
1957
1958 isp_unregister_entities(isp);
1959 isp_cleanup_modules(isp);
1960
1961 omap3isp_get(isp);
1962 iommu_put(isp->iommu);
1963 omap3isp_put(isp);
1964
1965 free_irq(isp->irq_num, isp);
1966 isp_put_clocks(isp);
1967
1968 for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
1969 if (isp->mmio_base[i]) {
1970 iounmap(isp->mmio_base[i]);
1971 isp->mmio_base[i] = NULL;
1972 }
1973
1974 if (isp->mmio_base_phys[i]) {
1975 release_mem_region(isp->mmio_base_phys[i],
1976 isp->mmio_size[i]);
1977 isp->mmio_base_phys[i] = 0;
1978 }
1979 }
1980
1981 regulator_put(isp->isp_csiphy1.vdd);
1982 regulator_put(isp->isp_csiphy2.vdd);
1983 kfree(isp);
1984
1985 return 0;
1986}
1987
1988static int isp_map_mem_resource(struct platform_device *pdev,
1989 struct isp_device *isp,
1990 enum isp_mem_resources res)
1991{
1992 struct resource *mem;
1993
1994 /* request the mem region for the camera registers */
1995
1996 mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
1997 if (!mem) {
1998 dev_err(isp->dev, "no mem resource?\n");
1999 return -ENODEV;
2000 }
2001
2002 if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
2003 dev_err(isp->dev,
2004 "cannot reserve camera register I/O region\n");
2005 return -ENODEV;
2006 }
2007 isp->mmio_base_phys[res] = mem->start;
2008 isp->mmio_size[res] = resource_size(mem);
2009
2010 /* map the region */
2011 isp->mmio_base[res] = ioremap_nocache(isp->mmio_base_phys[res],
2012 isp->mmio_size[res]);
2013 if (!isp->mmio_base[res]) {
2014 dev_err(isp->dev, "cannot map camera register I/O region\n");
2015 return -ENODEV;
2016 }
2017
2018 return 0;
2019}
2020
2021/*
2022 * isp_probe - Probe ISP platform device
2023 * @pdev: Pointer to ISP platform device
2024 *
2025 * Returns 0 if successful,
2026 * -ENOMEM if no memory available,
2027 * -ENODEV if no platform device resources found
2028 * or no space for remapping registers,
2029 * -EINVAL if couldn't install ISR,
2030 * or clk_get return error value.
2031 */
2032static int isp_probe(struct platform_device *pdev)
2033{
2034 struct isp_platform_data *pdata = pdev->dev.platform_data;
2035 struct isp_device *isp;
2036 int ret;
2037 int i, m;
2038
2039 if (pdata == NULL)
2040 return -EINVAL;
2041
2042 isp = kzalloc(sizeof(*isp), GFP_KERNEL);
2043 if (!isp) {
2044 dev_err(&pdev->dev, "could not allocate memory\n");
2045 return -ENOMEM;
2046 }
2047
2048 isp->autoidle = autoidle;
2049 isp->platform_cb.set_xclk = isp_set_xclk;
2050 isp->platform_cb.set_pixel_clock = isp_set_pixel_clock;
2051
2052 mutex_init(&isp->isp_mutex);
2053 spin_lock_init(&isp->stat_lock);
2054
2055 isp->dev = &pdev->dev;
2056 isp->pdata = pdata;
2057 isp->ref_count = 0;
2058
2059 isp->raw_dmamask = DMA_BIT_MASK(32);
2060 isp->dev->dma_mask = &isp->raw_dmamask;
2061 isp->dev->coherent_dma_mask = DMA_BIT_MASK(32);
2062
2063 platform_set_drvdata(pdev, isp);
2064
2065 /* Regulators */
2066 isp->isp_csiphy1.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY1");
2067 isp->isp_csiphy2.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY2");
2068
2069 /* Clocks */
2070 ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN);
2071 if (ret < 0)
2072 goto error;
2073
2074 ret = isp_get_clocks(isp);
2075 if (ret < 0)
2076 goto error;
2077
2078 if (omap3isp_get(isp) == NULL)
2079 goto error;
2080
2081 ret = isp_reset(isp);
2082 if (ret < 0)
2083 goto error_isp;
2084
2085 /* Memory resources */
2086 isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
2087 dev_info(isp->dev, "Revision %d.%d found\n",
2088 (isp->revision & 0xf0) >> 4, isp->revision & 0x0f);
2089
2090 for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++)
2091 if (isp->revision == isp_res_maps[m].isp_rev)
2092 break;
2093
2094 if (m == ARRAY_SIZE(isp_res_maps)) {
2095 dev_err(isp->dev, "No resource map found for ISP rev %d.%d\n",
2096 (isp->revision & 0xf0) >> 4, isp->revision & 0xf);
2097 ret = -ENODEV;
2098 goto error_isp;
2099 }
2100
2101 for (i = 1; i < OMAP3_ISP_IOMEM_LAST; i++) {
2102 if (isp_res_maps[m].map & 1 << i) {
2103 ret = isp_map_mem_resource(pdev, isp, i);
2104 if (ret)
2105 goto error_isp;
2106 }
2107 }
2108
2109 /* IOMMU */
2110 isp->iommu = iommu_get("isp");
2111 if (IS_ERR_OR_NULL(isp->iommu)) {
2112 isp->iommu = NULL;
2113 ret = -ENODEV;
2114 goto error_isp;
2115 }
2116
2117 /* Interrupt */
2118 isp->irq_num = platform_get_irq(pdev, 0);
2119 if (isp->irq_num <= 0) {
2120 dev_err(isp->dev, "No IRQ resource\n");
2121 ret = -ENODEV;
2122 goto error_isp;
2123 }
2124
2125 if (request_irq(isp->irq_num, isp_isr, IRQF_SHARED, "OMAP3 ISP", isp)) {
2126 dev_err(isp->dev, "Unable to request IRQ\n");
2127 ret = -EINVAL;
2128 goto error_isp;
2129 }
2130
2131 /* Entities */
2132 ret = isp_initialize_modules(isp);
2133 if (ret < 0)
2134 goto error_irq;
2135
2136 ret = isp_register_entities(isp);
2137 if (ret < 0)
2138 goto error_modules;
2139
2140 isp_power_settings(isp, 1);
2141 omap3isp_put(isp);
2142
2143 return 0;
2144
2145error_modules:
2146 isp_cleanup_modules(isp);
2147error_irq:
2148 free_irq(isp->irq_num, isp);
2149error_isp:
2150 iommu_put(isp->iommu);
2151 omap3isp_put(isp);
2152error:
2153 isp_put_clocks(isp);
2154
2155 for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
2156 if (isp->mmio_base[i]) {
2157 iounmap(isp->mmio_base[i]);
2158 isp->mmio_base[i] = NULL;
2159 }
2160
2161 if (isp->mmio_base_phys[i]) {
2162 release_mem_region(isp->mmio_base_phys[i],
2163 isp->mmio_size[i]);
2164 isp->mmio_base_phys[i] = 0;
2165 }
2166 }
2167 regulator_put(isp->isp_csiphy2.vdd);
2168 regulator_put(isp->isp_csiphy1.vdd);
2169 platform_set_drvdata(pdev, NULL);
2170 kfree(isp);
2171
2172 return ret;
2173}
2174
2175static const struct dev_pm_ops omap3isp_pm_ops = {
2176 .prepare = isp_pm_prepare,
2177 .suspend = isp_pm_suspend,
2178 .resume = isp_pm_resume,
2179 .complete = isp_pm_complete,
2180};
2181
2182static struct platform_device_id omap3isp_id_table[] = {
2183 { "omap3isp", 0 },
2184 { },
2185};
2186MODULE_DEVICE_TABLE(platform, omap3isp_id_table);
2187
2188static struct platform_driver omap3isp_driver = {
2189 .probe = isp_probe,
2190 .remove = isp_remove,
2191 .id_table = omap3isp_id_table,
2192 .driver = {
2193 .owner = THIS_MODULE,
2194 .name = "omap3isp",
2195 .pm = &omap3isp_pm_ops,
2196 },
2197};
2198
2199/*
2200 * isp_init - ISP module initialization.
2201 */
2202static int __init isp_init(void)
2203{
2204 return platform_driver_register(&omap3isp_driver);
2205}
2206
2207/*
2208 * isp_cleanup - ISP module cleanup.
2209 */
2210static void __exit isp_cleanup(void)
2211{
2212 platform_driver_unregister(&omap3isp_driver);
2213}
2214
2215module_init(isp_init);
2216module_exit(isp_cleanup);
2217
2218MODULE_AUTHOR("Nokia Corporation");
2219MODULE_DESCRIPTION("TI OMAP3 ISP driver");
2220MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h
new file mode 100644
index 000000000000..cf5214e95a92
--- /dev/null
+++ b/drivers/media/video/omap3isp/isp.h
@@ -0,0 +1,431 @@
1/*
2 * isp.h
3 *
4 * TI OMAP3 ISP - Core
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CORE_H
28#define OMAP3_ISP_CORE_H
29
30#include <media/v4l2-device.h>
31#include <linux/device.h>
32#include <linux/io.h>
33#include <linux/platform_device.h>
34#include <linux/wait.h>
35#include <plat/iommu.h>
36#include <plat/iovmm.h>
37
38#include "ispstat.h"
39#include "ispccdc.h"
40#include "ispreg.h"
41#include "ispresizer.h"
42#include "isppreview.h"
43#include "ispcsiphy.h"
44#include "ispcsi2.h"
45#include "ispccp2.h"
46
47#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
48
49#define ISP_TOK_TERM 0xFFFFFFFF /*
50 * terminating token for ISP
51 * modules reg list
52 */
53#define to_isp_device(ptr_module) \
54 container_of(ptr_module, struct isp_device, isp_##ptr_module)
55#define to_device(ptr_module) \
56 (to_isp_device(ptr_module)->dev)
57
58enum isp_mem_resources {
59 OMAP3_ISP_IOMEM_MAIN,
60 OMAP3_ISP_IOMEM_CCP2,
61 OMAP3_ISP_IOMEM_CCDC,
62 OMAP3_ISP_IOMEM_HIST,
63 OMAP3_ISP_IOMEM_H3A,
64 OMAP3_ISP_IOMEM_PREV,
65 OMAP3_ISP_IOMEM_RESZ,
66 OMAP3_ISP_IOMEM_SBL,
67 OMAP3_ISP_IOMEM_CSI2A_REGS1,
68 OMAP3_ISP_IOMEM_CSIPHY2,
69 OMAP3_ISP_IOMEM_CSI2A_REGS2,
70 OMAP3_ISP_IOMEM_CSI2C_REGS1,
71 OMAP3_ISP_IOMEM_CSIPHY1,
72 OMAP3_ISP_IOMEM_CSI2C_REGS2,
73 OMAP3_ISP_IOMEM_LAST
74};
75
76enum isp_sbl_resource {
77 OMAP3_ISP_SBL_CSI1_READ = 0x1,
78 OMAP3_ISP_SBL_CSI1_WRITE = 0x2,
79 OMAP3_ISP_SBL_CSI2A_WRITE = 0x4,
80 OMAP3_ISP_SBL_CSI2C_WRITE = 0x8,
81 OMAP3_ISP_SBL_CCDC_LSC_READ = 0x10,
82 OMAP3_ISP_SBL_CCDC_WRITE = 0x20,
83 OMAP3_ISP_SBL_PREVIEW_READ = 0x40,
84 OMAP3_ISP_SBL_PREVIEW_WRITE = 0x80,
85 OMAP3_ISP_SBL_RESIZER_READ = 0x100,
86 OMAP3_ISP_SBL_RESIZER_WRITE = 0x200,
87};
88
89enum isp_subclk_resource {
90 OMAP3_ISP_SUBCLK_CCDC = (1 << 0),
91 OMAP3_ISP_SUBCLK_H3A = (1 << 1),
92 OMAP3_ISP_SUBCLK_HIST = (1 << 2),
93 OMAP3_ISP_SUBCLK_PREVIEW = (1 << 3),
94 OMAP3_ISP_SUBCLK_RESIZER = (1 << 4),
95};
96
97enum isp_interface_type {
98 ISP_INTERFACE_PARALLEL,
99 ISP_INTERFACE_CSI2A_PHY2,
100 ISP_INTERFACE_CCP2B_PHY1,
101 ISP_INTERFACE_CCP2B_PHY2,
102 ISP_INTERFACE_CSI2C_PHY1,
103};
104
105/* ISP: OMAP 34xx ES 1.0 */
106#define ISP_REVISION_1_0 0x10
107/* ISP2: OMAP 34xx ES 2.0, 2.1 and 3.0 */
108#define ISP_REVISION_2_0 0x20
109/* ISP2P: OMAP 36xx */
110#define ISP_REVISION_15_0 0xF0
111
112/*
113 * struct isp_res_mapping - Map ISP io resources to ISP revision.
114 * @isp_rev: ISP_REVISION_x_x
115 * @map: bitmap for enum isp_mem_resources
116 */
117struct isp_res_mapping {
118 u32 isp_rev;
119 u32 map;
120};
121
122/*
123 * struct isp_reg - Structure for ISP register values.
124 * @reg: 32-bit Register address.
125 * @val: 32-bit Register value.
126 */
127struct isp_reg {
128 enum isp_mem_resources mmio_range;
129 u32 reg;
130 u32 val;
131};
132
133/**
134 * struct isp_parallel_platform_data - Parallel interface platform data
135 * @width: Parallel bus width in bits (8, 10, 11 or 12)
136 * @data_lane_shift: Data lane shifter
137 * 0 - CAMEXT[13:0] -> CAM[13:0]
138 * 1 - CAMEXT[13:2] -> CAM[11:0]
139 * 2 - CAMEXT[13:4] -> CAM[9:0]
140 * 3 - CAMEXT[13:6] -> CAM[7:0]
141 * @clk_pol: Pixel clock polarity
142 * 0 - Non Inverted, 1 - Inverted
143 * @bridge: CCDC Bridge input control
144 * ISPCTRL_PAR_BRIDGE_DISABLE - Disable
145 * ISPCTRL_PAR_BRIDGE_LENDIAN - Little endian
146 * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian
147 */
148struct isp_parallel_platform_data {
149 unsigned int width;
150 unsigned int data_lane_shift:2;
151 unsigned int clk_pol:1;
152 unsigned int bridge:4;
153};
154
155/**
156 * struct isp_ccp2_platform_data - CCP2 interface platform data
157 * @strobe_clk_pol: Strobe/clock polarity
158 * 0 - Non Inverted, 1 - Inverted
159 * @crc: Enable the cyclic redundancy check
160 * @ccp2_mode: Enable CCP2 compatibility mode
161 * 0 - MIPI-CSI1 mode, 1 - CCP2 mode
162 * @phy_layer: Physical layer selection
163 * ISPCCP2_CTRL_PHY_SEL_CLOCK - Data/clock physical layer
164 * ISPCCP2_CTRL_PHY_SEL_STROBE - Data/strobe physical layer
165 * @vpclk_div: Video port output clock control
166 */
167struct isp_ccp2_platform_data {
168 unsigned int strobe_clk_pol:1;
169 unsigned int crc:1;
170 unsigned int ccp2_mode:1;
171 unsigned int phy_layer:1;
172 unsigned int vpclk_div:2;
173};
174
175/**
176 * struct isp_csi2_platform_data - CSI2 interface platform data
177 * @crc: Enable the cyclic redundancy check
178 * @vpclk_div: Video port output clock control
179 */
180struct isp_csi2_platform_data {
181 unsigned crc:1;
182 unsigned vpclk_div:2;
183};
184
185struct isp_subdev_i2c_board_info {
186 struct i2c_board_info *board_info;
187 int i2c_adapter_id;
188};
189
190struct isp_v4l2_subdevs_group {
191 struct isp_subdev_i2c_board_info *subdevs;
192 enum isp_interface_type interface;
193 union {
194 struct isp_parallel_platform_data parallel;
195 struct isp_ccp2_platform_data ccp2;
196 struct isp_csi2_platform_data csi2;
197 } bus; /* gcc < 4.6.0 chokes on anonymous union initializers */
198};
199
200struct isp_platform_data {
201 struct isp_v4l2_subdevs_group *subdevs;
202 void (*set_constraints)(struct isp_device *isp, bool enable);
203};
204
205struct isp_platform_callback {
206 u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
207 int (*csiphy_config)(struct isp_csiphy *phy,
208 struct isp_csiphy_dphy_cfg *dphy,
209 struct isp_csiphy_lanes_cfg *lanes);
210 void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
211};
212
213/*
214 * struct isp_device - ISP device structure.
215 * @dev: Device pointer specific to the OMAP3 ISP.
216 * @revision: Stores current ISP module revision.
217 * @irq_num: Currently used IRQ number.
218 * @mmio_base: Array with kernel base addresses for ioremapped ISP register
219 * regions.
220 * @mmio_base_phys: Array with physical L4 bus addresses for ISP register
221 * regions.
222 * @mmio_size: Array with ISP register regions size in bytes.
223 * @raw_dmamask: Raw DMA mask
224 * @stat_lock: Spinlock for handling statistics
225 * @isp_mutex: Mutex for serializing requests to ISP.
226 * @has_context: Context has been saved at least once and can be restored.
227 * @ref_count: Reference count for handling multiple ISP requests.
228 * @cam_ick: Pointer to camera interface clock structure.
229 * @cam_mclk: Pointer to camera functional clock structure.
230 * @dpll4_m5_ck: Pointer to DPLL4 M5 clock structure.
231 * @csi2_fck: Pointer to camera CSI2 complexIO clock structure.
232 * @l3_ick: Pointer to OMAP3 L3 bus interface clock.
233 * @irq: Currently attached ISP ISR callbacks information structure.
234 * @isp_af: Pointer to current settings for ISP AutoFocus SCM.
235 * @isp_hist: Pointer to current settings for ISP Histogram SCM.
236 * @isp_h3a: Pointer to current settings for ISP Auto Exposure and
237 * White Balance SCM.
238 * @isp_res: Pointer to current settings for ISP Resizer.
239 * @isp_prev: Pointer to current settings for ISP Preview.
240 * @isp_ccdc: Pointer to current settings for ISP CCDC.
241 * @iommu: Pointer to requested IOMMU instance for ISP.
242 * @platform_cb: ISP driver callback function pointers for platform code
243 *
244 * This structure is used to store the OMAP ISP Information.
245 */
246struct isp_device {
247 struct v4l2_device v4l2_dev;
248 struct media_device media_dev;
249 struct device *dev;
250 u32 revision;
251
252 /* platform HW resources */
253 struct isp_platform_data *pdata;
254 unsigned int irq_num;
255
256 void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
257 unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST];
258 resource_size_t mmio_size[OMAP3_ISP_IOMEM_LAST];
259
260 u64 raw_dmamask;
261
262 /* ISP Obj */
263 spinlock_t stat_lock; /* common lock for statistic drivers */
264 struct mutex isp_mutex; /* For handling ref_count field */
265 int has_context;
266 int ref_count;
267 unsigned int autoidle;
268 u32 xclk_divisor[2]; /* Two clocks, a and b. */
269#define ISP_CLK_CAM_ICK 0
270#define ISP_CLK_CAM_MCLK 1
271#define ISP_CLK_DPLL4_M5_CK 2
272#define ISP_CLK_CSI2_FCK 3
273#define ISP_CLK_L3_ICK 4
274 struct clk *clock[5];
275
276 /* ISP modules */
277 struct ispstat isp_af;
278 struct ispstat isp_aewb;
279 struct ispstat isp_hist;
280 struct isp_res_device isp_res;
281 struct isp_prev_device isp_prev;
282 struct isp_ccdc_device isp_ccdc;
283 struct isp_csi2_device isp_csi2a;
284 struct isp_csi2_device isp_csi2c;
285 struct isp_ccp2_device isp_ccp2;
286 struct isp_csiphy isp_csiphy1;
287 struct isp_csiphy isp_csiphy2;
288
289 unsigned int sbl_resources;
290 unsigned int subclk_resources;
291
292 struct iommu *iommu;
293
294 struct isp_platform_callback platform_cb;
295};
296
297#define v4l2_dev_to_isp_device(dev) \
298 container_of(dev, struct isp_device, v4l2_dev)
299
300void omap3isp_hist_dma_done(struct isp_device *isp);
301
302void omap3isp_flush(struct isp_device *isp);
303
304int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
305 atomic_t *stopping);
306
307int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
308 atomic_t *stopping);
309
310int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
311 enum isp_pipeline_stream_state state);
312void omap3isp_configure_bridge(struct isp_device *isp,
313 enum ccdc_input_entity input,
314 const struct isp_parallel_platform_data *pdata);
315
316#define ISP_XCLK_NONE -1
317#define ISP_XCLK_A 0
318#define ISP_XCLK_B 1
319
320struct isp_device *omap3isp_get(struct isp_device *isp);
321void omap3isp_put(struct isp_device *isp);
322
323void omap3isp_print_status(struct isp_device *isp);
324
325void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res);
326void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res);
327
328void omap3isp_subclk_enable(struct isp_device *isp,
329 enum isp_subclk_resource res);
330void omap3isp_subclk_disable(struct isp_device *isp,
331 enum isp_subclk_resource res);
332
333int omap3isp_pipeline_pm_use(struct media_entity *entity, int use);
334
335int omap3isp_register_entities(struct platform_device *pdev,
336 struct v4l2_device *v4l2_dev);
337void omap3isp_unregister_entities(struct platform_device *pdev);
338
339/*
340 * isp_reg_readl - Read value of an OMAP3 ISP register
341 * @dev: Device pointer specific to the OMAP3 ISP.
342 * @isp_mmio_range: Range to which the register offset refers to.
343 * @reg_offset: Register offset to read from.
344 *
345 * Returns an unsigned 32 bit value with the required register contents.
346 */
347static inline
348u32 isp_reg_readl(struct isp_device *isp, enum isp_mem_resources isp_mmio_range,
349 u32 reg_offset)
350{
351 return __raw_readl(isp->mmio_base[isp_mmio_range] + reg_offset);
352}
353
354/*
355 * isp_reg_writel - Write value to an OMAP3 ISP register
356 * @dev: Device pointer specific to the OMAP3 ISP.
357 * @reg_value: 32 bit value to write to the register.
358 * @isp_mmio_range: Range to which the register offset refers to.
359 * @reg_offset: Register offset to write into.
360 */
361static inline
362void isp_reg_writel(struct isp_device *isp, u32 reg_value,
363 enum isp_mem_resources isp_mmio_range, u32 reg_offset)
364{
365 __raw_writel(reg_value, isp->mmio_base[isp_mmio_range] + reg_offset);
366}
367
368/*
369 * isp_reg_and - Clear individual bits in an OMAP3 ISP register
370 * @dev: Device pointer specific to the OMAP3 ISP.
371 * @mmio_range: Range to which the register offset refers to.
372 * @reg: Register offset to work on.
373 * @clr_bits: 32 bit value which would be cleared in the register.
374 */
375static inline
376void isp_reg_clr(struct isp_device *isp, enum isp_mem_resources mmio_range,
377 u32 reg, u32 clr_bits)
378{
379 u32 v = isp_reg_readl(isp, mmio_range, reg);
380
381 isp_reg_writel(isp, v & ~clr_bits, mmio_range, reg);
382}
383
384/*
385 * isp_reg_set - Set individual bits in an OMAP3 ISP register
386 * @dev: Device pointer specific to the OMAP3 ISP.
387 * @mmio_range: Range to which the register offset refers to.
388 * @reg: Register offset to work on.
389 * @set_bits: 32 bit value which would be set in the register.
390 */
391static inline
392void isp_reg_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
393 u32 reg, u32 set_bits)
394{
395 u32 v = isp_reg_readl(isp, mmio_range, reg);
396
397 isp_reg_writel(isp, v | set_bits, mmio_range, reg);
398}
399
400/*
401 * isp_reg_clr_set - Clear and set invidial bits in an OMAP3 ISP register
402 * @dev: Device pointer specific to the OMAP3 ISP.
403 * @mmio_range: Range to which the register offset refers to.
404 * @reg: Register offset to work on.
405 * @clr_bits: 32 bit value which would be cleared in the register.
406 * @set_bits: 32 bit value which would be set in the register.
407 *
408 * The clear operation is done first, and then the set operation.
409 */
410static inline
411void isp_reg_clr_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
412 u32 reg, u32 clr_bits, u32 set_bits)
413{
414 u32 v = isp_reg_readl(isp, mmio_range, reg);
415
416 isp_reg_writel(isp, (v & ~clr_bits) | set_bits, mmio_range, reg);
417}
418
419static inline enum v4l2_buf_type
420isp_pad_buffer_type(const struct v4l2_subdev *subdev, int pad)
421{
422 if (pad >= subdev->entity.num_pads)
423 return 0;
424
425 if (subdev->entity.pads[pad].flags & MEDIA_PAD_FL_SINK)
426 return V4L2_BUF_TYPE_VIDEO_OUTPUT;
427 else
428 return V4L2_BUF_TYPE_VIDEO_CAPTURE;
429}
430
431#endif /* OMAP3_ISP_CORE_H */
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
new file mode 100644
index 000000000000..5ff9d14ce710
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -0,0 +1,2268 @@
1/*
2 * ispccdc.c
3 *
4 * TI OMAP3 ISP - CCDC module
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/module.h>
28#include <linux/uaccess.h>
29#include <linux/delay.h>
30#include <linux/device.h>
31#include <linux/dma-mapping.h>
32#include <linux/mm.h>
33#include <linux/sched.h>
34#include <media/v4l2-event.h>
35
36#include "isp.h"
37#include "ispreg.h"
38#include "ispccdc.h"
39
40static struct v4l2_mbus_framefmt *
41__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
42 unsigned int pad, enum v4l2_subdev_format_whence which);
43
44static const unsigned int ccdc_fmts[] = {
45 V4L2_MBUS_FMT_Y8_1X8,
46 V4L2_MBUS_FMT_SGRBG10_1X10,
47 V4L2_MBUS_FMT_SRGGB10_1X10,
48 V4L2_MBUS_FMT_SBGGR10_1X10,
49 V4L2_MBUS_FMT_SGBRG10_1X10,
50 V4L2_MBUS_FMT_SGRBG12_1X12,
51 V4L2_MBUS_FMT_SRGGB12_1X12,
52 V4L2_MBUS_FMT_SBGGR12_1X12,
53 V4L2_MBUS_FMT_SGBRG12_1X12,
54};
55
56/*
57 * ccdc_print_status - Print current CCDC Module register values.
58 * @ccdc: Pointer to ISP CCDC device.
59 *
60 * Also prints other debug information stored in the CCDC module.
61 */
62#define CCDC_PRINT_REGISTER(isp, name)\
63 dev_dbg(isp->dev, "###CCDC " #name "=0x%08x\n", \
64 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_##name))
65
66static void ccdc_print_status(struct isp_ccdc_device *ccdc)
67{
68 struct isp_device *isp = to_isp_device(ccdc);
69
70 dev_dbg(isp->dev, "-------------CCDC Register dump-------------\n");
71
72 CCDC_PRINT_REGISTER(isp, PCR);
73 CCDC_PRINT_REGISTER(isp, SYN_MODE);
74 CCDC_PRINT_REGISTER(isp, HD_VD_WID);
75 CCDC_PRINT_REGISTER(isp, PIX_LINES);
76 CCDC_PRINT_REGISTER(isp, HORZ_INFO);
77 CCDC_PRINT_REGISTER(isp, VERT_START);
78 CCDC_PRINT_REGISTER(isp, VERT_LINES);
79 CCDC_PRINT_REGISTER(isp, CULLING);
80 CCDC_PRINT_REGISTER(isp, HSIZE_OFF);
81 CCDC_PRINT_REGISTER(isp, SDOFST);
82 CCDC_PRINT_REGISTER(isp, SDR_ADDR);
83 CCDC_PRINT_REGISTER(isp, CLAMP);
84 CCDC_PRINT_REGISTER(isp, DCSUB);
85 CCDC_PRINT_REGISTER(isp, COLPTN);
86 CCDC_PRINT_REGISTER(isp, BLKCMP);
87 CCDC_PRINT_REGISTER(isp, FPC);
88 CCDC_PRINT_REGISTER(isp, FPC_ADDR);
89 CCDC_PRINT_REGISTER(isp, VDINT);
90 CCDC_PRINT_REGISTER(isp, ALAW);
91 CCDC_PRINT_REGISTER(isp, REC656IF);
92 CCDC_PRINT_REGISTER(isp, CFG);
93 CCDC_PRINT_REGISTER(isp, FMTCFG);
94 CCDC_PRINT_REGISTER(isp, FMT_HORZ);
95 CCDC_PRINT_REGISTER(isp, FMT_VERT);
96 CCDC_PRINT_REGISTER(isp, PRGEVEN0);
97 CCDC_PRINT_REGISTER(isp, PRGEVEN1);
98 CCDC_PRINT_REGISTER(isp, PRGODD0);
99 CCDC_PRINT_REGISTER(isp, PRGODD1);
100 CCDC_PRINT_REGISTER(isp, VP_OUT);
101 CCDC_PRINT_REGISTER(isp, LSC_CONFIG);
102 CCDC_PRINT_REGISTER(isp, LSC_INITIAL);
103 CCDC_PRINT_REGISTER(isp, LSC_TABLE_BASE);
104 CCDC_PRINT_REGISTER(isp, LSC_TABLE_OFFSET);
105
106 dev_dbg(isp->dev, "--------------------------------------------\n");
107}
108
109/*
110 * omap3isp_ccdc_busy - Get busy state of the CCDC.
111 * @ccdc: Pointer to ISP CCDC device.
112 */
113int omap3isp_ccdc_busy(struct isp_ccdc_device *ccdc)
114{
115 struct isp_device *isp = to_isp_device(ccdc);
116
117 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR) &
118 ISPCCDC_PCR_BUSY;
119}
120
121/* -----------------------------------------------------------------------------
122 * Lens Shading Compensation
123 */
124
125/*
126 * ccdc_lsc_validate_config - Check that LSC configuration is valid.
127 * @ccdc: Pointer to ISP CCDC device.
128 * @lsc_cfg: the LSC configuration to check.
129 *
130 * Returns 0 if the LSC configuration is valid, or -EINVAL if invalid.
131 */
132static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc,
133 struct omap3isp_ccdc_lsc_config *lsc_cfg)
134{
135 struct isp_device *isp = to_isp_device(ccdc);
136 struct v4l2_mbus_framefmt *format;
137 unsigned int paxel_width, paxel_height;
138 unsigned int paxel_shift_x, paxel_shift_y;
139 unsigned int min_width, min_height, min_size;
140 unsigned int input_width, input_height;
141
142 paxel_shift_x = lsc_cfg->gain_mode_m;
143 paxel_shift_y = lsc_cfg->gain_mode_n;
144
145 if ((paxel_shift_x < 2) || (paxel_shift_x > 6) ||
146 (paxel_shift_y < 2) || (paxel_shift_y > 6)) {
147 dev_dbg(isp->dev, "CCDC: LSC: Invalid paxel size\n");
148 return -EINVAL;
149 }
150
151 if (lsc_cfg->offset & 3) {
152 dev_dbg(isp->dev, "CCDC: LSC: Offset must be a multiple of "
153 "4\n");
154 return -EINVAL;
155 }
156
157 if ((lsc_cfg->initial_x & 1) || (lsc_cfg->initial_y & 1)) {
158 dev_dbg(isp->dev, "CCDC: LSC: initial_x and y must be even\n");
159 return -EINVAL;
160 }
161
162 format = __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
163 V4L2_SUBDEV_FORMAT_ACTIVE);
164 input_width = format->width;
165 input_height = format->height;
166
167 /* Calculate minimum bytesize for validation */
168 paxel_width = 1 << paxel_shift_x;
169 min_width = ((input_width + lsc_cfg->initial_x + paxel_width - 1)
170 >> paxel_shift_x) + 1;
171
172 paxel_height = 1 << paxel_shift_y;
173 min_height = ((input_height + lsc_cfg->initial_y + paxel_height - 1)
174 >> paxel_shift_y) + 1;
175
176 min_size = 4 * min_width * min_height;
177 if (min_size > lsc_cfg->size) {
178 dev_dbg(isp->dev, "CCDC: LSC: too small table\n");
179 return -EINVAL;
180 }
181 if (lsc_cfg->offset < (min_width * 4)) {
182 dev_dbg(isp->dev, "CCDC: LSC: Offset is too small\n");
183 return -EINVAL;
184 }
185 if ((lsc_cfg->size / lsc_cfg->offset) < min_height) {
186 dev_dbg(isp->dev, "CCDC: LSC: Wrong size/offset combination\n");
187 return -EINVAL;
188 }
189 return 0;
190}
191
192/*
193 * ccdc_lsc_program_table - Program Lens Shading Compensation table address.
194 * @ccdc: Pointer to ISP CCDC device.
195 */
196static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc, u32 addr)
197{
198 isp_reg_writel(to_isp_device(ccdc), addr,
199 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE);
200}
201
202/*
203 * ccdc_lsc_setup_regs - Configures the lens shading compensation module
204 * @ccdc: Pointer to ISP CCDC device.
205 */
206static void ccdc_lsc_setup_regs(struct isp_ccdc_device *ccdc,
207 struct omap3isp_ccdc_lsc_config *cfg)
208{
209 struct isp_device *isp = to_isp_device(ccdc);
210 int reg;
211
212 isp_reg_writel(isp, cfg->offset, OMAP3_ISP_IOMEM_CCDC,
213 ISPCCDC_LSC_TABLE_OFFSET);
214
215 reg = 0;
216 reg |= cfg->gain_mode_n << ISPCCDC_LSC_GAIN_MODE_N_SHIFT;
217 reg |= cfg->gain_mode_m << ISPCCDC_LSC_GAIN_MODE_M_SHIFT;
218 reg |= cfg->gain_format << ISPCCDC_LSC_GAIN_FORMAT_SHIFT;
219 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG);
220
221 reg = 0;
222 reg &= ~ISPCCDC_LSC_INITIAL_X_MASK;
223 reg |= cfg->initial_x << ISPCCDC_LSC_INITIAL_X_SHIFT;
224 reg &= ~ISPCCDC_LSC_INITIAL_Y_MASK;
225 reg |= cfg->initial_y << ISPCCDC_LSC_INITIAL_Y_SHIFT;
226 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC,
227 ISPCCDC_LSC_INITIAL);
228}
229
230static int ccdc_lsc_wait_prefetch(struct isp_ccdc_device *ccdc)
231{
232 struct isp_device *isp = to_isp_device(ccdc);
233 unsigned int wait;
234
235 isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
236 OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
237
238 /* timeout 1 ms */
239 for (wait = 0; wait < 1000; wait++) {
240 if (isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS) &
241 IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ) {
242 isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
243 OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
244 return 0;
245 }
246
247 rmb();
248 udelay(1);
249 }
250
251 return -ETIMEDOUT;
252}
253
254/*
255 * __ccdc_lsc_enable - Enables/Disables the Lens Shading Compensation module.
256 * @ccdc: Pointer to ISP CCDC device.
257 * @enable: 0 Disables LSC, 1 Enables LSC.
258 */
259static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable)
260{
261 struct isp_device *isp = to_isp_device(ccdc);
262 const struct v4l2_mbus_framefmt *format =
263 __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
264 V4L2_SUBDEV_FORMAT_ACTIVE);
265
266 if ((format->code != V4L2_MBUS_FMT_SGRBG10_1X10) &&
267 (format->code != V4L2_MBUS_FMT_SRGGB10_1X10) &&
268 (format->code != V4L2_MBUS_FMT_SBGGR10_1X10) &&
269 (format->code != V4L2_MBUS_FMT_SGBRG10_1X10))
270 return -EINVAL;
271
272 if (enable)
273 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_LSC_READ);
274
275 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
276 ISPCCDC_LSC_ENABLE, enable ? ISPCCDC_LSC_ENABLE : 0);
277
278 if (enable) {
279 if (ccdc_lsc_wait_prefetch(ccdc) < 0) {
280 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC,
281 ISPCCDC_LSC_CONFIG, ISPCCDC_LSC_ENABLE);
282 ccdc->lsc.state = LSC_STATE_STOPPED;
283 dev_warn(to_device(ccdc), "LSC prefecth timeout\n");
284 return -ETIMEDOUT;
285 }
286 ccdc->lsc.state = LSC_STATE_RUNNING;
287 } else {
288 ccdc->lsc.state = LSC_STATE_STOPPING;
289 }
290
291 return 0;
292}
293
294static int ccdc_lsc_busy(struct isp_ccdc_device *ccdc)
295{
296 struct isp_device *isp = to_isp_device(ccdc);
297
298 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG) &
299 ISPCCDC_LSC_BUSY;
300}
301
302/* __ccdc_lsc_configure - Apply a new configuration to the LSC engine
303 * @ccdc: Pointer to ISP CCDC device
304 * @req: New configuration request
305 *
306 * context: in_interrupt()
307 */
308static int __ccdc_lsc_configure(struct isp_ccdc_device *ccdc,
309 struct ispccdc_lsc_config_req *req)
310{
311 if (!req->enable)
312 return -EINVAL;
313
314 if (ccdc_lsc_validate_config(ccdc, &req->config) < 0) {
315 dev_dbg(to_device(ccdc), "Discard LSC configuration\n");
316 return -EINVAL;
317 }
318
319 if (ccdc_lsc_busy(ccdc))
320 return -EBUSY;
321
322 ccdc_lsc_setup_regs(ccdc, &req->config);
323 ccdc_lsc_program_table(ccdc, req->table);
324 return 0;
325}
326
327/*
328 * ccdc_lsc_error_handler - Handle LSC prefetch error scenario.
329 * @ccdc: Pointer to ISP CCDC device.
330 *
331 * Disables LSC, and defers enablement to shadow registers update time.
332 */
333static void ccdc_lsc_error_handler(struct isp_ccdc_device *ccdc)
334{
335 struct isp_device *isp = to_isp_device(ccdc);
336 /*
337 * From OMAP3 TRM: When this event is pending, the module
338 * goes into transparent mode (output =input). Normal
339 * operation can be resumed at the start of the next frame
340 * after:
341 * 1) Clearing this event
342 * 2) Disabling the LSC module
343 * 3) Enabling it
344 */
345 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
346 ISPCCDC_LSC_ENABLE);
347 ccdc->lsc.state = LSC_STATE_STOPPED;
348}
349
350static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc,
351 struct ispccdc_lsc_config_req *req)
352{
353 struct isp_device *isp = to_isp_device(ccdc);
354
355 if (req == NULL)
356 return;
357
358 if (req->iovm)
359 dma_unmap_sg(isp->dev, req->iovm->sgt->sgl,
360 req->iovm->sgt->nents, DMA_TO_DEVICE);
361 if (req->table)
362 iommu_vfree(isp->iommu, req->table);
363 kfree(req);
364}
365
366static void ccdc_lsc_free_queue(struct isp_ccdc_device *ccdc,
367 struct list_head *queue)
368{
369 struct ispccdc_lsc_config_req *req, *n;
370 unsigned long flags;
371
372 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
373 list_for_each_entry_safe(req, n, queue, list) {
374 list_del(&req->list);
375 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
376 ccdc_lsc_free_request(ccdc, req);
377 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
378 }
379 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
380}
381
382static void ccdc_lsc_free_table_work(struct work_struct *work)
383{
384 struct isp_ccdc_device *ccdc;
385 struct ispccdc_lsc *lsc;
386
387 lsc = container_of(work, struct ispccdc_lsc, table_work);
388 ccdc = container_of(lsc, struct isp_ccdc_device, lsc);
389
390 ccdc_lsc_free_queue(ccdc, &lsc->free_queue);
391}
392
393/*
394 * ccdc_lsc_config - Configure the LSC module from a userspace request
395 *
396 * Store the request LSC configuration in the LSC engine request pointer. The
397 * configuration will be applied to the hardware when the CCDC will be enabled,
398 * or at the next LSC interrupt if the CCDC is already running.
399 */
400static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
401 struct omap3isp_ccdc_update_config *config)
402{
403 struct isp_device *isp = to_isp_device(ccdc);
404 struct ispccdc_lsc_config_req *req;
405 unsigned long flags;
406 void *table;
407 u16 update;
408 int ret;
409
410 update = config->update &
411 (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC);
412 if (!update)
413 return 0;
414
415 if (update != (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC)) {
416 dev_dbg(to_device(ccdc), "%s: Both LSC configuration and table "
417 "need to be supplied\n", __func__);
418 return -EINVAL;
419 }
420
421 req = kzalloc(sizeof(*req), GFP_KERNEL);
422 if (req == NULL)
423 return -ENOMEM;
424
425 if (config->flag & OMAP3ISP_CCDC_CONFIG_LSC) {
426 if (copy_from_user(&req->config, config->lsc_cfg,
427 sizeof(req->config))) {
428 ret = -EFAULT;
429 goto done;
430 }
431
432 req->enable = 1;
433
434 req->table = iommu_vmalloc(isp->iommu, 0, req->config.size,
435 IOMMU_FLAG);
436 if (IS_ERR_VALUE(req->table)) {
437 req->table = 0;
438 ret = -ENOMEM;
439 goto done;
440 }
441
442 req->iovm = find_iovm_area(isp->iommu, req->table);
443 if (req->iovm == NULL) {
444 ret = -ENOMEM;
445 goto done;
446 }
447
448 if (!dma_map_sg(isp->dev, req->iovm->sgt->sgl,
449 req->iovm->sgt->nents, DMA_TO_DEVICE)) {
450 ret = -ENOMEM;
451 req->iovm = NULL;
452 goto done;
453 }
454
455 dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl,
456 req->iovm->sgt->nents, DMA_TO_DEVICE);
457
458 table = da_to_va(isp->iommu, req->table);
459 if (copy_from_user(table, config->lsc, req->config.size)) {
460 ret = -EFAULT;
461 goto done;
462 }
463
464 dma_sync_sg_for_device(isp->dev, req->iovm->sgt->sgl,
465 req->iovm->sgt->nents, DMA_TO_DEVICE);
466 }
467
468 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
469 if (ccdc->lsc.request) {
470 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
471 schedule_work(&ccdc->lsc.table_work);
472 }
473 ccdc->lsc.request = req;
474 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
475
476 ret = 0;
477
478done:
479 if (ret < 0)
480 ccdc_lsc_free_request(ccdc, req);
481
482 return ret;
483}
484
485static inline int ccdc_lsc_is_configured(struct isp_ccdc_device *ccdc)
486{
487 unsigned long flags;
488
489 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
490 if (ccdc->lsc.active) {
491 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
492 return 1;
493 }
494 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
495 return 0;
496}
497
498static int ccdc_lsc_enable(struct isp_ccdc_device *ccdc)
499{
500 struct ispccdc_lsc *lsc = &ccdc->lsc;
501
502 if (lsc->state != LSC_STATE_STOPPED)
503 return -EINVAL;
504
505 if (lsc->active) {
506 list_add_tail(&lsc->active->list, &lsc->free_queue);
507 lsc->active = NULL;
508 }
509
510 if (__ccdc_lsc_configure(ccdc, lsc->request) < 0) {
511 omap3isp_sbl_disable(to_isp_device(ccdc),
512 OMAP3_ISP_SBL_CCDC_LSC_READ);
513 list_add_tail(&lsc->request->list, &lsc->free_queue);
514 lsc->request = NULL;
515 goto done;
516 }
517
518 lsc->active = lsc->request;
519 lsc->request = NULL;
520 __ccdc_lsc_enable(ccdc, 1);
521
522done:
523 if (!list_empty(&lsc->free_queue))
524 schedule_work(&lsc->table_work);
525
526 return 0;
527}
528
529/* -----------------------------------------------------------------------------
530 * Parameters configuration
531 */
532
533/*
534 * ccdc_configure_clamp - Configure optical-black or digital clamping
535 * @ccdc: Pointer to ISP CCDC device.
536 *
537 * The CCDC performs either optical-black or digital clamp. Configure and enable
538 * the selected clamp method.
539 */
540static void ccdc_configure_clamp(struct isp_ccdc_device *ccdc)
541{
542 struct isp_device *isp = to_isp_device(ccdc);
543 u32 clamp;
544
545 if (ccdc->obclamp) {
546 clamp = ccdc->clamp.obgain << ISPCCDC_CLAMP_OBGAIN_SHIFT;
547 clamp |= ccdc->clamp.oblen << ISPCCDC_CLAMP_OBSLEN_SHIFT;
548 clamp |= ccdc->clamp.oblines << ISPCCDC_CLAMP_OBSLN_SHIFT;
549 clamp |= ccdc->clamp.obstpixel << ISPCCDC_CLAMP_OBST_SHIFT;
550 isp_reg_writel(isp, clamp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP);
551 } else {
552 isp_reg_writel(isp, ccdc->clamp.dcsubval,
553 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_DCSUB);
554 }
555
556 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP,
557 ISPCCDC_CLAMP_CLAMPEN,
558 ccdc->obclamp ? ISPCCDC_CLAMP_CLAMPEN : 0);
559}
560
561/*
562 * ccdc_configure_fpc - Configure Faulty Pixel Correction
563 * @ccdc: Pointer to ISP CCDC device.
564 */
565static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
566{
567 struct isp_device *isp = to_isp_device(ccdc);
568
569 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC, ISPCCDC_FPC_FPCEN);
570
571 if (!ccdc->fpc_en)
572 return;
573
574 isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC,
575 ISPCCDC_FPC_ADDR);
576 /* The FPNUM field must be set before enabling FPC. */
577 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT),
578 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
579 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT) |
580 ISPCCDC_FPC_FPCEN, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
581}
582
583/*
584 * ccdc_configure_black_comp - Configure Black Level Compensation.
585 * @ccdc: Pointer to ISP CCDC device.
586 */
587static void ccdc_configure_black_comp(struct isp_ccdc_device *ccdc)
588{
589 struct isp_device *isp = to_isp_device(ccdc);
590 u32 blcomp;
591
592 blcomp = ccdc->blcomp.b_mg << ISPCCDC_BLKCMP_B_MG_SHIFT;
593 blcomp |= ccdc->blcomp.gb_g << ISPCCDC_BLKCMP_GB_G_SHIFT;
594 blcomp |= ccdc->blcomp.gr_cy << ISPCCDC_BLKCMP_GR_CY_SHIFT;
595 blcomp |= ccdc->blcomp.r_ye << ISPCCDC_BLKCMP_R_YE_SHIFT;
596
597 isp_reg_writel(isp, blcomp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_BLKCMP);
598}
599
600/*
601 * ccdc_configure_lpf - Configure Low-Pass Filter (LPF).
602 * @ccdc: Pointer to ISP CCDC device.
603 */
604static void ccdc_configure_lpf(struct isp_ccdc_device *ccdc)
605{
606 struct isp_device *isp = to_isp_device(ccdc);
607
608 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE,
609 ISPCCDC_SYN_MODE_LPF,
610 ccdc->lpf ? ISPCCDC_SYN_MODE_LPF : 0);
611}
612
613/*
614 * ccdc_configure_alaw - Configure A-law compression.
615 * @ccdc: Pointer to ISP CCDC device.
616 */
617static void ccdc_configure_alaw(struct isp_ccdc_device *ccdc)
618{
619 struct isp_device *isp = to_isp_device(ccdc);
620 u32 alaw = 0;
621
622 switch (ccdc->syncif.datsz) {
623 case 8:
624 return;
625
626 case 10:
627 alaw = ISPCCDC_ALAW_GWDI_9_0;
628 break;
629 case 11:
630 alaw = ISPCCDC_ALAW_GWDI_10_1;
631 break;
632 case 12:
633 alaw = ISPCCDC_ALAW_GWDI_11_2;
634 break;
635 case 13:
636 alaw = ISPCCDC_ALAW_GWDI_12_3;
637 break;
638 }
639
640 if (ccdc->alaw)
641 alaw |= ISPCCDC_ALAW_CCDTBL;
642
643 isp_reg_writel(isp, alaw, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW);
644}
645
646/*
647 * ccdc_config_imgattr - Configure sensor image specific attributes.
648 * @ccdc: Pointer to ISP CCDC device.
649 * @colptn: Color pattern of the sensor.
650 */
651static void ccdc_config_imgattr(struct isp_ccdc_device *ccdc, u32 colptn)
652{
653 struct isp_device *isp = to_isp_device(ccdc);
654
655 isp_reg_writel(isp, colptn, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN);
656}
657
658/*
659 * ccdc_config - Set CCDC configuration from userspace
660 * @ccdc: Pointer to ISP CCDC device.
661 * @userspace_add: Structure containing CCDC configuration sent from userspace.
662 *
663 * Returns 0 if successful, -EINVAL if the pointer to the configuration
664 * structure is null, or the copy_from_user function fails to copy user space
665 * memory to kernel space memory.
666 */
667static int ccdc_config(struct isp_ccdc_device *ccdc,
668 struct omap3isp_ccdc_update_config *ccdc_struct)
669{
670 struct isp_device *isp = to_isp_device(ccdc);
671 unsigned long flags;
672
673 spin_lock_irqsave(&ccdc->lock, flags);
674 ccdc->shadow_update = 1;
675 spin_unlock_irqrestore(&ccdc->lock, flags);
676
677 if (OMAP3ISP_CCDC_ALAW & ccdc_struct->update) {
678 ccdc->alaw = !!(OMAP3ISP_CCDC_ALAW & ccdc_struct->flag);
679 ccdc->update |= OMAP3ISP_CCDC_ALAW;
680 }
681
682 if (OMAP3ISP_CCDC_LPF & ccdc_struct->update) {
683 ccdc->lpf = !!(OMAP3ISP_CCDC_LPF & ccdc_struct->flag);
684 ccdc->update |= OMAP3ISP_CCDC_LPF;
685 }
686
687 if (OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->update) {
688 if (copy_from_user(&ccdc->clamp, ccdc_struct->bclamp,
689 sizeof(ccdc->clamp))) {
690 ccdc->shadow_update = 0;
691 return -EFAULT;
692 }
693
694 ccdc->obclamp = !!(OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->flag);
695 ccdc->update |= OMAP3ISP_CCDC_BLCLAMP;
696 }
697
698 if (OMAP3ISP_CCDC_BCOMP & ccdc_struct->update) {
699 if (copy_from_user(&ccdc->blcomp, ccdc_struct->blcomp,
700 sizeof(ccdc->blcomp))) {
701 ccdc->shadow_update = 0;
702 return -EFAULT;
703 }
704
705 ccdc->update |= OMAP3ISP_CCDC_BCOMP;
706 }
707
708 ccdc->shadow_update = 0;
709
710 if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) {
711 u32 table_old = 0;
712 u32 table_new;
713 u32 size;
714
715 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
716 return -EBUSY;
717
718 ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag);
719
720 if (ccdc->fpc_en) {
721 if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc,
722 sizeof(ccdc->fpc)))
723 return -EFAULT;
724
725 /*
726 * table_new must be 64-bytes aligned, but it's
727 * already done by iommu_vmalloc().
728 */
729 size = ccdc->fpc.fpnum * 4;
730 table_new = iommu_vmalloc(isp->iommu, 0, size,
731 IOMMU_FLAG);
732 if (IS_ERR_VALUE(table_new))
733 return -ENOMEM;
734
735 if (copy_from_user(da_to_va(isp->iommu, table_new),
736 (__force void __user *)
737 ccdc->fpc.fpcaddr, size)) {
738 iommu_vfree(isp->iommu, table_new);
739 return -EFAULT;
740 }
741
742 table_old = ccdc->fpc.fpcaddr;
743 ccdc->fpc.fpcaddr = table_new;
744 }
745
746 ccdc_configure_fpc(ccdc);
747 if (table_old != 0)
748 iommu_vfree(isp->iommu, table_old);
749 }
750
751 return ccdc_lsc_config(ccdc, ccdc_struct);
752}
753
754static void ccdc_apply_controls(struct isp_ccdc_device *ccdc)
755{
756 if (ccdc->update & OMAP3ISP_CCDC_ALAW) {
757 ccdc_configure_alaw(ccdc);
758 ccdc->update &= ~OMAP3ISP_CCDC_ALAW;
759 }
760
761 if (ccdc->update & OMAP3ISP_CCDC_LPF) {
762 ccdc_configure_lpf(ccdc);
763 ccdc->update &= ~OMAP3ISP_CCDC_LPF;
764 }
765
766 if (ccdc->update & OMAP3ISP_CCDC_BLCLAMP) {
767 ccdc_configure_clamp(ccdc);
768 ccdc->update &= ~OMAP3ISP_CCDC_BLCLAMP;
769 }
770
771 if (ccdc->update & OMAP3ISP_CCDC_BCOMP) {
772 ccdc_configure_black_comp(ccdc);
773 ccdc->update &= ~OMAP3ISP_CCDC_BCOMP;
774 }
775}
776
777/*
778 * omap3isp_ccdc_restore_context - Restore values of the CCDC module registers
779 * @dev: Pointer to ISP device
780 */
781void omap3isp_ccdc_restore_context(struct isp_device *isp)
782{
783 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
784
785 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC);
786
787 ccdc->update = OMAP3ISP_CCDC_ALAW | OMAP3ISP_CCDC_LPF
788 | OMAP3ISP_CCDC_BLCLAMP | OMAP3ISP_CCDC_BCOMP;
789 ccdc_apply_controls(ccdc);
790 ccdc_configure_fpc(ccdc);
791}
792
793/* -----------------------------------------------------------------------------
794 * Format- and pipeline-related configuration helpers
795 */
796
797/*
798 * ccdc_config_vp - Configure the Video Port.
799 * @ccdc: Pointer to ISP CCDC device.
800 */
801static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
802{
803 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
804 struct isp_device *isp = to_isp_device(ccdc);
805 unsigned long l3_ick = pipe->l3_ick;
806 unsigned int max_div = isp->revision == ISP_REVISION_15_0 ? 64 : 8;
807 unsigned int div = 0;
808 u32 fmtcfg_vp;
809
810 fmtcfg_vp = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)
811 & ~(ISPCCDC_FMTCFG_VPIN_MASK | ISPCCDC_FMTCFG_VPIF_FRQ_MASK);
812
813 switch (ccdc->syncif.datsz) {
814 case 8:
815 case 10:
816 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_9_0;
817 break;
818 case 11:
819 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_10_1;
820 break;
821 case 12:
822 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_11_2;
823 break;
824 case 13:
825 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_12_3;
826 break;
827 };
828
829 if (pipe->input)
830 div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
831 else if (ccdc->vpcfg.pixelclk)
832 div = l3_ick / ccdc->vpcfg.pixelclk;
833
834 div = clamp(div, 2U, max_div);
835 fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
836
837 isp_reg_writel(isp, fmtcfg_vp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG);
838}
839
840/*
841 * ccdc_enable_vp - Enable Video Port.
842 * @ccdc: Pointer to ISP CCDC device.
843 * @enable: 0 Disables VP, 1 Enables VP
844 *
845 * This is needed for outputting image to Preview, H3A and HIST ISP submodules.
846 */
847static void ccdc_enable_vp(struct isp_ccdc_device *ccdc, u8 enable)
848{
849 struct isp_device *isp = to_isp_device(ccdc);
850
851 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG,
852 ISPCCDC_FMTCFG_VPEN, enable ? ISPCCDC_FMTCFG_VPEN : 0);
853}
854
855/*
856 * ccdc_config_outlineoffset - Configure memory saving output line offset
857 * @ccdc: Pointer to ISP CCDC device.
858 * @offset: Address offset to start a new line. Must be twice the
859 * Output width and aligned on 32 byte boundary
860 * @oddeven: Specifies the odd/even line pattern to be chosen to store the
861 * output.
862 * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines.
863 *
864 * - Configures the output line offset when stored in memory
865 * - Sets the odd/even line pattern to store the output
866 * (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4))
867 * - Configures the number of even and odd line fields in case of rearranging
868 * the lines.
869 */
870static void ccdc_config_outlineoffset(struct isp_ccdc_device *ccdc,
871 u32 offset, u8 oddeven, u8 numlines)
872{
873 struct isp_device *isp = to_isp_device(ccdc);
874
875 isp_reg_writel(isp, offset & 0xffff,
876 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF);
877
878 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
879 ISPCCDC_SDOFST_FINV);
880
881 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
882 ISPCCDC_SDOFST_FOFST_4L);
883
884 switch (oddeven) {
885 case EVENEVEN:
886 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
887 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT);
888 break;
889 case ODDEVEN:
890 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
891 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT);
892 break;
893 case EVENODD:
894 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
895 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT);
896 break;
897 case ODDODD:
898 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
899 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT);
900 break;
901 default:
902 break;
903 }
904}
905
906/*
907 * ccdc_set_outaddr - Set memory address to save output image
908 * @ccdc: Pointer to ISP CCDC device.
909 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
910 *
911 * Sets the memory address where the output will be saved.
912 */
913static void ccdc_set_outaddr(struct isp_ccdc_device *ccdc, u32 addr)
914{
915 struct isp_device *isp = to_isp_device(ccdc);
916
917 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR);
918}
919
920/*
921 * omap3isp_ccdc_max_rate - Calculate maximum input data rate based on the input
922 * @ccdc: Pointer to ISP CCDC device.
923 * @max_rate: Maximum calculated data rate.
924 *
925 * Returns in *max_rate less value between calculated and passed
926 */
927void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
928 unsigned int *max_rate)
929{
930 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
931 unsigned int rate;
932
933 if (pipe == NULL)
934 return;
935
936 /*
937 * TRM says that for parallel sensors the maximum data rate
938 * should be 90% form L3/2 clock, otherwise just L3/2.
939 */
940 if (ccdc->input == CCDC_INPUT_PARALLEL)
941 rate = pipe->l3_ick / 2 * 9 / 10;
942 else
943 rate = pipe->l3_ick / 2;
944
945 *max_rate = min(*max_rate, rate);
946}
947
948/*
949 * ccdc_config_sync_if - Set CCDC sync interface configuration
950 * @ccdc: Pointer to ISP CCDC device.
951 * @syncif: Structure containing the sync parameters like field state, CCDC in
952 * master/slave mode, raw/yuv data, polarity of data, field, hs, vs
953 * signals.
954 */
955static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
956 struct ispccdc_syncif *syncif)
957{
958 struct isp_device *isp = to_isp_device(ccdc);
959 u32 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC,
960 ISPCCDC_SYN_MODE);
961
962 syn_mode |= ISPCCDC_SYN_MODE_VDHDEN;
963
964 if (syncif->fldstat)
965 syn_mode |= ISPCCDC_SYN_MODE_FLDSTAT;
966 else
967 syn_mode &= ~ISPCCDC_SYN_MODE_FLDSTAT;
968
969 syn_mode &= ~ISPCCDC_SYN_MODE_DATSIZ_MASK;
970 switch (syncif->datsz) {
971 case 8:
972 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8;
973 break;
974 case 10:
975 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_10;
976 break;
977 case 11:
978 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_11;
979 break;
980 case 12:
981 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_12;
982 break;
983 };
984
985 if (syncif->fldmode)
986 syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
987 else
988 syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE;
989
990 if (syncif->datapol)
991 syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
992 else
993 syn_mode &= ~ISPCCDC_SYN_MODE_DATAPOL;
994
995 if (syncif->fldpol)
996 syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
997 else
998 syn_mode &= ~ISPCCDC_SYN_MODE_FLDPOL;
999
1000 if (syncif->hdpol)
1001 syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
1002 else
1003 syn_mode &= ~ISPCCDC_SYN_MODE_HDPOL;
1004
1005 if (syncif->vdpol)
1006 syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
1007 else
1008 syn_mode &= ~ISPCCDC_SYN_MODE_VDPOL;
1009
1010 if (syncif->ccdc_mastermode) {
1011 syn_mode |= ISPCCDC_SYN_MODE_FLDOUT | ISPCCDC_SYN_MODE_VDHDOUT;
1012 isp_reg_writel(isp,
1013 syncif->hs_width << ISPCCDC_HD_VD_WID_HDW_SHIFT
1014 | syncif->vs_width << ISPCCDC_HD_VD_WID_VDW_SHIFT,
1015 OMAP3_ISP_IOMEM_CCDC,
1016 ISPCCDC_HD_VD_WID);
1017
1018 isp_reg_writel(isp,
1019 syncif->ppln << ISPCCDC_PIX_LINES_PPLN_SHIFT
1020 | syncif->hlprf << ISPCCDC_PIX_LINES_HLPRF_SHIFT,
1021 OMAP3_ISP_IOMEM_CCDC,
1022 ISPCCDC_PIX_LINES);
1023 } else
1024 syn_mode &= ~(ISPCCDC_SYN_MODE_FLDOUT |
1025 ISPCCDC_SYN_MODE_VDHDOUT);
1026
1027 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1028
1029 if (!syncif->bt_r656_en)
1030 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF,
1031 ISPCCDC_REC656IF_R656ON);
1032}
1033
1034/* CCDC formats descriptions */
1035static const u32 ccdc_sgrbg_pattern =
1036 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1037 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1038 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1039 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1040 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1041 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1042 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1043 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1044 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1045 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1046 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1047 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1048 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1049 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1050 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1051 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1052
1053static const u32 ccdc_srggb_pattern =
1054 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1055 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1056 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1057 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1058 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1059 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1060 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1061 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1062 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1063 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1064 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1065 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1066 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1067 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1068 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1069 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1070
1071static const u32 ccdc_sbggr_pattern =
1072 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1073 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1074 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1075 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1076 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1077 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1078 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1079 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1080 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1081 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1082 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1083 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1084 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1085 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1086 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1087 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1088
1089static const u32 ccdc_sgbrg_pattern =
1090 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1091 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1092 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1093 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1094 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1095 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1096 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1097 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1098 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1099 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1100 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1101 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1102 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1103 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1104 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1105 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1106
1107static void ccdc_configure(struct isp_ccdc_device *ccdc)
1108{
1109 struct isp_device *isp = to_isp_device(ccdc);
1110 struct isp_parallel_platform_data *pdata = NULL;
1111 struct v4l2_subdev *sensor;
1112 struct v4l2_mbus_framefmt *format;
1113 struct media_pad *pad;
1114 unsigned long flags;
1115 u32 syn_mode;
1116 u32 ccdc_pattern;
1117
1118 if (ccdc->input == CCDC_INPUT_PARALLEL) {
1119 pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
1120 sensor = media_entity_to_v4l2_subdev(pad->entity);
1121 pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
1122 ->bus.parallel;
1123 }
1124
1125 omap3isp_configure_bridge(isp, ccdc->input, pdata);
1126
1127 ccdc->syncif.datsz = pdata ? pdata->width : 10;
1128 ccdc_config_sync_if(ccdc, &ccdc->syncif);
1129
1130 /* CCDC_PAD_SINK */
1131 format = &ccdc->formats[CCDC_PAD_SINK];
1132
1133 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1134
1135 /* Use the raw, unprocessed data when writing to memory. The H3A and
1136 * histogram modules are still fed with lens shading corrected data.
1137 */
1138 syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
1139
1140 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1141 syn_mode |= ISPCCDC_SYN_MODE_WEN;
1142 else
1143 syn_mode &= ~ISPCCDC_SYN_MODE_WEN;
1144
1145 if (ccdc->output & CCDC_OUTPUT_RESIZER)
1146 syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ;
1147 else
1148 syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
1149
1150 /* Use PACK8 mode for 1byte per pixel formats. */
1151 if (omap3isp_video_format_info(format->code)->bpp <= 8)
1152 syn_mode |= ISPCCDC_SYN_MODE_PACK8;
1153 else
1154 syn_mode &= ~ISPCCDC_SYN_MODE_PACK8;
1155
1156 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1157
1158 /* Mosaic filter */
1159 switch (format->code) {
1160 case V4L2_MBUS_FMT_SRGGB10_1X10:
1161 case V4L2_MBUS_FMT_SRGGB12_1X12:
1162 ccdc_pattern = ccdc_srggb_pattern;
1163 break;
1164 case V4L2_MBUS_FMT_SBGGR10_1X10:
1165 case V4L2_MBUS_FMT_SBGGR12_1X12:
1166 ccdc_pattern = ccdc_sbggr_pattern;
1167 break;
1168 case V4L2_MBUS_FMT_SGBRG10_1X10:
1169 case V4L2_MBUS_FMT_SGBRG12_1X12:
1170 ccdc_pattern = ccdc_sgbrg_pattern;
1171 break;
1172 default:
1173 /* Use GRBG */
1174 ccdc_pattern = ccdc_sgrbg_pattern;
1175 break;
1176 }
1177 ccdc_config_imgattr(ccdc, ccdc_pattern);
1178
1179 /* Generate VD0 on the last line of the image and VD1 on the
1180 * 2/3 height line.
1181 */
1182 isp_reg_writel(isp, ((format->height - 2) << ISPCCDC_VDINT_0_SHIFT) |
1183 ((format->height * 2 / 3) << ISPCCDC_VDINT_1_SHIFT),
1184 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
1185
1186 /* CCDC_PAD_SOURCE_OF */
1187 format = &ccdc->formats[CCDC_PAD_SOURCE_OF];
1188
1189 isp_reg_writel(isp, (0 << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
1190 ((format->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT),
1191 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO);
1192 isp_reg_writel(isp, 0 << ISPCCDC_VERT_START_SLV0_SHIFT,
1193 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START);
1194 isp_reg_writel(isp, (format->height - 1)
1195 << ISPCCDC_VERT_LINES_NLV_SHIFT,
1196 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES);
1197
1198 ccdc_config_outlineoffset(ccdc, ccdc->video_out.bpl_value, 0, 0);
1199
1200 /* CCDC_PAD_SOURCE_VP */
1201 format = &ccdc->formats[CCDC_PAD_SOURCE_VP];
1202
1203 isp_reg_writel(isp, (0 << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) |
1204 (format->width << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT),
1205 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ);
1206 isp_reg_writel(isp, (0 << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) |
1207 ((format->height + 1) << ISPCCDC_FMT_VERT_FMTLNV_SHIFT),
1208 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT);
1209
1210 isp_reg_writel(isp, (format->width << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) |
1211 (format->height << ISPCCDC_VP_OUT_VERT_NUM_SHIFT),
1212 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT);
1213
1214 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1215 if (ccdc->lsc.request == NULL)
1216 goto unlock;
1217
1218 WARN_ON(ccdc->lsc.active);
1219
1220 /* Get last good LSC configuration. If it is not supported for
1221 * the current active resolution discard it.
1222 */
1223 if (ccdc->lsc.active == NULL &&
1224 __ccdc_lsc_configure(ccdc, ccdc->lsc.request) == 0) {
1225 ccdc->lsc.active = ccdc->lsc.request;
1226 } else {
1227 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
1228 schedule_work(&ccdc->lsc.table_work);
1229 }
1230
1231 ccdc->lsc.request = NULL;
1232
1233unlock:
1234 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1235
1236 ccdc_apply_controls(ccdc);
1237}
1238
1239static void __ccdc_enable(struct isp_ccdc_device *ccdc, int enable)
1240{
1241 struct isp_device *isp = to_isp_device(ccdc);
1242
1243 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR,
1244 ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0);
1245}
1246
1247static int ccdc_disable(struct isp_ccdc_device *ccdc)
1248{
1249 unsigned long flags;
1250 int ret = 0;
1251
1252 spin_lock_irqsave(&ccdc->lock, flags);
1253 if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1254 ccdc->stopping = CCDC_STOP_REQUEST;
1255 spin_unlock_irqrestore(&ccdc->lock, flags);
1256
1257 ret = wait_event_timeout(ccdc->wait,
1258 ccdc->stopping == CCDC_STOP_FINISHED,
1259 msecs_to_jiffies(2000));
1260 if (ret == 0) {
1261 ret = -ETIMEDOUT;
1262 dev_warn(to_device(ccdc), "CCDC stop timeout!\n");
1263 }
1264
1265 omap3isp_sbl_disable(to_isp_device(ccdc), OMAP3_ISP_SBL_CCDC_LSC_READ);
1266
1267 mutex_lock(&ccdc->ioctl_lock);
1268 ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
1269 ccdc->lsc.request = ccdc->lsc.active;
1270 ccdc->lsc.active = NULL;
1271 cancel_work_sync(&ccdc->lsc.table_work);
1272 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
1273 mutex_unlock(&ccdc->ioctl_lock);
1274
1275 ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
1276
1277 return ret > 0 ? 0 : ret;
1278}
1279
1280static void ccdc_enable(struct isp_ccdc_device *ccdc)
1281{
1282 if (ccdc_lsc_is_configured(ccdc))
1283 __ccdc_lsc_enable(ccdc, 1);
1284 __ccdc_enable(ccdc, 1);
1285}
1286
1287/* -----------------------------------------------------------------------------
1288 * Interrupt handling
1289 */
1290
1291/*
1292 * ccdc_sbl_busy - Poll idle state of CCDC and related SBL memory write bits
1293 * @ccdc: Pointer to ISP CCDC device.
1294 *
1295 * Returns zero if the CCDC is idle and the image has been written to
1296 * memory, too.
1297 */
1298static int ccdc_sbl_busy(struct isp_ccdc_device *ccdc)
1299{
1300 struct isp_device *isp = to_isp_device(ccdc);
1301
1302 return omap3isp_ccdc_busy(ccdc)
1303 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_0) &
1304 ISPSBL_CCDC_WR_0_DATA_READY)
1305 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_1) &
1306 ISPSBL_CCDC_WR_0_DATA_READY)
1307 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_2) &
1308 ISPSBL_CCDC_WR_0_DATA_READY)
1309 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_3) &
1310 ISPSBL_CCDC_WR_0_DATA_READY);
1311}
1312
1313/*
1314 * ccdc_sbl_wait_idle - Wait until the CCDC and related SBL are idle
1315 * @ccdc: Pointer to ISP CCDC device.
1316 * @max_wait: Max retry count in us for wait for idle/busy transition.
1317 */
1318static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
1319 unsigned int max_wait)
1320{
1321 unsigned int wait = 0;
1322
1323 if (max_wait == 0)
1324 max_wait = 10000; /* 10 ms */
1325
1326 for (wait = 0; wait <= max_wait; wait++) {
1327 if (!ccdc_sbl_busy(ccdc))
1328 return 0;
1329
1330 rmb();
1331 udelay(1);
1332 }
1333
1334 return -EBUSY;
1335}
1336
1337/* __ccdc_handle_stopping - Handle CCDC and/or LSC stopping sequence
1338 * @ccdc: Pointer to ISP CCDC device.
1339 * @event: Pointing which event trigger handler
1340 *
1341 * Return 1 when the event and stopping request combination is satisfyied,
1342 * zero otherwise.
1343 */
1344static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
1345{
1346 int rval = 0;
1347
1348 switch ((ccdc->stopping & 3) | event) {
1349 case CCDC_STOP_REQUEST | CCDC_EVENT_VD1:
1350 if (ccdc->lsc.state != LSC_STATE_STOPPED)
1351 __ccdc_lsc_enable(ccdc, 0);
1352 __ccdc_enable(ccdc, 0);
1353 ccdc->stopping = CCDC_STOP_EXECUTED;
1354 return 1;
1355
1356 case CCDC_STOP_EXECUTED | CCDC_EVENT_VD0:
1357 ccdc->stopping |= CCDC_STOP_CCDC_FINISHED;
1358 if (ccdc->lsc.state == LSC_STATE_STOPPED)
1359 ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1360 rval = 1;
1361 break;
1362
1363 case CCDC_STOP_EXECUTED | CCDC_EVENT_LSC_DONE:
1364 ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1365 rval = 1;
1366 break;
1367
1368 case CCDC_STOP_EXECUTED | CCDC_EVENT_VD1:
1369 return 1;
1370 }
1371
1372 if (ccdc->stopping == CCDC_STOP_FINISHED) {
1373 wake_up(&ccdc->wait);
1374 rval = 1;
1375 }
1376
1377 return rval;
1378}
1379
1380static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
1381{
1382 struct video_device *vdev = &ccdc->subdev.devnode;
1383 struct v4l2_event event;
1384
1385 memset(&event, 0, sizeof(event));
1386 event.type = V4L2_EVENT_OMAP3ISP_HS_VS;
1387
1388 v4l2_event_queue(vdev, &event);
1389}
1390
1391/*
1392 * ccdc_lsc_isr - Handle LSC events
1393 * @ccdc: Pointer to ISP CCDC device.
1394 * @events: LSC events
1395 */
1396static void ccdc_lsc_isr(struct isp_ccdc_device *ccdc, u32 events)
1397{
1398 unsigned long flags;
1399
1400 if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) {
1401 ccdc_lsc_error_handler(ccdc);
1402 ccdc->error = 1;
1403 dev_dbg(to_device(ccdc), "lsc prefetch error\n");
1404 }
1405
1406 if (!(events & IRQ0STATUS_CCDC_LSC_DONE_IRQ))
1407 return;
1408
1409 /* LSC_DONE interrupt occur, there are two cases
1410 * 1. stopping for reconfiguration
1411 * 2. stopping because of STREAM OFF command
1412 */
1413 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1414
1415 if (ccdc->lsc.state == LSC_STATE_STOPPING)
1416 ccdc->lsc.state = LSC_STATE_STOPPED;
1417
1418 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_LSC_DONE))
1419 goto done;
1420
1421 if (ccdc->lsc.state != LSC_STATE_RECONFIG)
1422 goto done;
1423
1424 /* LSC is in STOPPING state, change to the new state */
1425 ccdc->lsc.state = LSC_STATE_STOPPED;
1426
1427 /* This is an exception. Start of frame and LSC_DONE interrupt
1428 * have been received on the same time. Skip this event and wait
1429 * for better times.
1430 */
1431 if (events & IRQ0STATUS_HS_VS_IRQ)
1432 goto done;
1433
1434 /* The LSC engine is stopped at this point. Enable it if there's a
1435 * pending request.
1436 */
1437 if (ccdc->lsc.request == NULL)
1438 goto done;
1439
1440 ccdc_lsc_enable(ccdc);
1441
1442done:
1443 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1444}
1445
1446static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
1447{
1448 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
1449 struct isp_device *isp = to_isp_device(ccdc);
1450 struct isp_buffer *buffer;
1451 int restart = 0;
1452
1453 /* The CCDC generates VD0 interrupts even when disabled (the datasheet
1454 * doesn't explicitly state if that's supposed to happen or not, so it
1455 * can be considered as a hardware bug or as a feature, but we have to
1456 * deal with it anyway). Disabling the CCDC when no buffer is available
1457 * would thus not be enough, we need to handle the situation explicitly.
1458 */
1459 if (list_empty(&ccdc->video_out.dmaqueue))
1460 goto done;
1461
1462 /* We're in continuous mode, and memory writes were disabled due to a
1463 * buffer underrun. Reenable them now that we have a buffer. The buffer
1464 * address has been set in ccdc_video_queue.
1465 */
1466 if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS && ccdc->underrun) {
1467 restart = 1;
1468 ccdc->underrun = 0;
1469 goto done;
1470 }
1471
1472 if (ccdc_sbl_wait_idle(ccdc, 1000)) {
1473 dev_info(isp->dev, "CCDC won't become idle!\n");
1474 goto done;
1475 }
1476
1477 buffer = omap3isp_video_buffer_next(&ccdc->video_out, ccdc->error);
1478 if (buffer != NULL) {
1479 ccdc_set_outaddr(ccdc, buffer->isp_addr);
1480 restart = 1;
1481 }
1482
1483 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1484
1485 if (ccdc->state == ISP_PIPELINE_STREAM_SINGLESHOT &&
1486 isp_pipeline_ready(pipe))
1487 omap3isp_pipeline_set_stream(pipe,
1488 ISP_PIPELINE_STREAM_SINGLESHOT);
1489
1490done:
1491 ccdc->error = 0;
1492 return restart;
1493}
1494
1495/*
1496 * ccdc_vd0_isr - Handle VD0 event
1497 * @ccdc: Pointer to ISP CCDC device.
1498 *
1499 * Executes LSC deferred enablement before next frame starts.
1500 */
1501static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
1502{
1503 unsigned long flags;
1504 int restart = 0;
1505
1506 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1507 restart = ccdc_isr_buffer(ccdc);
1508
1509 spin_lock_irqsave(&ccdc->lock, flags);
1510 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) {
1511 spin_unlock_irqrestore(&ccdc->lock, flags);
1512 return;
1513 }
1514
1515 if (!ccdc->shadow_update)
1516 ccdc_apply_controls(ccdc);
1517 spin_unlock_irqrestore(&ccdc->lock, flags);
1518
1519 if (restart)
1520 ccdc_enable(ccdc);
1521}
1522
1523/*
1524 * ccdc_vd1_isr - Handle VD1 event
1525 * @ccdc: Pointer to ISP CCDC device.
1526 */
1527static void ccdc_vd1_isr(struct isp_ccdc_device *ccdc)
1528{
1529 unsigned long flags;
1530
1531 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1532
1533 /*
1534 * Depending on the CCDC pipeline state, CCDC stopping should be
1535 * handled differently. In SINGLESHOT we emulate an internal CCDC
1536 * stopping because the CCDC hw works only in continuous mode.
1537 * When CONTINUOUS pipeline state is used and the CCDC writes it's
1538 * data to memory the CCDC and LSC are stopped immediately but
1539 * without change the CCDC stopping state machine. The CCDC
1540 * stopping state machine should be used only when user request
1541 * for stopping is received (SINGLESHOT is an exeption).
1542 */
1543 switch (ccdc->state) {
1544 case ISP_PIPELINE_STREAM_SINGLESHOT:
1545 ccdc->stopping = CCDC_STOP_REQUEST;
1546 break;
1547
1548 case ISP_PIPELINE_STREAM_CONTINUOUS:
1549 if (ccdc->output & CCDC_OUTPUT_MEMORY) {
1550 if (ccdc->lsc.state != LSC_STATE_STOPPED)
1551 __ccdc_lsc_enable(ccdc, 0);
1552 __ccdc_enable(ccdc, 0);
1553 }
1554 break;
1555
1556 case ISP_PIPELINE_STREAM_STOPPED:
1557 break;
1558 }
1559
1560 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD1))
1561 goto done;
1562
1563 if (ccdc->lsc.request == NULL)
1564 goto done;
1565
1566 /*
1567 * LSC need to be reconfigured. Stop it here and on next LSC_DONE IRQ
1568 * do the appropriate changes in registers
1569 */
1570 if (ccdc->lsc.state == LSC_STATE_RUNNING) {
1571 __ccdc_lsc_enable(ccdc, 0);
1572 ccdc->lsc.state = LSC_STATE_RECONFIG;
1573 goto done;
1574 }
1575
1576 /* LSC has been in STOPPED state, enable it */
1577 if (ccdc->lsc.state == LSC_STATE_STOPPED)
1578 ccdc_lsc_enable(ccdc);
1579
1580done:
1581 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1582}
1583
1584/*
1585 * omap3isp_ccdc_isr - Configure CCDC during interframe time.
1586 * @ccdc: Pointer to ISP CCDC device.
1587 * @events: CCDC events
1588 */
1589int omap3isp_ccdc_isr(struct isp_ccdc_device *ccdc, u32 events)
1590{
1591 if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED)
1592 return 0;
1593
1594 if (events & IRQ0STATUS_CCDC_VD1_IRQ)
1595 ccdc_vd1_isr(ccdc);
1596
1597 ccdc_lsc_isr(ccdc, events);
1598
1599 if (events & IRQ0STATUS_CCDC_VD0_IRQ)
1600 ccdc_vd0_isr(ccdc);
1601
1602 if (events & IRQ0STATUS_HS_VS_IRQ)
1603 ccdc_hs_vs_isr(ccdc);
1604
1605 return 0;
1606}
1607
1608/* -----------------------------------------------------------------------------
1609 * ISP video operations
1610 */
1611
1612static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
1613{
1614 struct isp_ccdc_device *ccdc = &video->isp->isp_ccdc;
1615
1616 if (!(ccdc->output & CCDC_OUTPUT_MEMORY))
1617 return -ENODEV;
1618
1619 ccdc_set_outaddr(ccdc, buffer->isp_addr);
1620
1621 /* We now have a buffer queued on the output, restart the pipeline in
1622 * on the next CCDC interrupt if running in continuous mode (or when
1623 * starting the stream).
1624 */
1625 ccdc->underrun = 1;
1626
1627 return 0;
1628}
1629
1630static const struct isp_video_operations ccdc_video_ops = {
1631 .queue = ccdc_video_queue,
1632};
1633
1634/* -----------------------------------------------------------------------------
1635 * V4L2 subdev operations
1636 */
1637
1638/*
1639 * ccdc_ioctl - CCDC module private ioctl's
1640 * @sd: ISP CCDC V4L2 subdevice
1641 * @cmd: ioctl command
1642 * @arg: ioctl argument
1643 *
1644 * Return 0 on success or a negative error code otherwise.
1645 */
1646static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1647{
1648 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1649 int ret;
1650
1651 switch (cmd) {
1652 case VIDIOC_OMAP3ISP_CCDC_CFG:
1653 mutex_lock(&ccdc->ioctl_lock);
1654 ret = ccdc_config(ccdc, arg);
1655 mutex_unlock(&ccdc->ioctl_lock);
1656 break;
1657
1658 default:
1659 return -ENOIOCTLCMD;
1660 }
1661
1662 return ret;
1663}
1664
1665static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1666 struct v4l2_event_subscription *sub)
1667{
1668 if (sub->type != V4L2_EVENT_OMAP3ISP_HS_VS)
1669 return -EINVAL;
1670
1671 return v4l2_event_subscribe(fh, sub);
1672}
1673
1674static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1675 struct v4l2_event_subscription *sub)
1676{
1677 return v4l2_event_unsubscribe(fh, sub);
1678}
1679
1680/*
1681 * ccdc_set_stream - Enable/Disable streaming on the CCDC module
1682 * @sd: ISP CCDC V4L2 subdevice
1683 * @enable: Enable/disable stream
1684 *
1685 * When writing to memory, the CCDC hardware can't be enabled without a memory
1686 * buffer to write to. As the s_stream operation is called in response to a
1687 * STREAMON call without any buffer queued yet, just update the enabled field
1688 * and return immediately. The CCDC will be enabled in ccdc_isr_buffer().
1689 *
1690 * When not writing to memory enable the CCDC immediately.
1691 */
1692static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
1693{
1694 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1695 struct isp_device *isp = to_isp_device(ccdc);
1696 int ret = 0;
1697
1698 if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED) {
1699 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1700 return 0;
1701
1702 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_CCDC);
1703 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1704 ISPCCDC_CFG_VDLC);
1705
1706 ccdc_configure(ccdc);
1707
1708 /* TODO: Don't configure the video port if all of its output
1709 * links are inactive.
1710 */
1711 ccdc_config_vp(ccdc);
1712 ccdc_enable_vp(ccdc, 1);
1713 ccdc->error = 0;
1714 ccdc_print_status(ccdc);
1715 }
1716
1717 switch (enable) {
1718 case ISP_PIPELINE_STREAM_CONTINUOUS:
1719 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1720 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1721
1722 if (ccdc->underrun || !(ccdc->output & CCDC_OUTPUT_MEMORY))
1723 ccdc_enable(ccdc);
1724
1725 ccdc->underrun = 0;
1726 break;
1727
1728 case ISP_PIPELINE_STREAM_SINGLESHOT:
1729 if (ccdc->output & CCDC_OUTPUT_MEMORY &&
1730 ccdc->state != ISP_PIPELINE_STREAM_SINGLESHOT)
1731 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1732
1733 ccdc_enable(ccdc);
1734 break;
1735
1736 case ISP_PIPELINE_STREAM_STOPPED:
1737 ret = ccdc_disable(ccdc);
1738 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1739 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1740 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_CCDC);
1741 ccdc->underrun = 0;
1742 break;
1743 }
1744
1745 ccdc->state = enable;
1746 return ret;
1747}
1748
1749static struct v4l2_mbus_framefmt *
1750__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1751 unsigned int pad, enum v4l2_subdev_format_whence which)
1752{
1753 if (which == V4L2_SUBDEV_FORMAT_TRY)
1754 return v4l2_subdev_get_try_format(fh, pad);
1755 else
1756 return &ccdc->formats[pad];
1757}
1758
1759/*
1760 * ccdc_try_format - Try video format on a pad
1761 * @ccdc: ISP CCDC device
1762 * @fh : V4L2 subdev file handle
1763 * @pad: Pad number
1764 * @fmt: Format
1765 */
1766static void
1767ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1768 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
1769 enum v4l2_subdev_format_whence which)
1770{
1771 struct v4l2_mbus_framefmt *format;
1772 const struct isp_format_info *info;
1773 unsigned int width = fmt->width;
1774 unsigned int height = fmt->height;
1775 unsigned int i;
1776
1777 switch (pad) {
1778 case CCDC_PAD_SINK:
1779 /* TODO: If the CCDC output formatter pad is connected directly
1780 * to the resizer, only YUV formats can be used.
1781 */
1782 for (i = 0; i < ARRAY_SIZE(ccdc_fmts); i++) {
1783 if (fmt->code == ccdc_fmts[i])
1784 break;
1785 }
1786
1787 /* If not found, use SGRBG10 as default */
1788 if (i >= ARRAY_SIZE(ccdc_fmts))
1789 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
1790
1791 /* Clamp the input size. */
1792 fmt->width = clamp_t(u32, width, 32, 4096);
1793 fmt->height = clamp_t(u32, height, 32, 4096);
1794 break;
1795
1796 case CCDC_PAD_SOURCE_OF:
1797 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1798 memcpy(fmt, format, sizeof(*fmt));
1799
1800 /* The data formatter truncates the number of horizontal output
1801 * pixels to a multiple of 16. To avoid clipping data, allow
1802 * callers to request an output size bigger than the input size
1803 * up to the nearest multiple of 16.
1804 */
1805 fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15);
1806 fmt->width &= ~15;
1807 fmt->height = clamp_t(u32, height, 32, fmt->height);
1808 break;
1809
1810 case CCDC_PAD_SOURCE_VP:
1811 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1812 memcpy(fmt, format, sizeof(*fmt));
1813
1814 /* The video port interface truncates the data to 10 bits. */
1815 info = omap3isp_video_format_info(fmt->code);
1816 fmt->code = info->truncated;
1817
1818 /* The number of lines that can be clocked out from the video
1819 * port output must be at least one line less than the number
1820 * of input lines.
1821 */
1822 fmt->width = clamp_t(u32, width, 32, fmt->width);
1823 fmt->height = clamp_t(u32, height, 32, fmt->height - 1);
1824 break;
1825 }
1826
1827 /* Data is written to memory unpacked, each 10-bit or 12-bit pixel is
1828 * stored on 2 bytes.
1829 */
1830 fmt->colorspace = V4L2_COLORSPACE_SRGB;
1831 fmt->field = V4L2_FIELD_NONE;
1832}
1833
1834/*
1835 * ccdc_enum_mbus_code - Handle pixel format enumeration
1836 * @sd : pointer to v4l2 subdev structure
1837 * @fh : V4L2 subdev file handle
1838 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1839 * return -EINVAL or zero on success
1840 */
1841static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
1842 struct v4l2_subdev_fh *fh,
1843 struct v4l2_subdev_mbus_code_enum *code)
1844{
1845 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1846 struct v4l2_mbus_framefmt *format;
1847
1848 switch (code->pad) {
1849 case CCDC_PAD_SINK:
1850 if (code->index >= ARRAY_SIZE(ccdc_fmts))
1851 return -EINVAL;
1852
1853 code->code = ccdc_fmts[code->index];
1854 break;
1855
1856 case CCDC_PAD_SOURCE_OF:
1857 case CCDC_PAD_SOURCE_VP:
1858 /* No format conversion inside CCDC */
1859 if (code->index != 0)
1860 return -EINVAL;
1861
1862 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK,
1863 V4L2_SUBDEV_FORMAT_TRY);
1864
1865 code->code = format->code;
1866 break;
1867
1868 default:
1869 return -EINVAL;
1870 }
1871
1872 return 0;
1873}
1874
1875static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
1876 struct v4l2_subdev_fh *fh,
1877 struct v4l2_subdev_frame_size_enum *fse)
1878{
1879 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1880 struct v4l2_mbus_framefmt format;
1881
1882 if (fse->index != 0)
1883 return -EINVAL;
1884
1885 format.code = fse->code;
1886 format.width = 1;
1887 format.height = 1;
1888 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1889 fse->min_width = format.width;
1890 fse->min_height = format.height;
1891
1892 if (format.code != fse->code)
1893 return -EINVAL;
1894
1895 format.code = fse->code;
1896 format.width = -1;
1897 format.height = -1;
1898 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1899 fse->max_width = format.width;
1900 fse->max_height = format.height;
1901
1902 return 0;
1903}
1904
1905/*
1906 * ccdc_get_format - Retrieve the video format on a pad
1907 * @sd : ISP CCDC V4L2 subdevice
1908 * @fh : V4L2 subdev file handle
1909 * @fmt: Format
1910 *
1911 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
1912 * to the format type.
1913 */
1914static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1915 struct v4l2_subdev_format *fmt)
1916{
1917 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1918 struct v4l2_mbus_framefmt *format;
1919
1920 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1921 if (format == NULL)
1922 return -EINVAL;
1923
1924 fmt->format = *format;
1925 return 0;
1926}
1927
1928/*
1929 * ccdc_set_format - Set the video format on a pad
1930 * @sd : ISP CCDC V4L2 subdevice
1931 * @fh : V4L2 subdev file handle
1932 * @fmt: Format
1933 *
1934 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
1935 * to the format type.
1936 */
1937static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1938 struct v4l2_subdev_format *fmt)
1939{
1940 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1941 struct v4l2_mbus_framefmt *format;
1942
1943 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1944 if (format == NULL)
1945 return -EINVAL;
1946
1947 ccdc_try_format(ccdc, fh, fmt->pad, &fmt->format, fmt->which);
1948 *format = fmt->format;
1949
1950 /* Propagate the format from sink to source */
1951 if (fmt->pad == CCDC_PAD_SINK) {
1952 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF,
1953 fmt->which);
1954 *format = fmt->format;
1955 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format,
1956 fmt->which);
1957
1958 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_VP,
1959 fmt->which);
1960 *format = fmt->format;
1961 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_VP, format,
1962 fmt->which);
1963 }
1964
1965 return 0;
1966}
1967
1968/*
1969 * ccdc_init_formats - Initialize formats on all pads
1970 * @sd: ISP CCDC V4L2 subdevice
1971 * @fh: V4L2 subdev file handle
1972 *
1973 * Initialize all pad formats with default values. If fh is not NULL, try
1974 * formats are initialized on the file handle. Otherwise active formats are
1975 * initialized on the device.
1976 */
1977static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1978{
1979 struct v4l2_subdev_format format;
1980
1981 memset(&format, 0, sizeof(format));
1982 format.pad = CCDC_PAD_SINK;
1983 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1984 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1985 format.format.width = 4096;
1986 format.format.height = 4096;
1987 ccdc_set_format(sd, fh, &format);
1988
1989 return 0;
1990}
1991
1992/* V4L2 subdev core operations */
1993static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops = {
1994 .ioctl = ccdc_ioctl,
1995 .subscribe_event = ccdc_subscribe_event,
1996 .unsubscribe_event = ccdc_unsubscribe_event,
1997};
1998
1999/* V4L2 subdev video operations */
2000static const struct v4l2_subdev_video_ops ccdc_v4l2_video_ops = {
2001 .s_stream = ccdc_set_stream,
2002};
2003
2004/* V4L2 subdev pad operations */
2005static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
2006 .enum_mbus_code = ccdc_enum_mbus_code,
2007 .enum_frame_size = ccdc_enum_frame_size,
2008 .get_fmt = ccdc_get_format,
2009 .set_fmt = ccdc_set_format,
2010};
2011
2012/* V4L2 subdev operations */
2013static const struct v4l2_subdev_ops ccdc_v4l2_ops = {
2014 .core = &ccdc_v4l2_core_ops,
2015 .video = &ccdc_v4l2_video_ops,
2016 .pad = &ccdc_v4l2_pad_ops,
2017};
2018
2019/* V4L2 subdev internal operations */
2020static const struct v4l2_subdev_internal_ops ccdc_v4l2_internal_ops = {
2021 .open = ccdc_init_formats,
2022};
2023
2024/* -----------------------------------------------------------------------------
2025 * Media entity operations
2026 */
2027
2028/*
2029 * ccdc_link_setup - Setup CCDC connections
2030 * @entity: CCDC media entity
2031 * @local: Pad at the local end of the link
2032 * @remote: Pad at the remote end of the link
2033 * @flags: Link flags
2034 *
2035 * return -EINVAL or zero on success
2036 */
2037static int ccdc_link_setup(struct media_entity *entity,
2038 const struct media_pad *local,
2039 const struct media_pad *remote, u32 flags)
2040{
2041 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
2042 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2043 struct isp_device *isp = to_isp_device(ccdc);
2044
2045 switch (local->index | media_entity_type(remote->entity)) {
2046 case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
2047 /* Read from the sensor (parallel interface), CCP2, CSI2a or
2048 * CSI2c.
2049 */
2050 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
2051 ccdc->input = CCDC_INPUT_NONE;
2052 break;
2053 }
2054
2055 if (ccdc->input != CCDC_INPUT_NONE)
2056 return -EBUSY;
2057
2058 if (remote->entity == &isp->isp_ccp2.subdev.entity)
2059 ccdc->input = CCDC_INPUT_CCP2B;
2060 else if (remote->entity == &isp->isp_csi2a.subdev.entity)
2061 ccdc->input = CCDC_INPUT_CSI2A;
2062 else if (remote->entity == &isp->isp_csi2c.subdev.entity)
2063 ccdc->input = CCDC_INPUT_CSI2C;
2064 else
2065 ccdc->input = CCDC_INPUT_PARALLEL;
2066
2067 break;
2068
2069 /*
2070 * The ISP core doesn't support pipelines with multiple video outputs.
2071 * Revisit this when it will be implemented, and return -EBUSY for now.
2072 */
2073
2074 case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
2075 /* Write to preview engine, histogram and H3A. When none of
2076 * those links are active, the video port can be disabled.
2077 */
2078 if (flags & MEDIA_LNK_FL_ENABLED) {
2079 if (ccdc->output & ~CCDC_OUTPUT_PREVIEW)
2080 return -EBUSY;
2081 ccdc->output |= CCDC_OUTPUT_PREVIEW;
2082 } else {
2083 ccdc->output &= ~CCDC_OUTPUT_PREVIEW;
2084 }
2085 break;
2086
2087 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
2088 /* Write to memory */
2089 if (flags & MEDIA_LNK_FL_ENABLED) {
2090 if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
2091 return -EBUSY;
2092 ccdc->output |= CCDC_OUTPUT_MEMORY;
2093 } else {
2094 ccdc->output &= ~CCDC_OUTPUT_MEMORY;
2095 }
2096 break;
2097
2098 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
2099 /* Write to resizer */
2100 if (flags & MEDIA_LNK_FL_ENABLED) {
2101 if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
2102 return -EBUSY;
2103 ccdc->output |= CCDC_OUTPUT_RESIZER;
2104 } else {
2105 ccdc->output &= ~CCDC_OUTPUT_RESIZER;
2106 }
2107 break;
2108
2109 default:
2110 return -EINVAL;
2111 }
2112
2113 return 0;
2114}
2115
2116/* media operations */
2117static const struct media_entity_operations ccdc_media_ops = {
2118 .link_setup = ccdc_link_setup,
2119};
2120
2121/*
2122 * ccdc_init_entities - Initialize V4L2 subdev and media entity
2123 * @ccdc: ISP CCDC module
2124 *
2125 * Return 0 on success and a negative error code on failure.
2126 */
2127static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2128{
2129 struct v4l2_subdev *sd = &ccdc->subdev;
2130 struct media_pad *pads = ccdc->pads;
2131 struct media_entity *me = &sd->entity;
2132 int ret;
2133
2134 ccdc->input = CCDC_INPUT_NONE;
2135
2136 v4l2_subdev_init(sd, &ccdc_v4l2_ops);
2137 sd->internal_ops = &ccdc_v4l2_internal_ops;
2138 strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name));
2139 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
2140 v4l2_set_subdevdata(sd, ccdc);
2141 sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
2142 sd->nevents = OMAP3ISP_CCDC_NEVENTS;
2143
2144 pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2145 pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
2146 pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
2147
2148 me->ops = &ccdc_media_ops;
2149 ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
2150 if (ret < 0)
2151 return ret;
2152
2153 ccdc_init_formats(sd, NULL);
2154
2155 ccdc->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2156 ccdc->video_out.ops = &ccdc_video_ops;
2157 ccdc->video_out.isp = to_isp_device(ccdc);
2158 ccdc->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
2159 ccdc->video_out.bpl_alignment = 32;
2160
2161 ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2162 if (ret < 0)
2163 return ret;
2164
2165 /* Connect the CCDC subdev to the video node. */
2166 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2167 &ccdc->video_out.video.entity, 0, 0);
2168 if (ret < 0)
2169 return ret;
2170
2171 return 0;
2172}
2173
2174void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2175{
2176 media_entity_cleanup(&ccdc->subdev.entity);
2177
2178 v4l2_device_unregister_subdev(&ccdc->subdev);
2179 omap3isp_video_unregister(&ccdc->video_out);
2180}
2181
2182int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2183 struct v4l2_device *vdev)
2184{
2185 int ret;
2186
2187 /* Register the subdev and video node. */
2188 ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2189 if (ret < 0)
2190 goto error;
2191
2192 ret = omap3isp_video_register(&ccdc->video_out, vdev);
2193 if (ret < 0)
2194 goto error;
2195
2196 return 0;
2197
2198error:
2199 omap3isp_ccdc_unregister_entities(ccdc);
2200 return ret;
2201}
2202
2203/* -----------------------------------------------------------------------------
2204 * ISP CCDC initialisation and cleanup
2205 */
2206
2207/*
2208 * omap3isp_ccdc_init - CCDC module initialization.
2209 * @dev: Device pointer specific to the OMAP3 ISP.
2210 *
2211 * TODO: Get the initialisation values from platform data.
2212 *
2213 * Return 0 on success or a negative error code otherwise.
2214 */
2215int omap3isp_ccdc_init(struct isp_device *isp)
2216{
2217 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2218
2219 spin_lock_init(&ccdc->lock);
2220 init_waitqueue_head(&ccdc->wait);
2221 mutex_init(&ccdc->ioctl_lock);
2222
2223 ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
2224
2225 INIT_WORK(&ccdc->lsc.table_work, ccdc_lsc_free_table_work);
2226 ccdc->lsc.state = LSC_STATE_STOPPED;
2227 INIT_LIST_HEAD(&ccdc->lsc.free_queue);
2228 spin_lock_init(&ccdc->lsc.req_lock);
2229
2230 ccdc->syncif.ccdc_mastermode = 0;
2231 ccdc->syncif.datapol = 0;
2232 ccdc->syncif.datsz = 0;
2233 ccdc->syncif.fldmode = 0;
2234 ccdc->syncif.fldout = 0;
2235 ccdc->syncif.fldpol = 0;
2236 ccdc->syncif.fldstat = 0;
2237 ccdc->syncif.hdpol = 0;
2238 ccdc->syncif.vdpol = 0;
2239
2240 ccdc->clamp.oblen = 0;
2241 ccdc->clamp.dcsubval = 0;
2242
2243 ccdc->vpcfg.pixelclk = 0;
2244
2245 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2246 ccdc_apply_controls(ccdc);
2247
2248 return ccdc_init_entities(ccdc);
2249}
2250
2251/*
2252 * omap3isp_ccdc_cleanup - CCDC module cleanup.
2253 * @dev: Device pointer specific to the OMAP3 ISP.
2254 */
2255void omap3isp_ccdc_cleanup(struct isp_device *isp)
2256{
2257 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2258
2259 /* Free LSC requests. As the CCDC is stopped there's no active request,
2260 * so only the pending request and the free queue need to be handled.
2261 */
2262 ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
2263 cancel_work_sync(&ccdc->lsc.table_work);
2264 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
2265
2266 if (ccdc->fpc.fpcaddr != 0)
2267 iommu_vfree(isp->iommu, ccdc->fpc.fpcaddr);
2268}
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h
new file mode 100644
index 000000000000..d403af5d31d2
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccdc.h
@@ -0,0 +1,219 @@
1/*
2 * ispccdc.h
3 *
4 * TI OMAP3 ISP - CCDC module
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CCDC_H
28#define OMAP3_ISP_CCDC_H
29
30#include <linux/omap3isp.h>
31#include <linux/workqueue.h>
32
33#include "ispvideo.h"
34
35enum ccdc_input_entity {
36 CCDC_INPUT_NONE,
37 CCDC_INPUT_PARALLEL,
38 CCDC_INPUT_CSI2A,
39 CCDC_INPUT_CCP2B,
40 CCDC_INPUT_CSI2C
41};
42
43#define CCDC_OUTPUT_MEMORY (1 << 0)
44#define CCDC_OUTPUT_PREVIEW (1 << 1)
45#define CCDC_OUTPUT_RESIZER (1 << 2)
46
47#define OMAP3ISP_CCDC_NEVENTS 16
48
49/*
50 * struct ispccdc_syncif - Structure for Sync Interface between sensor and CCDC
51 * @ccdc_mastermode: Master mode. 1 - Master, 0 - Slave.
52 * @fldstat: Field state. 0 - Odd Field, 1 - Even Field.
53 * @datsz: Data size.
54 * @fldmode: 0 - Progressive, 1 - Interlaced.
55 * @datapol: 0 - Positive, 1 - Negative.
56 * @fldpol: 0 - Positive, 1 - Negative.
57 * @hdpol: 0 - Positive, 1 - Negative.
58 * @vdpol: 0 - Positive, 1 - Negative.
59 * @fldout: 0 - Input, 1 - Output.
60 * @hs_width: Width of the Horizontal Sync pulse, used for HS/VS Output.
61 * @vs_width: Width of the Vertical Sync pulse, used for HS/VS Output.
62 * @ppln: Number of pixels per line, used for HS/VS Output.
63 * @hlprf: Number of half lines per frame, used for HS/VS Output.
64 * @bt_r656_en: 1 - Enable ITU-R BT656 mode, 0 - Sync mode.
65 */
66struct ispccdc_syncif {
67 u8 ccdc_mastermode;
68 u8 fldstat;
69 u8 datsz;
70 u8 fldmode;
71 u8 datapol;
72 u8 fldpol;
73 u8 hdpol;
74 u8 vdpol;
75 u8 fldout;
76 u8 hs_width;
77 u8 vs_width;
78 u8 ppln;
79 u8 hlprf;
80 u8 bt_r656_en;
81};
82
83/*
84 * struct ispccdc_vp - Structure for Video Port parameters
85 * @pixelclk: Input pixel clock in Hz
86 */
87struct ispccdc_vp {
88 unsigned int pixelclk;
89};
90
91enum ispccdc_lsc_state {
92 LSC_STATE_STOPPED = 0,
93 LSC_STATE_STOPPING = 1,
94 LSC_STATE_RUNNING = 2,
95 LSC_STATE_RECONFIG = 3,
96};
97
98struct ispccdc_lsc_config_req {
99 struct list_head list;
100 struct omap3isp_ccdc_lsc_config config;
101 unsigned char enable;
102 u32 table;
103 struct iovm_struct *iovm;
104};
105
106/*
107 * ispccdc_lsc - CCDC LSC parameters
108 * @update_config: Set when user changes config
109 * @request_enable: Whether LSC is requested to be enabled
110 * @config: LSC config set by user
111 * @update_table: Set when user provides a new LSC table to table_new
112 * @table_new: LSC table set by user, ISP address
113 * @table_inuse: LSC table currently in use, ISP address
114 */
115struct ispccdc_lsc {
116 enum ispccdc_lsc_state state;
117 struct work_struct table_work;
118
119 /* LSC queue of configurations */
120 spinlock_t req_lock;
121 struct ispccdc_lsc_config_req *request; /* requested configuration */
122 struct ispccdc_lsc_config_req *active; /* active configuration */
123 struct list_head free_queue; /* configurations for freeing */
124};
125
126#define CCDC_STOP_NOT_REQUESTED 0x00
127#define CCDC_STOP_REQUEST 0x01
128#define CCDC_STOP_EXECUTED (0x02 | CCDC_STOP_REQUEST)
129#define CCDC_STOP_CCDC_FINISHED 0x04
130#define CCDC_STOP_LSC_FINISHED 0x08
131#define CCDC_STOP_FINISHED \
132 (CCDC_STOP_EXECUTED | CCDC_STOP_CCDC_FINISHED | CCDC_STOP_LSC_FINISHED)
133
134#define CCDC_EVENT_VD1 0x10
135#define CCDC_EVENT_VD0 0x20
136#define CCDC_EVENT_LSC_DONE 0x40
137
138/* Sink and source CCDC pads */
139#define CCDC_PAD_SINK 0
140#define CCDC_PAD_SOURCE_OF 1
141#define CCDC_PAD_SOURCE_VP 2
142#define CCDC_PADS_NUM 3
143
144/*
145 * struct isp_ccdc_device - Structure for the CCDC module to store its own
146 * information
147 * @subdev: V4L2 subdevice
148 * @pads: Sink and source media entity pads
149 * @formats: Active video formats
150 * @input: Active input
151 * @output: Active outputs
152 * @video_out: Output video node
153 * @error: A hardware error occured during capture
154 * @alaw: A-law compression enabled (1) or disabled (0)
155 * @lpf: Low pass filter enabled (1) or disabled (0)
156 * @obclamp: Optical-black clamp enabled (1) or disabled (0)
157 * @fpc_en: Faulty pixels correction enabled (1) or disabled (0)
158 * @blcomp: Black level compensation configuration
159 * @clamp: Optical-black or digital clamp configuration
160 * @fpc: Faulty pixels correction configuration
161 * @lsc: Lens shading compensation configuration
162 * @update: Bitmask of controls to update during the next interrupt
163 * @shadow_update: Controls update in progress by userspace
164 * @syncif: Interface synchronization configuration
165 * @vpcfg: Video port configuration
166 * @underrun: A buffer underrun occured and a new buffer has been queued
167 * @state: Streaming state
168 * @lock: Serializes shadow_update with interrupt handler
169 * @wait: Wait queue used to stop the module
170 * @stopping: Stopping state
171 * @ioctl_lock: Serializes ioctl calls and LSC requests freeing
172 */
173struct isp_ccdc_device {
174 struct v4l2_subdev subdev;
175 struct media_pad pads[CCDC_PADS_NUM];
176 struct v4l2_mbus_framefmt formats[CCDC_PADS_NUM];
177
178 enum ccdc_input_entity input;
179 unsigned int output;
180 struct isp_video video_out;
181 unsigned int error;
182
183 unsigned int alaw:1,
184 lpf:1,
185 obclamp:1,
186 fpc_en:1;
187 struct omap3isp_ccdc_blcomp blcomp;
188 struct omap3isp_ccdc_bclamp clamp;
189 struct omap3isp_ccdc_fpc fpc;
190 struct ispccdc_lsc lsc;
191 unsigned int update;
192 unsigned int shadow_update;
193
194 struct ispccdc_syncif syncif;
195 struct ispccdc_vp vpcfg;
196
197 unsigned int underrun:1;
198 enum isp_pipeline_stream_state state;
199 spinlock_t lock;
200 wait_queue_head_t wait;
201 unsigned int stopping;
202 struct mutex ioctl_lock;
203};
204
205struct isp_device;
206
207int omap3isp_ccdc_init(struct isp_device *isp);
208void omap3isp_ccdc_cleanup(struct isp_device *isp);
209int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
210 struct v4l2_device *vdev);
211void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc);
212
213int omap3isp_ccdc_busy(struct isp_ccdc_device *isp_ccdc);
214int omap3isp_ccdc_isr(struct isp_ccdc_device *isp_ccdc, u32 events);
215void omap3isp_ccdc_restore_context(struct isp_device *isp);
216void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
217 unsigned int *max_rate);
218
219#endif /* OMAP3_ISP_CCDC_H */
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
new file mode 100644
index 000000000000..0efef2e78d93
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccp2.c
@@ -0,0 +1,1173 @@
1/*
2 * ispccp2.c
3 *
4 * TI OMAP3 ISP - CCP2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/delay.h>
28#include <linux/device.h>
29#include <linux/mm.h>
30#include <linux/module.h>
31#include <linux/mutex.h>
32#include <linux/uaccess.h>
33
34#include "isp.h"
35#include "ispreg.h"
36#include "ispccp2.h"
37
38/* Number of LCX channels */
39#define CCP2_LCx_CHANS_NUM 3
40/* Max/Min size for CCP2 video port */
41#define ISPCCP2_DAT_START_MIN 0
42#define ISPCCP2_DAT_START_MAX 4095
43#define ISPCCP2_DAT_SIZE_MIN 0
44#define ISPCCP2_DAT_SIZE_MAX 4095
45#define ISPCCP2_VPCLK_FRACDIV 65536
46#define ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP 0x12
47#define ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP 0x16
48/* Max/Min size for CCP2 memory channel */
49#define ISPCCP2_LCM_HSIZE_COUNT_MIN 16
50#define ISPCCP2_LCM_HSIZE_COUNT_MAX 8191
51#define ISPCCP2_LCM_HSIZE_SKIP_MIN 0
52#define ISPCCP2_LCM_HSIZE_SKIP_MAX 8191
53#define ISPCCP2_LCM_VSIZE_MIN 1
54#define ISPCCP2_LCM_VSIZE_MAX 8191
55#define ISPCCP2_LCM_HWORDS_MIN 1
56#define ISPCCP2_LCM_HWORDS_MAX 4095
57#define ISPCCP2_LCM_CTRL_BURST_SIZE_32X 5
58#define ISPCCP2_LCM_CTRL_READ_THROTTLE_FULL 0
59#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 2
60#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 2
61#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 3
62#define ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 3
63#define ISPCCP2_LCM_CTRL_DST_PORT_VP 0
64#define ISPCCP2_LCM_CTRL_DST_PORT_MEM 1
65
66/* Set only the required bits */
67#define BIT_SET(var, shift, mask, val) \
68 do { \
69 var = ((var) & ~((mask) << (shift))) \
70 | ((val) << (shift)); \
71 } while (0)
72
73/*
74 * ccp2_print_status - Print current CCP2 module register values.
75 */
76#define CCP2_PRINT_REGISTER(isp, name)\
77 dev_dbg(isp->dev, "###CCP2 " #name "=0x%08x\n", \
78 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_##name))
79
80static void ccp2_print_status(struct isp_ccp2_device *ccp2)
81{
82 struct isp_device *isp = to_isp_device(ccp2);
83
84 dev_dbg(isp->dev, "-------------CCP2 Register dump-------------\n");
85
86 CCP2_PRINT_REGISTER(isp, SYSCONFIG);
87 CCP2_PRINT_REGISTER(isp, SYSSTATUS);
88 CCP2_PRINT_REGISTER(isp, LC01_IRQENABLE);
89 CCP2_PRINT_REGISTER(isp, LC01_IRQSTATUS);
90 CCP2_PRINT_REGISTER(isp, LC23_IRQENABLE);
91 CCP2_PRINT_REGISTER(isp, LC23_IRQSTATUS);
92 CCP2_PRINT_REGISTER(isp, LCM_IRQENABLE);
93 CCP2_PRINT_REGISTER(isp, LCM_IRQSTATUS);
94 CCP2_PRINT_REGISTER(isp, CTRL);
95 CCP2_PRINT_REGISTER(isp, LCx_CTRL(0));
96 CCP2_PRINT_REGISTER(isp, LCx_CODE(0));
97 CCP2_PRINT_REGISTER(isp, LCx_STAT_START(0));
98 CCP2_PRINT_REGISTER(isp, LCx_STAT_SIZE(0));
99 CCP2_PRINT_REGISTER(isp, LCx_SOF_ADDR(0));
100 CCP2_PRINT_REGISTER(isp, LCx_EOF_ADDR(0));
101 CCP2_PRINT_REGISTER(isp, LCx_DAT_START(0));
102 CCP2_PRINT_REGISTER(isp, LCx_DAT_SIZE(0));
103 CCP2_PRINT_REGISTER(isp, LCx_DAT_PING_ADDR(0));
104 CCP2_PRINT_REGISTER(isp, LCx_DAT_PONG_ADDR(0));
105 CCP2_PRINT_REGISTER(isp, LCx_DAT_OFST(0));
106 CCP2_PRINT_REGISTER(isp, LCM_CTRL);
107 CCP2_PRINT_REGISTER(isp, LCM_VSIZE);
108 CCP2_PRINT_REGISTER(isp, LCM_HSIZE);
109 CCP2_PRINT_REGISTER(isp, LCM_PREFETCH);
110 CCP2_PRINT_REGISTER(isp, LCM_SRC_ADDR);
111 CCP2_PRINT_REGISTER(isp, LCM_SRC_OFST);
112 CCP2_PRINT_REGISTER(isp, LCM_DST_ADDR);
113 CCP2_PRINT_REGISTER(isp, LCM_DST_OFST);
114
115 dev_dbg(isp->dev, "--------------------------------------------\n");
116}
117
118/*
119 * ccp2_reset - Reset the CCP2
120 * @ccp2: pointer to ISP CCP2 device
121 */
122static void ccp2_reset(struct isp_ccp2_device *ccp2)
123{
124 struct isp_device *isp = to_isp_device(ccp2);
125 int i = 0;
126
127 /* Reset the CSI1/CCP2B and wait for reset to complete */
128 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,
129 ISPCCP2_SYSCONFIG_SOFT_RESET);
130 while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &
131 ISPCCP2_SYSSTATUS_RESET_DONE)) {
132 udelay(10);
133 if (i++ > 10) { /* try read 10 times */
134 dev_warn(isp->dev,
135 "omap3_isp: timeout waiting for ccp2 reset\n");
136 break;
137 }
138 }
139}
140
141/*
142 * ccp2_pwr_cfg - Configure the power mode settings
143 * @ccp2: pointer to ISP CCP2 device
144 */
145static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2)
146{
147 struct isp_device *isp = to_isp_device(ccp2);
148
149 isp_reg_writel(isp, ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART |
150 ((isp->revision == ISP_REVISION_15_0 && isp->autoidle) ?
151 ISPCCP2_SYSCONFIG_AUTO_IDLE : 0),
152 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG);
153}
154
155/*
156 * ccp2_if_enable - Enable CCP2 interface.
157 * @ccp2: pointer to ISP CCP2 device
158 * @enable: enable/disable flag
159 */
160static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
161{
162 struct isp_device *isp = to_isp_device(ccp2);
163 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
164 int i;
165
166 /* Enable/Disable all the LCx channels */
167 for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
168 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),
169 ISPCCP2_LCx_CTRL_CHAN_EN,
170 enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);
171
172 /* Enable/Disable ccp2 interface in ccp2 mode */
173 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
174 ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
175 enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);
176
177 /* For frame count propagation */
178 if (pipe->do_propagation) {
179 /* We may want the Frame Start IRQ from LC0 */
180 if (enable)
181 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2,
182 ISPCCP2_LC01_IRQENABLE,
183 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
184 else
185 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCP2,
186 ISPCCP2_LC01_IRQENABLE,
187 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
188 }
189}
190
191/*
192 * ccp2_mem_enable - Enable CCP2 memory interface.
193 * @ccp2: pointer to ISP CCP2 device
194 * @enable: enable/disable flag
195 */
196static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
197{
198 struct isp_device *isp = to_isp_device(ccp2);
199
200 if (enable)
201 ccp2_if_enable(ccp2, 0);
202
203 /* Enable/Disable ccp2 interface in ccp2 mode */
204 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
205 ISPCCP2_CTRL_MODE, enable ? ISPCCP2_CTRL_MODE : 0);
206
207 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL,
208 ISPCCP2_LCM_CTRL_CHAN_EN,
209 enable ? ISPCCP2_LCM_CTRL_CHAN_EN : 0);
210}
211
212/*
213 * ccp2_phyif_config - Initialize CCP2 phy interface config
214 * @ccp2: Pointer to ISP CCP2 device
215 * @config: CCP2 platform data
216 *
217 * Configure the CCP2 physical interface module from platform data.
218 *
219 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
220 */
221static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
222 const struct isp_ccp2_platform_data *pdata)
223{
224 struct isp_device *isp = to_isp_device(ccp2);
225 u32 val;
226
227 /* CCP2B mode */
228 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) |
229 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
230 /* Data/strobe physical layer */
231 BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
232 pdata->phy_layer);
233 BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
234 pdata->strobe_clk_pol);
235 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
236
237 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
238 if (!(val & ISPCCP2_CTRL_MODE)) {
239 if (pdata->ccp2_mode)
240 dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
241 if (pdata->phy_layer == ISPCCP2_CTRL_PHY_SEL_STROBE)
242 /* Strobe mode requires CCP2 */
243 return -EIO;
244 }
245
246 return 0;
247}
248
249/*
250 * ccp2_vp_config - Initialize CCP2 video port interface.
251 * @ccp2: Pointer to ISP CCP2 device
252 * @vpclk_div: Video port divisor
253 *
254 * Configure the CCP2 video port with the given clock divisor. The valid divisor
255 * values depend on the ISP revision:
256 *
257 * - revision 1.0 and 2.0 1 to 4
258 * - revision 15.0 1 to 65536
259 *
260 * The exact divisor value used might differ from the requested value, as ISP
261 * revision 15.0 represent the divisor by 65536 divided by an integer.
262 */
263static void ccp2_vp_config(struct isp_ccp2_device *ccp2,
264 unsigned int vpclk_div)
265{
266 struct isp_device *isp = to_isp_device(ccp2);
267 u32 val;
268
269 /* ISPCCP2_CTRL Video port */
270 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
271 val |= ISPCCP2_CTRL_VP_ONLY_EN; /* Disable the memory write port */
272
273 if (isp->revision == ISP_REVISION_15_0) {
274 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 65536);
275 vpclk_div = min(ISPCCP2_VPCLK_FRACDIV / vpclk_div, 65535U);
276 BIT_SET(val, ISPCCP2_CTRL_VPCLK_DIV_SHIFT,
277 ISPCCP2_CTRL_VPCLK_DIV_MASK, vpclk_div);
278 } else {
279 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 4);
280 BIT_SET(val, ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT,
281 ISPCCP2_CTRL_VP_OUT_CTRL_MASK, vpclk_div - 1);
282 }
283
284 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
285}
286
287/*
288 * ccp2_lcx_config - Initialize CCP2 logical channel interface.
289 * @ccp2: Pointer to ISP CCP2 device
290 * @config: Pointer to ISP LCx config structure.
291 *
292 * This will analyze the parameters passed by the interface config
293 * and configure CSI1/CCP2 logical channel
294 *
295 */
296static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
297 struct isp_interface_lcx_config *config)
298{
299 struct isp_device *isp = to_isp_device(ccp2);
300 u32 val, format;
301
302 switch (config->format) {
303 case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
304 format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP;
305 break;
306 case V4L2_MBUS_FMT_SGRBG10_1X10:
307 default:
308 format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP; /* RAW10+VP */
309 break;
310 }
311 /* ISPCCP2_LCx_CTRL logical channel #0 */
312 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0))
313 | (ISPCCP2_LCx_CTRL_REGION_EN); /* Region */
314
315 if (isp->revision == ISP_REVISION_15_0) {
316 /* CRC */
317 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0,
318 ISPCCP2_LCx_CTRL_CRC_MASK,
319 config->crc);
320 /* Format = RAW10+VP or RAW8+DPCM10+VP*/
321 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0,
322 ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0, format);
323 } else {
324 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT,
325 ISPCCP2_LCx_CTRL_CRC_MASK,
326 config->crc);
327
328 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT,
329 ISPCCP2_LCx_CTRL_FORMAT_MASK, format);
330 }
331 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0));
332
333 /* ISPCCP2_DAT_START for logical channel #0 */
334 isp_reg_writel(isp, config->data_start << ISPCCP2_LCx_DAT_SHIFT,
335 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_START(0));
336
337 /* ISPCCP2_DAT_SIZE for logical channel #0 */
338 isp_reg_writel(isp, config->data_size << ISPCCP2_LCx_DAT_SHIFT,
339 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_SIZE(0));
340
341 /* Enable error IRQs for logical channel #0 */
342 val = ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
343 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
344 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
345 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
346 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ |
347 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
348 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
349
350 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQSTATUS);
351 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQENABLE, val);
352}
353
354/*
355 * ccp2_if_configure - Configure ccp2 with data from sensor
356 * @ccp2: Pointer to ISP CCP2 device
357 *
358 * Return 0 on success or a negative error code
359 */
360static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
361{
362 const struct isp_v4l2_subdevs_group *pdata;
363 struct v4l2_mbus_framefmt *format;
364 struct media_pad *pad;
365 struct v4l2_subdev *sensor;
366 u32 lines = 0;
367 int ret;
368
369 ccp2_pwr_cfg(ccp2);
370
371 pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
372 sensor = media_entity_to_v4l2_subdev(pad->entity);
373 pdata = sensor->host_priv;
374
375 ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2);
376 if (ret < 0)
377 return ret;
378
379 ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1);
380
381 v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
382
383 format = &ccp2->formats[CCP2_PAD_SINK];
384
385 ccp2->if_cfg.data_start = lines;
386 ccp2->if_cfg.crc = pdata->bus.ccp2.crc;
387 ccp2->if_cfg.format = format->code;
388 ccp2->if_cfg.data_size = format->height;
389
390 ccp2_lcx_config(ccp2, &ccp2->if_cfg);
391
392 return 0;
393}
394
395static int ccp2_adjust_bandwidth(struct isp_ccp2_device *ccp2)
396{
397 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
398 struct isp_device *isp = to_isp_device(ccp2);
399 const struct v4l2_mbus_framefmt *ofmt = &ccp2->formats[CCP2_PAD_SOURCE];
400 unsigned long l3_ick = pipe->l3_ick;
401 struct v4l2_fract *timeperframe;
402 unsigned int vpclk_div = 2;
403 unsigned int value;
404 u64 bound;
405 u64 area;
406
407 /* Compute the minimum clock divisor, based on the pipeline maximum
408 * data rate. This is an absolute lower bound if we don't want SBL
409 * overflows, so round the value up.
410 */
411 vpclk_div = max_t(unsigned int, DIV_ROUND_UP(l3_ick, pipe->max_rate),
412 vpclk_div);
413
414 /* Compute the maximum clock divisor, based on the requested frame rate.
415 * This is a soft lower bound to achieve a frame rate equal or higher
416 * than the requested value, so round the value down.
417 */
418 timeperframe = &pipe->max_timeperframe;
419
420 if (timeperframe->numerator) {
421 area = ofmt->width * ofmt->height;
422 bound = div_u64(area * timeperframe->denominator,
423 timeperframe->numerator);
424 value = min_t(u64, bound, l3_ick);
425 vpclk_div = max_t(unsigned int, l3_ick / value, vpclk_div);
426 }
427
428 dev_dbg(isp->dev, "%s: minimum clock divisor = %u\n", __func__,
429 vpclk_div);
430
431 return vpclk_div;
432}
433
434/*
435 * ccp2_mem_configure - Initialize CCP2 memory input/output interface
436 * @ccp2: Pointer to ISP CCP2 device
437 * @config: Pointer to ISP mem interface config structure
438 *
439 * This will analyze the parameters passed by the interface config
440 * structure, and configure the respective registers for proper
441 * CSI1/CCP2 memory input.
442 */
443static void ccp2_mem_configure(struct isp_ccp2_device *ccp2,
444 struct isp_interface_mem_config *config)
445{
446 struct isp_device *isp = to_isp_device(ccp2);
447 u32 sink_pixcode = ccp2->formats[CCP2_PAD_SINK].code;
448 u32 source_pixcode = ccp2->formats[CCP2_PAD_SOURCE].code;
449 unsigned int dpcm_decompress = 0;
450 u32 val, hwords;
451
452 if (sink_pixcode != source_pixcode &&
453 sink_pixcode == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
454 dpcm_decompress = 1;
455
456 ccp2_pwr_cfg(ccp2);
457
458 /* Hsize, Skip */
459 isp_reg_writel(isp, ISPCCP2_LCM_HSIZE_SKIP_MIN |
460 (config->hsize_count << ISPCCP2_LCM_HSIZE_SHIFT),
461 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_HSIZE);
462
463 /* Vsize, no. of lines */
464 isp_reg_writel(isp, config->vsize_count << ISPCCP2_LCM_VSIZE_SHIFT,
465 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_VSIZE);
466
467 if (ccp2->video_in.bpl_padding == 0)
468 config->src_ofst = 0;
469 else
470 config->src_ofst = ccp2->video_in.bpl_value;
471
472 isp_reg_writel(isp, config->src_ofst, OMAP3_ISP_IOMEM_CCP2,
473 ISPCCP2_LCM_SRC_OFST);
474
475 /* Source and Destination formats */
476 val = ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 <<
477 ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT;
478
479 if (dpcm_decompress) {
480 /* source format is RAW8 */
481 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 <<
482 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
483
484 /* RAW8 + DPCM10 - simple predictor */
485 val |= ISPCCP2_LCM_CTRL_SRC_DPCM_PRED;
486
487 /* enable source DPCM decompression */
488 val |= ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 <<
489 ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT;
490 } else {
491 /* source format is RAW10 */
492 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 <<
493 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
494 }
495
496 /* Burst size to 32x64 */
497 val |= ISPCCP2_LCM_CTRL_BURST_SIZE_32X <<
498 ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT;
499
500 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL);
501
502 /* Prefetch setup */
503 if (dpcm_decompress)
504 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
505 config->hsize_count) >> 3;
506 else
507 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
508 config->hsize_count) >> 2;
509
510 isp_reg_writel(isp, hwords << ISPCCP2_LCM_PREFETCH_SHIFT,
511 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_PREFETCH);
512
513 /* Video port */
514 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
515 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE);
516 ccp2_vp_config(ccp2, ccp2_adjust_bandwidth(ccp2));
517
518 /* Clear LCM interrupts */
519 isp_reg_writel(isp, ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ |
520 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ,
521 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS);
522
523 /* Enable LCM interupts */
524 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE,
525 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ |
526 ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ);
527}
528
529/*
530 * ccp2_set_inaddr - Sets memory address of input frame.
531 * @ccp2: Pointer to ISP CCP2 device
532 * @addr: 32bit memory address aligned on 32byte boundary.
533 *
534 * Configures the memory address from which the input frame is to be read.
535 */
536static void ccp2_set_inaddr(struct isp_ccp2_device *ccp2, u32 addr)
537{
538 struct isp_device *isp = to_isp_device(ccp2);
539
540 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_SRC_ADDR);
541}
542
543/* -----------------------------------------------------------------------------
544 * Interrupt handling
545 */
546
547static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2)
548{
549 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
550 struct isp_buffer *buffer;
551
552 buffer = omap3isp_video_buffer_next(&ccp2->video_in, ccp2->error);
553 if (buffer != NULL)
554 ccp2_set_inaddr(ccp2, buffer->isp_addr);
555
556 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
557
558 if (ccp2->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
559 if (isp_pipeline_ready(pipe))
560 omap3isp_pipeline_set_stream(pipe,
561 ISP_PIPELINE_STREAM_SINGLESHOT);
562 }
563
564 ccp2->error = 0;
565}
566
567/*
568 * omap3isp_ccp2_isr - Handle ISP CCP2 interrupts
569 * @ccp2: Pointer to ISP CCP2 device
570 *
571 * This will handle the CCP2 interrupts
572 *
573 * Returns -EIO in case of error, or 0 on success.
574 */
575int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
576{
577 struct isp_device *isp = to_isp_device(ccp2);
578 int ret = 0;
579 static const u32 ISPCCP2_LC01_ERROR =
580 ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
581 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
582 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
583 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
584 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
585 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
586 u32 lcx_irqstatus, lcm_irqstatus;
587
588 /* First clear the interrupts */
589 lcx_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
590 ISPCCP2_LC01_IRQSTATUS);
591 isp_reg_writel(isp, lcx_irqstatus, OMAP3_ISP_IOMEM_CCP2,
592 ISPCCP2_LC01_IRQSTATUS);
593
594 lcm_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
595 ISPCCP2_LCM_IRQSTATUS);
596 isp_reg_writel(isp, lcm_irqstatus, OMAP3_ISP_IOMEM_CCP2,
597 ISPCCP2_LCM_IRQSTATUS);
598 /* Errors */
599 if (lcx_irqstatus & ISPCCP2_LC01_ERROR) {
600 ccp2->error = 1;
601 dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus);
602 return -EIO;
603 }
604
605 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) {
606 ccp2->error = 1;
607 dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus);
608 ret = -EIO;
609 }
610
611 if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))
612 return 0;
613
614 /* Frame number propagation */
615 if (lcx_irqstatus & ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ) {
616 struct isp_pipeline *pipe =
617 to_isp_pipeline(&ccp2->subdev.entity);
618 if (pipe->do_propagation)
619 atomic_inc(&pipe->frame_number);
620 }
621
622 /* Handle queued buffers on frame end interrupts */
623 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)
624 ccp2_isr_buffer(ccp2);
625
626 return ret;
627}
628
629/* -----------------------------------------------------------------------------
630 * V4L2 subdev operations
631 */
632
633static const unsigned int ccp2_fmts[] = {
634 V4L2_MBUS_FMT_SGRBG10_1X10,
635 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
636};
637
638/*
639 * __ccp2_get_format - helper function for getting ccp2 format
640 * @ccp2 : Pointer to ISP CCP2 device
641 * @fh : V4L2 subdev file handle
642 * @pad : pad number
643 * @which : wanted subdev format
644 * return format structure or NULL on error
645 */
646static struct v4l2_mbus_framefmt *
647__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh,
648 unsigned int pad, enum v4l2_subdev_format_whence which)
649{
650 if (which == V4L2_SUBDEV_FORMAT_TRY)
651 return v4l2_subdev_get_try_format(fh, pad);
652 else
653 return &ccp2->formats[pad];
654}
655
656/*
657 * ccp2_try_format - Handle try format by pad subdev method
658 * @ccp2 : Pointer to ISP CCP2 device
659 * @fh : V4L2 subdev file handle
660 * @pad : pad num
661 * @fmt : pointer to v4l2 mbus format structure
662 * @which : wanted subdev format
663 */
664static void ccp2_try_format(struct isp_ccp2_device *ccp2,
665 struct v4l2_subdev_fh *fh, unsigned int pad,
666 struct v4l2_mbus_framefmt *fmt,
667 enum v4l2_subdev_format_whence which)
668{
669 struct v4l2_mbus_framefmt *format;
670
671 switch (pad) {
672 case CCP2_PAD_SINK:
673 if (fmt->code != V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
674 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
675
676 if (ccp2->input == CCP2_INPUT_SENSOR) {
677 fmt->width = clamp_t(u32, fmt->width,
678 ISPCCP2_DAT_START_MIN,
679 ISPCCP2_DAT_START_MAX);
680 fmt->height = clamp_t(u32, fmt->height,
681 ISPCCP2_DAT_SIZE_MIN,
682 ISPCCP2_DAT_SIZE_MAX);
683 } else if (ccp2->input == CCP2_INPUT_MEMORY) {
684 fmt->width = clamp_t(u32, fmt->width,
685 ISPCCP2_LCM_HSIZE_COUNT_MIN,
686 ISPCCP2_LCM_HSIZE_COUNT_MAX);
687 fmt->height = clamp_t(u32, fmt->height,
688 ISPCCP2_LCM_VSIZE_MIN,
689 ISPCCP2_LCM_VSIZE_MAX);
690 }
691 break;
692
693 case CCP2_PAD_SOURCE:
694 /* Source format - copy sink format and change pixel code
695 * to SGRBG10_1X10 as we don't support CCP2 write to memory.
696 * When CCP2 write to memory feature will be added this
697 * should be changed properly.
698 */
699 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which);
700 memcpy(fmt, format, sizeof(*fmt));
701 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
702 break;
703 }
704
705 fmt->field = V4L2_FIELD_NONE;
706 fmt->colorspace = V4L2_COLORSPACE_SRGB;
707}
708
709/*
710 * ccp2_enum_mbus_code - Handle pixel format enumeration
711 * @sd : pointer to v4l2 subdev structure
712 * @fh : V4L2 subdev file handle
713 * @code : pointer to v4l2_subdev_mbus_code_enum structure
714 * return -EINVAL or zero on success
715 */
716static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
717 struct v4l2_subdev_fh *fh,
718 struct v4l2_subdev_mbus_code_enum *code)
719{
720 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
721 struct v4l2_mbus_framefmt *format;
722
723 if (code->pad == CCP2_PAD_SINK) {
724 if (code->index >= ARRAY_SIZE(ccp2_fmts))
725 return -EINVAL;
726
727 code->code = ccp2_fmts[code->index];
728 } else {
729 if (code->index != 0)
730 return -EINVAL;
731
732 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK,
733 V4L2_SUBDEV_FORMAT_TRY);
734 code->code = format->code;
735 }
736
737 return 0;
738}
739
740static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
741 struct v4l2_subdev_fh *fh,
742 struct v4l2_subdev_frame_size_enum *fse)
743{
744 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
745 struct v4l2_mbus_framefmt format;
746
747 if (fse->index != 0)
748 return -EINVAL;
749
750 format.code = fse->code;
751 format.width = 1;
752 format.height = 1;
753 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
754 fse->min_width = format.width;
755 fse->min_height = format.height;
756
757 if (format.code != fse->code)
758 return -EINVAL;
759
760 format.code = fse->code;
761 format.width = -1;
762 format.height = -1;
763 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
764 fse->max_width = format.width;
765 fse->max_height = format.height;
766
767 return 0;
768}
769
770/*
771 * ccp2_get_format - Handle get format by pads subdev method
772 * @sd : pointer to v4l2 subdev structure
773 * @fh : V4L2 subdev file handle
774 * @fmt : pointer to v4l2 subdev format structure
775 * return -EINVAL or zero on sucess
776 */
777static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
778 struct v4l2_subdev_format *fmt)
779{
780 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
781 struct v4l2_mbus_framefmt *format;
782
783 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
784 if (format == NULL)
785 return -EINVAL;
786
787 fmt->format = *format;
788 return 0;
789}
790
791/*
792 * ccp2_set_format - Handle set format by pads subdev method
793 * @sd : pointer to v4l2 subdev structure
794 * @fh : V4L2 subdev file handle
795 * @fmt : pointer to v4l2 subdev format structure
796 * returns zero
797 */
798static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
799 struct v4l2_subdev_format *fmt)
800{
801 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
802 struct v4l2_mbus_framefmt *format;
803
804 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
805 if (format == NULL)
806 return -EINVAL;
807
808 ccp2_try_format(ccp2, fh, fmt->pad, &fmt->format, fmt->which);
809 *format = fmt->format;
810
811 /* Propagate the format from sink to source */
812 if (fmt->pad == CCP2_PAD_SINK) {
813 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SOURCE,
814 fmt->which);
815 *format = fmt->format;
816 ccp2_try_format(ccp2, fh, CCP2_PAD_SOURCE, format, fmt->which);
817 }
818
819 return 0;
820}
821
822/*
823 * ccp2_init_formats - Initialize formats on all pads
824 * @sd: ISP CCP2 V4L2 subdevice
825 * @fh: V4L2 subdev file handle
826 *
827 * Initialize all pad formats with default values. If fh is not NULL, try
828 * formats are initialized on the file handle. Otherwise active formats are
829 * initialized on the device.
830 */
831static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
832{
833 struct v4l2_subdev_format format;
834
835 memset(&format, 0, sizeof(format));
836 format.pad = CCP2_PAD_SINK;
837 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
838 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
839 format.format.width = 4096;
840 format.format.height = 4096;
841 ccp2_set_format(sd, fh, &format);
842
843 return 0;
844}
845
846/*
847 * ccp2_s_stream - Enable/Disable streaming on ccp2 subdev
848 * @sd : pointer to v4l2 subdev structure
849 * @enable: 1 == Enable, 0 == Disable
850 * return zero
851 */
852static int ccp2_s_stream(struct v4l2_subdev *sd, int enable)
853{
854 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
855 struct isp_device *isp = to_isp_device(ccp2);
856 struct device *dev = to_device(ccp2);
857 int ret;
858
859 if (ccp2->state == ISP_PIPELINE_STREAM_STOPPED) {
860 if (enable == ISP_PIPELINE_STREAM_STOPPED)
861 return 0;
862 atomic_set(&ccp2->stopping, 0);
863 ccp2->error = 0;
864 }
865
866 switch (enable) {
867 case ISP_PIPELINE_STREAM_CONTINUOUS:
868 if (ccp2->phy) {
869 ret = omap3isp_csiphy_acquire(ccp2->phy);
870 if (ret < 0)
871 return ret;
872 }
873
874 ccp2_if_configure(ccp2);
875 ccp2_print_status(ccp2);
876
877 /* Enable CSI1/CCP2 interface */
878 ccp2_if_enable(ccp2, 1);
879 break;
880
881 case ISP_PIPELINE_STREAM_SINGLESHOT:
882 if (ccp2->state != ISP_PIPELINE_STREAM_SINGLESHOT) {
883 struct v4l2_mbus_framefmt *format;
884
885 format = &ccp2->formats[CCP2_PAD_SINK];
886
887 ccp2->mem_cfg.hsize_count = format->width;
888 ccp2->mem_cfg.vsize_count = format->height;
889 ccp2->mem_cfg.src_ofst = 0;
890
891 ccp2_mem_configure(ccp2, &ccp2->mem_cfg);
892 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI1_READ);
893 ccp2_print_status(ccp2);
894 }
895 ccp2_mem_enable(ccp2, 1);
896 break;
897
898 case ISP_PIPELINE_STREAM_STOPPED:
899 if (omap3isp_module_sync_idle(&sd->entity, &ccp2->wait,
900 &ccp2->stopping))
901 dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
902 if (ccp2->input == CCP2_INPUT_MEMORY) {
903 ccp2_mem_enable(ccp2, 0);
904 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI1_READ);
905 } else if (ccp2->input == CCP2_INPUT_SENSOR) {
906 /* Disable CSI1/CCP2 interface */
907 ccp2_if_enable(ccp2, 0);
908 if (ccp2->phy)
909 omap3isp_csiphy_release(ccp2->phy);
910 }
911 break;
912 }
913
914 ccp2->state = enable;
915 return 0;
916}
917
918/* subdev video operations */
919static const struct v4l2_subdev_video_ops ccp2_sd_video_ops = {
920 .s_stream = ccp2_s_stream,
921};
922
923/* subdev pad operations */
924static const struct v4l2_subdev_pad_ops ccp2_sd_pad_ops = {
925 .enum_mbus_code = ccp2_enum_mbus_code,
926 .enum_frame_size = ccp2_enum_frame_size,
927 .get_fmt = ccp2_get_format,
928 .set_fmt = ccp2_set_format,
929};
930
931/* subdev operations */
932static const struct v4l2_subdev_ops ccp2_sd_ops = {
933 .video = &ccp2_sd_video_ops,
934 .pad = &ccp2_sd_pad_ops,
935};
936
937/* subdev internal operations */
938static const struct v4l2_subdev_internal_ops ccp2_sd_internal_ops = {
939 .open = ccp2_init_formats,
940};
941
942/* --------------------------------------------------------------------------
943 * ISP ccp2 video device node
944 */
945
946/*
947 * ccp2_video_queue - Queue video buffer.
948 * @video : Pointer to isp video structure
949 * @buffer: Pointer to isp_buffer structure
950 * return -EIO or zero on success
951 */
952static int ccp2_video_queue(struct isp_video *video, struct isp_buffer *buffer)
953{
954 struct isp_ccp2_device *ccp2 = &video->isp->isp_ccp2;
955
956 ccp2_set_inaddr(ccp2, buffer->isp_addr);
957 return 0;
958}
959
960static const struct isp_video_operations ccp2_video_ops = {
961 .queue = ccp2_video_queue,
962};
963
964/* -----------------------------------------------------------------------------
965 * Media entity operations
966 */
967
968/*
969 * ccp2_link_setup - Setup ccp2 connections.
970 * @entity : Pointer to media entity structure
971 * @local : Pointer to local pad array
972 * @remote : Pointer to remote pad array
973 * @flags : Link flags
974 * return -EINVAL on error or zero on success
975 */
976static int ccp2_link_setup(struct media_entity *entity,
977 const struct media_pad *local,
978 const struct media_pad *remote, u32 flags)
979{
980 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
981 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
982
983 switch (local->index | media_entity_type(remote->entity)) {
984 case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE:
985 /* read from memory */
986 if (flags & MEDIA_LNK_FL_ENABLED) {
987 if (ccp2->input == CCP2_INPUT_SENSOR)
988 return -EBUSY;
989 ccp2->input = CCP2_INPUT_MEMORY;
990 } else {
991 if (ccp2->input == CCP2_INPUT_MEMORY)
992 ccp2->input = CCP2_INPUT_NONE;
993 }
994 break;
995
996 case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
997 /* read from sensor/phy */
998 if (flags & MEDIA_LNK_FL_ENABLED) {
999 if (ccp2->input == CCP2_INPUT_MEMORY)
1000 return -EBUSY;
1001 ccp2->input = CCP2_INPUT_SENSOR;
1002 } else {
1003 if (ccp2->input == CCP2_INPUT_SENSOR)
1004 ccp2->input = CCP2_INPUT_NONE;
1005 } break;
1006
1007 case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1008 /* write to video port/ccdc */
1009 if (flags & MEDIA_LNK_FL_ENABLED)
1010 ccp2->output = CCP2_OUTPUT_CCDC;
1011 else
1012 ccp2->output = CCP2_OUTPUT_NONE;
1013 break;
1014
1015 default:
1016 return -EINVAL;
1017 }
1018
1019 return 0;
1020}
1021
1022/* media operations */
1023static const struct media_entity_operations ccp2_media_ops = {
1024 .link_setup = ccp2_link_setup,
1025};
1026
1027/*
1028 * ccp2_init_entities - Initialize ccp2 subdev and media entity.
1029 * @ccp2: Pointer to ISP CCP2 device
1030 * return negative error code or zero on success
1031 */
1032static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1033{
1034 struct v4l2_subdev *sd = &ccp2->subdev;
1035 struct media_pad *pads = ccp2->pads;
1036 struct media_entity *me = &sd->entity;
1037 int ret;
1038
1039 ccp2->input = CCP2_INPUT_NONE;
1040 ccp2->output = CCP2_OUTPUT_NONE;
1041
1042 v4l2_subdev_init(sd, &ccp2_sd_ops);
1043 sd->internal_ops = &ccp2_sd_internal_ops;
1044 strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));
1045 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1046 v4l2_set_subdevdata(sd, ccp2);
1047 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1048
1049 pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1050 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1051
1052 me->ops = &ccp2_media_ops;
1053 ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
1054 if (ret < 0)
1055 return ret;
1056
1057 ccp2_init_formats(sd, NULL);
1058
1059 /*
1060 * The CCP2 has weird line alignment requirements, possibly caused by
1061 * DPCM8 decompression. Line length for data read from memory must be a
1062 * multiple of 128 bits (16 bytes) in continuous mode (when no padding
1063 * is present at end of lines). Additionally, if padding is used, the
1064 * padded line length must be a multiple of 32 bytes. To simplify the
1065 * implementation we use a fixed 32 bytes alignment regardless of the
1066 * input format and width. If strict 128 bits alignment support is
1067 * required ispvideo will need to be made aware of this special dual
1068 * alignement requirements.
1069 */
1070 ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1071 ccp2->video_in.bpl_alignment = 32;
1072 ccp2->video_in.bpl_max = 0xffffffe0;
1073 ccp2->video_in.isp = to_isp_device(ccp2);
1074 ccp2->video_in.ops = &ccp2_video_ops;
1075 ccp2->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1076
1077 ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1078 if (ret < 0)
1079 return ret;
1080
1081 /* Connect the video node to the ccp2 subdev. */
1082 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1083 &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1084 if (ret < 0)
1085 return ret;
1086
1087 return 0;
1088}
1089
1090/*
1091 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
1092 * @ccp2: Pointer to ISP CCP2 device
1093 */
1094void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1095{
1096 media_entity_cleanup(&ccp2->subdev.entity);
1097
1098 v4l2_device_unregister_subdev(&ccp2->subdev);
1099 omap3isp_video_unregister(&ccp2->video_in);
1100}
1101
1102/*
1103 * omap3isp_ccp2_register_entities - Register the subdev media entity
1104 * @ccp2: Pointer to ISP CCP2 device
1105 * @vdev: Pointer to v4l device
1106 * return negative error code or zero on success
1107 */
1108
1109int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1110 struct v4l2_device *vdev)
1111{
1112 int ret;
1113
1114 /* Register the subdev and video nodes. */
1115 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1116 if (ret < 0)
1117 goto error;
1118
1119 ret = omap3isp_video_register(&ccp2->video_in, vdev);
1120 if (ret < 0)
1121 goto error;
1122
1123 return 0;
1124
1125error:
1126 omap3isp_ccp2_unregister_entities(ccp2);
1127 return ret;
1128}
1129
1130/* -----------------------------------------------------------------------------
1131 * ISP ccp2 initialisation and cleanup
1132 */
1133
1134/*
1135 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1136 * @isp : Pointer to ISP device
1137 */
1138void omap3isp_ccp2_cleanup(struct isp_device *isp)
1139{
1140}
1141
1142/*
1143 * omap3isp_ccp2_init - CCP2 initialization.
1144 * @isp : Pointer to ISP device
1145 * return negative error code or zero on success
1146 */
1147int omap3isp_ccp2_init(struct isp_device *isp)
1148{
1149 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1150 int ret;
1151
1152 init_waitqueue_head(&ccp2->wait);
1153
1154 /* On the OMAP36xx, the CCP2 uses the CSI PHY1 or PHY2, shared with
1155 * the CSI2c or CSI2a receivers. The PHY then needs to be explicitly
1156 * configured.
1157 *
1158 * TODO: Don't hardcode the usage of PHY1 (shared with CSI2c).
1159 */
1160 if (isp->revision == ISP_REVISION_15_0)
1161 ccp2->phy = &isp->isp_csiphy1;
1162
1163 ret = ccp2_init_entities(ccp2);
1164 if (ret < 0)
1165 goto out;
1166
1167 ccp2_reset(ccp2);
1168out:
1169 if (ret)
1170 omap3isp_ccp2_cleanup(isp);
1171
1172 return ret;
1173}
diff --git a/drivers/media/video/omap3isp/ispccp2.h b/drivers/media/video/omap3isp/ispccp2.h
new file mode 100644
index 000000000000..5505a86a9a74
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccp2.h
@@ -0,0 +1,98 @@
1/*
2 * ispccp2.h
3 *
4 * TI OMAP3 ISP - CCP2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CCP2_H
28#define OMAP3_ISP_CCP2_H
29
30#include <linux/videodev2.h>
31
32struct isp_device;
33struct isp_csiphy;
34
35/* Sink and source ccp2 pads */
36#define CCP2_PAD_SINK 0
37#define CCP2_PAD_SOURCE 1
38#define CCP2_PADS_NUM 2
39
40/* CCP2 input media entity */
41enum ccp2_input_entity {
42 CCP2_INPUT_NONE,
43 CCP2_INPUT_SENSOR,
44 CCP2_INPUT_MEMORY,
45};
46
47/* CCP2 output media entity */
48enum ccp2_output_entity {
49 CCP2_OUTPUT_NONE,
50 CCP2_OUTPUT_CCDC,
51 CCP2_OUTPUT_MEMORY,
52};
53
54
55/* Logical channel configuration */
56struct isp_interface_lcx_config {
57 int crc;
58 u32 data_start;
59 u32 data_size;
60 u32 format;
61};
62
63/* Memory channel configuration */
64struct isp_interface_mem_config {
65 u32 dst_port;
66 u32 vsize_count;
67 u32 hsize_count;
68 u32 src_ofst;
69 u32 dst_ofst;
70};
71
72/* CCP2 device */
73struct isp_ccp2_device {
74 struct v4l2_subdev subdev;
75 struct v4l2_mbus_framefmt formats[CCP2_PADS_NUM];
76 struct media_pad pads[CCP2_PADS_NUM];
77
78 enum ccp2_input_entity input;
79 enum ccp2_output_entity output;
80 struct isp_interface_lcx_config if_cfg;
81 struct isp_interface_mem_config mem_cfg;
82 struct isp_video video_in;
83 struct isp_csiphy *phy;
84 unsigned int error;
85 enum isp_pipeline_stream_state state;
86 wait_queue_head_t wait;
87 atomic_t stopping;
88};
89
90/* Function declarations */
91int omap3isp_ccp2_init(struct isp_device *isp);
92void omap3isp_ccp2_cleanup(struct isp_device *isp);
93int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
94 struct v4l2_device *vdev);
95void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2);
96int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2);
97
98#endif /* OMAP3_ISP_CCP2_H */
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
new file mode 100644
index 000000000000..fb503f3db3be
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsi2.c
@@ -0,0 +1,1317 @@
1/*
2 * ispcsi2.c
3 *
4 * TI OMAP3 ISP - CSI2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26#include <linux/delay.h>
27#include <media/v4l2-common.h>
28#include <linux/v4l2-mediabus.h>
29#include <linux/mm.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispcsi2.h"
34
35/*
36 * csi2_if_enable - Enable CSI2 Receiver interface.
37 * @enable: enable flag
38 *
39 */
40static void csi2_if_enable(struct isp_device *isp,
41 struct isp_csi2_device *csi2, u8 enable)
42{
43 struct isp_csi2_ctrl_cfg *currctrl = &csi2->ctrl;
44
45 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_CTRL, ISPCSI2_CTRL_IF_EN,
46 enable ? ISPCSI2_CTRL_IF_EN : 0);
47
48 currctrl->if_enable = enable;
49}
50
51/*
52 * csi2_recv_config - CSI2 receiver module configuration.
53 * @currctrl: isp_csi2_ctrl_cfg structure
54 *
55 */
56static void csi2_recv_config(struct isp_device *isp,
57 struct isp_csi2_device *csi2,
58 struct isp_csi2_ctrl_cfg *currctrl)
59{
60 u32 reg;
61
62 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTRL);
63
64 if (currctrl->frame_mode)
65 reg |= ISPCSI2_CTRL_FRAME;
66 else
67 reg &= ~ISPCSI2_CTRL_FRAME;
68
69 if (currctrl->vp_clk_enable)
70 reg |= ISPCSI2_CTRL_VP_CLK_EN;
71 else
72 reg &= ~ISPCSI2_CTRL_VP_CLK_EN;
73
74 if (currctrl->vp_only_enable)
75 reg |= ISPCSI2_CTRL_VP_ONLY_EN;
76 else
77 reg &= ~ISPCSI2_CTRL_VP_ONLY_EN;
78
79 reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK;
80 reg |= currctrl->vp_out_ctrl << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT;
81
82 if (currctrl->ecc_enable)
83 reg |= ISPCSI2_CTRL_ECC_EN;
84 else
85 reg &= ~ISPCSI2_CTRL_ECC_EN;
86
87 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTRL);
88}
89
90static const unsigned int csi2_input_fmts[] = {
91 V4L2_MBUS_FMT_SGRBG10_1X10,
92 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
93 V4L2_MBUS_FMT_SRGGB10_1X10,
94 V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
95 V4L2_MBUS_FMT_SBGGR10_1X10,
96 V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
97 V4L2_MBUS_FMT_SGBRG10_1X10,
98 V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
99};
100
101/* To set the format on the CSI2 requires a mapping function that takes
102 * the following inputs:
103 * - 2 different formats (at this time)
104 * - 2 destinations (mem, vp+mem) (vp only handled separately)
105 * - 2 decompression options (on, off)
106 * - 2 isp revisions (certain format must be handled differently on OMAP3630)
107 * Output should be CSI2 frame format code
108 * Array indices as follows: [format][dest][decompr][is_3630]
109 * Not all combinations are valid. 0 means invalid.
110 */
111static const u16 __csi2_fmt_map[2][2][2][2] = {
112 /* RAW10 formats */
113 {
114 /* Output to memory */
115 {
116 /* No DPCM decompression */
117 { CSI2_PIX_FMT_RAW10_EXP16, CSI2_PIX_FMT_RAW10_EXP16 },
118 /* DPCM decompression */
119 { 0, 0 },
120 },
121 /* Output to both */
122 {
123 /* No DPCM decompression */
124 { CSI2_PIX_FMT_RAW10_EXP16_VP,
125 CSI2_PIX_FMT_RAW10_EXP16_VP },
126 /* DPCM decompression */
127 { 0, 0 },
128 },
129 },
130 /* RAW10 DPCM8 formats */
131 {
132 /* Output to memory */
133 {
134 /* No DPCM decompression */
135 { CSI2_PIX_FMT_RAW8, CSI2_USERDEF_8BIT_DATA1 },
136 /* DPCM decompression */
137 { CSI2_PIX_FMT_RAW8_DPCM10_EXP16,
138 CSI2_USERDEF_8BIT_DATA1_DPCM10 },
139 },
140 /* Output to both */
141 {
142 /* No DPCM decompression */
143 { CSI2_PIX_FMT_RAW8_VP,
144 CSI2_PIX_FMT_RAW8_VP },
145 /* DPCM decompression */
146 { CSI2_PIX_FMT_RAW8_DPCM10_VP,
147 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP },
148 },
149 },
150};
151
152/*
153 * csi2_ctx_map_format - Map CSI2 sink media bus format to CSI2 format ID
154 * @csi2: ISP CSI2 device
155 *
156 * Returns CSI2 physical format id
157 */
158static u16 csi2_ctx_map_format(struct isp_csi2_device *csi2)
159{
160 const struct v4l2_mbus_framefmt *fmt = &csi2->formats[CSI2_PAD_SINK];
161 int fmtidx, destidx, is_3630;
162
163 switch (fmt->code) {
164 case V4L2_MBUS_FMT_SGRBG10_1X10:
165 case V4L2_MBUS_FMT_SRGGB10_1X10:
166 case V4L2_MBUS_FMT_SBGGR10_1X10:
167 case V4L2_MBUS_FMT_SGBRG10_1X10:
168 fmtidx = 0;
169 break;
170 case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
171 case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8:
172 case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8:
173 case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8:
174 fmtidx = 1;
175 break;
176 default:
177 WARN(1, KERN_ERR "CSI2: pixel format %08x unsupported!\n",
178 fmt->code);
179 return 0;
180 }
181
182 if (!(csi2->output & CSI2_OUTPUT_CCDC) &&
183 !(csi2->output & CSI2_OUTPUT_MEMORY)) {
184 /* Neither output enabled is a valid combination */
185 return CSI2_PIX_FMT_OTHERS;
186 }
187
188 /* If we need to skip frames at the beginning of the stream disable the
189 * video port to avoid sending the skipped frames to the CCDC.
190 */
191 destidx = csi2->frame_skip ? 0 : !!(csi2->output & CSI2_OUTPUT_CCDC);
192 is_3630 = csi2->isp->revision == ISP_REVISION_15_0;
193
194 return __csi2_fmt_map[fmtidx][destidx][csi2->dpcm_decompress][is_3630];
195}
196
197/*
198 * csi2_set_outaddr - Set memory address to save output image
199 * @csi2: Pointer to ISP CSI2a device.
200 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
201 *
202 * Sets the memory address where the output will be saved.
203 *
204 * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte
205 * boundary.
206 */
207static void csi2_set_outaddr(struct isp_csi2_device *csi2, u32 addr)
208{
209 struct isp_device *isp = csi2->isp;
210 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[0];
211
212 ctx->ping_addr = addr;
213 ctx->pong_addr = addr;
214 isp_reg_writel(isp, ctx->ping_addr,
215 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
216 isp_reg_writel(isp, ctx->pong_addr,
217 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
218}
219
220/*
221 * is_usr_def_mapping - Checks whether USER_DEF_MAPPING should
222 * be enabled by CSI2.
223 * @format_id: mapped format id
224 *
225 */
226static inline int is_usr_def_mapping(u32 format_id)
227{
228 return (format_id & 0x40) ? 1 : 0;
229}
230
231/*
232 * csi2_ctx_enable - Enable specified CSI2 context
233 * @ctxnum: Context number, valid between 0 and 7 values.
234 * @enable: enable
235 *
236 */
237static void csi2_ctx_enable(struct isp_device *isp,
238 struct isp_csi2_device *csi2, u8 ctxnum, u8 enable)
239{
240 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[ctxnum];
241 unsigned int skip = 0;
242 u32 reg;
243
244 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
245
246 if (enable) {
247 if (csi2->frame_skip)
248 skip = csi2->frame_skip;
249 else if (csi2->output & CSI2_OUTPUT_MEMORY)
250 skip = 1;
251
252 reg &= ~ISPCSI2_CTX_CTRL1_COUNT_MASK;
253 reg |= ISPCSI2_CTX_CTRL1_COUNT_UNLOCK
254 | (skip << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
255 | ISPCSI2_CTX_CTRL1_CTX_EN;
256 } else {
257 reg &= ~ISPCSI2_CTX_CTRL1_CTX_EN;
258 }
259
260 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
261 ctx->enabled = enable;
262}
263
264/*
265 * csi2_ctx_config - CSI2 context configuration.
266 * @ctx: context configuration
267 *
268 */
269static void csi2_ctx_config(struct isp_device *isp,
270 struct isp_csi2_device *csi2,
271 struct isp_csi2_ctx_cfg *ctx)
272{
273 u32 reg;
274
275 /* Set up CSI2_CTx_CTRL1 */
276 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
277
278 if (ctx->eof_enabled)
279 reg |= ISPCSI2_CTX_CTRL1_EOF_EN;
280 else
281 reg &= ~ISPCSI2_CTX_CTRL1_EOF_EN;
282
283 if (ctx->eol_enabled)
284 reg |= ISPCSI2_CTX_CTRL1_EOL_EN;
285 else
286 reg &= ~ISPCSI2_CTX_CTRL1_EOL_EN;
287
288 if (ctx->checksum_enabled)
289 reg |= ISPCSI2_CTX_CTRL1_CS_EN;
290 else
291 reg &= ~ISPCSI2_CTX_CTRL1_CS_EN;
292
293 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
294
295 /* Set up CSI2_CTx_CTRL2 */
296 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
297
298 reg &= ~(ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK);
299 reg |= ctx->virtual_id << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT;
300
301 reg &= ~(ISPCSI2_CTX_CTRL2_FORMAT_MASK);
302 reg |= ctx->format_id << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT;
303
304 if (ctx->dpcm_decompress) {
305 if (ctx->dpcm_predictor)
306 reg |= ISPCSI2_CTX_CTRL2_DPCM_PRED;
307 else
308 reg &= ~ISPCSI2_CTX_CTRL2_DPCM_PRED;
309 }
310
311 if (is_usr_def_mapping(ctx->format_id)) {
312 reg &= ~ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK;
313 reg |= 2 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT;
314 }
315
316 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
317
318 /* Set up CSI2_CTx_CTRL3 */
319 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
320 reg &= ~(ISPCSI2_CTX_CTRL3_ALPHA_MASK);
321 reg |= (ctx->alpha << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT);
322
323 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
324
325 /* Set up CSI2_CTx_DAT_OFST */
326 reg = isp_reg_readl(isp, csi2->regs1,
327 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
328 reg &= ~ISPCSI2_CTX_DAT_OFST_OFST_MASK;
329 reg |= ctx->data_offset << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT;
330 isp_reg_writel(isp, reg, csi2->regs1,
331 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
332
333 isp_reg_writel(isp, ctx->ping_addr,
334 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
335
336 isp_reg_writel(isp, ctx->pong_addr,
337 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
338}
339
340/*
341 * csi2_timing_config - CSI2 timing configuration.
342 * @timing: csi2_timing_cfg structure
343 */
344static void csi2_timing_config(struct isp_device *isp,
345 struct isp_csi2_device *csi2,
346 struct isp_csi2_timing_cfg *timing)
347{
348 u32 reg;
349
350 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_TIMING);
351
352 if (timing->force_rx_mode)
353 reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
354 else
355 reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
356
357 if (timing->stop_state_16x)
358 reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
359 else
360 reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
361
362 if (timing->stop_state_4x)
363 reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
364 else
365 reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
366
367 reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(timing->ionum);
368 reg |= timing->stop_state_counter <<
369 ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(timing->ionum);
370
371 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_TIMING);
372}
373
374/*
375 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
376 * @enable: Enable/disable CSI2 Context interrupts
377 */
378static void csi2_irq_ctx_set(struct isp_device *isp,
379 struct isp_csi2_device *csi2, int enable)
380{
381 u32 reg = ISPCSI2_CTX_IRQSTATUS_FE_IRQ;
382 int i;
383
384 if (csi2->use_fs_irq)
385 reg |= ISPCSI2_CTX_IRQSTATUS_FS_IRQ;
386
387 for (i = 0; i < 8; i++) {
388 isp_reg_writel(isp, reg, csi2->regs1,
389 ISPCSI2_CTX_IRQSTATUS(i));
390 if (enable)
391 isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
392 reg);
393 else
394 isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
395 reg);
396 }
397}
398
399/*
400 * csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs.
401 * @enable: Enable/disable CSI2 ComplexIO #1 interrupts
402 */
403static void csi2_irq_complexio1_set(struct isp_device *isp,
404 struct isp_csi2_device *csi2, int enable)
405{
406 u32 reg;
407 reg = ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT |
408 ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER |
409 ISPCSI2_PHY_IRQENABLE_STATEULPM5 |
410 ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 |
411 ISPCSI2_PHY_IRQENABLE_ERRESC5 |
412 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 |
413 ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 |
414 ISPCSI2_PHY_IRQENABLE_STATEULPM4 |
415 ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 |
416 ISPCSI2_PHY_IRQENABLE_ERRESC4 |
417 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 |
418 ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 |
419 ISPCSI2_PHY_IRQENABLE_STATEULPM3 |
420 ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 |
421 ISPCSI2_PHY_IRQENABLE_ERRESC3 |
422 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 |
423 ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 |
424 ISPCSI2_PHY_IRQENABLE_STATEULPM2 |
425 ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 |
426 ISPCSI2_PHY_IRQENABLE_ERRESC2 |
427 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 |
428 ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 |
429 ISPCSI2_PHY_IRQENABLE_STATEULPM1 |
430 ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 |
431 ISPCSI2_PHY_IRQENABLE_ERRESC1 |
432 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 |
433 ISPCSI2_PHY_IRQENABLE_ERRSOTHS1;
434 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
435 if (enable)
436 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
437 else
438 reg = 0;
439 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
440}
441
442/*
443 * csi2_irq_status_set - Enables CSI2 Status IRQs.
444 * @enable: Enable/disable CSI2 Status interrupts
445 */
446static void csi2_irq_status_set(struct isp_device *isp,
447 struct isp_csi2_device *csi2, int enable)
448{
449 u32 reg;
450 reg = ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
451 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
452 ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ |
453 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
454 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
455 ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ |
456 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ |
457 ISPCSI2_IRQSTATUS_CONTEXT(0);
458 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQSTATUS);
459 if (enable)
460 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQENABLE);
461 else
462 reg = 0;
463
464 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQENABLE);
465}
466
467/*
468 * omap3isp_csi2_reset - Resets the CSI2 module.
469 *
470 * Must be called with the phy lock held.
471 *
472 * Returns 0 if successful, or -EBUSY if power command didn't respond.
473 */
474int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
475{
476 struct isp_device *isp = csi2->isp;
477 u8 soft_reset_retries = 0;
478 u32 reg;
479 int i;
480
481 if (!csi2->available)
482 return -ENODEV;
483
484 if (csi2->phy->phy_in_use)
485 return -EBUSY;
486
487 isp_reg_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
488 ISPCSI2_SYSCONFIG_SOFT_RESET);
489
490 do {
491 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_SYSSTATUS) &
492 ISPCSI2_SYSSTATUS_RESET_DONE;
493 if (reg == ISPCSI2_SYSSTATUS_RESET_DONE)
494 break;
495 soft_reset_retries++;
496 if (soft_reset_retries < 5)
497 udelay(100);
498 } while (soft_reset_retries < 5);
499
500 if (soft_reset_retries == 5) {
501 printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n");
502 return -EBUSY;
503 }
504
505 if (isp->revision == ISP_REVISION_15_0)
506 isp_reg_set(isp, csi2->regs1, ISPCSI2_PHY_CFG,
507 ISPCSI2_PHY_CFG_RESET_CTRL);
508
509 i = 100;
510 do {
511 reg = isp_reg_readl(isp, csi2->phy->phy_regs, ISPCSIPHY_REG1)
512 & ISPCSIPHY_REG1_RESET_DONE_CTRLCLK;
513 if (reg == ISPCSIPHY_REG1_RESET_DONE_CTRLCLK)
514 break;
515 udelay(100);
516 } while (--i > 0);
517
518 if (i == 0) {
519 printk(KERN_ERR
520 "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
521 return -EBUSY;
522 }
523
524 if (isp->autoidle)
525 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
526 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
527 ISPCSI2_SYSCONFIG_AUTO_IDLE,
528 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART |
529 ((isp->revision == ISP_REVISION_15_0) ?
530 ISPCSI2_SYSCONFIG_AUTO_IDLE : 0));
531 else
532 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
533 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
534 ISPCSI2_SYSCONFIG_AUTO_IDLE,
535 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO);
536
537 return 0;
538}
539
540static int csi2_configure(struct isp_csi2_device *csi2)
541{
542 const struct isp_v4l2_subdevs_group *pdata;
543 struct isp_device *isp = csi2->isp;
544 struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
545 struct v4l2_subdev *sensor;
546 struct media_pad *pad;
547
548 /*
549 * CSI2 fields that can be updated while the context has
550 * been enabled or the interface has been enabled are not
551 * updated dynamically currently. So we do not allow to
552 * reconfigure if either has been enabled
553 */
554 if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
555 return -EBUSY;
556
557 pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
558 sensor = media_entity_to_v4l2_subdev(pad->entity);
559 pdata = sensor->host_priv;
560
561 csi2->frame_skip = 0;
562 v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
563
564 csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div;
565 csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
566 csi2->ctrl.ecc_enable = pdata->bus.csi2.crc;
567
568 timing->ionum = 1;
569 timing->force_rx_mode = 1;
570 timing->stop_state_16x = 1;
571 timing->stop_state_4x = 1;
572 timing->stop_state_counter = 0x1FF;
573
574 /*
575 * The CSI2 receiver can't do any format conversion except DPCM
576 * decompression, so every set_format call configures both pads
577 * and enables DPCM decompression as a special case:
578 */
579 if (csi2->formats[CSI2_PAD_SINK].code !=
580 csi2->formats[CSI2_PAD_SOURCE].code)
581 csi2->dpcm_decompress = true;
582 else
583 csi2->dpcm_decompress = false;
584
585 csi2->contexts[0].format_id = csi2_ctx_map_format(csi2);
586
587 if (csi2->video_out.bpl_padding == 0)
588 csi2->contexts[0].data_offset = 0;
589 else
590 csi2->contexts[0].data_offset = csi2->video_out.bpl_value;
591
592 /*
593 * Enable end of frame and end of line signals generation for
594 * context 0. These signals are generated from CSI2 receiver to
595 * qualify the last pixel of a frame and the last pixel of a line.
596 * Without enabling the signals CSI2 receiver writes data to memory
597 * beyond buffer size and/or data line offset is not handled correctly.
598 */
599 csi2->contexts[0].eof_enabled = 1;
600 csi2->contexts[0].eol_enabled = 1;
601
602 csi2_irq_complexio1_set(isp, csi2, 1);
603 csi2_irq_ctx_set(isp, csi2, 1);
604 csi2_irq_status_set(isp, csi2, 1);
605
606 /* Set configuration (timings, format and links) */
607 csi2_timing_config(isp, csi2, timing);
608 csi2_recv_config(isp, csi2, &csi2->ctrl);
609 csi2_ctx_config(isp, csi2, &csi2->contexts[0]);
610
611 return 0;
612}
613
614/*
615 * csi2_print_status - Prints CSI2 debug information.
616 */
617#define CSI2_PRINT_REGISTER(isp, regs, name)\
618 dev_dbg(isp->dev, "###CSI2 " #name "=0x%08x\n", \
619 isp_reg_readl(isp, regs, ISPCSI2_##name))
620
621static void csi2_print_status(struct isp_csi2_device *csi2)
622{
623 struct isp_device *isp = csi2->isp;
624
625 if (!csi2->available)
626 return;
627
628 dev_dbg(isp->dev, "-------------CSI2 Register dump-------------\n");
629
630 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSCONFIG);
631 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSSTATUS);
632 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQENABLE);
633 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQSTATUS);
634 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTRL);
635 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_H);
636 CSI2_PRINT_REGISTER(isp, csi2->regs1, GNQ);
637 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_CFG);
638 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQSTATUS);
639 CSI2_PRINT_REGISTER(isp, csi2->regs1, SHORT_PACKET);
640 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQENABLE);
641 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_P);
642 CSI2_PRINT_REGISTER(isp, csi2->regs1, TIMING);
643 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL1(0));
644 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL2(0));
645 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_OFST(0));
646 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PING_ADDR(0));
647 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PONG_ADDR(0));
648 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQENABLE(0));
649 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQSTATUS(0));
650 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL3(0));
651
652 dev_dbg(isp->dev, "--------------------------------------------\n");
653}
654
655/* -----------------------------------------------------------------------------
656 * Interrupt handling
657 */
658
659/*
660 * csi2_isr_buffer - Does buffer handling at end-of-frame
661 * when writing to memory.
662 */
663static void csi2_isr_buffer(struct isp_csi2_device *csi2)
664{
665 struct isp_device *isp = csi2->isp;
666 struct isp_buffer *buffer;
667
668 csi2_ctx_enable(isp, csi2, 0, 0);
669
670 buffer = omap3isp_video_buffer_next(&csi2->video_out, 0);
671
672 /*
673 * Let video queue operation restart engine if there is an underrun
674 * condition.
675 */
676 if (buffer == NULL)
677 return;
678
679 csi2_set_outaddr(csi2, buffer->isp_addr);
680 csi2_ctx_enable(isp, csi2, 0, 1);
681}
682
683static void csi2_isr_ctx(struct isp_csi2_device *csi2,
684 struct isp_csi2_ctx_cfg *ctx)
685{
686 struct isp_device *isp = csi2->isp;
687 unsigned int n = ctx->ctxnum;
688 u32 status;
689
690 status = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
691 isp_reg_writel(isp, status, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
692
693 /* Propagate frame number */
694 if (status & ISPCSI2_CTX_IRQSTATUS_FS_IRQ) {
695 struct isp_pipeline *pipe =
696 to_isp_pipeline(&csi2->subdev.entity);
697 if (pipe->do_propagation)
698 atomic_inc(&pipe->frame_number);
699 }
700
701 if (!(status & ISPCSI2_CTX_IRQSTATUS_FE_IRQ))
702 return;
703
704 /* Skip interrupts until we reach the frame skip count. The CSI2 will be
705 * automatically disabled, as the frame skip count has been programmed
706 * in the CSI2_CTx_CTRL1::COUNT field, so reenable it.
707 *
708 * It would have been nice to rely on the FRAME_NUMBER interrupt instead
709 * but it turned out that the interrupt is only generated when the CSI2
710 * writes to memory (the CSI2_CTx_CTRL1::COUNT field is decreased
711 * correctly and reaches 0 when data is forwarded to the video port only
712 * but no interrupt arrives). Maybe a CSI2 hardware bug.
713 */
714 if (csi2->frame_skip) {
715 csi2->frame_skip--;
716 if (csi2->frame_skip == 0) {
717 ctx->format_id = csi2_ctx_map_format(csi2);
718 csi2_ctx_config(isp, csi2, ctx);
719 csi2_ctx_enable(isp, csi2, n, 1);
720 }
721 return;
722 }
723
724 if (csi2->output & CSI2_OUTPUT_MEMORY)
725 csi2_isr_buffer(csi2);
726}
727
728/*
729 * omap3isp_csi2_isr - CSI2 interrupt handling.
730 *
731 * Return -EIO on Transmission error
732 */
733int omap3isp_csi2_isr(struct isp_csi2_device *csi2)
734{
735 u32 csi2_irqstatus, cpxio1_irqstatus;
736 struct isp_device *isp = csi2->isp;
737 int retval = 0;
738
739 if (!csi2->available)
740 return -ENODEV;
741
742 csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS);
743 isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS);
744
745 /* Failure Cases */
746 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) {
747 cpxio1_irqstatus = isp_reg_readl(isp, csi2->regs1,
748 ISPCSI2_PHY_IRQSTATUS);
749 isp_reg_writel(isp, cpxio1_irqstatus,
750 csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
751 dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ "
752 "%x\n", cpxio1_irqstatus);
753 retval = -EIO;
754 }
755
756 if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
757 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
758 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
759 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
760 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ)) {
761 dev_dbg(isp->dev, "CSI2 Err:"
762 " OCP:%d,"
763 " Short_pack:%d,"
764 " ECC:%d,"
765 " CPXIO2:%d,"
766 " FIFO_OVF:%d,"
767 "\n",
768 (csi2_irqstatus &
769 ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) ? 1 : 0,
770 (csi2_irqstatus &
771 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) ? 1 : 0,
772 (csi2_irqstatus &
773 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) ? 1 : 0,
774 (csi2_irqstatus &
775 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0,
776 (csi2_irqstatus &
777 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0);
778 retval = -EIO;
779 }
780
781 if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
782 return 0;
783
784 /* Successful cases */
785 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0))
786 csi2_isr_ctx(csi2, &csi2->contexts[0]);
787
788 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ)
789 dev_dbg(isp->dev, "CSI2: ECC correction done\n");
790
791 return retval;
792}
793
794/* -----------------------------------------------------------------------------
795 * ISP video operations
796 */
797
798/*
799 * csi2_queue - Queues the first buffer when using memory output
800 * @video: The video node
801 * @buffer: buffer to queue
802 */
803static int csi2_queue(struct isp_video *video, struct isp_buffer *buffer)
804{
805 struct isp_device *isp = video->isp;
806 struct isp_csi2_device *csi2 = &isp->isp_csi2a;
807
808 csi2_set_outaddr(csi2, buffer->isp_addr);
809
810 /*
811 * If streaming was enabled before there was a buffer queued
812 * or underrun happened in the ISR, the hardware was not enabled
813 * and DMA queue flag ISP_VIDEO_DMAQUEUE_UNDERRUN is still set.
814 * Enable it now.
815 */
816 if (csi2->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
817 /* Enable / disable context 0 and IRQs */
818 csi2_if_enable(isp, csi2, 1);
819 csi2_ctx_enable(isp, csi2, 0, 1);
820 isp_video_dmaqueue_flags_clr(&csi2->video_out);
821 }
822
823 return 0;
824}
825
826static const struct isp_video_operations csi2_ispvideo_ops = {
827 .queue = csi2_queue,
828};
829
830/* -----------------------------------------------------------------------------
831 * V4L2 subdev operations
832 */
833
834static struct v4l2_mbus_framefmt *
835__csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
836 unsigned int pad, enum v4l2_subdev_format_whence which)
837{
838 if (which == V4L2_SUBDEV_FORMAT_TRY)
839 return v4l2_subdev_get_try_format(fh, pad);
840 else
841 return &csi2->formats[pad];
842}
843
844static void
845csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
846 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
847 enum v4l2_subdev_format_whence which)
848{
849 enum v4l2_mbus_pixelcode pixelcode;
850 struct v4l2_mbus_framefmt *format;
851 const struct isp_format_info *info;
852 unsigned int i;
853
854 switch (pad) {
855 case CSI2_PAD_SINK:
856 /* Clamp the width and height to valid range (1-8191). */
857 for (i = 0; i < ARRAY_SIZE(csi2_input_fmts); i++) {
858 if (fmt->code == csi2_input_fmts[i])
859 break;
860 }
861
862 /* If not found, use SGRBG10 as default */
863 if (i >= ARRAY_SIZE(csi2_input_fmts))
864 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
865
866 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
867 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
868 break;
869
870 case CSI2_PAD_SOURCE:
871 /* Source format same as sink format, except for DPCM
872 * compression.
873 */
874 pixelcode = fmt->code;
875 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which);
876 memcpy(fmt, format, sizeof(*fmt));
877
878 /*
879 * Only Allow DPCM decompression, and check that the
880 * pattern is preserved
881 */
882 info = omap3isp_video_format_info(fmt->code);
883 if (info->uncompressed == pixelcode)
884 fmt->code = pixelcode;
885 break;
886 }
887
888 /* RGB, non-interlaced */
889 fmt->colorspace = V4L2_COLORSPACE_SRGB;
890 fmt->field = V4L2_FIELD_NONE;
891}
892
893/*
894 * csi2_enum_mbus_code - Handle pixel format enumeration
895 * @sd : pointer to v4l2 subdev structure
896 * @fh : V4L2 subdev file handle
897 * @code : pointer to v4l2_subdev_mbus_code_enum structure
898 * return -EINVAL or zero on success
899 */
900static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
901 struct v4l2_subdev_fh *fh,
902 struct v4l2_subdev_mbus_code_enum *code)
903{
904 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
905 struct v4l2_mbus_framefmt *format;
906 const struct isp_format_info *info;
907
908 if (code->pad == CSI2_PAD_SINK) {
909 if (code->index >= ARRAY_SIZE(csi2_input_fmts))
910 return -EINVAL;
911
912 code->code = csi2_input_fmts[code->index];
913 } else {
914 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK,
915 V4L2_SUBDEV_FORMAT_TRY);
916 switch (code->index) {
917 case 0:
918 /* Passthrough sink pad code */
919 code->code = format->code;
920 break;
921 case 1:
922 /* Uncompressed code */
923 info = omap3isp_video_format_info(format->code);
924 if (info->uncompressed == format->code)
925 return -EINVAL;
926
927 code->code = info->uncompressed;
928 break;
929 default:
930 return -EINVAL;
931 }
932 }
933
934 return 0;
935}
936
937static int csi2_enum_frame_size(struct v4l2_subdev *sd,
938 struct v4l2_subdev_fh *fh,
939 struct v4l2_subdev_frame_size_enum *fse)
940{
941 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
942 struct v4l2_mbus_framefmt format;
943
944 if (fse->index != 0)
945 return -EINVAL;
946
947 format.code = fse->code;
948 format.width = 1;
949 format.height = 1;
950 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
951 fse->min_width = format.width;
952 fse->min_height = format.height;
953
954 if (format.code != fse->code)
955 return -EINVAL;
956
957 format.code = fse->code;
958 format.width = -1;
959 format.height = -1;
960 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
961 fse->max_width = format.width;
962 fse->max_height = format.height;
963
964 return 0;
965}
966
967/*
968 * csi2_get_format - Handle get format by pads subdev method
969 * @sd : pointer to v4l2 subdev structure
970 * @fh : V4L2 subdev file handle
971 * @fmt: pointer to v4l2 subdev format structure
972 * return -EINVAL or zero on sucess
973 */
974static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
975 struct v4l2_subdev_format *fmt)
976{
977 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
978 struct v4l2_mbus_framefmt *format;
979
980 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
981 if (format == NULL)
982 return -EINVAL;
983
984 fmt->format = *format;
985 return 0;
986}
987
988/*
989 * csi2_set_format - Handle set format by pads subdev method
990 * @sd : pointer to v4l2 subdev structure
991 * @fh : V4L2 subdev file handle
992 * @fmt: pointer to v4l2 subdev format structure
993 * return -EINVAL or zero on success
994 */
995static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
996 struct v4l2_subdev_format *fmt)
997{
998 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
999 struct v4l2_mbus_framefmt *format;
1000
1001 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
1002 if (format == NULL)
1003 return -EINVAL;
1004
1005 csi2_try_format(csi2, fh, fmt->pad, &fmt->format, fmt->which);
1006 *format = fmt->format;
1007
1008 /* Propagate the format from sink to source */
1009 if (fmt->pad == CSI2_PAD_SINK) {
1010 format = __csi2_get_format(csi2, fh, CSI2_PAD_SOURCE,
1011 fmt->which);
1012 *format = fmt->format;
1013 csi2_try_format(csi2, fh, CSI2_PAD_SOURCE, format, fmt->which);
1014 }
1015
1016 return 0;
1017}
1018
1019/*
1020 * csi2_init_formats - Initialize formats on all pads
1021 * @sd: ISP CSI2 V4L2 subdevice
1022 * @fh: V4L2 subdev file handle
1023 *
1024 * Initialize all pad formats with default values. If fh is not NULL, try
1025 * formats are initialized on the file handle. Otherwise active formats are
1026 * initialized on the device.
1027 */
1028static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1029{
1030 struct v4l2_subdev_format format;
1031
1032 memset(&format, 0, sizeof(format));
1033 format.pad = CSI2_PAD_SINK;
1034 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1035 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1036 format.format.width = 4096;
1037 format.format.height = 4096;
1038 csi2_set_format(sd, fh, &format);
1039
1040 return 0;
1041}
1042
1043/*
1044 * csi2_set_stream - Enable/Disable streaming on the CSI2 module
1045 * @sd: ISP CSI2 V4L2 subdevice
1046 * @enable: ISP pipeline stream state
1047 *
1048 * Return 0 on success or a negative error code otherwise.
1049 */
1050static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
1051{
1052 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1053 struct isp_device *isp = csi2->isp;
1054 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
1055 struct isp_video *video_out = &csi2->video_out;
1056
1057 switch (enable) {
1058 case ISP_PIPELINE_STREAM_CONTINUOUS:
1059 if (omap3isp_csiphy_acquire(csi2->phy) < 0)
1060 return -ENODEV;
1061 csi2->use_fs_irq = pipe->do_propagation;
1062 if (csi2->output & CSI2_OUTPUT_MEMORY)
1063 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
1064 csi2_configure(csi2);
1065 csi2_print_status(csi2);
1066
1067 /*
1068 * When outputting to memory with no buffer available, let the
1069 * buffer queue handler start the hardware. A DMA queue flag
1070 * ISP_VIDEO_DMAQUEUE_QUEUED will be set as soon as there is
1071 * a buffer available.
1072 */
1073 if (csi2->output & CSI2_OUTPUT_MEMORY &&
1074 !(video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED))
1075 break;
1076 /* Enable context 0 and IRQs */
1077 atomic_set(&csi2->stopping, 0);
1078 csi2_ctx_enable(isp, csi2, 0, 1);
1079 csi2_if_enable(isp, csi2, 1);
1080 isp_video_dmaqueue_flags_clr(video_out);
1081 break;
1082
1083 case ISP_PIPELINE_STREAM_STOPPED:
1084 if (csi2->state == ISP_PIPELINE_STREAM_STOPPED)
1085 return 0;
1086 if (omap3isp_module_sync_idle(&sd->entity, &csi2->wait,
1087 &csi2->stopping))
1088 dev_dbg(isp->dev, "%s: module stop timeout.\n",
1089 sd->name);
1090 csi2_ctx_enable(isp, csi2, 0, 0);
1091 csi2_if_enable(isp, csi2, 0);
1092 csi2_irq_ctx_set(isp, csi2, 0);
1093 omap3isp_csiphy_release(csi2->phy);
1094 isp_video_dmaqueue_flags_clr(video_out);
1095 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
1096 break;
1097 }
1098
1099 csi2->state = enable;
1100 return 0;
1101}
1102
1103/* subdev video operations */
1104static const struct v4l2_subdev_video_ops csi2_video_ops = {
1105 .s_stream = csi2_set_stream,
1106};
1107
1108/* subdev pad operations */
1109static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
1110 .enum_mbus_code = csi2_enum_mbus_code,
1111 .enum_frame_size = csi2_enum_frame_size,
1112 .get_fmt = csi2_get_format,
1113 .set_fmt = csi2_set_format,
1114};
1115
1116/* subdev operations */
1117static const struct v4l2_subdev_ops csi2_ops = {
1118 .video = &csi2_video_ops,
1119 .pad = &csi2_pad_ops,
1120};
1121
1122/* subdev internal operations */
1123static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
1124 .open = csi2_init_formats,
1125};
1126
1127/* -----------------------------------------------------------------------------
1128 * Media entity operations
1129 */
1130
1131/*
1132 * csi2_link_setup - Setup CSI2 connections.
1133 * @entity : Pointer to media entity structure
1134 * @local : Pointer to local pad array
1135 * @remote : Pointer to remote pad array
1136 * @flags : Link flags
1137 * return -EINVAL or zero on success
1138 */
1139static int csi2_link_setup(struct media_entity *entity,
1140 const struct media_pad *local,
1141 const struct media_pad *remote, u32 flags)
1142{
1143 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1144 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1145 struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
1146
1147 /*
1148 * The ISP core doesn't support pipelines with multiple video outputs.
1149 * Revisit this when it will be implemented, and return -EBUSY for now.
1150 */
1151
1152 switch (local->index | media_entity_type(remote->entity)) {
1153 case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1154 if (flags & MEDIA_LNK_FL_ENABLED) {
1155 if (csi2->output & ~CSI2_OUTPUT_MEMORY)
1156 return -EBUSY;
1157 csi2->output |= CSI2_OUTPUT_MEMORY;
1158 } else {
1159 csi2->output &= ~CSI2_OUTPUT_MEMORY;
1160 }
1161 break;
1162
1163 case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1164 if (flags & MEDIA_LNK_FL_ENABLED) {
1165 if (csi2->output & ~CSI2_OUTPUT_CCDC)
1166 return -EBUSY;
1167 csi2->output |= CSI2_OUTPUT_CCDC;
1168 } else {
1169 csi2->output &= ~CSI2_OUTPUT_CCDC;
1170 }
1171 break;
1172
1173 default:
1174 /* Link from camera to CSI2 is fixed... */
1175 return -EINVAL;
1176 }
1177
1178 ctrl->vp_only_enable =
1179 (csi2->output & CSI2_OUTPUT_MEMORY) ? false : true;
1180 ctrl->vp_clk_enable = !!(csi2->output & CSI2_OUTPUT_CCDC);
1181
1182 return 0;
1183}
1184
1185/* media operations */
1186static const struct media_entity_operations csi2_media_ops = {
1187 .link_setup = csi2_link_setup,
1188};
1189
1190/*
1191 * csi2_init_entities - Initialize subdev and media entity.
1192 * @csi2: Pointer to csi2 structure.
1193 * return -ENOMEM or zero on success
1194 */
1195static int csi2_init_entities(struct isp_csi2_device *csi2)
1196{
1197 struct v4l2_subdev *sd = &csi2->subdev;
1198 struct media_pad *pads = csi2->pads;
1199 struct media_entity *me = &sd->entity;
1200 int ret;
1201
1202 v4l2_subdev_init(sd, &csi2_ops);
1203 sd->internal_ops = &csi2_internal_ops;
1204 strlcpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name));
1205
1206 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1207 v4l2_set_subdevdata(sd, csi2);
1208 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1209
1210 pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1211 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1212
1213 me->ops = &csi2_media_ops;
1214 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
1215 if (ret < 0)
1216 return ret;
1217
1218 csi2_init_formats(sd, NULL);
1219
1220 /* Video device node */
1221 csi2->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1222 csi2->video_out.ops = &csi2_ispvideo_ops;
1223 csi2->video_out.bpl_alignment = 32;
1224 csi2->video_out.bpl_zero_padding = 1;
1225 csi2->video_out.bpl_max = 0x1ffe0;
1226 csi2->video_out.isp = csi2->isp;
1227 csi2->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1228
1229 ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
1230 if (ret < 0)
1231 return ret;
1232
1233 /* Connect the CSI2 subdev to the video node. */
1234 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1235 &csi2->video_out.video.entity, 0, 0);
1236 if (ret < 0)
1237 return ret;
1238
1239 return 0;
1240}
1241
1242void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
1243{
1244 media_entity_cleanup(&csi2->subdev.entity);
1245
1246 v4l2_device_unregister_subdev(&csi2->subdev);
1247 omap3isp_video_unregister(&csi2->video_out);
1248}
1249
1250int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
1251 struct v4l2_device *vdev)
1252{
1253 int ret;
1254
1255 /* Register the subdev and video nodes. */
1256 ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
1257 if (ret < 0)
1258 goto error;
1259
1260 ret = omap3isp_video_register(&csi2->video_out, vdev);
1261 if (ret < 0)
1262 goto error;
1263
1264 return 0;
1265
1266error:
1267 omap3isp_csi2_unregister_entities(csi2);
1268 return ret;
1269}
1270
1271/* -----------------------------------------------------------------------------
1272 * ISP CSI2 initialisation and cleanup
1273 */
1274
1275/*
1276 * omap3isp_csi2_cleanup - Routine for module driver cleanup
1277 */
1278void omap3isp_csi2_cleanup(struct isp_device *isp)
1279{
1280}
1281
1282/*
1283 * omap3isp_csi2_init - Routine for module driver init
1284 */
1285int omap3isp_csi2_init(struct isp_device *isp)
1286{
1287 struct isp_csi2_device *csi2a = &isp->isp_csi2a;
1288 struct isp_csi2_device *csi2c = &isp->isp_csi2c;
1289 int ret;
1290
1291 csi2a->isp = isp;
1292 csi2a->available = 1;
1293 csi2a->regs1 = OMAP3_ISP_IOMEM_CSI2A_REGS1;
1294 csi2a->regs2 = OMAP3_ISP_IOMEM_CSI2A_REGS2;
1295 csi2a->phy = &isp->isp_csiphy2;
1296 csi2a->state = ISP_PIPELINE_STREAM_STOPPED;
1297 init_waitqueue_head(&csi2a->wait);
1298
1299 ret = csi2_init_entities(csi2a);
1300 if (ret < 0)
1301 goto fail;
1302
1303 if (isp->revision == ISP_REVISION_15_0) {
1304 csi2c->isp = isp;
1305 csi2c->available = 1;
1306 csi2c->regs1 = OMAP3_ISP_IOMEM_CSI2C_REGS1;
1307 csi2c->regs2 = OMAP3_ISP_IOMEM_CSI2C_REGS2;
1308 csi2c->phy = &isp->isp_csiphy1;
1309 csi2c->state = ISP_PIPELINE_STREAM_STOPPED;
1310 init_waitqueue_head(&csi2c->wait);
1311 }
1312
1313 return 0;
1314fail:
1315 omap3isp_csi2_cleanup(isp);
1316 return ret;
1317}
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/video/omap3isp/ispcsi2.h
new file mode 100644
index 000000000000..456fb7fb8a0f
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsi2.h
@@ -0,0 +1,166 @@
1/*
2 * ispcsi2.h
3 *
4 * TI OMAP3 ISP - CSI2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CSI2_H
28#define OMAP3_ISP_CSI2_H
29
30#include <linux/types.h>
31#include <linux/videodev2.h>
32
33struct isp_csiphy;
34
35/* This is not an exhaustive list */
36enum isp_csi2_pix_formats {
37 CSI2_PIX_FMT_OTHERS = 0,
38 CSI2_PIX_FMT_YUV422_8BIT = 0x1e,
39 CSI2_PIX_FMT_YUV422_8BIT_VP = 0x9e,
40 CSI2_PIX_FMT_RAW10_EXP16 = 0xab,
41 CSI2_PIX_FMT_RAW10_EXP16_VP = 0x12f,
42 CSI2_PIX_FMT_RAW8 = 0x2a,
43 CSI2_PIX_FMT_RAW8_DPCM10_EXP16 = 0x2aa,
44 CSI2_PIX_FMT_RAW8_DPCM10_VP = 0x32a,
45 CSI2_PIX_FMT_RAW8_VP = 0x12a,
46 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP = 0x340,
47 CSI2_USERDEF_8BIT_DATA1_DPCM10 = 0x2c0,
48 CSI2_USERDEF_8BIT_DATA1 = 0x40,
49};
50
51enum isp_csi2_irqevents {
52 OCP_ERR_IRQ = 0x4000,
53 SHORT_PACKET_IRQ = 0x2000,
54 ECC_CORRECTION_IRQ = 0x1000,
55 ECC_NO_CORRECTION_IRQ = 0x800,
56 COMPLEXIO2_ERR_IRQ = 0x400,
57 COMPLEXIO1_ERR_IRQ = 0x200,
58 FIFO_OVF_IRQ = 0x100,
59 CONTEXT7 = 0x80,
60 CONTEXT6 = 0x40,
61 CONTEXT5 = 0x20,
62 CONTEXT4 = 0x10,
63 CONTEXT3 = 0x8,
64 CONTEXT2 = 0x4,
65 CONTEXT1 = 0x2,
66 CONTEXT0 = 0x1,
67};
68
69enum isp_csi2_ctx_irqevents {
70 CTX_ECC_CORRECTION = 0x100,
71 CTX_LINE_NUMBER = 0x80,
72 CTX_FRAME_NUMBER = 0x40,
73 CTX_CS = 0x20,
74 CTX_LE = 0x8,
75 CTX_LS = 0x4,
76 CTX_FE = 0x2,
77 CTX_FS = 0x1,
78};
79
80enum isp_csi2_frame_mode {
81 ISP_CSI2_FRAME_IMMEDIATE,
82 ISP_CSI2_FRAME_AFTERFEC,
83};
84
85#define ISP_CSI2_MAX_CTX_NUM 7
86
87struct isp_csi2_ctx_cfg {
88 u8 ctxnum; /* context number 0 - 7 */
89 u8 dpcm_decompress;
90
91 /* Fields in CSI2_CTx_CTRL2 - locked by CSI2_CTx_CTRL1.CTX_EN */
92 u8 virtual_id;
93 u16 format_id; /* as in CSI2_CTx_CTRL2[9:0] */
94 u8 dpcm_predictor; /* 1: simple, 0: advanced */
95
96 /* Fields in CSI2_CTx_CTRL1/3 - Shadowed */
97 u16 alpha;
98 u16 data_offset;
99 u32 ping_addr;
100 u32 pong_addr;
101 u8 eof_enabled;
102 u8 eol_enabled;
103 u8 checksum_enabled;
104 u8 enabled;
105};
106
107struct isp_csi2_timing_cfg {
108 u8 ionum; /* IO1 or IO2 as in CSI2_TIMING */
109 unsigned force_rx_mode:1;
110 unsigned stop_state_16x:1;
111 unsigned stop_state_4x:1;
112 u16 stop_state_counter;
113};
114
115struct isp_csi2_ctrl_cfg {
116 bool vp_clk_enable;
117 bool vp_only_enable;
118 u8 vp_out_ctrl;
119 enum isp_csi2_frame_mode frame_mode;
120 bool ecc_enable;
121 bool if_enable;
122};
123
124#define CSI2_PAD_SINK 0
125#define CSI2_PAD_SOURCE 1
126#define CSI2_PADS_NUM 2
127
128#define CSI2_OUTPUT_CCDC (1 << 0)
129#define CSI2_OUTPUT_MEMORY (1 << 1)
130
131struct isp_csi2_device {
132 struct v4l2_subdev subdev;
133 struct media_pad pads[CSI2_PADS_NUM];
134 struct v4l2_mbus_framefmt formats[CSI2_PADS_NUM];
135
136 struct isp_video video_out;
137 struct isp_device *isp;
138
139 u8 available; /* Is the IP present on the silicon? */
140
141 /* mem resources - enums as defined in enum isp_mem_resources */
142 u8 regs1;
143 u8 regs2;
144
145 u32 output; /* output to CCDC, memory or both? */
146 bool dpcm_decompress;
147 unsigned int frame_skip;
148 bool use_fs_irq;
149
150 struct isp_csiphy *phy;
151 struct isp_csi2_ctx_cfg contexts[ISP_CSI2_MAX_CTX_NUM + 1];
152 struct isp_csi2_timing_cfg timing[2];
153 struct isp_csi2_ctrl_cfg ctrl;
154 enum isp_pipeline_stream_state state;
155 wait_queue_head_t wait;
156 atomic_t stopping;
157};
158
159int omap3isp_csi2_isr(struct isp_csi2_device *csi2);
160int omap3isp_csi2_reset(struct isp_csi2_device *csi2);
161int omap3isp_csi2_init(struct isp_device *isp);
162void omap3isp_csi2_cleanup(struct isp_device *isp);
163void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2);
164int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
165 struct v4l2_device *vdev);
166#endif /* OMAP3_ISP_CSI2_H */
diff --git a/drivers/media/video/omap3isp/ispcsiphy.c b/drivers/media/video/omap3isp/ispcsiphy.c
new file mode 100644
index 000000000000..5be37ce7d0c2
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsiphy.c
@@ -0,0 +1,247 @@
1/*
2 * ispcsiphy.c
3 *
4 * TI OMAP3 ISP - CSI PHY module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/delay.h>
28#include <linux/device.h>
29#include <linux/regulator/consumer.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispcsiphy.h"
34
35/*
36 * csiphy_lanes_config - Configuration of CSIPHY lanes.
37 *
38 * Updates HW configuration.
39 * Called with phy->mutex taken.
40 */
41static void csiphy_lanes_config(struct isp_csiphy *phy)
42{
43 unsigned int i;
44 u32 reg;
45
46 reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG);
47
48 for (i = 0; i < phy->num_data_lanes; i++) {
49 reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) |
50 ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1));
51 reg |= (phy->lanes.data[i].pol <<
52 ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1));
53 reg |= (phy->lanes.data[i].pos <<
54 ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1));
55 }
56
57 reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK |
58 ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK);
59 reg |= phy->lanes.clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT;
60 reg |= phy->lanes.clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT;
61
62 isp_reg_writel(phy->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG);
63}
64
65/*
66 * csiphy_power_autoswitch_enable
67 * @enable: Sets or clears the autoswitch function enable flag.
68 */
69static void csiphy_power_autoswitch_enable(struct isp_csiphy *phy, bool enable)
70{
71 isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
72 ISPCSI2_PHY_CFG_PWR_AUTO,
73 enable ? ISPCSI2_PHY_CFG_PWR_AUTO : 0);
74}
75
76/*
77 * csiphy_set_power
78 * @power: Power state to be set.
79 *
80 * Returns 0 if successful, or -EBUSY if the retry count is exceeded.
81 */
82static int csiphy_set_power(struct isp_csiphy *phy, u32 power)
83{
84 u32 reg;
85 u8 retry_count;
86
87 isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
88 ISPCSI2_PHY_CFG_PWR_CMD_MASK, power);
89
90 retry_count = 0;
91 do {
92 udelay(50);
93 reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG) &
94 ISPCSI2_PHY_CFG_PWR_STATUS_MASK;
95
96 if (reg != power >> 2)
97 retry_count++;
98
99 } while ((reg != power >> 2) && (retry_count < 100));
100
101 if (retry_count == 100) {
102 printk(KERN_ERR "CSI2 CIO set power failed!\n");
103 return -EBUSY;
104 }
105
106 return 0;
107}
108
109/*
110 * csiphy_dphy_config - Configure CSI2 D-PHY parameters.
111 *
112 * Called with phy->mutex taken.
113 */
114static void csiphy_dphy_config(struct isp_csiphy *phy)
115{
116 u32 reg;
117
118 /* Set up ISPCSIPHY_REG0 */
119 reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG0);
120
121 reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK |
122 ISPCSIPHY_REG0_THS_SETTLE_MASK);
123 reg |= phy->dphy.ths_term << ISPCSIPHY_REG0_THS_TERM_SHIFT;
124 reg |= phy->dphy.ths_settle << ISPCSIPHY_REG0_THS_SETTLE_SHIFT;
125
126 isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG0);
127
128 /* Set up ISPCSIPHY_REG1 */
129 reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG1);
130
131 reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK |
132 ISPCSIPHY_REG1_TCLK_MISS_MASK |
133 ISPCSIPHY_REG1_TCLK_SETTLE_MASK);
134 reg |= phy->dphy.tclk_term << ISPCSIPHY_REG1_TCLK_TERM_SHIFT;
135 reg |= phy->dphy.tclk_miss << ISPCSIPHY_REG1_TCLK_MISS_SHIFT;
136 reg |= phy->dphy.tclk_settle << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT;
137
138 isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
139}
140
141static int csiphy_config(struct isp_csiphy *phy,
142 struct isp_csiphy_dphy_cfg *dphy,
143 struct isp_csiphy_lanes_cfg *lanes)
144{
145 unsigned int used_lanes = 0;
146 unsigned int i;
147
148 /* Clock and data lanes verification */
149 for (i = 0; i < phy->num_data_lanes; i++) {
150 if (lanes->data[i].pol > 1 || lanes->data[i].pos > 3)
151 return -EINVAL;
152
153 if (used_lanes & (1 << lanes->data[i].pos))
154 return -EINVAL;
155
156 used_lanes |= 1 << lanes->data[i].pos;
157 }
158
159 if (lanes->clk.pol > 1 || lanes->clk.pos > 3)
160 return -EINVAL;
161
162 if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
163 return -EINVAL;
164
165 mutex_lock(&phy->mutex);
166 phy->dphy = *dphy;
167 phy->lanes = *lanes;
168 mutex_unlock(&phy->mutex);
169
170 return 0;
171}
172
173int omap3isp_csiphy_acquire(struct isp_csiphy *phy)
174{
175 int rval;
176
177 if (phy->vdd == NULL) {
178 dev_err(phy->isp->dev, "Power regulator for CSI PHY not "
179 "available\n");
180 return -ENODEV;
181 }
182
183 mutex_lock(&phy->mutex);
184
185 rval = regulator_enable(phy->vdd);
186 if (rval < 0)
187 goto done;
188
189 omap3isp_csi2_reset(phy->csi2);
190
191 csiphy_dphy_config(phy);
192 csiphy_lanes_config(phy);
193
194 rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON);
195 if (rval) {
196 regulator_disable(phy->vdd);
197 goto done;
198 }
199
200 csiphy_power_autoswitch_enable(phy, true);
201 phy->phy_in_use = 1;
202
203done:
204 mutex_unlock(&phy->mutex);
205 return rval;
206}
207
208void omap3isp_csiphy_release(struct isp_csiphy *phy)
209{
210 mutex_lock(&phy->mutex);
211 if (phy->phy_in_use) {
212 csiphy_power_autoswitch_enable(phy, false);
213 csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
214 regulator_disable(phy->vdd);
215 phy->phy_in_use = 0;
216 }
217 mutex_unlock(&phy->mutex);
218}
219
220/*
221 * omap3isp_csiphy_init - Initialize the CSI PHY frontends
222 */
223int omap3isp_csiphy_init(struct isp_device *isp)
224{
225 struct isp_csiphy *phy1 = &isp->isp_csiphy1;
226 struct isp_csiphy *phy2 = &isp->isp_csiphy2;
227
228 isp->platform_cb.csiphy_config = csiphy_config;
229
230 phy2->isp = isp;
231 phy2->csi2 = &isp->isp_csi2a;
232 phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES;
233 phy2->cfg_regs = OMAP3_ISP_IOMEM_CSI2A_REGS1;
234 phy2->phy_regs = OMAP3_ISP_IOMEM_CSIPHY2;
235 mutex_init(&phy2->mutex);
236
237 if (isp->revision == ISP_REVISION_15_0) {
238 phy1->isp = isp;
239 phy1->csi2 = &isp->isp_csi2c;
240 phy1->num_data_lanes = ISP_CSIPHY1_NUM_DATA_LANES;
241 phy1->cfg_regs = OMAP3_ISP_IOMEM_CSI2C_REGS1;
242 phy1->phy_regs = OMAP3_ISP_IOMEM_CSIPHY1;
243 mutex_init(&phy1->mutex);
244 }
245
246 return 0;
247}
diff --git a/drivers/media/video/omap3isp/ispcsiphy.h b/drivers/media/video/omap3isp/ispcsiphy.h
new file mode 100644
index 000000000000..9596dc6830a6
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsiphy.h
@@ -0,0 +1,74 @@
1/*
2 * ispcsiphy.h
3 *
4 * TI OMAP3 ISP - CSI PHY module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CSI_PHY_H
28#define OMAP3_ISP_CSI_PHY_H
29
30struct isp_csi2_device;
31struct regulator;
32
33struct csiphy_lane {
34 u8 pos;
35 u8 pol;
36};
37
38#define ISP_CSIPHY2_NUM_DATA_LANES 2
39#define ISP_CSIPHY1_NUM_DATA_LANES 1
40
41struct isp_csiphy_lanes_cfg {
42 struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
43 struct csiphy_lane clk;
44};
45
46struct isp_csiphy_dphy_cfg {
47 u8 ths_term;
48 u8 ths_settle;
49 u8 tclk_term;
50 unsigned tclk_miss:1;
51 u8 tclk_settle;
52};
53
54struct isp_csiphy {
55 struct isp_device *isp;
56 struct mutex mutex; /* serialize csiphy configuration */
57 u8 phy_in_use;
58 struct isp_csi2_device *csi2;
59 struct regulator *vdd;
60
61 /* mem resources - enums as defined in enum isp_mem_resources */
62 unsigned int cfg_regs;
63 unsigned int phy_regs;
64
65 u8 num_data_lanes; /* number of CSI2 Data Lanes supported */
66 struct isp_csiphy_lanes_cfg lanes;
67 struct isp_csiphy_dphy_cfg dphy;
68};
69
70int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
71void omap3isp_csiphy_release(struct isp_csiphy *phy);
72int omap3isp_csiphy_init(struct isp_device *isp);
73
74#endif /* OMAP3_ISP_CSI_PHY_H */
diff --git a/drivers/media/video/omap3isp/isph3a.h b/drivers/media/video/omap3isp/isph3a.h
new file mode 100644
index 000000000000..fb09fd4ca755
--- /dev/null
+++ b/drivers/media/video/omap3isp/isph3a.h
@@ -0,0 +1,117 @@
1/*
2 * isph3a.h
3 *
4 * TI OMAP3 ISP - H3A AF module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_H3A_H
29#define OMAP3_ISP_H3A_H
30
31#include <linux/omap3isp.h>
32
33/*
34 * ----------
35 * -H3A AEWB-
36 * ----------
37 */
38
39#define AEWB_PACKET_SIZE 16
40#define AEWB_SATURATION_LIMIT 0x3ff
41
42/* Flags for changed registers */
43#define PCR_CHNG (1 << 0)
44#define AEWWIN1_CHNG (1 << 1)
45#define AEWINSTART_CHNG (1 << 2)
46#define AEWINBLK_CHNG (1 << 3)
47#define AEWSUBWIN_CHNG (1 << 4)
48#define PRV_WBDGAIN_CHNG (1 << 5)
49#define PRV_WBGAIN_CHNG (1 << 6)
50
51/* ISPH3A REGISTERS bits */
52#define ISPH3A_PCR_AF_EN (1 << 0)
53#define ISPH3A_PCR_AF_ALAW_EN (1 << 1)
54#define ISPH3A_PCR_AF_MED_EN (1 << 2)
55#define ISPH3A_PCR_AF_BUSY (1 << 15)
56#define ISPH3A_PCR_AEW_EN (1 << 16)
57#define ISPH3A_PCR_AEW_ALAW_EN (1 << 17)
58#define ISPH3A_PCR_AEW_BUSY (1 << 18)
59#define ISPH3A_PCR_AEW_MASK (ISPH3A_PCR_AEW_ALAW_EN | \
60 ISPH3A_PCR_AEW_AVE2LMT_MASK)
61
62/*
63 * --------
64 * -H3A AF-
65 * --------
66 */
67
68/* Peripheral Revision */
69#define AFPID 0x0
70
71#define AFCOEF_OFFSET 0x00000004 /* COEF base address */
72
73/* PCR fields */
74#define AF_BUSYAF (1 << 15)
75#define AF_FVMODE (1 << 14)
76#define AF_RGBPOS (0x7 << 11)
77#define AF_MED_TH (0xFF << 3)
78#define AF_MED_EN (1 << 2)
79#define AF_ALAW_EN (1 << 1)
80#define AF_EN (1 << 0)
81#define AF_PCR_MASK (AF_FVMODE | AF_RGBPOS | AF_MED_TH | \
82 AF_MED_EN | AF_ALAW_EN)
83
84/* AFPAX1 fields */
85#define AF_PAXW (0x7F << 16)
86#define AF_PAXH 0x7F
87
88/* AFPAX2 fields */
89#define AF_AFINCV (0xF << 13)
90#define AF_PAXVC (0x7F << 6)
91#define AF_PAXHC 0x3F
92
93/* AFPAXSTART fields */
94#define AF_PAXSH (0xFFF<<16)
95#define AF_PAXSV 0xFFF
96
97/* COEFFICIENT MASK */
98#define AF_COEF_MASK0 0xFFF
99#define AF_COEF_MASK1 (0xFFF<<16)
100
101/* BIT SHIFTS */
102#define AF_RGBPOS_SHIFT 11
103#define AF_MED_TH_SHIFT 3
104#define AF_PAXW_SHIFT 16
105#define AF_LINE_INCR_SHIFT 13
106#define AF_VT_COUNT_SHIFT 6
107#define AF_HZ_START_SHIFT 16
108#define AF_COEF_SHIFT 16
109
110/* Init and cleanup functions */
111int omap3isp_h3a_aewb_init(struct isp_device *isp);
112int omap3isp_h3a_af_init(struct isp_device *isp);
113
114void omap3isp_h3a_aewb_cleanup(struct isp_device *isp);
115void omap3isp_h3a_af_cleanup(struct isp_device *isp);
116
117#endif /* OMAP3_ISP_H3A_H */
diff --git a/drivers/media/video/omap3isp/isph3a_aewb.c b/drivers/media/video/omap3isp/isph3a_aewb.c
new file mode 100644
index 000000000000..8068cefd8d89
--- /dev/null
+++ b/drivers/media/video/omap3isp/isph3a_aewb.c
@@ -0,0 +1,374 @@
1/*
2 * isph3a.c
3 *
4 * TI OMAP3 ISP - H3A module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/slab.h>
29#include <linux/uaccess.h>
30
31#include "isp.h"
32#include "isph3a.h"
33#include "ispstat.h"
34
35/*
36 * h3a_aewb_update_regs - Helper function to update h3a registers.
37 */
38static void h3a_aewb_setup_regs(struct ispstat *aewb, void *priv)
39{
40 struct omap3isp_h3a_aewb_config *conf = priv;
41 u32 pcr;
42 u32 win1;
43 u32 start;
44 u32 blk;
45 u32 subwin;
46
47 if (aewb->state == ISPSTAT_DISABLED)
48 return;
49
50 isp_reg_writel(aewb->isp, aewb->active_buf->iommu_addr,
51 OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST);
52
53 if (!aewb->update)
54 return;
55
56 /* Converting config metadata into reg values */
57 pcr = conf->saturation_limit << ISPH3A_PCR_AEW_AVE2LMT_SHIFT;
58 pcr |= !!conf->alaw_enable << ISPH3A_PCR_AEW_ALAW_EN_SHIFT;
59
60 win1 = ((conf->win_height >> 1) - 1) << ISPH3A_AEWWIN1_WINH_SHIFT;
61 win1 |= ((conf->win_width >> 1) - 1) << ISPH3A_AEWWIN1_WINW_SHIFT;
62 win1 |= (conf->ver_win_count - 1) << ISPH3A_AEWWIN1_WINVC_SHIFT;
63 win1 |= (conf->hor_win_count - 1) << ISPH3A_AEWWIN1_WINHC_SHIFT;
64
65 start = conf->hor_win_start << ISPH3A_AEWINSTART_WINSH_SHIFT;
66 start |= conf->ver_win_start << ISPH3A_AEWINSTART_WINSV_SHIFT;
67
68 blk = conf->blk_ver_win_start << ISPH3A_AEWINBLK_WINSV_SHIFT;
69 blk |= ((conf->blk_win_height >> 1) - 1) << ISPH3A_AEWINBLK_WINH_SHIFT;
70
71 subwin = ((conf->subsample_ver_inc >> 1) - 1) <<
72 ISPH3A_AEWSUBWIN_AEWINCV_SHIFT;
73 subwin |= ((conf->subsample_hor_inc >> 1) - 1) <<
74 ISPH3A_AEWSUBWIN_AEWINCH_SHIFT;
75
76 isp_reg_writel(aewb->isp, win1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1);
77 isp_reg_writel(aewb->isp, start, OMAP3_ISP_IOMEM_H3A,
78 ISPH3A_AEWINSTART);
79 isp_reg_writel(aewb->isp, blk, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK);
80 isp_reg_writel(aewb->isp, subwin, OMAP3_ISP_IOMEM_H3A,
81 ISPH3A_AEWSUBWIN);
82 isp_reg_clr_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
83 ISPH3A_PCR_AEW_MASK, pcr);
84
85 aewb->update = 0;
86 aewb->config_counter += aewb->inc_config;
87 aewb->inc_config = 0;
88 aewb->buf_size = conf->buf_size;
89}
90
91static void h3a_aewb_enable(struct ispstat *aewb, int enable)
92{
93 if (enable) {
94 isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
95 ISPH3A_PCR_AEW_EN);
96 /* This bit is already set if AF is enabled */
97 if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
98 isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
99 ISPCTRL_H3A_CLK_EN);
100 } else {
101 isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
102 ISPH3A_PCR_AEW_EN);
103 /* This bit can't be cleared if AF is enabled */
104 if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
105 isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
106 ISPCTRL_H3A_CLK_EN);
107 }
108}
109
110static int h3a_aewb_busy(struct ispstat *aewb)
111{
112 return isp_reg_readl(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
113 & ISPH3A_PCR_BUSYAEAWB;
114}
115
116static u32 h3a_aewb_get_buf_size(struct omap3isp_h3a_aewb_config *conf)
117{
118 /* Number of configured windows + extra row for black data */
119 u32 win_count = (conf->ver_win_count + 1) * conf->hor_win_count;
120
121 /*
122 * Unsaturated block counts for each 8 windows.
123 * 1 extra for the last (win_count % 8) windows if win_count is not
124 * divisible by 8.
125 */
126 win_count += (win_count + 7) / 8;
127
128 return win_count * AEWB_PACKET_SIZE;
129}
130
131static int h3a_aewb_validate_params(struct ispstat *aewb, void *new_conf)
132{
133 struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
134 u32 buf_size;
135
136 if (unlikely(user_cfg->saturation_limit >
137 OMAP3ISP_AEWB_MAX_SATURATION_LIM))
138 return -EINVAL;
139
140 if (unlikely(user_cfg->win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
141 user_cfg->win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
142 user_cfg->win_height & 0x01))
143 return -EINVAL;
144
145 if (unlikely(user_cfg->win_width < OMAP3ISP_AEWB_MIN_WIN_W ||
146 user_cfg->win_width > OMAP3ISP_AEWB_MAX_WIN_W ||
147 user_cfg->win_width & 0x01))
148 return -EINVAL;
149
150 if (unlikely(user_cfg->ver_win_count < OMAP3ISP_AEWB_MIN_WINVC ||
151 user_cfg->ver_win_count > OMAP3ISP_AEWB_MAX_WINVC))
152 return -EINVAL;
153
154 if (unlikely(user_cfg->hor_win_count < OMAP3ISP_AEWB_MIN_WINHC ||
155 user_cfg->hor_win_count > OMAP3ISP_AEWB_MAX_WINHC))
156 return -EINVAL;
157
158 if (unlikely(user_cfg->ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
159 return -EINVAL;
160
161 if (unlikely(user_cfg->hor_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
162 return -EINVAL;
163
164 if (unlikely(user_cfg->blk_ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
165 return -EINVAL;
166
167 if (unlikely(user_cfg->blk_win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
168 user_cfg->blk_win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
169 user_cfg->blk_win_height & 0x01))
170 return -EINVAL;
171
172 if (unlikely(user_cfg->subsample_ver_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
173 user_cfg->subsample_ver_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
174 user_cfg->subsample_ver_inc & 0x01))
175 return -EINVAL;
176
177 if (unlikely(user_cfg->subsample_hor_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
178 user_cfg->subsample_hor_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
179 user_cfg->subsample_hor_inc & 0x01))
180 return -EINVAL;
181
182 buf_size = h3a_aewb_get_buf_size(user_cfg);
183 if (buf_size > user_cfg->buf_size)
184 user_cfg->buf_size = buf_size;
185 else if (user_cfg->buf_size > OMAP3ISP_AEWB_MAX_BUF_SIZE)
186 user_cfg->buf_size = OMAP3ISP_AEWB_MAX_BUF_SIZE;
187
188 return 0;
189}
190
191/*
192 * h3a_aewb_set_params - Helper function to check & store user given params.
193 * @new_conf: Pointer to AE and AWB parameters struct.
194 *
195 * As most of them are busy-lock registers, need to wait until AEW_BUSY = 0 to
196 * program them during ISR.
197 */
198static void h3a_aewb_set_params(struct ispstat *aewb, void *new_conf)
199{
200 struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
201 struct omap3isp_h3a_aewb_config *cur_cfg = aewb->priv;
202 int update = 0;
203
204 if (cur_cfg->saturation_limit != user_cfg->saturation_limit) {
205 cur_cfg->saturation_limit = user_cfg->saturation_limit;
206 update = 1;
207 }
208 if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
209 cur_cfg->alaw_enable = user_cfg->alaw_enable;
210 update = 1;
211 }
212 if (cur_cfg->win_height != user_cfg->win_height) {
213 cur_cfg->win_height = user_cfg->win_height;
214 update = 1;
215 }
216 if (cur_cfg->win_width != user_cfg->win_width) {
217 cur_cfg->win_width = user_cfg->win_width;
218 update = 1;
219 }
220 if (cur_cfg->ver_win_count != user_cfg->ver_win_count) {
221 cur_cfg->ver_win_count = user_cfg->ver_win_count;
222 update = 1;
223 }
224 if (cur_cfg->hor_win_count != user_cfg->hor_win_count) {
225 cur_cfg->hor_win_count = user_cfg->hor_win_count;
226 update = 1;
227 }
228 if (cur_cfg->ver_win_start != user_cfg->ver_win_start) {
229 cur_cfg->ver_win_start = user_cfg->ver_win_start;
230 update = 1;
231 }
232 if (cur_cfg->hor_win_start != user_cfg->hor_win_start) {
233 cur_cfg->hor_win_start = user_cfg->hor_win_start;
234 update = 1;
235 }
236 if (cur_cfg->blk_ver_win_start != user_cfg->blk_ver_win_start) {
237 cur_cfg->blk_ver_win_start = user_cfg->blk_ver_win_start;
238 update = 1;
239 }
240 if (cur_cfg->blk_win_height != user_cfg->blk_win_height) {
241 cur_cfg->blk_win_height = user_cfg->blk_win_height;
242 update = 1;
243 }
244 if (cur_cfg->subsample_ver_inc != user_cfg->subsample_ver_inc) {
245 cur_cfg->subsample_ver_inc = user_cfg->subsample_ver_inc;
246 update = 1;
247 }
248 if (cur_cfg->subsample_hor_inc != user_cfg->subsample_hor_inc) {
249 cur_cfg->subsample_hor_inc = user_cfg->subsample_hor_inc;
250 update = 1;
251 }
252
253 if (update || !aewb->configured) {
254 aewb->inc_config++;
255 aewb->update = 1;
256 cur_cfg->buf_size = h3a_aewb_get_buf_size(cur_cfg);
257 }
258}
259
260static long h3a_aewb_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
261{
262 struct ispstat *stat = v4l2_get_subdevdata(sd);
263
264 switch (cmd) {
265 case VIDIOC_OMAP3ISP_AEWB_CFG:
266 return omap3isp_stat_config(stat, arg);
267 case VIDIOC_OMAP3ISP_STAT_REQ:
268 return omap3isp_stat_request_statistics(stat, arg);
269 case VIDIOC_OMAP3ISP_STAT_EN: {
270 unsigned long *en = arg;
271 return omap3isp_stat_enable(stat, !!*en);
272 }
273 }
274
275 return -ENOIOCTLCMD;
276}
277
278static const struct ispstat_ops h3a_aewb_ops = {
279 .validate_params = h3a_aewb_validate_params,
280 .set_params = h3a_aewb_set_params,
281 .setup_regs = h3a_aewb_setup_regs,
282 .enable = h3a_aewb_enable,
283 .busy = h3a_aewb_busy,
284};
285
286static const struct v4l2_subdev_core_ops h3a_aewb_subdev_core_ops = {
287 .ioctl = h3a_aewb_ioctl,
288 .subscribe_event = omap3isp_stat_subscribe_event,
289 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
290};
291
292static const struct v4l2_subdev_video_ops h3a_aewb_subdev_video_ops = {
293 .s_stream = omap3isp_stat_s_stream,
294};
295
296static const struct v4l2_subdev_ops h3a_aewb_subdev_ops = {
297 .core = &h3a_aewb_subdev_core_ops,
298 .video = &h3a_aewb_subdev_video_ops,
299};
300
301/*
302 * omap3isp_h3a_aewb_init - Module Initialisation.
303 */
304int omap3isp_h3a_aewb_init(struct isp_device *isp)
305{
306 struct ispstat *aewb = &isp->isp_aewb;
307 struct omap3isp_h3a_aewb_config *aewb_cfg;
308 struct omap3isp_h3a_aewb_config *aewb_recover_cfg;
309 int ret;
310
311 aewb_cfg = kzalloc(sizeof(*aewb_cfg), GFP_KERNEL);
312 if (!aewb_cfg)
313 return -ENOMEM;
314
315 memset(aewb, 0, sizeof(*aewb));
316 aewb->ops = &h3a_aewb_ops;
317 aewb->priv = aewb_cfg;
318 aewb->dma_ch = -1;
319 aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB;
320 aewb->isp = isp;
321
322 /* Set recover state configuration */
323 aewb_recover_cfg = kzalloc(sizeof(*aewb_recover_cfg), GFP_KERNEL);
324 if (!aewb_recover_cfg) {
325 dev_err(aewb->isp->dev, "AEWB: cannot allocate memory for "
326 "recover configuration.\n");
327 ret = -ENOMEM;
328 goto err_recover_alloc;
329 }
330
331 aewb_recover_cfg->saturation_limit = OMAP3ISP_AEWB_MAX_SATURATION_LIM;
332 aewb_recover_cfg->win_height = OMAP3ISP_AEWB_MIN_WIN_H;
333 aewb_recover_cfg->win_width = OMAP3ISP_AEWB_MIN_WIN_W;
334 aewb_recover_cfg->ver_win_count = OMAP3ISP_AEWB_MIN_WINVC;
335 aewb_recover_cfg->hor_win_count = OMAP3ISP_AEWB_MIN_WINHC;
336 aewb_recover_cfg->blk_ver_win_start = aewb_recover_cfg->ver_win_start +
337 aewb_recover_cfg->win_height * aewb_recover_cfg->ver_win_count;
338 aewb_recover_cfg->blk_win_height = OMAP3ISP_AEWB_MIN_WIN_H;
339 aewb_recover_cfg->subsample_ver_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
340 aewb_recover_cfg->subsample_hor_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
341
342 if (h3a_aewb_validate_params(aewb, aewb_recover_cfg)) {
343 dev_err(aewb->isp->dev, "AEWB: recover configuration is "
344 "invalid.\n");
345 ret = -EINVAL;
346 goto err_conf;
347 }
348
349 aewb_recover_cfg->buf_size = h3a_aewb_get_buf_size(aewb_recover_cfg);
350 aewb->recover_priv = aewb_recover_cfg;
351
352 ret = omap3isp_stat_init(aewb, "AEWB", &h3a_aewb_subdev_ops);
353 if (ret)
354 goto err_conf;
355
356 return 0;
357
358err_conf:
359 kfree(aewb_recover_cfg);
360err_recover_alloc:
361 kfree(aewb_cfg);
362
363 return ret;
364}
365
366/*
367 * omap3isp_h3a_aewb_cleanup - Module exit.
368 */
369void omap3isp_h3a_aewb_cleanup(struct isp_device *isp)
370{
371 kfree(isp->isp_aewb.priv);
372 kfree(isp->isp_aewb.recover_priv);
373 omap3isp_stat_free(&isp->isp_aewb);
374}
diff --git a/drivers/media/video/omap3isp/isph3a_af.c b/drivers/media/video/omap3isp/isph3a_af.c
new file mode 100644
index 000000000000..ba54d0acdecf
--- /dev/null
+++ b/drivers/media/video/omap3isp/isph3a_af.c
@@ -0,0 +1,429 @@
1/*
2 * isph3a_af.c
3 *
4 * TI OMAP3 ISP - H3A AF module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28/* Linux specific include files */
29#include <linux/device.h>
30#include <linux/slab.h>
31
32#include "isp.h"
33#include "isph3a.h"
34#include "ispstat.h"
35
36#define IS_OUT_OF_BOUNDS(value, min, max) \
37 (((value) < (min)) || ((value) > (max)))
38
39static void h3a_af_setup_regs(struct ispstat *af, void *priv)
40{
41 struct omap3isp_h3a_af_config *conf = priv;
42 u32 pcr;
43 u32 pax1;
44 u32 pax2;
45 u32 paxstart;
46 u32 coef;
47 u32 base_coef_set0;
48 u32 base_coef_set1;
49 int index;
50
51 if (af->state == ISPSTAT_DISABLED)
52 return;
53
54 isp_reg_writel(af->isp, af->active_buf->iommu_addr, OMAP3_ISP_IOMEM_H3A,
55 ISPH3A_AFBUFST);
56
57 if (!af->update)
58 return;
59
60 /* Configure Hardware Registers */
61 pax1 = ((conf->paxel.width >> 1) - 1) << AF_PAXW_SHIFT;
62 /* Set height in AFPAX1 */
63 pax1 |= (conf->paxel.height >> 1) - 1;
64 isp_reg_writel(af->isp, pax1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1);
65
66 /* Configure AFPAX2 Register */
67 /* Set Line Increment in AFPAX2 Register */
68 pax2 = ((conf->paxel.line_inc >> 1) - 1) << AF_LINE_INCR_SHIFT;
69 /* Set Vertical Count */
70 pax2 |= (conf->paxel.v_cnt - 1) << AF_VT_COUNT_SHIFT;
71 /* Set Horizontal Count */
72 pax2 |= (conf->paxel.h_cnt - 1);
73 isp_reg_writel(af->isp, pax2, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2);
74
75 /* Configure PAXSTART Register */
76 /*Configure Horizontal Start */
77 paxstart = conf->paxel.h_start << AF_HZ_START_SHIFT;
78 /* Configure Vertical Start */
79 paxstart |= conf->paxel.v_start;
80 isp_reg_writel(af->isp, paxstart, OMAP3_ISP_IOMEM_H3A,
81 ISPH3A_AFPAXSTART);
82
83 /*SetIIRSH Register */
84 isp_reg_writel(af->isp, conf->iir.h_start,
85 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFIIRSH);
86
87 base_coef_set0 = ISPH3A_AFCOEF010;
88 base_coef_set1 = ISPH3A_AFCOEF110;
89 for (index = 0; index <= 8; index += 2) {
90 /*Set IIR Filter0 Coefficients */
91 coef = 0;
92 coef |= conf->iir.coeff_set0[index];
93 coef |= conf->iir.coeff_set0[index + 1] <<
94 AF_COEF_SHIFT;
95 isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
96 base_coef_set0);
97 base_coef_set0 += AFCOEF_OFFSET;
98
99 /*Set IIR Filter1 Coefficients */
100 coef = 0;
101 coef |= conf->iir.coeff_set1[index];
102 coef |= conf->iir.coeff_set1[index + 1] <<
103 AF_COEF_SHIFT;
104 isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
105 base_coef_set1);
106 base_coef_set1 += AFCOEF_OFFSET;
107 }
108 /* set AFCOEF0010 Register */
109 isp_reg_writel(af->isp, conf->iir.coeff_set0[10],
110 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF0010);
111 /* set AFCOEF1010 Register */
112 isp_reg_writel(af->isp, conf->iir.coeff_set1[10],
113 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF1010);
114
115 /* PCR Register */
116 /* Set RGB Position */
117 pcr = conf->rgb_pos << AF_RGBPOS_SHIFT;
118 /* Set Accumulator Mode */
119 if (conf->fvmode == OMAP3ISP_AF_MODE_PEAK)
120 pcr |= AF_FVMODE;
121 /* Set A-law */
122 if (conf->alaw_enable)
123 pcr |= AF_ALAW_EN;
124 /* HMF Configurations */
125 if (conf->hmf.enable) {
126 /* Enable HMF */
127 pcr |= AF_MED_EN;
128 /* Set Median Threshold */
129 pcr |= conf->hmf.threshold << AF_MED_TH_SHIFT;
130 }
131 /* Set PCR Register */
132 isp_reg_clr_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
133 AF_PCR_MASK, pcr);
134
135 af->update = 0;
136 af->config_counter += af->inc_config;
137 af->inc_config = 0;
138 af->buf_size = conf->buf_size;
139}
140
141static void h3a_af_enable(struct ispstat *af, int enable)
142{
143 if (enable) {
144 isp_reg_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
145 ISPH3A_PCR_AF_EN);
146 /* This bit is already set if AEWB is enabled */
147 if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
148 isp_reg_set(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
149 ISPCTRL_H3A_CLK_EN);
150 } else {
151 isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
152 ISPH3A_PCR_AF_EN);
153 /* This bit can't be cleared if AEWB is enabled */
154 if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
155 isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
156 ISPCTRL_H3A_CLK_EN);
157 }
158}
159
160static int h3a_af_busy(struct ispstat *af)
161{
162 return isp_reg_readl(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
163 & ISPH3A_PCR_BUSYAF;
164}
165
166static u32 h3a_af_get_buf_size(struct omap3isp_h3a_af_config *conf)
167{
168 return conf->paxel.h_cnt * conf->paxel.v_cnt * OMAP3ISP_AF_PAXEL_SIZE;
169}
170
171/* Function to check paxel parameters */
172static int h3a_af_validate_params(struct ispstat *af, void *new_conf)
173{
174 struct omap3isp_h3a_af_config *user_cfg = new_conf;
175 struct omap3isp_h3a_af_paxel *paxel_cfg = &user_cfg->paxel;
176 struct omap3isp_h3a_af_iir *iir_cfg = &user_cfg->iir;
177 int index;
178 u32 buf_size;
179
180 /* Check horizontal Count */
181 if (IS_OUT_OF_BOUNDS(paxel_cfg->h_cnt,
182 OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN,
183 OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MAX))
184 return -EINVAL;
185
186 /* Check Vertical Count */
187 if (IS_OUT_OF_BOUNDS(paxel_cfg->v_cnt,
188 OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN,
189 OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MAX))
190 return -EINVAL;
191
192 if (IS_OUT_OF_BOUNDS(paxel_cfg->height, OMAP3ISP_AF_PAXEL_HEIGHT_MIN,
193 OMAP3ISP_AF_PAXEL_HEIGHT_MAX) ||
194 paxel_cfg->height % 2)
195 return -EINVAL;
196
197 /* Check width */
198 if (IS_OUT_OF_BOUNDS(paxel_cfg->width, OMAP3ISP_AF_PAXEL_WIDTH_MIN,
199 OMAP3ISP_AF_PAXEL_WIDTH_MAX) ||
200 paxel_cfg->width % 2)
201 return -EINVAL;
202
203 /* Check Line Increment */
204 if (IS_OUT_OF_BOUNDS(paxel_cfg->line_inc,
205 OMAP3ISP_AF_PAXEL_INCREMENT_MIN,
206 OMAP3ISP_AF_PAXEL_INCREMENT_MAX) ||
207 paxel_cfg->line_inc % 2)
208 return -EINVAL;
209
210 /* Check Horizontal Start */
211 if ((paxel_cfg->h_start < iir_cfg->h_start) ||
212 IS_OUT_OF_BOUNDS(paxel_cfg->h_start,
213 OMAP3ISP_AF_PAXEL_HZSTART_MIN,
214 OMAP3ISP_AF_PAXEL_HZSTART_MAX))
215 return -EINVAL;
216
217 /* Check IIR */
218 for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
219 if ((iir_cfg->coeff_set0[index]) > OMAP3ISP_AF_COEF_MAX)
220 return -EINVAL;
221
222 if ((iir_cfg->coeff_set1[index]) > OMAP3ISP_AF_COEF_MAX)
223 return -EINVAL;
224 }
225
226 if (IS_OUT_OF_BOUNDS(iir_cfg->h_start, OMAP3ISP_AF_IIRSH_MIN,
227 OMAP3ISP_AF_IIRSH_MAX))
228 return -EINVAL;
229
230 /* Hack: If paxel size is 12, the 10th AF window may be corrupted */
231 if ((paxel_cfg->h_cnt * paxel_cfg->v_cnt > 9) &&
232 (paxel_cfg->width * paxel_cfg->height == 12))
233 return -EINVAL;
234
235 buf_size = h3a_af_get_buf_size(user_cfg);
236 if (buf_size > user_cfg->buf_size)
237 /* User buf_size request wasn't enough */
238 user_cfg->buf_size = buf_size;
239 else if (user_cfg->buf_size > OMAP3ISP_AF_MAX_BUF_SIZE)
240 user_cfg->buf_size = OMAP3ISP_AF_MAX_BUF_SIZE;
241
242 return 0;
243}
244
245/* Update local parameters */
246static void h3a_af_set_params(struct ispstat *af, void *new_conf)
247{
248 struct omap3isp_h3a_af_config *user_cfg = new_conf;
249 struct omap3isp_h3a_af_config *cur_cfg = af->priv;
250 int update = 0;
251 int index;
252
253 /* alaw */
254 if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
255 update = 1;
256 goto out;
257 }
258
259 /* hmf */
260 if (cur_cfg->hmf.enable != user_cfg->hmf.enable) {
261 update = 1;
262 goto out;
263 }
264 if (cur_cfg->hmf.threshold != user_cfg->hmf.threshold) {
265 update = 1;
266 goto out;
267 }
268
269 /* rgbpos */
270 if (cur_cfg->rgb_pos != user_cfg->rgb_pos) {
271 update = 1;
272 goto out;
273 }
274
275 /* iir */
276 if (cur_cfg->iir.h_start != user_cfg->iir.h_start) {
277 update = 1;
278 goto out;
279 }
280 for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
281 if (cur_cfg->iir.coeff_set0[index] !=
282 user_cfg->iir.coeff_set0[index]) {
283 update = 1;
284 goto out;
285 }
286 if (cur_cfg->iir.coeff_set1[index] !=
287 user_cfg->iir.coeff_set1[index]) {
288 update = 1;
289 goto out;
290 }
291 }
292
293 /* paxel */
294 if ((cur_cfg->paxel.width != user_cfg->paxel.width) ||
295 (cur_cfg->paxel.height != user_cfg->paxel.height) ||
296 (cur_cfg->paxel.h_start != user_cfg->paxel.h_start) ||
297 (cur_cfg->paxel.v_start != user_cfg->paxel.v_start) ||
298 (cur_cfg->paxel.h_cnt != user_cfg->paxel.h_cnt) ||
299 (cur_cfg->paxel.v_cnt != user_cfg->paxel.v_cnt) ||
300 (cur_cfg->paxel.line_inc != user_cfg->paxel.line_inc)) {
301 update = 1;
302 goto out;
303 }
304
305 /* af_mode */
306 if (cur_cfg->fvmode != user_cfg->fvmode)
307 update = 1;
308
309out:
310 if (update || !af->configured) {
311 memcpy(cur_cfg, user_cfg, sizeof(*cur_cfg));
312 af->inc_config++;
313 af->update = 1;
314 /*
315 * User might be asked for a bigger buffer than necessary for
316 * this configuration. In order to return the right amount of
317 * data during buffer request, let's calculate the size here
318 * instead of stick with user_cfg->buf_size.
319 */
320 cur_cfg->buf_size = h3a_af_get_buf_size(cur_cfg);
321 }
322}
323
324static long h3a_af_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
325{
326 struct ispstat *stat = v4l2_get_subdevdata(sd);
327
328 switch (cmd) {
329 case VIDIOC_OMAP3ISP_AF_CFG:
330 return omap3isp_stat_config(stat, arg);
331 case VIDIOC_OMAP3ISP_STAT_REQ:
332 return omap3isp_stat_request_statistics(stat, arg);
333 case VIDIOC_OMAP3ISP_STAT_EN: {
334 int *en = arg;
335 return omap3isp_stat_enable(stat, !!*en);
336 }
337 }
338
339 return -ENOIOCTLCMD;
340
341}
342
343static const struct ispstat_ops h3a_af_ops = {
344 .validate_params = h3a_af_validate_params,
345 .set_params = h3a_af_set_params,
346 .setup_regs = h3a_af_setup_regs,
347 .enable = h3a_af_enable,
348 .busy = h3a_af_busy,
349};
350
351static const struct v4l2_subdev_core_ops h3a_af_subdev_core_ops = {
352 .ioctl = h3a_af_ioctl,
353 .subscribe_event = omap3isp_stat_subscribe_event,
354 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
355};
356
357static const struct v4l2_subdev_video_ops h3a_af_subdev_video_ops = {
358 .s_stream = omap3isp_stat_s_stream,
359};
360
361static const struct v4l2_subdev_ops h3a_af_subdev_ops = {
362 .core = &h3a_af_subdev_core_ops,
363 .video = &h3a_af_subdev_video_ops,
364};
365
366/* Function to register the AF character device driver. */
367int omap3isp_h3a_af_init(struct isp_device *isp)
368{
369 struct ispstat *af = &isp->isp_af;
370 struct omap3isp_h3a_af_config *af_cfg;
371 struct omap3isp_h3a_af_config *af_recover_cfg;
372 int ret;
373
374 af_cfg = kzalloc(sizeof(*af_cfg), GFP_KERNEL);
375 if (af_cfg == NULL)
376 return -ENOMEM;
377
378 memset(af, 0, sizeof(*af));
379 af->ops = &h3a_af_ops;
380 af->priv = af_cfg;
381 af->dma_ch = -1;
382 af->event_type = V4L2_EVENT_OMAP3ISP_AF;
383 af->isp = isp;
384
385 /* Set recover state configuration */
386 af_recover_cfg = kzalloc(sizeof(*af_recover_cfg), GFP_KERNEL);
387 if (!af_recover_cfg) {
388 dev_err(af->isp->dev, "AF: cannot allocate memory for recover "
389 "configuration.\n");
390 ret = -ENOMEM;
391 goto err_recover_alloc;
392 }
393
394 af_recover_cfg->paxel.h_start = OMAP3ISP_AF_PAXEL_HZSTART_MIN;
395 af_recover_cfg->paxel.width = OMAP3ISP_AF_PAXEL_WIDTH_MIN;
396 af_recover_cfg->paxel.height = OMAP3ISP_AF_PAXEL_HEIGHT_MIN;
397 af_recover_cfg->paxel.h_cnt = OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN;
398 af_recover_cfg->paxel.v_cnt = OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN;
399 af_recover_cfg->paxel.line_inc = OMAP3ISP_AF_PAXEL_INCREMENT_MIN;
400 if (h3a_af_validate_params(af, af_recover_cfg)) {
401 dev_err(af->isp->dev, "AF: recover configuration is "
402 "invalid.\n");
403 ret = -EINVAL;
404 goto err_conf;
405 }
406
407 af_recover_cfg->buf_size = h3a_af_get_buf_size(af_recover_cfg);
408 af->recover_priv = af_recover_cfg;
409
410 ret = omap3isp_stat_init(af, "AF", &h3a_af_subdev_ops);
411 if (ret)
412 goto err_conf;
413
414 return 0;
415
416err_conf:
417 kfree(af_recover_cfg);
418err_recover_alloc:
419 kfree(af_cfg);
420
421 return ret;
422}
423
424void omap3isp_h3a_af_cleanup(struct isp_device *isp)
425{
426 kfree(isp->isp_af.priv);
427 kfree(isp->isp_af.recover_priv);
428 omap3isp_stat_free(&isp->isp_af);
429}
diff --git a/drivers/media/video/omap3isp/isphist.c b/drivers/media/video/omap3isp/isphist.c
new file mode 100644
index 000000000000..1743856b30d1
--- /dev/null
+++ b/drivers/media/video/omap3isp/isphist.c
@@ -0,0 +1,520 @@
1/*
2 * isphist.c
3 *
4 * TI OMAP3 ISP - Histogram module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/uaccess.h>
31#include <linux/device.h>
32
33#include "isp.h"
34#include "ispreg.h"
35#include "isphist.h"
36
37#define HIST_CONFIG_DMA 1
38
39#define HIST_USING_DMA(hist) ((hist)->dma_ch >= 0)
40
41/*
42 * hist_reset_mem - clear Histogram memory before start stats engine.
43 */
44static void hist_reset_mem(struct ispstat *hist)
45{
46 struct isp_device *isp = hist->isp;
47 struct omap3isp_hist_config *conf = hist->priv;
48 unsigned int i;
49
50 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
51
52 /*
53 * By setting it, the histogram internal buffer is being cleared at the
54 * same time it's being read. This bit must be cleared afterwards.
55 */
56 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
57
58 /*
59 * We'll clear 4 words at each iteration for optimization. It avoids
60 * 3/4 of the jumps. We also know HIST_MEM_SIZE is divisible by 4.
61 */
62 for (i = OMAP3ISP_HIST_MEM_SIZE / 4; i > 0; i--) {
63 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
64 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
65 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
66 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
67 }
68 isp_reg_clr(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
69
70 hist->wait_acc_frames = conf->num_acc_frames;
71}
72
73static void hist_dma_config(struct ispstat *hist)
74{
75 hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32;
76 hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT;
77 hist->dma_config.frame_count = 1;
78 hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT;
79 hist->dma_config.src_start = OMAP3ISP_HIST_REG_BASE + ISPHIST_DATA;
80 hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC;
81 hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
82}
83
84/*
85 * hist_setup_regs - Helper function to update Histogram registers.
86 */
87static void hist_setup_regs(struct ispstat *hist, void *priv)
88{
89 struct isp_device *isp = hist->isp;
90 struct omap3isp_hist_config *conf = priv;
91 int c;
92 u32 cnt;
93 u32 wb_gain;
94 u32 reg_hor[OMAP3ISP_HIST_MAX_REGIONS];
95 u32 reg_ver[OMAP3ISP_HIST_MAX_REGIONS];
96
97 if (!hist->update || hist->state == ISPSTAT_DISABLED ||
98 hist->state == ISPSTAT_DISABLING)
99 return;
100
101 cnt = conf->cfa << ISPHIST_CNT_CFA_SHIFT;
102
103 wb_gain = conf->wg[0] << ISPHIST_WB_GAIN_WG00_SHIFT;
104 wb_gain |= conf->wg[1] << ISPHIST_WB_GAIN_WG01_SHIFT;
105 wb_gain |= conf->wg[2] << ISPHIST_WB_GAIN_WG02_SHIFT;
106 if (conf->cfa == OMAP3ISP_HIST_CFA_BAYER)
107 wb_gain |= conf->wg[3] << ISPHIST_WB_GAIN_WG03_SHIFT;
108
109 /* Regions size and position */
110 for (c = 0; c < OMAP3ISP_HIST_MAX_REGIONS; c++) {
111 if (c < conf->num_regions) {
112 reg_hor[c] = conf->region[c].h_start <<
113 ISPHIST_REG_START_SHIFT;
114 reg_hor[c] = conf->region[c].h_end <<
115 ISPHIST_REG_END_SHIFT;
116 reg_ver[c] = conf->region[c].v_start <<
117 ISPHIST_REG_START_SHIFT;
118 reg_ver[c] = conf->region[c].v_end <<
119 ISPHIST_REG_END_SHIFT;
120 } else {
121 reg_hor[c] = 0;
122 reg_ver[c] = 0;
123 }
124 }
125
126 cnt |= conf->hist_bins << ISPHIST_CNT_BINS_SHIFT;
127 switch (conf->hist_bins) {
128 case OMAP3ISP_HIST_BINS_256:
129 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 8) <<
130 ISPHIST_CNT_SHIFT_SHIFT;
131 break;
132 case OMAP3ISP_HIST_BINS_128:
133 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 7) <<
134 ISPHIST_CNT_SHIFT_SHIFT;
135 break;
136 case OMAP3ISP_HIST_BINS_64:
137 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 6) <<
138 ISPHIST_CNT_SHIFT_SHIFT;
139 break;
140 default: /* OMAP3ISP_HIST_BINS_32 */
141 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 5) <<
142 ISPHIST_CNT_SHIFT_SHIFT;
143 break;
144 }
145
146 hist_reset_mem(hist);
147
148 isp_reg_writel(isp, cnt, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT);
149 isp_reg_writel(isp, wb_gain, OMAP3_ISP_IOMEM_HIST, ISPHIST_WB_GAIN);
150 isp_reg_writel(isp, reg_hor[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_HORZ);
151 isp_reg_writel(isp, reg_ver[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_VERT);
152 isp_reg_writel(isp, reg_hor[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_HORZ);
153 isp_reg_writel(isp, reg_ver[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_VERT);
154 isp_reg_writel(isp, reg_hor[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_HORZ);
155 isp_reg_writel(isp, reg_ver[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_VERT);
156 isp_reg_writel(isp, reg_hor[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_HORZ);
157 isp_reg_writel(isp, reg_ver[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_VERT);
158
159 hist->update = 0;
160 hist->config_counter += hist->inc_config;
161 hist->inc_config = 0;
162 hist->buf_size = conf->buf_size;
163}
164
165static void hist_enable(struct ispstat *hist, int enable)
166{
167 if (enable) {
168 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
169 ISPHIST_PCR_ENABLE);
170 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
171 ISPCTRL_HIST_CLK_EN);
172 } else {
173 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
174 ISPHIST_PCR_ENABLE);
175 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
176 ISPCTRL_HIST_CLK_EN);
177 }
178}
179
180static int hist_busy(struct ispstat *hist)
181{
182 return isp_reg_readl(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR)
183 & ISPHIST_PCR_BUSY;
184}
185
186static void hist_dma_cb(int lch, u16 ch_status, void *data)
187{
188 struct ispstat *hist = data;
189
190 if (ch_status & ~OMAP_DMA_BLOCK_IRQ) {
191 dev_dbg(hist->isp->dev, "hist: DMA error. status = 0x%04x\n",
192 ch_status);
193 omap_stop_dma(lch);
194 hist_reset_mem(hist);
195 atomic_set(&hist->buf_err, 1);
196 }
197 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
198 ISPHIST_CNT_CLEAR);
199
200 omap3isp_stat_dma_isr(hist);
201 if (hist->state != ISPSTAT_DISABLED)
202 omap3isp_hist_dma_done(hist->isp);
203}
204
205static int hist_buf_dma(struct ispstat *hist)
206{
207 dma_addr_t dma_addr = hist->active_buf->dma_addr;
208
209 if (unlikely(!dma_addr)) {
210 dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n");
211 hist_reset_mem(hist);
212 return STAT_NO_BUF;
213 }
214
215 isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
216 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
217 ISPHIST_CNT_CLEAR);
218 omap3isp_flush(hist->isp);
219 hist->dma_config.dst_start = dma_addr;
220 hist->dma_config.elem_count = hist->buf_size / sizeof(u32);
221 omap_set_dma_params(hist->dma_ch, &hist->dma_config);
222
223 omap_start_dma(hist->dma_ch);
224
225 return STAT_BUF_WAITING_DMA;
226}
227
228static int hist_buf_pio(struct ispstat *hist)
229{
230 struct isp_device *isp = hist->isp;
231 u32 *buf = hist->active_buf->virt_addr;
232 unsigned int i;
233
234 if (!buf) {
235 dev_dbg(isp->dev, "hist: invalid PIO buffer address\n");
236 hist_reset_mem(hist);
237 return STAT_NO_BUF;
238 }
239
240 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
241
242 /*
243 * By setting it, the histogram internal buffer is being cleared at the
244 * same time it's being read. This bit must be cleared just after all
245 * data is acquired.
246 */
247 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
248
249 /*
250 * We'll read 4 times a 4-bytes-word at each iteration for
251 * optimization. It avoids 3/4 of the jumps. We also know buf_size is
252 * divisible by 16.
253 */
254 for (i = hist->buf_size / 16; i > 0; i--) {
255 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
256 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
257 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
258 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
259 }
260 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
261 ISPHIST_CNT_CLEAR);
262
263 return STAT_BUF_DONE;
264}
265
266/*
267 * hist_buf_process - Callback from ISP driver for HIST interrupt.
268 */
269static int hist_buf_process(struct ispstat *hist)
270{
271 struct omap3isp_hist_config *user_cfg = hist->priv;
272 int ret;
273
274 if (atomic_read(&hist->buf_err) || hist->state != ISPSTAT_ENABLED) {
275 hist_reset_mem(hist);
276 return STAT_NO_BUF;
277 }
278
279 if (--(hist->wait_acc_frames))
280 return STAT_NO_BUF;
281
282 if (HIST_USING_DMA(hist))
283 ret = hist_buf_dma(hist);
284 else
285 ret = hist_buf_pio(hist);
286
287 hist->wait_acc_frames = user_cfg->num_acc_frames;
288
289 return ret;
290}
291
292static u32 hist_get_buf_size(struct omap3isp_hist_config *conf)
293{
294 return OMAP3ISP_HIST_MEM_SIZE_BINS(conf->hist_bins) * conf->num_regions;
295}
296
297/*
298 * hist_validate_params - Helper function to check user given params.
299 * @user_cfg: Pointer to user configuration structure.
300 *
301 * Returns 0 on success configuration.
302 */
303static int hist_validate_params(struct ispstat *hist, void *new_conf)
304{
305 struct omap3isp_hist_config *user_cfg = new_conf;
306 int c;
307 u32 buf_size;
308
309 if (user_cfg->cfa > OMAP3ISP_HIST_CFA_FOVEONX3)
310 return -EINVAL;
311
312 /* Regions size and position */
313
314 if ((user_cfg->num_regions < OMAP3ISP_HIST_MIN_REGIONS) ||
315 (user_cfg->num_regions > OMAP3ISP_HIST_MAX_REGIONS))
316 return -EINVAL;
317
318 /* Regions */
319 for (c = 0; c < user_cfg->num_regions; c++) {
320 if (user_cfg->region[c].h_start & ~ISPHIST_REG_START_END_MASK)
321 return -EINVAL;
322 if (user_cfg->region[c].h_end & ~ISPHIST_REG_START_END_MASK)
323 return -EINVAL;
324 if (user_cfg->region[c].v_start & ~ISPHIST_REG_START_END_MASK)
325 return -EINVAL;
326 if (user_cfg->region[c].v_end & ~ISPHIST_REG_START_END_MASK)
327 return -EINVAL;
328 if (user_cfg->region[c].h_start > user_cfg->region[c].h_end)
329 return -EINVAL;
330 if (user_cfg->region[c].v_start > user_cfg->region[c].v_end)
331 return -EINVAL;
332 }
333
334 switch (user_cfg->num_regions) {
335 case 1:
336 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_256)
337 return -EINVAL;
338 break;
339 case 2:
340 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_128)
341 return -EINVAL;
342 break;
343 default: /* 3 or 4 */
344 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_64)
345 return -EINVAL;
346 break;
347 }
348
349 buf_size = hist_get_buf_size(user_cfg);
350 if (buf_size > user_cfg->buf_size)
351 /* User's buf_size request wasn't enoght */
352 user_cfg->buf_size = buf_size;
353 else if (user_cfg->buf_size > OMAP3ISP_HIST_MAX_BUF_SIZE)
354 user_cfg->buf_size = OMAP3ISP_HIST_MAX_BUF_SIZE;
355
356 return 0;
357}
358
359static int hist_comp_params(struct ispstat *hist,
360 struct omap3isp_hist_config *user_cfg)
361{
362 struct omap3isp_hist_config *cur_cfg = hist->priv;
363 int c;
364
365 if (cur_cfg->cfa != user_cfg->cfa)
366 return 1;
367
368 if (cur_cfg->num_acc_frames != user_cfg->num_acc_frames)
369 return 1;
370
371 if (cur_cfg->hist_bins != user_cfg->hist_bins)
372 return 1;
373
374 for (c = 0; c < OMAP3ISP_HIST_MAX_WG; c++) {
375 if (c == 3 && user_cfg->cfa == OMAP3ISP_HIST_CFA_FOVEONX3)
376 break;
377 else if (cur_cfg->wg[c] != user_cfg->wg[c])
378 return 1;
379 }
380
381 if (cur_cfg->num_regions != user_cfg->num_regions)
382 return 1;
383
384 /* Regions */
385 for (c = 0; c < user_cfg->num_regions; c++) {
386 if (cur_cfg->region[c].h_start != user_cfg->region[c].h_start)
387 return 1;
388 if (cur_cfg->region[c].h_end != user_cfg->region[c].h_end)
389 return 1;
390 if (cur_cfg->region[c].v_start != user_cfg->region[c].v_start)
391 return 1;
392 if (cur_cfg->region[c].v_end != user_cfg->region[c].v_end)
393 return 1;
394 }
395
396 return 0;
397}
398
399/*
400 * hist_update_params - Helper function to check and store user given params.
401 * @new_conf: Pointer to user configuration structure.
402 */
403static void hist_set_params(struct ispstat *hist, void *new_conf)
404{
405 struct omap3isp_hist_config *user_cfg = new_conf;
406 struct omap3isp_hist_config *cur_cfg = hist->priv;
407
408 if (!hist->configured || hist_comp_params(hist, user_cfg)) {
409 memcpy(cur_cfg, user_cfg, sizeof(*user_cfg));
410 if (user_cfg->num_acc_frames == 0)
411 user_cfg->num_acc_frames = 1;
412 hist->inc_config++;
413 hist->update = 1;
414 /*
415 * User might be asked for a bigger buffer than necessary for
416 * this configuration. In order to return the right amount of
417 * data during buffer request, let's calculate the size here
418 * instead of stick with user_cfg->buf_size.
419 */
420 cur_cfg->buf_size = hist_get_buf_size(cur_cfg);
421
422 }
423}
424
425static long hist_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
426{
427 struct ispstat *stat = v4l2_get_subdevdata(sd);
428
429 switch (cmd) {
430 case VIDIOC_OMAP3ISP_HIST_CFG:
431 return omap3isp_stat_config(stat, arg);
432 case VIDIOC_OMAP3ISP_STAT_REQ:
433 return omap3isp_stat_request_statistics(stat, arg);
434 case VIDIOC_OMAP3ISP_STAT_EN: {
435 int *en = arg;
436 return omap3isp_stat_enable(stat, !!*en);
437 }
438 }
439
440 return -ENOIOCTLCMD;
441
442}
443
444static const struct ispstat_ops hist_ops = {
445 .validate_params = hist_validate_params,
446 .set_params = hist_set_params,
447 .setup_regs = hist_setup_regs,
448 .enable = hist_enable,
449 .busy = hist_busy,
450 .buf_process = hist_buf_process,
451};
452
453static const struct v4l2_subdev_core_ops hist_subdev_core_ops = {
454 .ioctl = hist_ioctl,
455 .subscribe_event = omap3isp_stat_subscribe_event,
456 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
457};
458
459static const struct v4l2_subdev_video_ops hist_subdev_video_ops = {
460 .s_stream = omap3isp_stat_s_stream,
461};
462
463static const struct v4l2_subdev_ops hist_subdev_ops = {
464 .core = &hist_subdev_core_ops,
465 .video = &hist_subdev_video_ops,
466};
467
468/*
469 * omap3isp_hist_init - Module Initialization.
470 */
471int omap3isp_hist_init(struct isp_device *isp)
472{
473 struct ispstat *hist = &isp->isp_hist;
474 struct omap3isp_hist_config *hist_cfg;
475 int ret = -1;
476
477 hist_cfg = kzalloc(sizeof(*hist_cfg), GFP_KERNEL);
478 if (hist_cfg == NULL)
479 return -ENOMEM;
480
481 memset(hist, 0, sizeof(*hist));
482 if (HIST_CONFIG_DMA)
483 ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST",
484 hist_dma_cb, hist, &hist->dma_ch);
485 if (ret) {
486 if (HIST_CONFIG_DMA)
487 dev_warn(isp->dev, "hist: DMA request channel failed. "
488 "Using PIO only.\n");
489 hist->dma_ch = -1;
490 } else {
491 dev_dbg(isp->dev, "hist: DMA channel = %d\n", hist->dma_ch);
492 hist_dma_config(hist);
493 omap_enable_dma_irq(hist->dma_ch, OMAP_DMA_BLOCK_IRQ);
494 }
495
496 hist->ops = &hist_ops;
497 hist->priv = hist_cfg;
498 hist->event_type = V4L2_EVENT_OMAP3ISP_HIST;
499 hist->isp = isp;
500
501 ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops);
502 if (ret) {
503 kfree(hist_cfg);
504 if (HIST_USING_DMA(hist))
505 omap_free_dma(hist->dma_ch);
506 }
507
508 return ret;
509}
510
511/*
512 * omap3isp_hist_cleanup - Module cleanup.
513 */
514void omap3isp_hist_cleanup(struct isp_device *isp)
515{
516 if (HIST_USING_DMA(&isp->isp_hist))
517 omap_free_dma(isp->isp_hist.dma_ch);
518 kfree(isp->isp_hist.priv);
519 omap3isp_stat_free(&isp->isp_hist);
520}
diff --git a/drivers/media/video/omap3isp/isphist.h b/drivers/media/video/omap3isp/isphist.h
new file mode 100644
index 000000000000..0b2a38ec94c4
--- /dev/null
+++ b/drivers/media/video/omap3isp/isphist.h
@@ -0,0 +1,40 @@
1/*
2 * isphist.h
3 *
4 * TI OMAP3 ISP - Histogram module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_HIST_H
29#define OMAP3_ISP_HIST_H
30
31#include <linux/omap3isp.h>
32
33#define ISPHIST_IN_BIT_WIDTH_CCDC 10
34
35struct isp_device;
36
37int omap3isp_hist_init(struct isp_device *isp);
38void omap3isp_hist_cleanup(struct isp_device *isp);
39
40#endif /* OMAP3_ISP_HIST */
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
new file mode 100644
index 000000000000..baf9374201dc
--- /dev/null
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -0,0 +1,2113 @@
1/*
2 * isppreview.c
3 *
4 * TI OMAP3 ISP driver - Preview module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/device.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/mutex.h>
31#include <linux/uaccess.h>
32
33#include "isp.h"
34#include "ispreg.h"
35#include "isppreview.h"
36
37/* Default values in Office Flourescent Light for RGBtoRGB Blending */
38static struct omap3isp_prev_rgbtorgb flr_rgb2rgb = {
39 { /* RGB-RGB Matrix */
40 {0x01E2, 0x0F30, 0x0FEE},
41 {0x0F9B, 0x01AC, 0x0FB9},
42 {0x0FE0, 0x0EC0, 0x0260}
43 }, /* RGB Offset */
44 {0x0000, 0x0000, 0x0000}
45};
46
47/* Default values in Office Flourescent Light for RGB to YUV Conversion*/
48static struct omap3isp_prev_csc flr_prev_csc = {
49 { /* CSC Coef Matrix */
50 {66, 129, 25},
51 {-38, -75, 112},
52 {112, -94 , -18}
53 }, /* CSC Offset */
54 {0x0, 0x0, 0x0}
55};
56
57/* Default values in Office Flourescent Light for CFA Gradient*/
58#define FLR_CFA_GRADTHRS_HORZ 0x28
59#define FLR_CFA_GRADTHRS_VERT 0x28
60
61/* Default values in Office Flourescent Light for Chroma Suppression*/
62#define FLR_CSUP_GAIN 0x0D
63#define FLR_CSUP_THRES 0xEB
64
65/* Default values in Office Flourescent Light for Noise Filter*/
66#define FLR_NF_STRGTH 0x03
67
68/* Default values for White Balance */
69#define FLR_WBAL_DGAIN 0x100
70#define FLR_WBAL_COEF 0x20
71
72/* Default values in Office Flourescent Light for Black Adjustment*/
73#define FLR_BLKADJ_BLUE 0x0
74#define FLR_BLKADJ_GREEN 0x0
75#define FLR_BLKADJ_RED 0x0
76
77#define DEF_DETECT_CORRECT_VAL 0xe
78
79#define PREV_MIN_WIDTH 64
80#define PREV_MIN_HEIGHT 8
81#define PREV_MAX_HEIGHT 16384
82
83/*
84 * Coeficient Tables for the submodules in Preview.
85 * Array is initialised with the values from.the tables text file.
86 */
87
88/*
89 * CFA Filter Coefficient Table
90 *
91 */
92static u32 cfa_coef_table[] = {
93#include "cfa_coef_table.h"
94};
95
96/*
97 * Default Gamma Correction Table - All components
98 */
99static u32 gamma_table[] = {
100#include "gamma_table.h"
101};
102
103/*
104 * Noise Filter Threshold table
105 */
106static u32 noise_filter_table[] = {
107#include "noise_filter_table.h"
108};
109
110/*
111 * Luminance Enhancement Table
112 */
113static u32 luma_enhance_table[] = {
114#include "luma_enhance_table.h"
115};
116
117/*
118 * preview_enable_invalaw - Enable/Disable Inverse A-Law module in Preview.
119 * @enable: 1 - Reverse the A-Law done in CCDC.
120 */
121static void
122preview_enable_invalaw(struct isp_prev_device *prev, u8 enable)
123{
124 struct isp_device *isp = to_isp_device(prev);
125
126 if (enable)
127 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
128 ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
129 else
130 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
131 ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
132}
133
134/*
135 * preview_enable_drkframe_capture - Enable/Disable of the darkframe capture.
136 * @prev -
137 * @enable: 1 - Enable, 0 - Disable
138 *
139 * NOTE: PRV_WSDR_ADDR and PRV_WADD_OFFSET must be set also
140 * The proccess is applied for each captured frame.
141 */
142static void
143preview_enable_drkframe_capture(struct isp_prev_device *prev, u8 enable)
144{
145 struct isp_device *isp = to_isp_device(prev);
146
147 if (enable)
148 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
149 ISPPRV_PCR_DRKFCAP);
150 else
151 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
152 ISPPRV_PCR_DRKFCAP);
153}
154
155/*
156 * preview_enable_drkframe - Enable/Disable of the darkframe subtract.
157 * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is
158 * subtracted with the pixels in the current frame.
159 *
160 * The proccess is applied for each captured frame.
161 */
162static void
163preview_enable_drkframe(struct isp_prev_device *prev, u8 enable)
164{
165 struct isp_device *isp = to_isp_device(prev);
166
167 if (enable)
168 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
169 ISPPRV_PCR_DRKFEN);
170 else
171 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
172 ISPPRV_PCR_DRKFEN);
173}
174
175/*
176 * preview_config_drkf_shadcomp - Configures shift value in shading comp.
177 * @scomp_shtval: 3bit value of shift used in shading compensation.
178 */
179static void
180preview_config_drkf_shadcomp(struct isp_prev_device *prev,
181 const void *scomp_shtval)
182{
183 struct isp_device *isp = to_isp_device(prev);
184 const u32 *shtval = scomp_shtval;
185
186 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
187 ISPPRV_PCR_SCOMP_SFT_MASK,
188 *shtval << ISPPRV_PCR_SCOMP_SFT_SHIFT);
189}
190
191/*
192 * preview_enable_hmed - Enables/Disables of the Horizontal Median Filter.
193 * @enable: 1 - Enables Horizontal Median Filter.
194 */
195static void
196preview_enable_hmed(struct isp_prev_device *prev, u8 enable)
197{
198 struct isp_device *isp = to_isp_device(prev);
199
200 if (enable)
201 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
202 ISPPRV_PCR_HMEDEN);
203 else
204 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
205 ISPPRV_PCR_HMEDEN);
206}
207
208/*
209 * preview_config_hmed - Configures the Horizontal Median Filter.
210 * @prev_hmed: Structure containing the odd and even distance between the
211 * pixels in the image along with the filter threshold.
212 */
213static void
214preview_config_hmed(struct isp_prev_device *prev, const void *prev_hmed)
215{
216 struct isp_device *isp = to_isp_device(prev);
217 const struct omap3isp_prev_hmed *hmed = prev_hmed;
218
219 isp_reg_writel(isp, (hmed->odddist == 1 ? 0 : ISPPRV_HMED_ODDDIST) |
220 (hmed->evendist == 1 ? 0 : ISPPRV_HMED_EVENDIST) |
221 (hmed->thres << ISPPRV_HMED_THRESHOLD_SHIFT),
222 OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED);
223}
224
225/*
226 * preview_config_noisefilter - Configures the Noise Filter.
227 * @prev_nf: Structure containing the noisefilter table, strength to be used
228 * for the noise filter and the defect correction enable flag.
229 */
230static void
231preview_config_noisefilter(struct isp_prev_device *prev, const void *prev_nf)
232{
233 struct isp_device *isp = to_isp_device(prev);
234 const struct omap3isp_prev_nf *nf = prev_nf;
235 unsigned int i;
236
237 isp_reg_writel(isp, nf->spread, OMAP3_ISP_IOMEM_PREV, ISPPRV_NF);
238 isp_reg_writel(isp, ISPPRV_NF_TABLE_ADDR,
239 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
240 for (i = 0; i < OMAP3ISP_PREV_NF_TBL_SIZE; i++) {
241 isp_reg_writel(isp, nf->table[i],
242 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
243 }
244}
245
246/*
247 * preview_config_dcor - Configures the defect correction
248 * @prev_dcor: Structure containing the defect correct thresholds
249 */
250static void
251preview_config_dcor(struct isp_prev_device *prev, const void *prev_dcor)
252{
253 struct isp_device *isp = to_isp_device(prev);
254 const struct omap3isp_prev_dcor *dcor = prev_dcor;
255
256 isp_reg_writel(isp, dcor->detect_correct[0],
257 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0);
258 isp_reg_writel(isp, dcor->detect_correct[1],
259 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1);
260 isp_reg_writel(isp, dcor->detect_correct[2],
261 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2);
262 isp_reg_writel(isp, dcor->detect_correct[3],
263 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3);
264 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
265 ISPPRV_PCR_DCCOUP,
266 dcor->couplet_mode_en ? ISPPRV_PCR_DCCOUP : 0);
267}
268
269/*
270 * preview_config_cfa - Configures the CFA Interpolation parameters.
271 * @prev_cfa: Structure containing the CFA interpolation table, CFA format
272 * in the image, vertical and horizontal gradient threshold.
273 */
274static void
275preview_config_cfa(struct isp_prev_device *prev, const void *prev_cfa)
276{
277 struct isp_device *isp = to_isp_device(prev);
278 const struct omap3isp_prev_cfa *cfa = prev_cfa;
279 unsigned int i;
280
281 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
282 ISPPRV_PCR_CFAFMT_MASK,
283 cfa->format << ISPPRV_PCR_CFAFMT_SHIFT);
284
285 isp_reg_writel(isp,
286 (cfa->gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) |
287 (cfa->gradthrs_horz << ISPPRV_CFA_GRADTH_HOR_SHIFT),
288 OMAP3_ISP_IOMEM_PREV, ISPPRV_CFA);
289
290 isp_reg_writel(isp, ISPPRV_CFA_TABLE_ADDR,
291 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
292
293 for (i = 0; i < OMAP3ISP_PREV_CFA_TBL_SIZE; i++) {
294 isp_reg_writel(isp, cfa->table[i],
295 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
296 }
297}
298
299/*
300 * preview_config_gammacorrn - Configures the Gamma Correction table values
301 * @gtable: Structure containing the table for red, blue, green gamma table.
302 */
303static void
304preview_config_gammacorrn(struct isp_prev_device *prev, const void *gtable)
305{
306 struct isp_device *isp = to_isp_device(prev);
307 const struct omap3isp_prev_gtables *gt = gtable;
308 unsigned int i;
309
310 isp_reg_writel(isp, ISPPRV_REDGAMMA_TABLE_ADDR,
311 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
312 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
313 isp_reg_writel(isp, gt->red[i], OMAP3_ISP_IOMEM_PREV,
314 ISPPRV_SET_TBL_DATA);
315
316 isp_reg_writel(isp, ISPPRV_GREENGAMMA_TABLE_ADDR,
317 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
318 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
319 isp_reg_writel(isp, gt->green[i], OMAP3_ISP_IOMEM_PREV,
320 ISPPRV_SET_TBL_DATA);
321
322 isp_reg_writel(isp, ISPPRV_BLUEGAMMA_TABLE_ADDR,
323 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
324 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
325 isp_reg_writel(isp, gt->blue[i], OMAP3_ISP_IOMEM_PREV,
326 ISPPRV_SET_TBL_DATA);
327}
328
329/*
330 * preview_config_luma_enhancement - Sets the Luminance Enhancement table.
331 * @ytable: Structure containing the table for Luminance Enhancement table.
332 */
333static void
334preview_config_luma_enhancement(struct isp_prev_device *prev,
335 const void *ytable)
336{
337 struct isp_device *isp = to_isp_device(prev);
338 const struct omap3isp_prev_luma *yt = ytable;
339 unsigned int i;
340
341 isp_reg_writel(isp, ISPPRV_YENH_TABLE_ADDR,
342 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
343 for (i = 0; i < OMAP3ISP_PREV_YENH_TBL_SIZE; i++) {
344 isp_reg_writel(isp, yt->table[i],
345 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
346 }
347}
348
349/*
350 * preview_config_chroma_suppression - Configures the Chroma Suppression.
351 * @csup: Structure containing the threshold value for suppression
352 * and the hypass filter enable flag.
353 */
354static void
355preview_config_chroma_suppression(struct isp_prev_device *prev,
356 const void *csup)
357{
358 struct isp_device *isp = to_isp_device(prev);
359 const struct omap3isp_prev_csup *cs = csup;
360
361 isp_reg_writel(isp,
362 cs->gain | (cs->thres << ISPPRV_CSUP_THRES_SHIFT) |
363 (cs->hypf_en << ISPPRV_CSUP_HPYF_SHIFT),
364 OMAP3_ISP_IOMEM_PREV, ISPPRV_CSUP);
365}
366
367/*
368 * preview_enable_noisefilter - Enables/Disables the Noise Filter.
369 * @enable: 1 - Enables the Noise Filter.
370 */
371static void
372preview_enable_noisefilter(struct isp_prev_device *prev, u8 enable)
373{
374 struct isp_device *isp = to_isp_device(prev);
375
376 if (enable)
377 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
378 ISPPRV_PCR_NFEN);
379 else
380 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
381 ISPPRV_PCR_NFEN);
382}
383
384/*
385 * preview_enable_dcor - Enables/Disables the defect correction.
386 * @enable: 1 - Enables the defect correction.
387 */
388static void
389preview_enable_dcor(struct isp_prev_device *prev, u8 enable)
390{
391 struct isp_device *isp = to_isp_device(prev);
392
393 if (enable)
394 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
395 ISPPRV_PCR_DCOREN);
396 else
397 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
398 ISPPRV_PCR_DCOREN);
399}
400
401/*
402 * preview_enable_cfa - Enable/Disable the CFA Interpolation.
403 * @enable: 1 - Enables the CFA.
404 */
405static void
406preview_enable_cfa(struct isp_prev_device *prev, u8 enable)
407{
408 struct isp_device *isp = to_isp_device(prev);
409
410 if (enable)
411 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
412 ISPPRV_PCR_CFAEN);
413 else
414 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
415 ISPPRV_PCR_CFAEN);
416}
417
418/*
419 * preview_enable_gammabypass - Enables/Disables the GammaByPass
420 * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB.
421 * 0 - Goes through Gamma Correction. input and output is 10bit.
422 */
423static void
424preview_enable_gammabypass(struct isp_prev_device *prev, u8 enable)
425{
426 struct isp_device *isp = to_isp_device(prev);
427
428 if (enable)
429 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
430 ISPPRV_PCR_GAMMA_BYPASS);
431 else
432 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
433 ISPPRV_PCR_GAMMA_BYPASS);
434}
435
436/*
437 * preview_enable_luma_enhancement - Enables/Disables Luminance Enhancement
438 * @enable: 1 - Enable the Luminance Enhancement.
439 */
440static void
441preview_enable_luma_enhancement(struct isp_prev_device *prev, u8 enable)
442{
443 struct isp_device *isp = to_isp_device(prev);
444
445 if (enable)
446 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
447 ISPPRV_PCR_YNENHEN);
448 else
449 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
450 ISPPRV_PCR_YNENHEN);
451}
452
453/*
454 * preview_enable_chroma_suppression - Enables/Disables Chrominance Suppr.
455 * @enable: 1 - Enable the Chrominance Suppression.
456 */
457static void
458preview_enable_chroma_suppression(struct isp_prev_device *prev, u8 enable)
459{
460 struct isp_device *isp = to_isp_device(prev);
461
462 if (enable)
463 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
464 ISPPRV_PCR_SUPEN);
465 else
466 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
467 ISPPRV_PCR_SUPEN);
468}
469
470/*
471 * preview_config_whitebalance - Configures the White Balance parameters.
472 * @prev_wbal: Structure containing the digital gain and white balance
473 * coefficient.
474 *
475 * Coefficient matrix always with default values.
476 */
477static void
478preview_config_whitebalance(struct isp_prev_device *prev, const void *prev_wbal)
479{
480 struct isp_device *isp = to_isp_device(prev);
481 const struct omap3isp_prev_wbal *wbal = prev_wbal;
482 u32 val;
483
484 isp_reg_writel(isp, wbal->dgain, OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN);
485
486 val = wbal->coef0 << ISPPRV_WBGAIN_COEF0_SHIFT;
487 val |= wbal->coef1 << ISPPRV_WBGAIN_COEF1_SHIFT;
488 val |= wbal->coef2 << ISPPRV_WBGAIN_COEF2_SHIFT;
489 val |= wbal->coef3 << ISPPRV_WBGAIN_COEF3_SHIFT;
490 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN);
491
492 isp_reg_writel(isp,
493 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_0_SHIFT |
494 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_1_SHIFT |
495 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_2_SHIFT |
496 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_3_SHIFT |
497 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_0_SHIFT |
498 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_1_SHIFT |
499 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_2_SHIFT |
500 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_3_SHIFT |
501 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_0_SHIFT |
502 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_1_SHIFT |
503 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_2_SHIFT |
504 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_3_SHIFT |
505 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_0_SHIFT |
506 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_1_SHIFT |
507 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_2_SHIFT |
508 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_3_SHIFT,
509 OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL);
510}
511
512/*
513 * preview_config_blkadj - Configures the Black Adjustment parameters.
514 * @prev_blkadj: Structure containing the black adjustment towards red, green,
515 * blue.
516 */
517static void
518preview_config_blkadj(struct isp_prev_device *prev, const void *prev_blkadj)
519{
520 struct isp_device *isp = to_isp_device(prev);
521 const struct omap3isp_prev_blkadj *blkadj = prev_blkadj;
522
523 isp_reg_writel(isp, (blkadj->blue << ISPPRV_BLKADJOFF_B_SHIFT) |
524 (blkadj->green << ISPPRV_BLKADJOFF_G_SHIFT) |
525 (blkadj->red << ISPPRV_BLKADJOFF_R_SHIFT),
526 OMAP3_ISP_IOMEM_PREV, ISPPRV_BLKADJOFF);
527}
528
529/*
530 * preview_config_rgb_blending - Configures the RGB-RGB Blending matrix.
531 * @rgb2rgb: Structure containing the rgb to rgb blending matrix and the rgb
532 * offset.
533 */
534static void
535preview_config_rgb_blending(struct isp_prev_device *prev, const void *rgb2rgb)
536{
537 struct isp_device *isp = to_isp_device(prev);
538 const struct omap3isp_prev_rgbtorgb *rgbrgb = rgb2rgb;
539 u32 val;
540
541 val = (rgbrgb->matrix[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT;
542 val |= (rgbrgb->matrix[0][1] & 0xfff) << ISPPRV_RGB_MAT1_MTX_GR_SHIFT;
543 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT1);
544
545 val = (rgbrgb->matrix[0][2] & 0xfff) << ISPPRV_RGB_MAT2_MTX_BR_SHIFT;
546 val |= (rgbrgb->matrix[1][0] & 0xfff) << ISPPRV_RGB_MAT2_MTX_RG_SHIFT;
547 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT2);
548
549 val = (rgbrgb->matrix[1][1] & 0xfff) << ISPPRV_RGB_MAT3_MTX_GG_SHIFT;
550 val |= (rgbrgb->matrix[1][2] & 0xfff) << ISPPRV_RGB_MAT3_MTX_BG_SHIFT;
551 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT3);
552
553 val = (rgbrgb->matrix[2][0] & 0xfff) << ISPPRV_RGB_MAT4_MTX_RB_SHIFT;
554 val |= (rgbrgb->matrix[2][1] & 0xfff) << ISPPRV_RGB_MAT4_MTX_GB_SHIFT;
555 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT4);
556
557 val = (rgbrgb->matrix[2][2] & 0xfff) << ISPPRV_RGB_MAT5_MTX_BB_SHIFT;
558 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT5);
559
560 val = (rgbrgb->offset[0] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT;
561 val |= (rgbrgb->offset[1] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT;
562 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF1);
563
564 val = (rgbrgb->offset[2] & 0x3ff) << ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT;
565 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF2);
566}
567
568/*
569 * Configures the RGB-YCbYCr conversion matrix
570 * @prev_csc: Structure containing the RGB to YCbYCr matrix and the
571 * YCbCr offset.
572 */
573static void
574preview_config_rgb_to_ycbcr(struct isp_prev_device *prev, const void *prev_csc)
575{
576 struct isp_device *isp = to_isp_device(prev);
577 const struct omap3isp_prev_csc *csc = prev_csc;
578 u32 val;
579
580 val = (csc->matrix[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT;
581 val |= (csc->matrix[0][1] & 0x3ff) << ISPPRV_CSC0_GY_SHIFT;
582 val |= (csc->matrix[0][2] & 0x3ff) << ISPPRV_CSC0_BY_SHIFT;
583 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC0);
584
585 val = (csc->matrix[1][0] & 0x3ff) << ISPPRV_CSC1_RCB_SHIFT;
586 val |= (csc->matrix[1][1] & 0x3ff) << ISPPRV_CSC1_GCB_SHIFT;
587 val |= (csc->matrix[1][2] & 0x3ff) << ISPPRV_CSC1_BCB_SHIFT;
588 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC1);
589
590 val = (csc->matrix[2][0] & 0x3ff) << ISPPRV_CSC2_RCR_SHIFT;
591 val |= (csc->matrix[2][1] & 0x3ff) << ISPPRV_CSC2_GCR_SHIFT;
592 val |= (csc->matrix[2][2] & 0x3ff) << ISPPRV_CSC2_BCR_SHIFT;
593 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC2);
594
595 val = (csc->offset[0] & 0xff) << ISPPRV_CSC_OFFSET_Y_SHIFT;
596 val |= (csc->offset[1] & 0xff) << ISPPRV_CSC_OFFSET_CB_SHIFT;
597 val |= (csc->offset[2] & 0xff) << ISPPRV_CSC_OFFSET_CR_SHIFT;
598 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC_OFFSET);
599}
600
601/*
602 * preview_update_contrast - Updates the contrast.
603 * @contrast: Pointer to hold the current programmed contrast value.
604 *
605 * Value should be programmed before enabling the module.
606 */
607static void
608preview_update_contrast(struct isp_prev_device *prev, u8 contrast)
609{
610 struct prev_params *params = &prev->params;
611
612 if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) {
613 params->contrast = contrast * ISPPRV_CONTRAST_UNITS;
614 prev->update |= PREV_CONTRAST;
615 }
616}
617
618/*
619 * preview_config_contrast - Configures the Contrast.
620 * @params: Contrast value (u8 pointer, U8Q0 format).
621 *
622 * Value should be programmed before enabling the module.
623 */
624static void
625preview_config_contrast(struct isp_prev_device *prev, const void *params)
626{
627 struct isp_device *isp = to_isp_device(prev);
628
629 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
630 0xff << ISPPRV_CNT_BRT_CNT_SHIFT,
631 *(u8 *)params << ISPPRV_CNT_BRT_CNT_SHIFT);
632}
633
634/*
635 * preview_update_brightness - Updates the brightness in preview module.
636 * @brightness: Pointer to hold the current programmed brightness value.
637 *
638 */
639static void
640preview_update_brightness(struct isp_prev_device *prev, u8 brightness)
641{
642 struct prev_params *params = &prev->params;
643
644 if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) {
645 params->brightness = brightness * ISPPRV_BRIGHT_UNITS;
646 prev->update |= PREV_BRIGHTNESS;
647 }
648}
649
650/*
651 * preview_config_brightness - Configures the brightness.
652 * @params: Brightness value (u8 pointer, U8Q0 format).
653 */
654static void
655preview_config_brightness(struct isp_prev_device *prev, const void *params)
656{
657 struct isp_device *isp = to_isp_device(prev);
658
659 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
660 0xff << ISPPRV_CNT_BRT_BRT_SHIFT,
661 *(u8 *)params << ISPPRV_CNT_BRT_BRT_SHIFT);
662}
663
664/*
665 * preview_config_yc_range - Configures the max and min Y and C values.
666 * @yclimit: Structure containing the range of Y and C values.
667 */
668static void
669preview_config_yc_range(struct isp_prev_device *prev, const void *yclimit)
670{
671 struct isp_device *isp = to_isp_device(prev);
672 const struct omap3isp_prev_yclimit *yc = yclimit;
673
674 isp_reg_writel(isp,
675 yc->maxC << ISPPRV_SETUP_YC_MAXC_SHIFT |
676 yc->maxY << ISPPRV_SETUP_YC_MAXY_SHIFT |
677 yc->minC << ISPPRV_SETUP_YC_MINC_SHIFT |
678 yc->minY << ISPPRV_SETUP_YC_MINY_SHIFT,
679 OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
680}
681
682/* preview parameters update structure */
683struct preview_update {
684 int cfg_bit;
685 int feature_bit;
686 void (*config)(struct isp_prev_device *, const void *);
687 void (*enable)(struct isp_prev_device *, u8);
688};
689
690static struct preview_update update_attrs[] = {
691 {OMAP3ISP_PREV_LUMAENH, PREV_LUMA_ENHANCE,
692 preview_config_luma_enhancement,
693 preview_enable_luma_enhancement},
694 {OMAP3ISP_PREV_INVALAW, PREV_INVERSE_ALAW,
695 NULL,
696 preview_enable_invalaw},
697 {OMAP3ISP_PREV_HRZ_MED, PREV_HORZ_MEDIAN_FILTER,
698 preview_config_hmed,
699 preview_enable_hmed},
700 {OMAP3ISP_PREV_CFA, PREV_CFA,
701 preview_config_cfa,
702 preview_enable_cfa},
703 {OMAP3ISP_PREV_CHROMA_SUPP, PREV_CHROMA_SUPPRESS,
704 preview_config_chroma_suppression,
705 preview_enable_chroma_suppression},
706 {OMAP3ISP_PREV_WB, PREV_WB,
707 preview_config_whitebalance,
708 NULL},
709 {OMAP3ISP_PREV_BLKADJ, PREV_BLKADJ,
710 preview_config_blkadj,
711 NULL},
712 {OMAP3ISP_PREV_RGB2RGB, PREV_RGB2RGB,
713 preview_config_rgb_blending,
714 NULL},
715 {OMAP3ISP_PREV_COLOR_CONV, PREV_COLOR_CONV,
716 preview_config_rgb_to_ycbcr,
717 NULL},
718 {OMAP3ISP_PREV_YC_LIMIT, PREV_YCLIMITS,
719 preview_config_yc_range,
720 NULL},
721 {OMAP3ISP_PREV_DEFECT_COR, PREV_DEFECT_COR,
722 preview_config_dcor,
723 preview_enable_dcor},
724 {OMAP3ISP_PREV_GAMMABYPASS, PREV_GAMMA_BYPASS,
725 NULL,
726 preview_enable_gammabypass},
727 {OMAP3ISP_PREV_DRK_FRM_CAPTURE, PREV_DARK_FRAME_CAPTURE,
728 NULL,
729 preview_enable_drkframe_capture},
730 {OMAP3ISP_PREV_DRK_FRM_SUBTRACT, PREV_DARK_FRAME_SUBTRACT,
731 NULL,
732 preview_enable_drkframe},
733 {OMAP3ISP_PREV_LENS_SHADING, PREV_LENS_SHADING,
734 preview_config_drkf_shadcomp,
735 preview_enable_drkframe},
736 {OMAP3ISP_PREV_NF, PREV_NOISE_FILTER,
737 preview_config_noisefilter,
738 preview_enable_noisefilter},
739 {OMAP3ISP_PREV_GAMMA, PREV_GAMMA,
740 preview_config_gammacorrn,
741 NULL},
742 {-1, PREV_CONTRAST,
743 preview_config_contrast,
744 NULL},
745 {-1, PREV_BRIGHTNESS,
746 preview_config_brightness,
747 NULL},
748};
749
750/*
751 * __preview_get_ptrs - helper function which return pointers to members
752 * of params and config structures.
753 * @params - pointer to preview_params structure.
754 * @param - return pointer to appropriate structure field.
755 * @configs - pointer to update config structure.
756 * @config - return pointer to appropriate structure field.
757 * @bit - for which feature to return pointers.
758 * Return size of coresponding prev_params member
759 */
760static u32
761__preview_get_ptrs(struct prev_params *params, void **param,
762 struct omap3isp_prev_update_config *configs,
763 void __user **config, u32 bit)
764{
765#define CHKARG(cfgs, cfg, field) \
766 if (cfgs && cfg) { \
767 *(cfg) = (cfgs)->field; \
768 }
769
770 switch (bit) {
771 case PREV_HORZ_MEDIAN_FILTER:
772 *param = &params->hmed;
773 CHKARG(configs, config, hmed)
774 return sizeof(params->hmed);
775 case PREV_NOISE_FILTER:
776 *param = &params->nf;
777 CHKARG(configs, config, nf)
778 return sizeof(params->nf);
779 break;
780 case PREV_CFA:
781 *param = &params->cfa;
782 CHKARG(configs, config, cfa)
783 return sizeof(params->cfa);
784 case PREV_LUMA_ENHANCE:
785 *param = &params->luma;
786 CHKARG(configs, config, luma)
787 return sizeof(params->luma);
788 case PREV_CHROMA_SUPPRESS:
789 *param = &params->csup;
790 CHKARG(configs, config, csup)
791 return sizeof(params->csup);
792 case PREV_DEFECT_COR:
793 *param = &params->dcor;
794 CHKARG(configs, config, dcor)
795 return sizeof(params->dcor);
796 case PREV_BLKADJ:
797 *param = &params->blk_adj;
798 CHKARG(configs, config, blkadj)
799 return sizeof(params->blk_adj);
800 case PREV_YCLIMITS:
801 *param = &params->yclimit;
802 CHKARG(configs, config, yclimit)
803 return sizeof(params->yclimit);
804 case PREV_RGB2RGB:
805 *param = &params->rgb2rgb;
806 CHKARG(configs, config, rgb2rgb)
807 return sizeof(params->rgb2rgb);
808 case PREV_COLOR_CONV:
809 *param = &params->rgb2ycbcr;
810 CHKARG(configs, config, csc)
811 return sizeof(params->rgb2ycbcr);
812 case PREV_WB:
813 *param = &params->wbal;
814 CHKARG(configs, config, wbal)
815 return sizeof(params->wbal);
816 case PREV_GAMMA:
817 *param = &params->gamma;
818 CHKARG(configs, config, gamma)
819 return sizeof(params->gamma);
820 case PREV_CONTRAST:
821 *param = &params->contrast;
822 return 0;
823 case PREV_BRIGHTNESS:
824 *param = &params->brightness;
825 return 0;
826 default:
827 *param = NULL;
828 *config = NULL;
829 break;
830 }
831 return 0;
832}
833
834/*
835 * preview_config - Copy and update local structure with userspace preview
836 * configuration.
837 * @prev: ISP preview engine
838 * @cfg: Configuration
839 *
840 * Return zero if success or -EFAULT if the configuration can't be copied from
841 * userspace.
842 */
843static int preview_config(struct isp_prev_device *prev,
844 struct omap3isp_prev_update_config *cfg)
845{
846 struct prev_params *params;
847 struct preview_update *attr;
848 int i, bit, rval = 0;
849
850 params = &prev->params;
851
852 if (prev->state != ISP_PIPELINE_STREAM_STOPPED) {
853 unsigned long flags;
854
855 spin_lock_irqsave(&prev->lock, flags);
856 prev->shadow_update = 1;
857 spin_unlock_irqrestore(&prev->lock, flags);
858 }
859
860 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
861 attr = &update_attrs[i];
862 bit = 0;
863
864 if (!(cfg->update & attr->cfg_bit))
865 continue;
866
867 bit = cfg->flag & attr->cfg_bit;
868 if (bit) {
869 void *to = NULL, __user *from = NULL;
870 unsigned long sz = 0;
871
872 sz = __preview_get_ptrs(params, &to, cfg, &from,
873 bit);
874 if (to && from && sz) {
875 if (copy_from_user(to, from, sz)) {
876 rval = -EFAULT;
877 break;
878 }
879 }
880 params->features |= attr->feature_bit;
881 } else {
882 params->features &= ~attr->feature_bit;
883 }
884
885 prev->update |= attr->feature_bit;
886 }
887
888 prev->shadow_update = 0;
889 return rval;
890}
891
892/*
893 * preview_setup_hw - Setup preview registers and/or internal memory
894 * @prev: pointer to preview private structure
895 * Note: can be called from interrupt context
896 * Return none
897 */
898static void preview_setup_hw(struct isp_prev_device *prev)
899{
900 struct prev_params *params = &prev->params;
901 struct preview_update *attr;
902 int i, bit;
903 void *param_ptr;
904
905 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
906 attr = &update_attrs[i];
907
908 if (!(prev->update & attr->feature_bit))
909 continue;
910 bit = params->features & attr->feature_bit;
911 if (bit) {
912 if (attr->config) {
913 __preview_get_ptrs(params, &param_ptr, NULL,
914 NULL, bit);
915 attr->config(prev, param_ptr);
916 }
917 if (attr->enable)
918 attr->enable(prev, 1);
919 } else
920 if (attr->enable)
921 attr->enable(prev, 0);
922
923 prev->update &= ~attr->feature_bit;
924 }
925}
926
927/*
928 * preview_config_ycpos - Configure byte layout of YUV image.
929 * @mode: Indicates the required byte layout.
930 */
931static void
932preview_config_ycpos(struct isp_prev_device *prev,
933 enum v4l2_mbus_pixelcode pixelcode)
934{
935 struct isp_device *isp = to_isp_device(prev);
936 enum preview_ycpos_mode mode;
937
938 switch (pixelcode) {
939 case V4L2_MBUS_FMT_YUYV8_1X16:
940 mode = YCPOS_CrYCbY;
941 break;
942 case V4L2_MBUS_FMT_UYVY8_1X16:
943 mode = YCPOS_YCrYCb;
944 break;
945 default:
946 return;
947 }
948
949 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
950 ISPPRV_PCR_YCPOS_CrYCbY,
951 mode << ISPPRV_PCR_YCPOS_SHIFT);
952}
953
954/*
955 * preview_config_averager - Enable / disable / configure averager
956 * @average: Average value to be configured.
957 */
958static void preview_config_averager(struct isp_prev_device *prev, u8 average)
959{
960 struct isp_device *isp = to_isp_device(prev);
961 int reg = 0;
962
963 if (prev->params.cfa.format == OMAP3ISP_CFAFMT_BAYER)
964 reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
965 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
966 average;
967 else if (prev->params.cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON)
968 reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT |
969 ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT |
970 average;
971 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
972}
973
974/*
975 * preview_config_input_size - Configure the input frame size
976 *
977 * The preview engine crops several rows and columns internally depending on
978 * which processing blocks are enabled. The driver assumes all those blocks are
979 * enabled when reporting source pad formats to userspace. If this assumption is
980 * not true, rows and columns must be manually cropped at the preview engine
981 * input to avoid overflows at the end of lines and frames.
982 */
983static void preview_config_input_size(struct isp_prev_device *prev)
984{
985 struct isp_device *isp = to_isp_device(prev);
986 struct prev_params *params = &prev->params;
987 struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
988 unsigned int sph = 0;
989 unsigned int eph = format->width - 1;
990 unsigned int slv = 0;
991 unsigned int elv = format->height - 1;
992
993 if (prev->input == PREVIEW_INPUT_CCDC) {
994 sph += 2;
995 eph -= 2;
996 }
997
998 /*
999 * Median filter 4 pixels
1000 * Noise filter 4 pixels, 4 lines
1001 * or faulty pixels correction
1002 * CFA filter 4 pixels, 4 lines in Bayer mode
1003 * 2 lines in other modes
1004 * Color suppression 2 pixels
1005 * or luma enhancement
1006 * -------------------------------------------------------------
1007 * Maximum total 14 pixels, 8 lines
1008 */
1009
1010 if (!(params->features & PREV_CFA)) {
1011 sph += 2;
1012 eph -= 2;
1013 slv += 2;
1014 elv -= 2;
1015 }
1016 if (!(params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER))) {
1017 sph += 2;
1018 eph -= 2;
1019 slv += 2;
1020 elv -= 2;
1021 }
1022 if (!(params->features & PREV_HORZ_MEDIAN_FILTER)) {
1023 sph += 2;
1024 eph -= 2;
1025 }
1026 if (!(params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE)))
1027 sph += 2;
1028
1029 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
1030 OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO);
1031 isp_reg_writel(isp, (slv << ISPPRV_VERT_INFO_SLV_SHIFT) | elv,
1032 OMAP3_ISP_IOMEM_PREV, ISPPRV_VERT_INFO);
1033}
1034
1035/*
1036 * preview_config_inlineoffset - Configures the Read address line offset.
1037 * @prev: Preview module
1038 * @offset: Line offset
1039 *
1040 * According to the TRM, the line offset must be aligned on a 32 bytes boundary.
1041 * However, a hardware bug requires the memory start address to be aligned on a
1042 * 64 bytes boundary, so the offset probably should be aligned on 64 bytes as
1043 * well.
1044 */
1045static void
1046preview_config_inlineoffset(struct isp_prev_device *prev, u32 offset)
1047{
1048 struct isp_device *isp = to_isp_device(prev);
1049
1050 isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
1051 ISPPRV_RADR_OFFSET);
1052}
1053
1054/*
1055 * preview_set_inaddr - Sets memory address of input frame.
1056 * @addr: 32bit memory address aligned on 32byte boundary.
1057 *
1058 * Configures the memory address from which the input frame is to be read.
1059 */
1060static void preview_set_inaddr(struct isp_prev_device *prev, u32 addr)
1061{
1062 struct isp_device *isp = to_isp_device(prev);
1063
1064 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_RSDR_ADDR);
1065}
1066
1067/*
1068 * preview_config_outlineoffset - Configures the Write address line offset.
1069 * @offset: Line Offset for the preview output.
1070 *
1071 * The offset must be a multiple of 32 bytes.
1072 */
1073static void preview_config_outlineoffset(struct isp_prev_device *prev,
1074 u32 offset)
1075{
1076 struct isp_device *isp = to_isp_device(prev);
1077
1078 isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
1079 ISPPRV_WADD_OFFSET);
1080}
1081
1082/*
1083 * preview_set_outaddr - Sets the memory address to store output frame
1084 * @addr: 32bit memory address aligned on 32byte boundary.
1085 *
1086 * Configures the memory address to which the output frame is written.
1087 */
1088static void preview_set_outaddr(struct isp_prev_device *prev, u32 addr)
1089{
1090 struct isp_device *isp = to_isp_device(prev);
1091
1092 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_WSDR_ADDR);
1093}
1094
1095static void preview_adjust_bandwidth(struct isp_prev_device *prev)
1096{
1097 struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
1098 struct isp_device *isp = to_isp_device(prev);
1099 const struct v4l2_mbus_framefmt *ifmt = &prev->formats[PREV_PAD_SINK];
1100 unsigned long l3_ick = pipe->l3_ick;
1101 struct v4l2_fract *timeperframe;
1102 unsigned int cycles_per_frame;
1103 unsigned int requests_per_frame;
1104 unsigned int cycles_per_request;
1105 unsigned int minimum;
1106 unsigned int maximum;
1107 unsigned int value;
1108
1109 if (prev->input != PREVIEW_INPUT_MEMORY) {
1110 isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
1111 ISPSBL_SDR_REQ_PRV_EXP_MASK);
1112 return;
1113 }
1114
1115 /* Compute the minimum number of cycles per request, based on the
1116 * pipeline maximum data rate. This is an absolute lower bound if we
1117 * don't want SBL overflows, so round the value up.
1118 */
1119 cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
1120 pipe->max_rate);
1121 minimum = DIV_ROUND_UP(cycles_per_request, 32);
1122
1123 /* Compute the maximum number of cycles per request, based on the
1124 * requested frame rate. This is a soft upper bound to achieve a frame
1125 * rate equal or higher than the requested value, so round the value
1126 * down.
1127 */
1128 timeperframe = &pipe->max_timeperframe;
1129
1130 requests_per_frame = DIV_ROUND_UP(ifmt->width * 2, 256) * ifmt->height;
1131 cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
1132 timeperframe->denominator);
1133 cycles_per_request = cycles_per_frame / requests_per_frame;
1134
1135 maximum = cycles_per_request / 32;
1136
1137 value = max(minimum, maximum);
1138
1139 dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
1140 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
1141 ISPSBL_SDR_REQ_PRV_EXP_MASK,
1142 value << ISPSBL_SDR_REQ_PRV_EXP_SHIFT);
1143}
1144
1145/*
1146 * omap3isp_preview_busy - Gets busy state of preview module.
1147 */
1148int omap3isp_preview_busy(struct isp_prev_device *prev)
1149{
1150 struct isp_device *isp = to_isp_device(prev);
1151
1152 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR)
1153 & ISPPRV_PCR_BUSY;
1154}
1155
1156/*
1157 * omap3isp_preview_restore_context - Restores the values of preview registers
1158 */
1159void omap3isp_preview_restore_context(struct isp_device *isp)
1160{
1161 isp->isp_prev.update = PREV_FEATURES_END - 1;
1162 preview_setup_hw(&isp->isp_prev);
1163}
1164
1165/*
1166 * preview_print_status - Dump preview module registers to the kernel log
1167 */
1168#define PREV_PRINT_REGISTER(isp, name)\
1169 dev_dbg(isp->dev, "###PRV " #name "=0x%08x\n", \
1170 isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_##name))
1171
1172static void preview_print_status(struct isp_prev_device *prev)
1173{
1174 struct isp_device *isp = to_isp_device(prev);
1175
1176 dev_dbg(isp->dev, "-------------Preview Register dump----------\n");
1177
1178 PREV_PRINT_REGISTER(isp, PCR);
1179 PREV_PRINT_REGISTER(isp, HORZ_INFO);
1180 PREV_PRINT_REGISTER(isp, VERT_INFO);
1181 PREV_PRINT_REGISTER(isp, RSDR_ADDR);
1182 PREV_PRINT_REGISTER(isp, RADR_OFFSET);
1183 PREV_PRINT_REGISTER(isp, DSDR_ADDR);
1184 PREV_PRINT_REGISTER(isp, DRKF_OFFSET);
1185 PREV_PRINT_REGISTER(isp, WSDR_ADDR);
1186 PREV_PRINT_REGISTER(isp, WADD_OFFSET);
1187 PREV_PRINT_REGISTER(isp, AVE);
1188 PREV_PRINT_REGISTER(isp, HMED);
1189 PREV_PRINT_REGISTER(isp, NF);
1190 PREV_PRINT_REGISTER(isp, WB_DGAIN);
1191 PREV_PRINT_REGISTER(isp, WBGAIN);
1192 PREV_PRINT_REGISTER(isp, WBSEL);
1193 PREV_PRINT_REGISTER(isp, CFA);
1194 PREV_PRINT_REGISTER(isp, BLKADJOFF);
1195 PREV_PRINT_REGISTER(isp, RGB_MAT1);
1196 PREV_PRINT_REGISTER(isp, RGB_MAT2);
1197 PREV_PRINT_REGISTER(isp, RGB_MAT3);
1198 PREV_PRINT_REGISTER(isp, RGB_MAT4);
1199 PREV_PRINT_REGISTER(isp, RGB_MAT5);
1200 PREV_PRINT_REGISTER(isp, RGB_OFF1);
1201 PREV_PRINT_REGISTER(isp, RGB_OFF2);
1202 PREV_PRINT_REGISTER(isp, CSC0);
1203 PREV_PRINT_REGISTER(isp, CSC1);
1204 PREV_PRINT_REGISTER(isp, CSC2);
1205 PREV_PRINT_REGISTER(isp, CSC_OFFSET);
1206 PREV_PRINT_REGISTER(isp, CNT_BRT);
1207 PREV_PRINT_REGISTER(isp, CSUP);
1208 PREV_PRINT_REGISTER(isp, SETUP_YC);
1209 PREV_PRINT_REGISTER(isp, SET_TBL_ADDR);
1210 PREV_PRINT_REGISTER(isp, CDC_THR0);
1211 PREV_PRINT_REGISTER(isp, CDC_THR1);
1212 PREV_PRINT_REGISTER(isp, CDC_THR2);
1213 PREV_PRINT_REGISTER(isp, CDC_THR3);
1214
1215 dev_dbg(isp->dev, "--------------------------------------------\n");
1216}
1217
1218/*
1219 * preview_init_params - init image processing parameters.
1220 * @prev: pointer to previewer private structure
1221 * return none
1222 */
1223static void preview_init_params(struct isp_prev_device *prev)
1224{
1225 struct prev_params *params = &prev->params;
1226 int i = 0;
1227
1228 /* Init values */
1229 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
1230 params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS;
1231 params->average = NO_AVE;
1232 params->cfa.format = OMAP3ISP_CFAFMT_BAYER;
1233 memcpy(params->cfa.table, cfa_coef_table,
1234 sizeof(params->cfa.table));
1235 params->cfa.gradthrs_horz = FLR_CFA_GRADTHRS_HORZ;
1236 params->cfa.gradthrs_vert = FLR_CFA_GRADTHRS_VERT;
1237 params->csup.gain = FLR_CSUP_GAIN;
1238 params->csup.thres = FLR_CSUP_THRES;
1239 params->csup.hypf_en = 0;
1240 memcpy(params->luma.table, luma_enhance_table,
1241 sizeof(params->luma.table));
1242 params->nf.spread = FLR_NF_STRGTH;
1243 memcpy(params->nf.table, noise_filter_table, sizeof(params->nf.table));
1244 params->dcor.couplet_mode_en = 1;
1245 for (i = 0; i < OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS; i++)
1246 params->dcor.detect_correct[i] = DEF_DETECT_CORRECT_VAL;
1247 memcpy(params->gamma.blue, gamma_table, sizeof(params->gamma.blue));
1248 memcpy(params->gamma.green, gamma_table, sizeof(params->gamma.green));
1249 memcpy(params->gamma.red, gamma_table, sizeof(params->gamma.red));
1250 params->wbal.dgain = FLR_WBAL_DGAIN;
1251 params->wbal.coef0 = FLR_WBAL_COEF;
1252 params->wbal.coef1 = FLR_WBAL_COEF;
1253 params->wbal.coef2 = FLR_WBAL_COEF;
1254 params->wbal.coef3 = FLR_WBAL_COEF;
1255 params->blk_adj.red = FLR_BLKADJ_RED;
1256 params->blk_adj.green = FLR_BLKADJ_GREEN;
1257 params->blk_adj.blue = FLR_BLKADJ_BLUE;
1258 params->rgb2rgb = flr_rgb2rgb;
1259 params->rgb2ycbcr = flr_prev_csc;
1260 params->yclimit.minC = ISPPRV_YC_MIN;
1261 params->yclimit.maxC = ISPPRV_YC_MAX;
1262 params->yclimit.minY = ISPPRV_YC_MIN;
1263 params->yclimit.maxY = ISPPRV_YC_MAX;
1264
1265 params->features = PREV_CFA | PREV_DEFECT_COR | PREV_NOISE_FILTER
1266 | PREV_GAMMA | PREV_BLKADJ | PREV_YCLIMITS
1267 | PREV_RGB2RGB | PREV_COLOR_CONV | PREV_WB
1268 | PREV_BRIGHTNESS | PREV_CONTRAST;
1269
1270 prev->update = PREV_FEATURES_END - 1;
1271}
1272
1273/*
1274 * preview_max_out_width - Handle previewer hardware ouput limitations
1275 * @isp_revision : ISP revision
1276 * returns maximum width output for current isp revision
1277 */
1278static unsigned int preview_max_out_width(struct isp_prev_device *prev)
1279{
1280 struct isp_device *isp = to_isp_device(prev);
1281
1282 switch (isp->revision) {
1283 case ISP_REVISION_1_0:
1284 return ISPPRV_MAXOUTPUT_WIDTH;
1285
1286 case ISP_REVISION_2_0:
1287 default:
1288 return ISPPRV_MAXOUTPUT_WIDTH_ES2;
1289
1290 case ISP_REVISION_15_0:
1291 return ISPPRV_MAXOUTPUT_WIDTH_3630;
1292 }
1293}
1294
1295static void preview_configure(struct isp_prev_device *prev)
1296{
1297 struct isp_device *isp = to_isp_device(prev);
1298 struct v4l2_mbus_framefmt *format;
1299 unsigned int max_out_width;
1300 unsigned int format_avg;
1301
1302 preview_setup_hw(prev);
1303
1304 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1305 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1306 ISPPRV_PCR_SDRPORT);
1307 else
1308 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1309 ISPPRV_PCR_SDRPORT);
1310
1311 if (prev->output & PREVIEW_OUTPUT_RESIZER)
1312 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1313 ISPPRV_PCR_RSZPORT);
1314 else
1315 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1316 ISPPRV_PCR_RSZPORT);
1317
1318 /* PREV_PAD_SINK */
1319 format = &prev->formats[PREV_PAD_SINK];
1320
1321 preview_adjust_bandwidth(prev);
1322
1323 preview_config_input_size(prev);
1324
1325 if (prev->input == PREVIEW_INPUT_CCDC)
1326 preview_config_inlineoffset(prev, 0);
1327 else
1328 preview_config_inlineoffset(prev,
1329 ALIGN(format->width, 0x20) * 2);
1330
1331 /* PREV_PAD_SOURCE */
1332 format = &prev->formats[PREV_PAD_SOURCE];
1333
1334 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1335 preview_config_outlineoffset(prev,
1336 ALIGN(format->width, 0x10) * 2);
1337
1338 max_out_width = preview_max_out_width(prev);
1339
1340 format_avg = fls(DIV_ROUND_UP(format->width, max_out_width) - 1);
1341 preview_config_averager(prev, format_avg);
1342 preview_config_ycpos(prev, format->code);
1343}
1344
1345/* -----------------------------------------------------------------------------
1346 * Interrupt handling
1347 */
1348
1349static void preview_enable_oneshot(struct isp_prev_device *prev)
1350{
1351 struct isp_device *isp = to_isp_device(prev);
1352
1353 /* The PCR.SOURCE bit is automatically reset to 0 when the PCR.ENABLE
1354 * bit is set. As the preview engine is used in single-shot mode, we
1355 * need to set PCR.SOURCE before enabling the preview engine.
1356 */
1357 if (prev->input == PREVIEW_INPUT_MEMORY)
1358 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1359 ISPPRV_PCR_SOURCE);
1360
1361 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1362 ISPPRV_PCR_EN | ISPPRV_PCR_ONESHOT);
1363}
1364
1365void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev)
1366{
1367 /*
1368 * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
1369 * condition, the module was paused and now we have a buffer queued
1370 * on the output again. Restart the pipeline if running in continuous
1371 * mode.
1372 */
1373 if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
1374 prev->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
1375 preview_enable_oneshot(prev);
1376 isp_video_dmaqueue_flags_clr(&prev->video_out);
1377 }
1378}
1379
1380static void preview_isr_buffer(struct isp_prev_device *prev)
1381{
1382 struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
1383 struct isp_buffer *buffer;
1384 int restart = 0;
1385
1386 if (prev->input == PREVIEW_INPUT_MEMORY) {
1387 buffer = omap3isp_video_buffer_next(&prev->video_in,
1388 prev->error);
1389 if (buffer != NULL)
1390 preview_set_inaddr(prev, buffer->isp_addr);
1391 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
1392 }
1393
1394 if (prev->output & PREVIEW_OUTPUT_MEMORY) {
1395 buffer = omap3isp_video_buffer_next(&prev->video_out,
1396 prev->error);
1397 if (buffer != NULL) {
1398 preview_set_outaddr(prev, buffer->isp_addr);
1399 restart = 1;
1400 }
1401 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1402 }
1403
1404 switch (prev->state) {
1405 case ISP_PIPELINE_STREAM_SINGLESHOT:
1406 if (isp_pipeline_ready(pipe))
1407 omap3isp_pipeline_set_stream(pipe,
1408 ISP_PIPELINE_STREAM_SINGLESHOT);
1409 break;
1410
1411 case ISP_PIPELINE_STREAM_CONTINUOUS:
1412 /* If an underrun occurs, the video queue operation handler will
1413 * restart the preview engine. Otherwise restart it immediately.
1414 */
1415 if (restart)
1416 preview_enable_oneshot(prev);
1417 break;
1418
1419 case ISP_PIPELINE_STREAM_STOPPED:
1420 default:
1421 return;
1422 }
1423
1424 prev->error = 0;
1425}
1426
1427/*
1428 * omap3isp_preview_isr - ISP preview engine interrupt handler
1429 *
1430 * Manage the preview engine video buffers and configure shadowed registers.
1431 */
1432void omap3isp_preview_isr(struct isp_prev_device *prev)
1433{
1434 unsigned long flags;
1435
1436 if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping))
1437 return;
1438
1439 spin_lock_irqsave(&prev->lock, flags);
1440 if (prev->shadow_update)
1441 goto done;
1442
1443 preview_setup_hw(prev);
1444 preview_config_input_size(prev);
1445
1446done:
1447 spin_unlock_irqrestore(&prev->lock, flags);
1448
1449 if (prev->input == PREVIEW_INPUT_MEMORY ||
1450 prev->output & PREVIEW_OUTPUT_MEMORY)
1451 preview_isr_buffer(prev);
1452 else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1453 preview_enable_oneshot(prev);
1454}
1455
1456/* -----------------------------------------------------------------------------
1457 * ISP video operations
1458 */
1459
1460static int preview_video_queue(struct isp_video *video,
1461 struct isp_buffer *buffer)
1462{
1463 struct isp_prev_device *prev = &video->isp->isp_prev;
1464
1465 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1466 preview_set_inaddr(prev, buffer->isp_addr);
1467
1468 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1469 preview_set_outaddr(prev, buffer->isp_addr);
1470
1471 return 0;
1472}
1473
1474static const struct isp_video_operations preview_video_ops = {
1475 .queue = preview_video_queue,
1476};
1477
1478/* -----------------------------------------------------------------------------
1479 * V4L2 subdev operations
1480 */
1481
1482/*
1483 * preview_s_ctrl - Handle set control subdev method
1484 * @ctrl: pointer to v4l2 control structure
1485 */
1486static int preview_s_ctrl(struct v4l2_ctrl *ctrl)
1487{
1488 struct isp_prev_device *prev =
1489 container_of(ctrl->handler, struct isp_prev_device, ctrls);
1490
1491 switch (ctrl->id) {
1492 case V4L2_CID_BRIGHTNESS:
1493 preview_update_brightness(prev, ctrl->val);
1494 break;
1495 case V4L2_CID_CONTRAST:
1496 preview_update_contrast(prev, ctrl->val);
1497 break;
1498 }
1499
1500 return 0;
1501}
1502
1503static const struct v4l2_ctrl_ops preview_ctrl_ops = {
1504 .s_ctrl = preview_s_ctrl,
1505};
1506
1507/*
1508 * preview_ioctl - Handle preview module private ioctl's
1509 * @prev: pointer to preview context structure
1510 * @cmd: configuration command
1511 * @arg: configuration argument
1512 * return -EINVAL or zero on success
1513 */
1514static long preview_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1515{
1516 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1517
1518 switch (cmd) {
1519 case VIDIOC_OMAP3ISP_PRV_CFG:
1520 return preview_config(prev, arg);
1521
1522 default:
1523 return -ENOIOCTLCMD;
1524 }
1525}
1526
1527/*
1528 * preview_set_stream - Enable/Disable streaming on preview subdev
1529 * @sd : pointer to v4l2 subdev structure
1530 * @enable: 1 == Enable, 0 == Disable
1531 * return -EINVAL or zero on sucess
1532 */
1533static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1534{
1535 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1536 struct isp_video *video_out = &prev->video_out;
1537 struct isp_device *isp = to_isp_device(prev);
1538 struct device *dev = to_device(prev);
1539 unsigned long flags;
1540
1541 if (prev->state == ISP_PIPELINE_STREAM_STOPPED) {
1542 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1543 return 0;
1544
1545 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1546 preview_configure(prev);
1547 atomic_set(&prev->stopping, 0);
1548 prev->error = 0;
1549 preview_print_status(prev);
1550 }
1551
1552 switch (enable) {
1553 case ISP_PIPELINE_STREAM_CONTINUOUS:
1554 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1555 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1556
1557 if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED ||
1558 !(prev->output & PREVIEW_OUTPUT_MEMORY))
1559 preview_enable_oneshot(prev);
1560
1561 isp_video_dmaqueue_flags_clr(video_out);
1562 break;
1563
1564 case ISP_PIPELINE_STREAM_SINGLESHOT:
1565 if (prev->input == PREVIEW_INPUT_MEMORY)
1566 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1567 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1568 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1569
1570 preview_enable_oneshot(prev);
1571 break;
1572
1573 case ISP_PIPELINE_STREAM_STOPPED:
1574 if (omap3isp_module_sync_idle(&sd->entity, &prev->wait,
1575 &prev->stopping))
1576 dev_dbg(dev, "%s: stop timeout.\n", sd->name);
1577 spin_lock_irqsave(&prev->lock, flags);
1578 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1579 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1580 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1581 spin_unlock_irqrestore(&prev->lock, flags);
1582 isp_video_dmaqueue_flags_clr(video_out);
1583 break;
1584 }
1585
1586 prev->state = enable;
1587 return 0;
1588}
1589
1590static struct v4l2_mbus_framefmt *
1591__preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1592 unsigned int pad, enum v4l2_subdev_format_whence which)
1593{
1594 if (which == V4L2_SUBDEV_FORMAT_TRY)
1595 return v4l2_subdev_get_try_format(fh, pad);
1596 else
1597 return &prev->formats[pad];
1598}
1599
1600/* previewer format descriptions */
1601static const unsigned int preview_input_fmts[] = {
1602 V4L2_MBUS_FMT_SGRBG10_1X10,
1603 V4L2_MBUS_FMT_SRGGB10_1X10,
1604 V4L2_MBUS_FMT_SBGGR10_1X10,
1605 V4L2_MBUS_FMT_SGBRG10_1X10,
1606};
1607
1608static const unsigned int preview_output_fmts[] = {
1609 V4L2_MBUS_FMT_UYVY8_1X16,
1610 V4L2_MBUS_FMT_YUYV8_1X16,
1611};
1612
1613/*
1614 * preview_try_format - Handle try format by pad subdev method
1615 * @prev: ISP preview device
1616 * @fh : V4L2 subdev file handle
1617 * @pad: pad num
1618 * @fmt: pointer to v4l2 format structure
1619 */
1620static void preview_try_format(struct isp_prev_device *prev,
1621 struct v4l2_subdev_fh *fh, unsigned int pad,
1622 struct v4l2_mbus_framefmt *fmt,
1623 enum v4l2_subdev_format_whence which)
1624{
1625 struct v4l2_mbus_framefmt *format;
1626 unsigned int max_out_width;
1627 enum v4l2_mbus_pixelcode pixelcode;
1628 unsigned int i;
1629
1630 max_out_width = preview_max_out_width(prev);
1631
1632 switch (pad) {
1633 case PREV_PAD_SINK:
1634 /* When reading data from the CCDC, the input size has already
1635 * been mangled by the CCDC output pad so it can be accepted
1636 * as-is.
1637 *
1638 * When reading data from memory, clamp the requested width and
1639 * height. The TRM doesn't specify a minimum input height, make
1640 * sure we got enough lines to enable the noise filter and color
1641 * filter array interpolation.
1642 */
1643 if (prev->input == PREVIEW_INPUT_MEMORY) {
1644 fmt->width = clamp_t(u32, fmt->width, PREV_MIN_WIDTH,
1645 max_out_width * 8);
1646 fmt->height = clamp_t(u32, fmt->height, PREV_MIN_HEIGHT,
1647 PREV_MAX_HEIGHT);
1648 }
1649
1650 fmt->colorspace = V4L2_COLORSPACE_SRGB;
1651
1652 for (i = 0; i < ARRAY_SIZE(preview_input_fmts); i++) {
1653 if (fmt->code == preview_input_fmts[i])
1654 break;
1655 }
1656
1657 /* If not found, use SGRBG10 as default */
1658 if (i >= ARRAY_SIZE(preview_input_fmts))
1659 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
1660 break;
1661
1662 case PREV_PAD_SOURCE:
1663 pixelcode = fmt->code;
1664 format = __preview_get_format(prev, fh, PREV_PAD_SINK, which);
1665 memcpy(fmt, format, sizeof(*fmt));
1666
1667 /* The preview module output size is configurable through the
1668 * input interface (horizontal and vertical cropping) and the
1669 * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). In
1670 * spite of this, hardcode the output size to the biggest
1671 * possible value for simplicity reasons.
1672 */
1673 switch (pixelcode) {
1674 case V4L2_MBUS_FMT_YUYV8_1X16:
1675 case V4L2_MBUS_FMT_UYVY8_1X16:
1676 fmt->code = pixelcode;
1677 break;
1678
1679 default:
1680 fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
1681 break;
1682 }
1683
1684 /* The TRM states (12.1.4.7.1.2) that 2 pixels must be cropped
1685 * from the left and right sides when the input source is the
1686 * CCDC. This seems not to be needed in practice, investigation
1687 * is required.
1688 */
1689 if (prev->input == PREVIEW_INPUT_CCDC)
1690 fmt->width -= 4;
1691
1692 /* The preview module can output a maximum of 3312 pixels
1693 * horizontally due to fixed memory-line sizes. Compute the
1694 * horizontal averaging factor accordingly. Note that the limit
1695 * applies to the noise filter and CFA interpolation blocks, so
1696 * it doesn't take cropping by further blocks into account.
1697 *
1698 * ES 1.0 hardware revision is limited to 1280 pixels
1699 * horizontally.
1700 */
1701 fmt->width >>= fls(DIV_ROUND_UP(fmt->width, max_out_width) - 1);
1702
1703 /* Assume that all blocks are enabled and crop pixels and lines
1704 * accordingly. See preview_config_input_size() for more
1705 * information.
1706 */
1707 fmt->width -= 14;
1708 fmt->height -= 8;
1709
1710 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1711 break;
1712 }
1713
1714 fmt->field = V4L2_FIELD_NONE;
1715}
1716
1717/*
1718 * preview_enum_mbus_code - Handle pixel format enumeration
1719 * @sd : pointer to v4l2 subdev structure
1720 * @fh : V4L2 subdev file handle
1721 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1722 * return -EINVAL or zero on success
1723 */
1724static int preview_enum_mbus_code(struct v4l2_subdev *sd,
1725 struct v4l2_subdev_fh *fh,
1726 struct v4l2_subdev_mbus_code_enum *code)
1727{
1728 switch (code->pad) {
1729 case PREV_PAD_SINK:
1730 if (code->index >= ARRAY_SIZE(preview_input_fmts))
1731 return -EINVAL;
1732
1733 code->code = preview_input_fmts[code->index];
1734 break;
1735 case PREV_PAD_SOURCE:
1736 if (code->index >= ARRAY_SIZE(preview_output_fmts))
1737 return -EINVAL;
1738
1739 code->code = preview_output_fmts[code->index];
1740 break;
1741 default:
1742 return -EINVAL;
1743 }
1744
1745 return 0;
1746}
1747
1748static int preview_enum_frame_size(struct v4l2_subdev *sd,
1749 struct v4l2_subdev_fh *fh,
1750 struct v4l2_subdev_frame_size_enum *fse)
1751{
1752 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1753 struct v4l2_mbus_framefmt format;
1754
1755 if (fse->index != 0)
1756 return -EINVAL;
1757
1758 format.code = fse->code;
1759 format.width = 1;
1760 format.height = 1;
1761 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1762 fse->min_width = format.width;
1763 fse->min_height = format.height;
1764
1765 if (format.code != fse->code)
1766 return -EINVAL;
1767
1768 format.code = fse->code;
1769 format.width = -1;
1770 format.height = -1;
1771 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1772 fse->max_width = format.width;
1773 fse->max_height = format.height;
1774
1775 return 0;
1776}
1777
1778/*
1779 * preview_get_format - Handle get format by pads subdev method
1780 * @sd : pointer to v4l2 subdev structure
1781 * @fh : V4L2 subdev file handle
1782 * @fmt: pointer to v4l2 subdev format structure
1783 * return -EINVAL or zero on sucess
1784 */
1785static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1786 struct v4l2_subdev_format *fmt)
1787{
1788 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1789 struct v4l2_mbus_framefmt *format;
1790
1791 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
1792 if (format == NULL)
1793 return -EINVAL;
1794
1795 fmt->format = *format;
1796 return 0;
1797}
1798
1799/*
1800 * preview_set_format - Handle set format by pads subdev method
1801 * @sd : pointer to v4l2 subdev structure
1802 * @fh : V4L2 subdev file handle
1803 * @fmt: pointer to v4l2 subdev format structure
1804 * return -EINVAL or zero on success
1805 */
1806static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1807 struct v4l2_subdev_format *fmt)
1808{
1809 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1810 struct v4l2_mbus_framefmt *format;
1811
1812 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
1813 if (format == NULL)
1814 return -EINVAL;
1815
1816 preview_try_format(prev, fh, fmt->pad, &fmt->format, fmt->which);
1817 *format = fmt->format;
1818
1819 /* Propagate the format from sink to source */
1820 if (fmt->pad == PREV_PAD_SINK) {
1821 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE,
1822 fmt->which);
1823 *format = fmt->format;
1824 preview_try_format(prev, fh, PREV_PAD_SOURCE, format,
1825 fmt->which);
1826 }
1827
1828 return 0;
1829}
1830
1831/*
1832 * preview_init_formats - Initialize formats on all pads
1833 * @sd: ISP preview V4L2 subdevice
1834 * @fh: V4L2 subdev file handle
1835 *
1836 * Initialize all pad formats with default values. If fh is not NULL, try
1837 * formats are initialized on the file handle. Otherwise active formats are
1838 * initialized on the device.
1839 */
1840static int preview_init_formats(struct v4l2_subdev *sd,
1841 struct v4l2_subdev_fh *fh)
1842{
1843 struct v4l2_subdev_format format;
1844
1845 memset(&format, 0, sizeof(format));
1846 format.pad = PREV_PAD_SINK;
1847 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1848 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1849 format.format.width = 4096;
1850 format.format.height = 4096;
1851 preview_set_format(sd, fh, &format);
1852
1853 return 0;
1854}
1855
1856/* subdev core operations */
1857static const struct v4l2_subdev_core_ops preview_v4l2_core_ops = {
1858 .ioctl = preview_ioctl,
1859};
1860
1861/* subdev video operations */
1862static const struct v4l2_subdev_video_ops preview_v4l2_video_ops = {
1863 .s_stream = preview_set_stream,
1864};
1865
1866/* subdev pad operations */
1867static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
1868 .enum_mbus_code = preview_enum_mbus_code,
1869 .enum_frame_size = preview_enum_frame_size,
1870 .get_fmt = preview_get_format,
1871 .set_fmt = preview_set_format,
1872};
1873
1874/* subdev operations */
1875static const struct v4l2_subdev_ops preview_v4l2_ops = {
1876 .core = &preview_v4l2_core_ops,
1877 .video = &preview_v4l2_video_ops,
1878 .pad = &preview_v4l2_pad_ops,
1879};
1880
1881/* subdev internal operations */
1882static const struct v4l2_subdev_internal_ops preview_v4l2_internal_ops = {
1883 .open = preview_init_formats,
1884};
1885
1886/* -----------------------------------------------------------------------------
1887 * Media entity operations
1888 */
1889
1890/*
1891 * preview_link_setup - Setup previewer connections.
1892 * @entity : Pointer to media entity structure
1893 * @local : Pointer to local pad array
1894 * @remote : Pointer to remote pad array
1895 * @flags : Link flags
1896 * return -EINVAL or zero on success
1897 */
1898static int preview_link_setup(struct media_entity *entity,
1899 const struct media_pad *local,
1900 const struct media_pad *remote, u32 flags)
1901{
1902 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1903 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1904
1905 switch (local->index | media_entity_type(remote->entity)) {
1906 case PREV_PAD_SINK | MEDIA_ENT_T_DEVNODE:
1907 /* read from memory */
1908 if (flags & MEDIA_LNK_FL_ENABLED) {
1909 if (prev->input == PREVIEW_INPUT_CCDC)
1910 return -EBUSY;
1911 prev->input = PREVIEW_INPUT_MEMORY;
1912 } else {
1913 if (prev->input == PREVIEW_INPUT_MEMORY)
1914 prev->input = PREVIEW_INPUT_NONE;
1915 }
1916 break;
1917
1918 case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
1919 /* read from ccdc */
1920 if (flags & MEDIA_LNK_FL_ENABLED) {
1921 if (prev->input == PREVIEW_INPUT_MEMORY)
1922 return -EBUSY;
1923 prev->input = PREVIEW_INPUT_CCDC;
1924 } else {
1925 if (prev->input == PREVIEW_INPUT_CCDC)
1926 prev->input = PREVIEW_INPUT_NONE;
1927 }
1928 break;
1929
1930 /*
1931 * The ISP core doesn't support pipelines with multiple video outputs.
1932 * Revisit this when it will be implemented, and return -EBUSY for now.
1933 */
1934
1935 case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1936 /* write to memory */
1937 if (flags & MEDIA_LNK_FL_ENABLED) {
1938 if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
1939 return -EBUSY;
1940 prev->output |= PREVIEW_OUTPUT_MEMORY;
1941 } else {
1942 prev->output &= ~PREVIEW_OUTPUT_MEMORY;
1943 }
1944 break;
1945
1946 case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1947 /* write to resizer */
1948 if (flags & MEDIA_LNK_FL_ENABLED) {
1949 if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
1950 return -EBUSY;
1951 prev->output |= PREVIEW_OUTPUT_RESIZER;
1952 } else {
1953 prev->output &= ~PREVIEW_OUTPUT_RESIZER;
1954 }
1955 break;
1956
1957 default:
1958 return -EINVAL;
1959 }
1960
1961 return 0;
1962}
1963
1964/* media operations */
1965static const struct media_entity_operations preview_media_ops = {
1966 .link_setup = preview_link_setup,
1967};
1968
1969/*
1970 * review_init_entities - Initialize subdev and media entity.
1971 * @prev : Pointer to preview structure
1972 * return -ENOMEM or zero on success
1973 */
1974static int preview_init_entities(struct isp_prev_device *prev)
1975{
1976 struct v4l2_subdev *sd = &prev->subdev;
1977 struct media_pad *pads = prev->pads;
1978 struct media_entity *me = &sd->entity;
1979 int ret;
1980
1981 prev->input = PREVIEW_INPUT_NONE;
1982
1983 v4l2_subdev_init(sd, &preview_v4l2_ops);
1984 sd->internal_ops = &preview_v4l2_internal_ops;
1985 strlcpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name));
1986 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1987 v4l2_set_subdevdata(sd, prev);
1988 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1989
1990 v4l2_ctrl_handler_init(&prev->ctrls, 2);
1991 v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_BRIGHTNESS,
1992 ISPPRV_BRIGHT_LOW, ISPPRV_BRIGHT_HIGH,
1993 ISPPRV_BRIGHT_STEP, ISPPRV_BRIGHT_DEF);
1994 v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_CONTRAST,
1995 ISPPRV_CONTRAST_LOW, ISPPRV_CONTRAST_HIGH,
1996 ISPPRV_CONTRAST_STEP, ISPPRV_CONTRAST_DEF);
1997 v4l2_ctrl_handler_setup(&prev->ctrls);
1998 sd->ctrl_handler = &prev->ctrls;
1999
2000 pads[PREV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2001 pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
2002
2003 me->ops = &preview_media_ops;
2004 ret = media_entity_init(me, PREV_PADS_NUM, pads, 0);
2005 if (ret < 0)
2006 return ret;
2007
2008 preview_init_formats(sd, NULL);
2009
2010 /* According to the OMAP34xx TRM, video buffers need to be aligned on a
2011 * 32 bytes boundary. However, an undocumented hardware bug requires a
2012 * 64 bytes boundary at the preview engine input.
2013 */
2014 prev->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2015 prev->video_in.ops = &preview_video_ops;
2016 prev->video_in.isp = to_isp_device(prev);
2017 prev->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
2018 prev->video_in.bpl_alignment = 64;
2019 prev->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2020 prev->video_out.ops = &preview_video_ops;
2021 prev->video_out.isp = to_isp_device(prev);
2022 prev->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
2023 prev->video_out.bpl_alignment = 32;
2024
2025 ret = omap3isp_video_init(&prev->video_in, "preview");
2026 if (ret < 0)
2027 return ret;
2028
2029 ret = omap3isp_video_init(&prev->video_out, "preview");
2030 if (ret < 0)
2031 return ret;
2032
2033 /* Connect the video nodes to the previewer subdev. */
2034 ret = media_entity_create_link(&prev->video_in.video.entity, 0,
2035 &prev->subdev.entity, PREV_PAD_SINK, 0);
2036 if (ret < 0)
2037 return ret;
2038
2039 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
2040 &prev->video_out.video.entity, 0, 0);
2041 if (ret < 0)
2042 return ret;
2043
2044 return 0;
2045}
2046
2047void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
2048{
2049 media_entity_cleanup(&prev->subdev.entity);
2050
2051 v4l2_device_unregister_subdev(&prev->subdev);
2052 v4l2_ctrl_handler_free(&prev->ctrls);
2053 omap3isp_video_unregister(&prev->video_in);
2054 omap3isp_video_unregister(&prev->video_out);
2055}
2056
2057int omap3isp_preview_register_entities(struct isp_prev_device *prev,
2058 struct v4l2_device *vdev)
2059{
2060 int ret;
2061
2062 /* Register the subdev and video nodes. */
2063 ret = v4l2_device_register_subdev(vdev, &prev->subdev);
2064 if (ret < 0)
2065 goto error;
2066
2067 ret = omap3isp_video_register(&prev->video_in, vdev);
2068 if (ret < 0)
2069 goto error;
2070
2071 ret = omap3isp_video_register(&prev->video_out, vdev);
2072 if (ret < 0)
2073 goto error;
2074
2075 return 0;
2076
2077error:
2078 omap3isp_preview_unregister_entities(prev);
2079 return ret;
2080}
2081
2082/* -----------------------------------------------------------------------------
2083 * ISP previewer initialisation and cleanup
2084 */
2085
2086void omap3isp_preview_cleanup(struct isp_device *isp)
2087{
2088}
2089
2090/*
2091 * isp_preview_init - Previewer initialization.
2092 * @dev : Pointer to ISP device
2093 * return -ENOMEM or zero on success
2094 */
2095int omap3isp_preview_init(struct isp_device *isp)
2096{
2097 struct isp_prev_device *prev = &isp->isp_prev;
2098 int ret;
2099
2100 spin_lock_init(&prev->lock);
2101 init_waitqueue_head(&prev->wait);
2102 preview_init_params(prev);
2103
2104 ret = preview_init_entities(prev);
2105 if (ret < 0)
2106 goto out;
2107
2108out:
2109 if (ret)
2110 omap3isp_preview_cleanup(isp);
2111
2112 return ret;
2113}
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
new file mode 100644
index 000000000000..f2d63ca4bd6f
--- /dev/null
+++ b/drivers/media/video/omap3isp/isppreview.h
@@ -0,0 +1,214 @@
1/*
2 * isppreview.h
3 *
4 * TI OMAP3 ISP - Preview module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_PREVIEW_H
28#define OMAP3_ISP_PREVIEW_H
29
30#include <linux/omap3isp.h>
31#include <linux/types.h>
32#include <media/v4l2-ctrls.h>
33
34#include "ispvideo.h"
35
36#define ISPPRV_BRIGHT_STEP 0x1
37#define ISPPRV_BRIGHT_DEF 0x0
38#define ISPPRV_BRIGHT_LOW 0x0
39#define ISPPRV_BRIGHT_HIGH 0xFF
40#define ISPPRV_BRIGHT_UNITS 0x1
41
42#define ISPPRV_CONTRAST_STEP 0x1
43#define ISPPRV_CONTRAST_DEF 0x10
44#define ISPPRV_CONTRAST_LOW 0x0
45#define ISPPRV_CONTRAST_HIGH 0xFF
46#define ISPPRV_CONTRAST_UNITS 0x1
47
48#define NO_AVE 0x0
49#define AVE_2_PIX 0x1
50#define AVE_4_PIX 0x2
51#define AVE_8_PIX 0x3
52
53/* Features list */
54#define PREV_LUMA_ENHANCE OMAP3ISP_PREV_LUMAENH
55#define PREV_INVERSE_ALAW OMAP3ISP_PREV_INVALAW
56#define PREV_HORZ_MEDIAN_FILTER OMAP3ISP_PREV_HRZ_MED
57#define PREV_CFA OMAP3ISP_PREV_CFA
58#define PREV_CHROMA_SUPPRESS OMAP3ISP_PREV_CHROMA_SUPP
59#define PREV_WB OMAP3ISP_PREV_WB
60#define PREV_BLKADJ OMAP3ISP_PREV_BLKADJ
61#define PREV_RGB2RGB OMAP3ISP_PREV_RGB2RGB
62#define PREV_COLOR_CONV OMAP3ISP_PREV_COLOR_CONV
63#define PREV_YCLIMITS OMAP3ISP_PREV_YC_LIMIT
64#define PREV_DEFECT_COR OMAP3ISP_PREV_DEFECT_COR
65#define PREV_GAMMA_BYPASS OMAP3ISP_PREV_GAMMABYPASS
66#define PREV_DARK_FRAME_CAPTURE OMAP3ISP_PREV_DRK_FRM_CAPTURE
67#define PREV_DARK_FRAME_SUBTRACT OMAP3ISP_PREV_DRK_FRM_SUBTRACT
68#define PREV_LENS_SHADING OMAP3ISP_PREV_LENS_SHADING
69#define PREV_NOISE_FILTER OMAP3ISP_PREV_NF
70#define PREV_GAMMA OMAP3ISP_PREV_GAMMA
71
72#define PREV_CONTRAST (1 << 17)
73#define PREV_BRIGHTNESS (1 << 18)
74#define PREV_AVERAGER (1 << 19)
75#define PREV_FEATURES_END (1 << 20)
76
77enum preview_input_entity {
78 PREVIEW_INPUT_NONE,
79 PREVIEW_INPUT_CCDC,
80 PREVIEW_INPUT_MEMORY,
81};
82
83#define PREVIEW_OUTPUT_RESIZER (1 << 1)
84#define PREVIEW_OUTPUT_MEMORY (1 << 2)
85
86/* Configure byte layout of YUV image */
87enum preview_ycpos_mode {
88 YCPOS_YCrYCb = 0,
89 YCPOS_YCbYCr = 1,
90 YCPOS_CbYCrY = 2,
91 YCPOS_CrYCbY = 3
92};
93
94/*
95 * struct prev_params - Structure for all configuration
96 * @features: Set of features enabled.
97 * @cfa: CFA coefficients.
98 * @csup: Chroma suppression coefficients.
99 * @luma: Luma enhancement coefficients.
100 * @nf: Noise filter coefficients.
101 * @dcor: Noise filter coefficients.
102 * @gamma: Gamma coefficients.
103 * @wbal: White Balance parameters.
104 * @blk_adj: Black adjustment parameters.
105 * @rgb2rgb: RGB blending parameters.
106 * @rgb2ycbcr: RGB to ycbcr parameters.
107 * @hmed: Horizontal median filter.
108 * @yclimit: YC limits parameters.
109 * @average: Downsampling rate for averager.
110 * @contrast: Contrast.
111 * @brightness: Brightness.
112 */
113struct prev_params {
114 u32 features;
115 struct omap3isp_prev_cfa cfa;
116 struct omap3isp_prev_csup csup;
117 struct omap3isp_prev_luma luma;
118 struct omap3isp_prev_nf nf;
119 struct omap3isp_prev_dcor dcor;
120 struct omap3isp_prev_gtables gamma;
121 struct omap3isp_prev_wbal wbal;
122 struct omap3isp_prev_blkadj blk_adj;
123 struct omap3isp_prev_rgbtorgb rgb2rgb;
124 struct omap3isp_prev_csc rgb2ycbcr;
125 struct omap3isp_prev_hmed hmed;
126 struct omap3isp_prev_yclimit yclimit;
127 u8 average;
128 u8 contrast;
129 u8 brightness;
130};
131
132/*
133 * struct isptables_update - Structure for Table Configuration.
134 * @update: Specifies which tables should be updated.
135 * @flag: Specifies which tables should be enabled.
136 * @nf: Pointer to structure for Noise Filter
137 * @lsc: Pointer to LSC gain table. (currently not used)
138 * @gamma: Pointer to gamma correction tables.
139 * @cfa: Pointer to color filter array configuration.
140 * @wbal: Pointer to colour and digital gain configuration.
141 */
142struct isptables_update {
143 u32 update;
144 u32 flag;
145 struct omap3isp_prev_nf *nf;
146 u32 *lsc;
147 struct omap3isp_prev_gtables *gamma;
148 struct omap3isp_prev_cfa *cfa;
149 struct omap3isp_prev_wbal *wbal;
150};
151
152/* Sink and source previewer pads */
153#define PREV_PAD_SINK 0
154#define PREV_PAD_SOURCE 1
155#define PREV_PADS_NUM 2
156
157/*
158 * struct isp_prev_device - Structure for storing ISP Preview module information
159 * @subdev: V4L2 subdevice
160 * @pads: Media entity pads
161 * @formats: Active formats at the subdev pad
162 * @input: Module currently connected to the input pad
163 * @output: Bitmask of the active output
164 * @video_in: Input video entity
165 * @video_out: Output video entity
166 * @error: A hardware error occured during capture
167 * @params: Module configuration data
168 * @shadow_update: If set, update the hardware configured in the next interrupt
169 * @underrun: Whether the preview entity has queued buffers on the output
170 * @state: Current preview pipeline state
171 * @lock: Shadow update lock
172 * @update: Bitmask of the parameters to be updated
173 *
174 * This structure is used to store the OMAP ISP Preview module Information.
175 */
176struct isp_prev_device {
177 struct v4l2_subdev subdev;
178 struct media_pad pads[PREV_PADS_NUM];
179 struct v4l2_mbus_framefmt formats[PREV_PADS_NUM];
180
181 struct v4l2_ctrl_handler ctrls;
182
183 enum preview_input_entity input;
184 unsigned int output;
185 struct isp_video video_in;
186 struct isp_video video_out;
187 unsigned int error;
188
189 struct prev_params params;
190 unsigned int shadow_update:1;
191 enum isp_pipeline_stream_state state;
192 wait_queue_head_t wait;
193 atomic_t stopping;
194 spinlock_t lock;
195 u32 update;
196};
197
198struct isp_device;
199
200int omap3isp_preview_init(struct isp_device *isp);
201void omap3isp_preview_cleanup(struct isp_device *isp);
202
203int omap3isp_preview_register_entities(struct isp_prev_device *prv,
204 struct v4l2_device *vdev);
205void omap3isp_preview_unregister_entities(struct isp_prev_device *prv);
206
207void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev);
208void omap3isp_preview_isr(struct isp_prev_device *prev);
209
210int omap3isp_preview_busy(struct isp_prev_device *isp_prev);
211
212void omap3isp_preview_restore_context(struct isp_device *isp);
213
214#endif /* OMAP3_ISP_PREVIEW_H */
diff --git a/drivers/media/video/omap3isp/ispqueue.c b/drivers/media/video/omap3isp/ispqueue.c
new file mode 100644
index 000000000000..8fddc5806b0d
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispqueue.c
@@ -0,0 +1,1153 @@
1/*
2 * ispqueue.c
3 *
4 * TI OMAP3 ISP - Video buffers queue handling
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <asm/cacheflush.h>
27#include <linux/dma-mapping.h>
28#include <linux/mm.h>
29#include <linux/pagemap.h>
30#include <linux/poll.h>
31#include <linux/scatterlist.h>
32#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35
36#include "ispqueue.h"
37
38/* -----------------------------------------------------------------------------
39 * Video buffers management
40 */
41
42/*
43 * isp_video_buffer_cache_sync - Keep the buffers coherent between CPU and ISP
44 *
45 * The typical operation required here is Cache Invalidation across
46 * the (user space) buffer address range. And this _must_ be done
47 * at QBUF stage (and *only* at QBUF).
48 *
49 * We try to use optimal cache invalidation function:
50 * - dmac_map_area:
51 * - used when the number of pages are _low_.
52 * - it becomes quite slow as the number of pages increase.
53 * - for 648x492 viewfinder (150 pages) it takes 1.3 ms.
54 * - for 5 Mpix buffer (2491 pages) it takes between 25-50 ms.
55 *
56 * - flush_cache_all:
57 * - used when the number of pages are _high_.
58 * - time taken in the range of 500-900 us.
59 * - has a higher penalty but, as whole dcache + icache is invalidated
60 */
61/*
62 * FIXME: dmac_inv_range crashes randomly on the user space buffer
63 * address. Fall back to flush_cache_all for now.
64 */
65#define ISP_CACHE_FLUSH_PAGES_MAX 0
66
67static void isp_video_buffer_cache_sync(struct isp_video_buffer *buf)
68{
69 if (buf->skip_cache)
70 return;
71
72 if (buf->vbuf.m.userptr == 0 || buf->npages == 0 ||
73 buf->npages > ISP_CACHE_FLUSH_PAGES_MAX)
74 flush_cache_all();
75 else {
76 dmac_map_area((void *)buf->vbuf.m.userptr, buf->vbuf.length,
77 DMA_FROM_DEVICE);
78 outer_inv_range(buf->vbuf.m.userptr,
79 buf->vbuf.m.userptr + buf->vbuf.length);
80 }
81}
82
83/*
84 * isp_video_buffer_lock_vma - Prevent VMAs from being unmapped
85 *
86 * Lock the VMAs underlying the given buffer into memory. This avoids the
87 * userspace buffer mapping from being swapped out, making VIPT cache handling
88 * easier.
89 *
90 * Note that the pages will not be freed as the buffers have been locked to
91 * memory using by a call to get_user_pages(), but the userspace mapping could
92 * still disappear if the VMAs are not locked. This is caused by the memory
93 * management code trying to be as lock-less as possible, which results in the
94 * userspace mapping manager not finding out that the pages are locked under
95 * some conditions.
96 */
97static int isp_video_buffer_lock_vma(struct isp_video_buffer *buf, int lock)
98{
99 struct vm_area_struct *vma;
100 unsigned long start;
101 unsigned long end;
102 int ret = 0;
103
104 if (buf->vbuf.memory == V4L2_MEMORY_MMAP)
105 return 0;
106
107 /* We can be called from workqueue context if the current task dies to
108 * unlock the VMAs. In that case there's no current memory management
109 * context so unlocking can't be performed, but the VMAs have been or
110 * are getting destroyed anyway so it doesn't really matter.
111 */
112 if (!current || !current->mm)
113 return lock ? -EINVAL : 0;
114
115 start = buf->vbuf.m.userptr;
116 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
117
118 down_write(&current->mm->mmap_sem);
119 spin_lock(&current->mm->page_table_lock);
120
121 do {
122 vma = find_vma(current->mm, start);
123 if (vma == NULL) {
124 ret = -EFAULT;
125 goto out;
126 }
127
128 if (lock)
129 vma->vm_flags |= VM_LOCKED;
130 else
131 vma->vm_flags &= ~VM_LOCKED;
132
133 start = vma->vm_end + 1;
134 } while (vma->vm_end < end);
135
136 if (lock)
137 buf->vm_flags |= VM_LOCKED;
138 else
139 buf->vm_flags &= ~VM_LOCKED;
140
141out:
142 spin_unlock(&current->mm->page_table_lock);
143 up_write(&current->mm->mmap_sem);
144 return ret;
145}
146
147/*
148 * isp_video_buffer_sglist_kernel - Build a scatter list for a vmalloc'ed buffer
149 *
150 * Iterate over the vmalloc'ed area and create a scatter list entry for every
151 * page.
152 */
153static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
154{
155 struct scatterlist *sglist;
156 unsigned int npages;
157 unsigned int i;
158 void *addr;
159
160 addr = buf->vaddr;
161 npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;
162
163 sglist = vmalloc(npages * sizeof(*sglist));
164 if (sglist == NULL)
165 return -ENOMEM;
166
167 sg_init_table(sglist, npages);
168
169 for (i = 0; i < npages; ++i, addr += PAGE_SIZE) {
170 struct page *page = vmalloc_to_page(addr);
171
172 if (page == NULL || PageHighMem(page)) {
173 vfree(sglist);
174 return -EINVAL;
175 }
176
177 sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
178 }
179
180 buf->sglen = npages;
181 buf->sglist = sglist;
182
183 return 0;
184}
185
186/*
187 * isp_video_buffer_sglist_user - Build a scatter list for a userspace buffer
188 *
189 * Walk the buffer pages list and create a 1:1 mapping to a scatter list.
190 */
191static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
192{
193 struct scatterlist *sglist;
194 unsigned int offset = buf->offset;
195 unsigned int i;
196
197 sglist = vmalloc(buf->npages * sizeof(*sglist));
198 if (sglist == NULL)
199 return -ENOMEM;
200
201 sg_init_table(sglist, buf->npages);
202
203 for (i = 0; i < buf->npages; ++i) {
204 if (PageHighMem(buf->pages[i])) {
205 vfree(sglist);
206 return -EINVAL;
207 }
208
209 sg_set_page(&sglist[i], buf->pages[i], PAGE_SIZE - offset,
210 offset);
211 offset = 0;
212 }
213
214 buf->sglen = buf->npages;
215 buf->sglist = sglist;
216
217 return 0;
218}
219
220/*
221 * isp_video_buffer_sglist_pfnmap - Build a scatter list for a VM_PFNMAP buffer
222 *
223 * Create a scatter list of physically contiguous pages starting at the buffer
224 * memory physical address.
225 */
226static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf)
227{
228 struct scatterlist *sglist;
229 unsigned int offset = buf->offset;
230 unsigned long pfn = buf->paddr >> PAGE_SHIFT;
231 unsigned int i;
232
233 sglist = vmalloc(buf->npages * sizeof(*sglist));
234 if (sglist == NULL)
235 return -ENOMEM;
236
237 sg_init_table(sglist, buf->npages);
238
239 for (i = 0; i < buf->npages; ++i, ++pfn) {
240 sg_set_page(&sglist[i], pfn_to_page(pfn), PAGE_SIZE - offset,
241 offset);
242 /* PFNMAP buffers will not get DMA-mapped, set the DMA address
243 * manually.
244 */
245 sg_dma_address(&sglist[i]) = (pfn << PAGE_SHIFT) + offset;
246 offset = 0;
247 }
248
249 buf->sglen = buf->npages;
250 buf->sglist = sglist;
251
252 return 0;
253}
254
255/*
256 * isp_video_buffer_cleanup - Release pages for a userspace VMA.
257 *
258 * Release pages locked by a call isp_video_buffer_prepare_user and free the
259 * pages table.
260 */
261static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
262{
263 enum dma_data_direction direction;
264 unsigned int i;
265
266 if (buf->queue->ops->buffer_cleanup)
267 buf->queue->ops->buffer_cleanup(buf);
268
269 if (!(buf->vm_flags & VM_PFNMAP)) {
270 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
271 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
272 dma_unmap_sg(buf->queue->dev, buf->sglist, buf->sglen,
273 direction);
274 }
275
276 vfree(buf->sglist);
277 buf->sglist = NULL;
278 buf->sglen = 0;
279
280 if (buf->pages != NULL) {
281 isp_video_buffer_lock_vma(buf, 0);
282
283 for (i = 0; i < buf->npages; ++i)
284 page_cache_release(buf->pages[i]);
285
286 vfree(buf->pages);
287 buf->pages = NULL;
288 }
289
290 buf->npages = 0;
291 buf->skip_cache = false;
292}
293
294/*
295 * isp_video_buffer_prepare_user - Pin userspace VMA pages to memory.
296 *
297 * This function creates a list of pages for a userspace VMA. The number of
298 * pages is first computed based on the buffer size, and pages are then
299 * retrieved by a call to get_user_pages.
300 *
301 * Pages are pinned to memory by get_user_pages, making them available for DMA
302 * transfers. However, due to memory management optimization, it seems the
303 * get_user_pages doesn't guarantee that the pinned pages will not be written
304 * to swap and removed from the userspace mapping(s). When this happens, a page
305 * fault can be generated when accessing those unmapped pages.
306 *
307 * If the fault is triggered by a page table walk caused by VIPT cache
308 * management operations, the page fault handler might oops if the MM semaphore
309 * is held, as it can't handle kernel page faults in that case. To fix that, a
310 * fixup entry needs to be added to the cache management code, or the userspace
311 * VMA must be locked to avoid removing pages from the userspace mapping in the
312 * first place.
313 *
314 * If the number of pages retrieved is smaller than the number required by the
315 * buffer size, the function returns -EFAULT.
316 */
317static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf)
318{
319 unsigned long data;
320 unsigned int first;
321 unsigned int last;
322 int ret;
323
324 data = buf->vbuf.m.userptr;
325 first = (data & PAGE_MASK) >> PAGE_SHIFT;
326 last = ((data + buf->vbuf.length - 1) & PAGE_MASK) >> PAGE_SHIFT;
327
328 buf->offset = data & ~PAGE_MASK;
329 buf->npages = last - first + 1;
330 buf->pages = vmalloc(buf->npages * sizeof(buf->pages[0]));
331 if (buf->pages == NULL)
332 return -ENOMEM;
333
334 down_read(&current->mm->mmap_sem);
335 ret = get_user_pages(current, current->mm, data & PAGE_MASK,
336 buf->npages,
337 buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
338 buf->pages, NULL);
339 up_read(&current->mm->mmap_sem);
340
341 if (ret != buf->npages) {
342 buf->npages = ret;
343 isp_video_buffer_cleanup(buf);
344 return -EFAULT;
345 }
346
347 ret = isp_video_buffer_lock_vma(buf, 1);
348 if (ret < 0)
349 isp_video_buffer_cleanup(buf);
350
351 return ret;
352}
353
354/*
355 * isp_video_buffer_prepare_pfnmap - Validate a VM_PFNMAP userspace buffer
356 *
357 * Userspace VM_PFNMAP buffers are supported only if they are contiguous in
358 * memory and if they span a single VMA.
359 *
360 * Return 0 if the buffer is valid, or -EFAULT otherwise.
361 */
362static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf)
363{
364 struct vm_area_struct *vma;
365 unsigned long prev_pfn;
366 unsigned long this_pfn;
367 unsigned long start;
368 unsigned long end;
369 dma_addr_t pa;
370 int ret = -EFAULT;
371
372 start = buf->vbuf.m.userptr;
373 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
374
375 buf->offset = start & ~PAGE_MASK;
376 buf->npages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
377 buf->pages = NULL;
378
379 down_read(&current->mm->mmap_sem);
380 vma = find_vma(current->mm, start);
381 if (vma == NULL || vma->vm_end < end)
382 goto done;
383
384 for (prev_pfn = 0; start <= end; start += PAGE_SIZE) {
385 ret = follow_pfn(vma, start, &this_pfn);
386 if (ret)
387 goto done;
388
389 if (prev_pfn == 0)
390 pa = this_pfn << PAGE_SHIFT;
391 else if (this_pfn != prev_pfn + 1) {
392 ret = -EFAULT;
393 goto done;
394 }
395
396 prev_pfn = this_pfn;
397 }
398
399 buf->paddr = pa + buf->offset;
400 ret = 0;
401
402done:
403 up_read(&current->mm->mmap_sem);
404 return ret;
405}
406
407/*
408 * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address
409 *
410 * This function locates the VMAs for the buffer's userspace address and checks
411 * that their flags match. The onlflag that we need to care for at the moment is
412 * VM_PFNMAP.
413 *
414 * The buffer vm_flags field is set to the first VMA flags.
415 *
416 * Return -EFAULT if no VMA can be found for part of the buffer, or if the VMAs
417 * have incompatible flags.
418 */
419static int isp_video_buffer_prepare_vm_flags(struct isp_video_buffer *buf)
420{
421 struct vm_area_struct *vma;
422 pgprot_t vm_page_prot;
423 unsigned long start;
424 unsigned long end;
425 int ret = -EFAULT;
426
427 start = buf->vbuf.m.userptr;
428 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
429
430 down_read(&current->mm->mmap_sem);
431
432 do {
433 vma = find_vma(current->mm, start);
434 if (vma == NULL)
435 goto done;
436
437 if (start == buf->vbuf.m.userptr) {
438 buf->vm_flags = vma->vm_flags;
439 vm_page_prot = vma->vm_page_prot;
440 }
441
442 if ((buf->vm_flags ^ vma->vm_flags) & VM_PFNMAP)
443 goto done;
444
445 if (vm_page_prot != vma->vm_page_prot)
446 goto done;
447
448 start = vma->vm_end + 1;
449 } while (vma->vm_end < end);
450
451 /* Skip cache management to enhance performances for non-cached or
452 * write-combining buffers.
453 */
454 if (vm_page_prot == pgprot_noncached(vm_page_prot) ||
455 vm_page_prot == pgprot_writecombine(vm_page_prot))
456 buf->skip_cache = true;
457
458 ret = 0;
459
460done:
461 up_read(&current->mm->mmap_sem);
462 return ret;
463}
464
465/*
466 * isp_video_buffer_prepare - Make a buffer ready for operation
467 *
468 * Preparing a buffer involves:
469 *
470 * - validating VMAs (userspace buffers only)
471 * - locking pages and VMAs into memory (userspace buffers only)
472 * - building page and scatter-gather lists
473 * - mapping buffers for DMA operation
474 * - performing driver-specific preparation
475 *
476 * The function must be called in userspace context with a valid mm context
477 * (this excludes cleanup paths such as sys_close when the userspace process
478 * segfaults).
479 */
480static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
481{
482 enum dma_data_direction direction;
483 int ret;
484
485 switch (buf->vbuf.memory) {
486 case V4L2_MEMORY_MMAP:
487 ret = isp_video_buffer_sglist_kernel(buf);
488 break;
489
490 case V4L2_MEMORY_USERPTR:
491 ret = isp_video_buffer_prepare_vm_flags(buf);
492 if (ret < 0)
493 return ret;
494
495 if (buf->vm_flags & VM_PFNMAP) {
496 ret = isp_video_buffer_prepare_pfnmap(buf);
497 if (ret < 0)
498 return ret;
499
500 ret = isp_video_buffer_sglist_pfnmap(buf);
501 } else {
502 ret = isp_video_buffer_prepare_user(buf);
503 if (ret < 0)
504 return ret;
505
506 ret = isp_video_buffer_sglist_user(buf);
507 }
508 break;
509
510 default:
511 return -EINVAL;
512 }
513
514 if (ret < 0)
515 goto done;
516
517 if (!(buf->vm_flags & VM_PFNMAP)) {
518 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
519 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
520 ret = dma_map_sg(buf->queue->dev, buf->sglist, buf->sglen,
521 direction);
522 if (ret != buf->sglen) {
523 ret = -EFAULT;
524 goto done;
525 }
526 }
527
528 if (buf->queue->ops->buffer_prepare)
529 ret = buf->queue->ops->buffer_prepare(buf);
530
531done:
532 if (ret < 0) {
533 isp_video_buffer_cleanup(buf);
534 return ret;
535 }
536
537 return ret;
538}
539
540/*
541 * isp_video_queue_query - Query the status of a given buffer
542 *
543 * Locking: must be called with the queue lock held.
544 */
545static void isp_video_buffer_query(struct isp_video_buffer *buf,
546 struct v4l2_buffer *vbuf)
547{
548 memcpy(vbuf, &buf->vbuf, sizeof(*vbuf));
549
550 if (buf->vma_use_count)
551 vbuf->flags |= V4L2_BUF_FLAG_MAPPED;
552
553 switch (buf->state) {
554 case ISP_BUF_STATE_ERROR:
555 vbuf->flags |= V4L2_BUF_FLAG_ERROR;
556 case ISP_BUF_STATE_DONE:
557 vbuf->flags |= V4L2_BUF_FLAG_DONE;
558 case ISP_BUF_STATE_QUEUED:
559 case ISP_BUF_STATE_ACTIVE:
560 vbuf->flags |= V4L2_BUF_FLAG_QUEUED;
561 break;
562 case ISP_BUF_STATE_IDLE:
563 default:
564 break;
565 }
566}
567
568/*
569 * isp_video_buffer_wait - Wait for a buffer to be ready
570 *
571 * In non-blocking mode, return immediately with 0 if the buffer is ready or
572 * -EAGAIN if the buffer is in the QUEUED or ACTIVE state.
573 *
574 * In blocking mode, wait (interruptibly but with no timeout) on the buffer wait
575 * queue using the same condition.
576 */
577static int isp_video_buffer_wait(struct isp_video_buffer *buf, int nonblocking)
578{
579 if (nonblocking) {
580 return (buf->state != ISP_BUF_STATE_QUEUED &&
581 buf->state != ISP_BUF_STATE_ACTIVE)
582 ? 0 : -EAGAIN;
583 }
584
585 return wait_event_interruptible(buf->wait,
586 buf->state != ISP_BUF_STATE_QUEUED &&
587 buf->state != ISP_BUF_STATE_ACTIVE);
588}
589
590/* -----------------------------------------------------------------------------
591 * Queue management
592 */
593
594/*
595 * isp_video_queue_free - Free video buffers memory
596 *
597 * Buffers can only be freed if the queue isn't streaming and if no buffer is
598 * mapped to userspace. Return -EBUSY if those conditions aren't statisfied.
599 *
600 * This function must be called with the queue lock held.
601 */
602static int isp_video_queue_free(struct isp_video_queue *queue)
603{
604 unsigned int i;
605
606 if (queue->streaming)
607 return -EBUSY;
608
609 for (i = 0; i < queue->count; ++i) {
610 if (queue->buffers[i]->vma_use_count != 0)
611 return -EBUSY;
612 }
613
614 for (i = 0; i < queue->count; ++i) {
615 struct isp_video_buffer *buf = queue->buffers[i];
616
617 isp_video_buffer_cleanup(buf);
618
619 vfree(buf->vaddr);
620 buf->vaddr = NULL;
621
622 kfree(buf);
623 queue->buffers[i] = NULL;
624 }
625
626 INIT_LIST_HEAD(&queue->queue);
627 queue->count = 0;
628 return 0;
629}
630
631/*
632 * isp_video_queue_alloc - Allocate video buffers memory
633 *
634 * This function must be called with the queue lock held.
635 */
636static int isp_video_queue_alloc(struct isp_video_queue *queue,
637 unsigned int nbuffers,
638 unsigned int size, enum v4l2_memory memory)
639{
640 struct isp_video_buffer *buf;
641 unsigned int i;
642 void *mem;
643 int ret;
644
645 /* Start by freeing the buffers. */
646 ret = isp_video_queue_free(queue);
647 if (ret < 0)
648 return ret;
649
650 /* Bail out of no buffers should be allocated. */
651 if (nbuffers == 0)
652 return 0;
653
654 /* Initialize the allocated buffers. */
655 for (i = 0; i < nbuffers; ++i) {
656 buf = kzalloc(queue->bufsize, GFP_KERNEL);
657 if (buf == NULL)
658 break;
659
660 if (memory == V4L2_MEMORY_MMAP) {
661 /* Allocate video buffers memory for mmap mode. Align
662 * the size to the page size.
663 */
664 mem = vmalloc_32_user(PAGE_ALIGN(size));
665 if (mem == NULL) {
666 kfree(buf);
667 break;
668 }
669
670 buf->vbuf.m.offset = i * PAGE_ALIGN(size);
671 buf->vaddr = mem;
672 }
673
674 buf->vbuf.index = i;
675 buf->vbuf.length = size;
676 buf->vbuf.type = queue->type;
677 buf->vbuf.field = V4L2_FIELD_NONE;
678 buf->vbuf.memory = memory;
679
680 buf->queue = queue;
681 init_waitqueue_head(&buf->wait);
682
683 queue->buffers[i] = buf;
684 }
685
686 if (i == 0)
687 return -ENOMEM;
688
689 queue->count = i;
690 return nbuffers;
691}
692
693/**
694 * omap3isp_video_queue_cleanup - Clean up the video buffers queue
695 * @queue: Video buffers queue
696 *
697 * Free all allocated resources and clean up the video buffers queue. The queue
698 * must not be busy (no ongoing video stream) and buffers must have been
699 * unmapped.
700 *
701 * Return 0 on success or -EBUSY if the queue is busy or buffers haven't been
702 * unmapped.
703 */
704int omap3isp_video_queue_cleanup(struct isp_video_queue *queue)
705{
706 return isp_video_queue_free(queue);
707}
708
709/**
710 * omap3isp_video_queue_init - Initialize the video buffers queue
711 * @queue: Video buffers queue
712 * @type: V4L2 buffer type (capture or output)
713 * @ops: Driver-specific queue operations
714 * @dev: Device used for DMA operations
715 * @bufsize: Size of the driver-specific buffer structure
716 *
717 * Initialize the video buffers queue with the supplied parameters.
718 *
719 * The queue type must be one of V4L2_BUF_TYPE_VIDEO_CAPTURE or
720 * V4L2_BUF_TYPE_VIDEO_OUTPUT. Other buffer types are not supported yet.
721 *
722 * Buffer objects will be allocated using the given buffer size to allow room
723 * for driver-specific fields. Driver-specific buffer structures must start
724 * with a struct isp_video_buffer field. Drivers with no driver-specific buffer
725 * structure must pass the size of the isp_video_buffer structure in the bufsize
726 * parameter.
727 *
728 * Return 0 on success.
729 */
730int omap3isp_video_queue_init(struct isp_video_queue *queue,
731 enum v4l2_buf_type type,
732 const struct isp_video_queue_operations *ops,
733 struct device *dev, unsigned int bufsize)
734{
735 INIT_LIST_HEAD(&queue->queue);
736 mutex_init(&queue->lock);
737 spin_lock_init(&queue->irqlock);
738
739 queue->type = type;
740 queue->ops = ops;
741 queue->dev = dev;
742 queue->bufsize = bufsize;
743
744 return 0;
745}
746
747/* -----------------------------------------------------------------------------
748 * V4L2 operations
749 */
750
751/**
752 * omap3isp_video_queue_reqbufs - Allocate video buffers memory
753 *
754 * This function is intended to be used as a VIDIOC_REQBUFS ioctl handler. It
755 * allocated video buffer objects and, for MMAP buffers, buffer memory.
756 *
757 * If the number of buffers is 0, all buffers are freed and the function returns
758 * without performing any allocation.
759 *
760 * If the number of buffers is not 0, currently allocated buffers (if any) are
761 * freed and the requested number of buffers are allocated. Depending on
762 * driver-specific requirements and on memory availability, a number of buffer
763 * smaller or bigger than requested can be allocated. This isn't considered as
764 * an error.
765 *
766 * Return 0 on success or one of the following error codes:
767 *
768 * -EINVAL if the buffer type or index are invalid
769 * -EBUSY if the queue is busy (streaming or buffers mapped)
770 * -ENOMEM if the buffers can't be allocated due to an out-of-memory condition
771 */
772int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
773 struct v4l2_requestbuffers *rb)
774{
775 unsigned int nbuffers = rb->count;
776 unsigned int size;
777 int ret;
778
779 if (rb->type != queue->type)
780 return -EINVAL;
781
782 queue->ops->queue_prepare(queue, &nbuffers, &size);
783 if (size == 0)
784 return -EINVAL;
785
786 nbuffers = min_t(unsigned int, nbuffers, ISP_VIDEO_MAX_BUFFERS);
787
788 mutex_lock(&queue->lock);
789
790 ret = isp_video_queue_alloc(queue, nbuffers, size, rb->memory);
791 if (ret < 0)
792 goto done;
793
794 rb->count = ret;
795 ret = 0;
796
797done:
798 mutex_unlock(&queue->lock);
799 return ret;
800}
801
802/**
803 * omap3isp_video_queue_querybuf - Query the status of a buffer in a queue
804 *
805 * This function is intended to be used as a VIDIOC_QUERYBUF ioctl handler. It
806 * returns the status of a given video buffer.
807 *
808 * Return 0 on success or -EINVAL if the buffer type or index are invalid.
809 */
810int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
811 struct v4l2_buffer *vbuf)
812{
813 struct isp_video_buffer *buf;
814 int ret = 0;
815
816 if (vbuf->type != queue->type)
817 return -EINVAL;
818
819 mutex_lock(&queue->lock);
820
821 if (vbuf->index >= queue->count) {
822 ret = -EINVAL;
823 goto done;
824 }
825
826 buf = queue->buffers[vbuf->index];
827 isp_video_buffer_query(buf, vbuf);
828
829done:
830 mutex_unlock(&queue->lock);
831 return ret;
832}
833
834/**
835 * omap3isp_video_queue_qbuf - Queue a buffer
836 *
837 * This function is intended to be used as a VIDIOC_QBUF ioctl handler.
838 *
839 * The v4l2_buffer structure passed from userspace is first sanity tested. If
840 * sane, the buffer is then processed and added to the main queue and, if the
841 * queue is streaming, to the IRQ queue.
842 *
843 * Before being enqueued, USERPTR buffers are checked for address changes. If
844 * the buffer has a different userspace address, the old memory area is unlocked
845 * and the new memory area is locked.
846 */
847int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
848 struct v4l2_buffer *vbuf)
849{
850 struct isp_video_buffer *buf;
851 unsigned long flags;
852 int ret = -EINVAL;
853
854 if (vbuf->type != queue->type)
855 goto done;
856
857 mutex_lock(&queue->lock);
858
859 if (vbuf->index >= queue->count)
860 goto done;
861
862 buf = queue->buffers[vbuf->index];
863
864 if (vbuf->memory != buf->vbuf.memory)
865 goto done;
866
867 if (buf->state != ISP_BUF_STATE_IDLE)
868 goto done;
869
870 if (vbuf->memory == V4L2_MEMORY_USERPTR &&
871 vbuf->m.userptr != buf->vbuf.m.userptr) {
872 isp_video_buffer_cleanup(buf);
873 buf->vbuf.m.userptr = vbuf->m.userptr;
874 buf->prepared = 0;
875 }
876
877 if (!buf->prepared) {
878 ret = isp_video_buffer_prepare(buf);
879 if (ret < 0)
880 goto done;
881 buf->prepared = 1;
882 }
883
884 isp_video_buffer_cache_sync(buf);
885
886 buf->state = ISP_BUF_STATE_QUEUED;
887 list_add_tail(&buf->stream, &queue->queue);
888
889 if (queue->streaming) {
890 spin_lock_irqsave(&queue->irqlock, flags);
891 queue->ops->buffer_queue(buf);
892 spin_unlock_irqrestore(&queue->irqlock, flags);
893 }
894
895 ret = 0;
896
897done:
898 mutex_unlock(&queue->lock);
899 return ret;
900}
901
902/**
903 * omap3isp_video_queue_dqbuf - Dequeue a buffer
904 *
905 * This function is intended to be used as a VIDIOC_DQBUF ioctl handler.
906 *
907 * The v4l2_buffer structure passed from userspace is first sanity tested. If
908 * sane, the buffer is then processed and added to the main queue and, if the
909 * queue is streaming, to the IRQ queue.
910 *
911 * Before being enqueued, USERPTR buffers are checked for address changes. If
912 * the buffer has a different userspace address, the old memory area is unlocked
913 * and the new memory area is locked.
914 */
915int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
916 struct v4l2_buffer *vbuf, int nonblocking)
917{
918 struct isp_video_buffer *buf;
919 int ret;
920
921 if (vbuf->type != queue->type)
922 return -EINVAL;
923
924 mutex_lock(&queue->lock);
925
926 if (list_empty(&queue->queue)) {
927 ret = -EINVAL;
928 goto done;
929 }
930
931 buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
932 ret = isp_video_buffer_wait(buf, nonblocking);
933 if (ret < 0)
934 goto done;
935
936 list_del(&buf->stream);
937
938 isp_video_buffer_query(buf, vbuf);
939 buf->state = ISP_BUF_STATE_IDLE;
940 vbuf->flags &= ~V4L2_BUF_FLAG_QUEUED;
941
942done:
943 mutex_unlock(&queue->lock);
944 return ret;
945}
946
947/**
948 * omap3isp_video_queue_streamon - Start streaming
949 *
950 * This function is intended to be used as a VIDIOC_STREAMON ioctl handler. It
951 * starts streaming on the queue and calls the buffer_queue operation for all
952 * queued buffers.
953 *
954 * Return 0 on success.
955 */
956int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
957{
958 struct isp_video_buffer *buf;
959 unsigned long flags;
960
961 mutex_lock(&queue->lock);
962
963 if (queue->streaming)
964 goto done;
965
966 queue->streaming = 1;
967
968 spin_lock_irqsave(&queue->irqlock, flags);
969 list_for_each_entry(buf, &queue->queue, stream)
970 queue->ops->buffer_queue(buf);
971 spin_unlock_irqrestore(&queue->irqlock, flags);
972
973done:
974 mutex_unlock(&queue->lock);
975 return 0;
976}
977
978/**
979 * omap3isp_video_queue_streamoff - Stop streaming
980 *
981 * This function is intended to be used as a VIDIOC_STREAMOFF ioctl handler. It
982 * stops streaming on the queue and wakes up all the buffers.
983 *
984 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
985 * delayed works before calling this function to make sure no buffer will be
986 * touched by the driver and/or hardware.
987 */
988void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
989{
990 struct isp_video_buffer *buf;
991 unsigned long flags;
992 unsigned int i;
993
994 mutex_lock(&queue->lock);
995
996 if (!queue->streaming)
997 goto done;
998
999 queue->streaming = 0;
1000
1001 spin_lock_irqsave(&queue->irqlock, flags);
1002 for (i = 0; i < queue->count; ++i) {
1003 buf = queue->buffers[i];
1004
1005 if (buf->state == ISP_BUF_STATE_ACTIVE)
1006 wake_up(&buf->wait);
1007
1008 buf->state = ISP_BUF_STATE_IDLE;
1009 }
1010 spin_unlock_irqrestore(&queue->irqlock, flags);
1011
1012 INIT_LIST_HEAD(&queue->queue);
1013
1014done:
1015 mutex_unlock(&queue->lock);
1016}
1017
1018/**
1019 * omap3isp_video_queue_discard_done - Discard all buffers marked as DONE
1020 *
1021 * This function is intended to be used with suspend/resume operations. It
1022 * discards all 'done' buffers as they would be too old to be requested after
1023 * resume.
1024 *
1025 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
1026 * delayed works before calling this function to make sure no buffer will be
1027 * touched by the driver and/or hardware.
1028 */
1029void omap3isp_video_queue_discard_done(struct isp_video_queue *queue)
1030{
1031 struct isp_video_buffer *buf;
1032 unsigned int i;
1033
1034 mutex_lock(&queue->lock);
1035
1036 if (!queue->streaming)
1037 goto done;
1038
1039 for (i = 0; i < queue->count; ++i) {
1040 buf = queue->buffers[i];
1041
1042 if (buf->state == ISP_BUF_STATE_DONE)
1043 buf->state = ISP_BUF_STATE_ERROR;
1044 }
1045
1046done:
1047 mutex_unlock(&queue->lock);
1048}
1049
1050static void isp_video_queue_vm_open(struct vm_area_struct *vma)
1051{
1052 struct isp_video_buffer *buf = vma->vm_private_data;
1053
1054 buf->vma_use_count++;
1055}
1056
1057static void isp_video_queue_vm_close(struct vm_area_struct *vma)
1058{
1059 struct isp_video_buffer *buf = vma->vm_private_data;
1060
1061 buf->vma_use_count--;
1062}
1063
1064static const struct vm_operations_struct isp_video_queue_vm_ops = {
1065 .open = isp_video_queue_vm_open,
1066 .close = isp_video_queue_vm_close,
1067};
1068
1069/**
1070 * omap3isp_video_queue_mmap - Map buffers to userspace
1071 *
1072 * This function is intended to be used as an mmap() file operation handler. It
1073 * maps a buffer to userspace based on the VMA offset.
1074 *
1075 * Only buffers of memory type MMAP are supported.
1076 */
1077int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
1078 struct vm_area_struct *vma)
1079{
1080 struct isp_video_buffer *uninitialized_var(buf);
1081 unsigned long size;
1082 unsigned int i;
1083 int ret = 0;
1084
1085 mutex_lock(&queue->lock);
1086
1087 for (i = 0; i < queue->count; ++i) {
1088 buf = queue->buffers[i];
1089 if ((buf->vbuf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
1090 break;
1091 }
1092
1093 if (i == queue->count) {
1094 ret = -EINVAL;
1095 goto done;
1096 }
1097
1098 size = vma->vm_end - vma->vm_start;
1099
1100 if (buf->vbuf.memory != V4L2_MEMORY_MMAP ||
1101 size != PAGE_ALIGN(buf->vbuf.length)) {
1102 ret = -EINVAL;
1103 goto done;
1104 }
1105
1106 ret = remap_vmalloc_range(vma, buf->vaddr, 0);
1107 if (ret < 0)
1108 goto done;
1109
1110 vma->vm_ops = &isp_video_queue_vm_ops;
1111 vma->vm_private_data = buf;
1112 isp_video_queue_vm_open(vma);
1113
1114done:
1115 mutex_unlock(&queue->lock);
1116 return ret;
1117}
1118
1119/**
1120 * omap3isp_video_queue_poll - Poll video queue state
1121 *
1122 * This function is intended to be used as a poll() file operation handler. It
1123 * polls the state of the video buffer at the front of the queue and returns an
1124 * events mask.
1125 *
1126 * If no buffer is present at the front of the queue, POLLERR is returned.
1127 */
1128unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
1129 struct file *file, poll_table *wait)
1130{
1131 struct isp_video_buffer *buf;
1132 unsigned int mask = 0;
1133
1134 mutex_lock(&queue->lock);
1135 if (list_empty(&queue->queue)) {
1136 mask |= POLLERR;
1137 goto done;
1138 }
1139 buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
1140
1141 poll_wait(file, &buf->wait, wait);
1142 if (buf->state == ISP_BUF_STATE_DONE ||
1143 buf->state == ISP_BUF_STATE_ERROR) {
1144 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1145 mask |= POLLIN | POLLRDNORM;
1146 else
1147 mask |= POLLOUT | POLLWRNORM;
1148 }
1149
1150done:
1151 mutex_unlock(&queue->lock);
1152 return mask;
1153}
diff --git a/drivers/media/video/omap3isp/ispqueue.h b/drivers/media/video/omap3isp/ispqueue.h
new file mode 100644
index 000000000000..251de3e1679d
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispqueue.h
@@ -0,0 +1,187 @@
1/*
2 * ispqueue.h
3 *
4 * TI OMAP3 ISP - Video buffers queue handling
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#ifndef OMAP3_ISP_QUEUE_H
27#define OMAP3_ISP_QUEUE_H
28
29#include <linux/kernel.h>
30#include <linux/list.h>
31#include <linux/mutex.h>
32#include <linux/videodev2.h>
33#include <linux/wait.h>
34
35struct isp_video_queue;
36struct page;
37struct scatterlist;
38
39#define ISP_VIDEO_MAX_BUFFERS 16
40
41/**
42 * enum isp_video_buffer_state - ISP video buffer state
43 * @ISP_BUF_STATE_IDLE: The buffer is under userspace control (dequeued
44 * or not queued yet).
45 * @ISP_BUF_STATE_QUEUED: The buffer has been queued but isn't used by the
46 * device yet.
47 * @ISP_BUF_STATE_ACTIVE: The buffer is in use for an active video transfer.
48 * @ISP_BUF_STATE_ERROR: The device is done with the buffer and an error
49 * occured. For capture device the buffer likely contains corrupted data or
50 * no data at all.
51 * @ISP_BUF_STATE_DONE: The device is done with the buffer and no error occured.
52 * For capture devices the buffer contains valid data.
53 */
54enum isp_video_buffer_state {
55 ISP_BUF_STATE_IDLE,
56 ISP_BUF_STATE_QUEUED,
57 ISP_BUF_STATE_ACTIVE,
58 ISP_BUF_STATE_ERROR,
59 ISP_BUF_STATE_DONE,
60};
61
62/**
63 * struct isp_video_buffer - ISP video buffer
64 * @vma_use_count: Number of times the buffer is mmap'ed to userspace
65 * @stream: List head for insertion into main queue
66 * @queue: ISP buffers queue this buffer belongs to
67 * @prepared: Whether the buffer has been prepared
68 * @skip_cache: Whether to skip cache management operations for this buffer
69 * @vaddr: Memory virtual address (for kernel buffers)
70 * @vm_flags: Buffer VMA flags (for userspace buffers)
71 * @offset: Offset inside the first page (for userspace buffers)
72 * @npages: Number of pages (for userspace buffers)
73 * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
74 * @paddr: Memory physical address (for userspace VM_PFNMAP buffers)
75 * @sglen: Number of elements in the scatter list (for non-VM_PFNMAP buffers)
76 * @sglist: Scatter list (for non-VM_PFNMAP buffers)
77 * @vbuf: V4L2 buffer
78 * @irqlist: List head for insertion into IRQ queue
79 * @state: Current buffer state
80 * @wait: Wait queue to signal buffer completion
81 */
82struct isp_video_buffer {
83 unsigned long vma_use_count;
84 struct list_head stream;
85 struct isp_video_queue *queue;
86 unsigned int prepared:1;
87 bool skip_cache;
88
89 /* For kernel buffers. */
90 void *vaddr;
91
92 /* For userspace buffers. */
93 unsigned long vm_flags;
94 unsigned long offset;
95 unsigned int npages;
96 struct page **pages;
97 dma_addr_t paddr;
98
99 /* For all buffers except VM_PFNMAP. */
100 unsigned int sglen;
101 struct scatterlist *sglist;
102
103 /* Touched by the interrupt handler. */
104 struct v4l2_buffer vbuf;
105 struct list_head irqlist;
106 enum isp_video_buffer_state state;
107 wait_queue_head_t wait;
108};
109
110#define to_isp_video_buffer(vb) container_of(vb, struct isp_video_buffer, vb)
111
112/**
113 * struct isp_video_queue_operations - Driver-specific operations
114 * @queue_prepare: Called before allocating buffers. Drivers should clamp the
115 * number of buffers according to their requirements, and must return the
116 * buffer size in bytes.
117 * @buffer_prepare: Called the first time a buffer is queued, or after changing
118 * the userspace memory address for a USERPTR buffer, with the queue lock
119 * held. Drivers should perform device-specific buffer preparation (such as
120 * mapping the buffer memory in an IOMMU). This operation is optional.
121 * @buffer_queue: Called when a buffer is being added to the queue with the
122 * queue irqlock spinlock held.
123 * @buffer_cleanup: Called before freeing buffers, or before changing the
124 * userspace memory address for a USERPTR buffer, with the queue lock held.
125 * Drivers must perform cleanup operations required to undo the
126 * buffer_prepare call. This operation is optional.
127 */
128struct isp_video_queue_operations {
129 void (*queue_prepare)(struct isp_video_queue *queue,
130 unsigned int *nbuffers, unsigned int *size);
131 int (*buffer_prepare)(struct isp_video_buffer *buf);
132 void (*buffer_queue)(struct isp_video_buffer *buf);
133 void (*buffer_cleanup)(struct isp_video_buffer *buf);
134};
135
136/**
137 * struct isp_video_queue - ISP video buffers queue
138 * @type: Type of video buffers handled by this queue
139 * @ops: Queue operations
140 * @dev: Device used for DMA operations
141 * @bufsize: Size of a driver-specific buffer object
142 * @count: Number of currently allocated buffers
143 * @buffers: ISP video buffers
144 * @lock: Mutex to protect access to the buffers, main queue and state
145 * @irqlock: Spinlock to protect access to the IRQ queue
146 * @streaming: Queue state, indicates whether the queue is streaming
147 * @queue: List of all queued buffers
148 */
149struct isp_video_queue {
150 enum v4l2_buf_type type;
151 const struct isp_video_queue_operations *ops;
152 struct device *dev;
153 unsigned int bufsize;
154
155 unsigned int count;
156 struct isp_video_buffer *buffers[ISP_VIDEO_MAX_BUFFERS];
157 struct mutex lock;
158 spinlock_t irqlock;
159
160 unsigned int streaming:1;
161
162 struct list_head queue;
163};
164
165int omap3isp_video_queue_cleanup(struct isp_video_queue *queue);
166int omap3isp_video_queue_init(struct isp_video_queue *queue,
167 enum v4l2_buf_type type,
168 const struct isp_video_queue_operations *ops,
169 struct device *dev, unsigned int bufsize);
170
171int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
172 struct v4l2_requestbuffers *rb);
173int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
174 struct v4l2_buffer *vbuf);
175int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
176 struct v4l2_buffer *vbuf);
177int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
178 struct v4l2_buffer *vbuf, int nonblocking);
179int omap3isp_video_queue_streamon(struct isp_video_queue *queue);
180void omap3isp_video_queue_streamoff(struct isp_video_queue *queue);
181void omap3isp_video_queue_discard_done(struct isp_video_queue *queue);
182int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
183 struct vm_area_struct *vma);
184unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
185 struct file *file, poll_table *wait);
186
187#endif /* OMAP3_ISP_QUEUE_H */
diff --git a/drivers/media/video/omap3isp/ispreg.h b/drivers/media/video/omap3isp/ispreg.h
new file mode 100644
index 000000000000..69f6af6f6b9c
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispreg.h
@@ -0,0 +1,1589 @@
1/*
2 * ispreg.h
3 *
4 * TI OMAP3 ISP - Registers definitions
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_REG_H
28#define OMAP3_ISP_REG_H
29
30#include <plat/omap34xx.h>
31
32
33#define CM_CAM_MCLK_HZ 172800000 /* Hz */
34
35/* ISP Submodules offset */
36
37#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE
38#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset))
39
40#define OMAP3ISP_CCP2_REG_OFFSET 0x0400
41#define OMAP3ISP_CCP2_REG_BASE (OMAP3ISP_REG_BASE + \
42 OMAP3ISP_CCP2_REG_OFFSET)
43#define OMAP3ISP_CCP2_REG(offset) (OMAP3ISP_CCP2_REG_BASE + (offset))
44
45#define OMAP3ISP_CCDC_REG_OFFSET 0x0600
46#define OMAP3ISP_CCDC_REG_BASE (OMAP3ISP_REG_BASE + \
47 OMAP3ISP_CCDC_REG_OFFSET)
48#define OMAP3ISP_CCDC_REG(offset) (OMAP3ISP_CCDC_REG_BASE + (offset))
49
50#define OMAP3ISP_HIST_REG_OFFSET 0x0A00
51#define OMAP3ISP_HIST_REG_BASE (OMAP3ISP_REG_BASE + \
52 OMAP3ISP_HIST_REG_OFFSET)
53#define OMAP3ISP_HIST_REG(offset) (OMAP3ISP_HIST_REG_BASE + (offset))
54
55#define OMAP3ISP_H3A_REG_OFFSET 0x0C00
56#define OMAP3ISP_H3A_REG_BASE (OMAP3ISP_REG_BASE + \
57 OMAP3ISP_H3A_REG_OFFSET)
58#define OMAP3ISP_H3A_REG(offset) (OMAP3ISP_H3A_REG_BASE + (offset))
59
60#define OMAP3ISP_PREV_REG_OFFSET 0x0E00
61#define OMAP3ISP_PREV_REG_BASE (OMAP3ISP_REG_BASE + \
62 OMAP3ISP_PREV_REG_OFFSET)
63#define OMAP3ISP_PREV_REG(offset) (OMAP3ISP_PREV_REG_BASE + (offset))
64
65#define OMAP3ISP_RESZ_REG_OFFSET 0x1000
66#define OMAP3ISP_RESZ_REG_BASE (OMAP3ISP_REG_BASE + \
67 OMAP3ISP_RESZ_REG_OFFSET)
68#define OMAP3ISP_RESZ_REG(offset) (OMAP3ISP_RESZ_REG_BASE + (offset))
69
70#define OMAP3ISP_SBL_REG_OFFSET 0x1200
71#define OMAP3ISP_SBL_REG_BASE (OMAP3ISP_REG_BASE + \
72 OMAP3ISP_SBL_REG_OFFSET)
73#define OMAP3ISP_SBL_REG(offset) (OMAP3ISP_SBL_REG_BASE + (offset))
74
75#define OMAP3ISP_CSI2A_REGS1_REG_OFFSET 0x1800
76#define OMAP3ISP_CSI2A_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
77 OMAP3ISP_CSI2A_REGS1_REG_OFFSET)
78#define OMAP3ISP_CSI2A_REGS1_REG(offset) \
79 (OMAP3ISP_CSI2A_REGS1_REG_BASE + (offset))
80
81#define OMAP3ISP_CSIPHY2_REG_OFFSET 0x1970
82#define OMAP3ISP_CSIPHY2_REG_BASE (OMAP3ISP_REG_BASE + \
83 OMAP3ISP_CSIPHY2_REG_OFFSET)
84#define OMAP3ISP_CSIPHY2_REG(offset) (OMAP3ISP_CSIPHY2_REG_BASE + (offset))
85
86#define OMAP3ISP_CSI2A_REGS2_REG_OFFSET 0x19C0
87#define OMAP3ISP_CSI2A_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
88 OMAP3ISP_CSI2A_REGS2_REG_OFFSET)
89#define OMAP3ISP_CSI2A_REGS2_REG(offset) \
90 (OMAP3ISP_CSI2A_REGS2_REG_BASE + (offset))
91
92#define OMAP3ISP_CSI2C_REGS1_REG_OFFSET 0x1C00
93#define OMAP3ISP_CSI2C_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
94 OMAP3ISP_CSI2C_REGS1_REG_OFFSET)
95#define OMAP3ISP_CSI2C_REGS1_REG(offset) \
96 (OMAP3ISP_CSI2C_REGS1_REG_BASE + (offset))
97
98#define OMAP3ISP_CSIPHY1_REG_OFFSET 0x1D70
99#define OMAP3ISP_CSIPHY1_REG_BASE (OMAP3ISP_REG_BASE + \
100 OMAP3ISP_CSIPHY1_REG_OFFSET)
101#define OMAP3ISP_CSIPHY1_REG(offset) (OMAP3ISP_CSIPHY1_REG_BASE + (offset))
102
103#define OMAP3ISP_CSI2C_REGS2_REG_OFFSET 0x1DC0
104#define OMAP3ISP_CSI2C_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
105 OMAP3ISP_CSI2C_REGS2_REG_OFFSET)
106#define OMAP3ISP_CSI2C_REGS2_REG(offset) \
107 (OMAP3ISP_CSI2C_REGS2_REG_BASE + (offset))
108
109/* ISP module register offset */
110
111#define ISP_REVISION (0x000)
112#define ISP_SYSCONFIG (0x004)
113#define ISP_SYSSTATUS (0x008)
114#define ISP_IRQ0ENABLE (0x00C)
115#define ISP_IRQ0STATUS (0x010)
116#define ISP_IRQ1ENABLE (0x014)
117#define ISP_IRQ1STATUS (0x018)
118#define ISP_TCTRL_GRESET_LENGTH (0x030)
119#define ISP_TCTRL_PSTRB_REPLAY (0x034)
120#define ISP_CTRL (0x040)
121#define ISP_SECURE (0x044)
122#define ISP_TCTRL_CTRL (0x050)
123#define ISP_TCTRL_FRAME (0x054)
124#define ISP_TCTRL_PSTRB_DELAY (0x058)
125#define ISP_TCTRL_STRB_DELAY (0x05C)
126#define ISP_TCTRL_SHUT_DELAY (0x060)
127#define ISP_TCTRL_PSTRB_LENGTH (0x064)
128#define ISP_TCTRL_STRB_LENGTH (0x068)
129#define ISP_TCTRL_SHUT_LENGTH (0x06C)
130#define ISP_PING_PONG_ADDR (0x070)
131#define ISP_PING_PONG_MEM_RANGE (0x074)
132#define ISP_PING_PONG_BUF_SIZE (0x078)
133
134/* CCP2 receiver registers */
135
136#define ISPCCP2_REVISION (0x000)
137#define ISPCCP2_SYSCONFIG (0x004)
138#define ISPCCP2_SYSCONFIG_SOFT_RESET (1 << 1)
139#define ISPCCP2_SYSCONFIG_AUTO_IDLE 0x1
140#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
141#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_FORCE \
142 (0x0 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
143#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_NO \
144 (0x1 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
145#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART \
146 (0x2 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
147#define ISPCCP2_SYSSTATUS (0x008)
148#define ISPCCP2_SYSSTATUS_RESET_DONE (1 << 0)
149#define ISPCCP2_LC01_IRQENABLE (0x00C)
150#define ISPCCP2_LC01_IRQSTATUS (0x010)
151#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ (1 << 11)
152#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ (1 << 10)
153#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ (1 << 9)
154#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ (1 << 8)
155#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ (1 << 7)
156#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ (1 << 5)
157#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ (1 << 4)
158#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ (1 << 3)
159#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ (1 << 2)
160#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ (1 << 1)
161#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ (1 << 0)
162
163#define ISPCCP2_LC23_IRQENABLE (0x014)
164#define ISPCCP2_LC23_IRQSTATUS (0x018)
165#define ISPCCP2_LCM_IRQENABLE (0x02C)
166#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ (1 << 0)
167#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ (1 << 1)
168#define ISPCCP2_LCM_IRQSTATUS (0x030)
169#define ISPCCP2_CTRL (0x040)
170#define ISPCCP2_CTRL_IF_EN (1 << 0)
171#define ISPCCP2_CTRL_PHY_SEL (1 << 1)
172#define ISPCCP2_CTRL_PHY_SEL_CLOCK (0 << 1)
173#define ISPCCP2_CTRL_PHY_SEL_STROBE (1 << 1)
174#define ISPCCP2_CTRL_PHY_SEL_MASK 0x1
175#define ISPCCP2_CTRL_PHY_SEL_SHIFT 1
176#define ISPCCP2_CTRL_IO_OUT_SEL (1 << 2)
177#define ISPCCP2_CTRL_MODE (1 << 4)
178#define ISPCCP2_CTRL_VP_CLK_FORCE_ON (1 << 9)
179#define ISPCCP2_CTRL_INV (1 << 10)
180#define ISPCCP2_CTRL_INV_MASK 0x1
181#define ISPCCP2_CTRL_INV_SHIFT 10
182#define ISPCCP2_CTRL_VP_ONLY_EN (1 << 11)
183#define ISPCCP2_CTRL_VP_CLK_POL (1 << 12)
184#define ISPCCP2_CTRL_VPCLK_DIV_SHIFT 15
185#define ISPCCP2_CTRL_VPCLK_DIV_MASK 0x1ffff /* [31:15] */
186#define ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT 8 /* 3430 bits */
187#define ISPCCP2_CTRL_VP_OUT_CTRL_MASK 0x3 /* 3430 bits */
188#define ISPCCP2_DBG (0x044)
189#define ISPCCP2_GNQ (0x048)
190#define ISPCCP2_LCx_CTRL(x) ((0x050)+0x30*(x))
191#define ISPCCP2_LCx_CTRL_CHAN_EN (1 << 0)
192#define ISPCCP2_LCx_CTRL_CRC_EN (1 << 19)
193#define ISPCCP2_LCx_CTRL_CRC_MASK 0x1
194#define ISPCCP2_LCx_CTRL_CRC_SHIFT 2
195#define ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0 19
196#define ISPCCP2_LCx_CTRL_REGION_EN (1 << 1)
197#define ISPCCP2_LCx_CTRL_REGION_MASK 0x1
198#define ISPCCP2_LCx_CTRL_REGION_SHIFT 1
199#define ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0 0x3f
200#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0 0x2
201#define ISPCCP2_LCx_CTRL_FORMAT_MASK 0x1f
202#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT 0x3
203#define ISPCCP2_LCx_CODE(x) ((0x054)+0x30*(x))
204#define ISPCCP2_LCx_STAT_START(x) ((0x058)+0x30*(x))
205#define ISPCCP2_LCx_STAT_SIZE(x) ((0x05C)+0x30*(x))
206#define ISPCCP2_LCx_SOF_ADDR(x) ((0x060)+0x30*(x))
207#define ISPCCP2_LCx_EOF_ADDR(x) ((0x064)+0x30*(x))
208#define ISPCCP2_LCx_DAT_START(x) ((0x068)+0x30*(x))
209#define ISPCCP2_LCx_DAT_SIZE(x) ((0x06C)+0x30*(x))
210#define ISPCCP2_LCx_DAT_MASK 0xFFF
211#define ISPCCP2_LCx_DAT_SHIFT 16
212#define ISPCCP2_LCx_DAT_PING_ADDR(x) ((0x070)+0x30*(x))
213#define ISPCCP2_LCx_DAT_PONG_ADDR(x) ((0x074)+0x30*(x))
214#define ISPCCP2_LCx_DAT_OFST(x) ((0x078)+0x30*(x))
215#define ISPCCP2_LCM_CTRL (0x1D0)
216#define ISPCCP2_LCM_CTRL_CHAN_EN (1 << 0)
217#define ISPCCP2_LCM_CTRL_DST_PORT (1 << 2)
218#define ISPCCP2_LCM_CTRL_DST_PORT_SHIFT 2
219#define ISPCCP2_LCM_CTRL_READ_THROTTLE_SHIFT 3
220#define ISPCCP2_LCM_CTRL_READ_THROTTLE_MASK 0x11
221#define ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT 5
222#define ISPCCP2_LCM_CTRL_BURST_SIZE_MASK 0x7
223#define ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT 16
224#define ISPCCP2_LCM_CTRL_SRC_FORMAT_MASK 0x7
225#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT 20
226#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_MASK 0x3
227#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED (1 << 22)
228#define ISPCCP2_LCM_CTRL_SRC_PACK (1 << 23)
229#define ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT 24
230#define ISPCCP2_LCM_CTRL_DST_FORMAT_MASK 0x7
231#define ISPCCP2_LCM_VSIZE (0x1D4)
232#define ISPCCP2_LCM_VSIZE_SHIFT 16
233#define ISPCCP2_LCM_HSIZE (0x1D8)
234#define ISPCCP2_LCM_HSIZE_SHIFT 16
235#define ISPCCP2_LCM_PREFETCH (0x1DC)
236#define ISPCCP2_LCM_PREFETCH_SHIFT 3
237#define ISPCCP2_LCM_SRC_ADDR (0x1E0)
238#define ISPCCP2_LCM_SRC_OFST (0x1E4)
239#define ISPCCP2_LCM_DST_ADDR (0x1E8)
240#define ISPCCP2_LCM_DST_OFST (0x1EC)
241
242/* CCDC module register offset */
243
244#define ISPCCDC_PID (0x000)
245#define ISPCCDC_PCR (0x004)
246#define ISPCCDC_SYN_MODE (0x008)
247#define ISPCCDC_HD_VD_WID (0x00C)
248#define ISPCCDC_PIX_LINES (0x010)
249#define ISPCCDC_HORZ_INFO (0x014)
250#define ISPCCDC_VERT_START (0x018)
251#define ISPCCDC_VERT_LINES (0x01C)
252#define ISPCCDC_CULLING (0x020)
253#define ISPCCDC_HSIZE_OFF (0x024)
254#define ISPCCDC_SDOFST (0x028)
255#define ISPCCDC_SDR_ADDR (0x02C)
256#define ISPCCDC_CLAMP (0x030)
257#define ISPCCDC_DCSUB (0x034)
258#define ISPCCDC_COLPTN (0x038)
259#define ISPCCDC_BLKCMP (0x03C)
260#define ISPCCDC_FPC (0x040)
261#define ISPCCDC_FPC_ADDR (0x044)
262#define ISPCCDC_VDINT (0x048)
263#define ISPCCDC_ALAW (0x04C)
264#define ISPCCDC_REC656IF (0x050)
265#define ISPCCDC_CFG (0x054)
266#define ISPCCDC_FMTCFG (0x058)
267#define ISPCCDC_FMT_HORZ (0x05C)
268#define ISPCCDC_FMT_VERT (0x060)
269#define ISPCCDC_FMT_ADDR0 (0x064)
270#define ISPCCDC_FMT_ADDR1 (0x068)
271#define ISPCCDC_FMT_ADDR2 (0x06C)
272#define ISPCCDC_FMT_ADDR3 (0x070)
273#define ISPCCDC_FMT_ADDR4 (0x074)
274#define ISPCCDC_FMT_ADDR5 (0x078)
275#define ISPCCDC_FMT_ADDR6 (0x07C)
276#define ISPCCDC_FMT_ADDR7 (0x080)
277#define ISPCCDC_PRGEVEN0 (0x084)
278#define ISPCCDC_PRGEVEN1 (0x088)
279#define ISPCCDC_PRGODD0 (0x08C)
280#define ISPCCDC_PRGODD1 (0x090)
281#define ISPCCDC_VP_OUT (0x094)
282
283#define ISPCCDC_LSC_CONFIG (0x098)
284#define ISPCCDC_LSC_INITIAL (0x09C)
285#define ISPCCDC_LSC_TABLE_BASE (0x0A0)
286#define ISPCCDC_LSC_TABLE_OFFSET (0x0A4)
287
288/* SBL */
289#define ISPSBL_PCR 0x4
290#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF (1 << 16)
291#define ISPSBL_PCR_H3A_AF_WBL_OVF (1 << 17)
292#define ISPSBL_PCR_RSZ4_WBL_OVF (1 << 18)
293#define ISPSBL_PCR_RSZ3_WBL_OVF (1 << 19)
294#define ISPSBL_PCR_RSZ2_WBL_OVF (1 << 20)
295#define ISPSBL_PCR_RSZ1_WBL_OVF (1 << 21)
296#define ISPSBL_PCR_PRV_WBL_OVF (1 << 22)
297#define ISPSBL_PCR_CCDC_WBL_OVF (1 << 23)
298#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF (1 << 24)
299#define ISPSBL_PCR_CSIA_WBL_OVF (1 << 25)
300#define ISPSBL_PCR_CSIB_WBL_OVF (1 << 26)
301#define ISPSBL_CCDC_WR_0 (0x028)
302#define ISPSBL_CCDC_WR_0_DATA_READY (1 << 21)
303#define ISPSBL_CCDC_WR_1 (0x02C)
304#define ISPSBL_CCDC_WR_2 (0x030)
305#define ISPSBL_CCDC_WR_3 (0x034)
306
307#define ISPSBL_SDR_REQ_EXP 0xF8
308#define ISPSBL_SDR_REQ_HIST_EXP_SHIFT 0
309#define ISPSBL_SDR_REQ_HIST_EXP_MASK (0x3FF)
310#define ISPSBL_SDR_REQ_RSZ_EXP_SHIFT 10
311#define ISPSBL_SDR_REQ_RSZ_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT)
312#define ISPSBL_SDR_REQ_PRV_EXP_SHIFT 20
313#define ISPSBL_SDR_REQ_PRV_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_PRV_EXP_SHIFT)
314
315/* Histogram registers */
316#define ISPHIST_PID (0x000)
317#define ISPHIST_PCR (0x004)
318#define ISPHIST_CNT (0x008)
319#define ISPHIST_WB_GAIN (0x00C)
320#define ISPHIST_R0_HORZ (0x010)
321#define ISPHIST_R0_VERT (0x014)
322#define ISPHIST_R1_HORZ (0x018)
323#define ISPHIST_R1_VERT (0x01C)
324#define ISPHIST_R2_HORZ (0x020)
325#define ISPHIST_R2_VERT (0x024)
326#define ISPHIST_R3_HORZ (0x028)
327#define ISPHIST_R3_VERT (0x02C)
328#define ISPHIST_ADDR (0x030)
329#define ISPHIST_DATA (0x034)
330#define ISPHIST_RADD (0x038)
331#define ISPHIST_RADD_OFF (0x03C)
332#define ISPHIST_H_V_INFO (0x040)
333
334/* H3A module registers */
335#define ISPH3A_PID (0x000)
336#define ISPH3A_PCR (0x004)
337#define ISPH3A_AEWWIN1 (0x04C)
338#define ISPH3A_AEWINSTART (0x050)
339#define ISPH3A_AEWINBLK (0x054)
340#define ISPH3A_AEWSUBWIN (0x058)
341#define ISPH3A_AEWBUFST (0x05C)
342#define ISPH3A_AFPAX1 (0x008)
343#define ISPH3A_AFPAX2 (0x00C)
344#define ISPH3A_AFPAXSTART (0x010)
345#define ISPH3A_AFIIRSH (0x014)
346#define ISPH3A_AFBUFST (0x018)
347#define ISPH3A_AFCOEF010 (0x01C)
348#define ISPH3A_AFCOEF032 (0x020)
349#define ISPH3A_AFCOEF054 (0x024)
350#define ISPH3A_AFCOEF076 (0x028)
351#define ISPH3A_AFCOEF098 (0x02C)
352#define ISPH3A_AFCOEF0010 (0x030)
353#define ISPH3A_AFCOEF110 (0x034)
354#define ISPH3A_AFCOEF132 (0x038)
355#define ISPH3A_AFCOEF154 (0x03C)
356#define ISPH3A_AFCOEF176 (0x040)
357#define ISPH3A_AFCOEF198 (0x044)
358#define ISPH3A_AFCOEF1010 (0x048)
359
360#define ISPPRV_PCR (0x004)
361#define ISPPRV_HORZ_INFO (0x008)
362#define ISPPRV_VERT_INFO (0x00C)
363#define ISPPRV_RSDR_ADDR (0x010)
364#define ISPPRV_RADR_OFFSET (0x014)
365#define ISPPRV_DSDR_ADDR (0x018)
366#define ISPPRV_DRKF_OFFSET (0x01C)
367#define ISPPRV_WSDR_ADDR (0x020)
368#define ISPPRV_WADD_OFFSET (0x024)
369#define ISPPRV_AVE (0x028)
370#define ISPPRV_HMED (0x02C)
371#define ISPPRV_NF (0x030)
372#define ISPPRV_WB_DGAIN (0x034)
373#define ISPPRV_WBGAIN (0x038)
374#define ISPPRV_WBSEL (0x03C)
375#define ISPPRV_CFA (0x040)
376#define ISPPRV_BLKADJOFF (0x044)
377#define ISPPRV_RGB_MAT1 (0x048)
378#define ISPPRV_RGB_MAT2 (0x04C)
379#define ISPPRV_RGB_MAT3 (0x050)
380#define ISPPRV_RGB_MAT4 (0x054)
381#define ISPPRV_RGB_MAT5 (0x058)
382#define ISPPRV_RGB_OFF1 (0x05C)
383#define ISPPRV_RGB_OFF2 (0x060)
384#define ISPPRV_CSC0 (0x064)
385#define ISPPRV_CSC1 (0x068)
386#define ISPPRV_CSC2 (0x06C)
387#define ISPPRV_CSC_OFFSET (0x070)
388#define ISPPRV_CNT_BRT (0x074)
389#define ISPPRV_CSUP (0x078)
390#define ISPPRV_SETUP_YC (0x07C)
391#define ISPPRV_SET_TBL_ADDR (0x080)
392#define ISPPRV_SET_TBL_DATA (0x084)
393#define ISPPRV_CDC_THR0 (0x090)
394#define ISPPRV_CDC_THR1 (ISPPRV_CDC_THR0 + (0x4))
395#define ISPPRV_CDC_THR2 (ISPPRV_CDC_THR0 + (0x4) * 2)
396#define ISPPRV_CDC_THR3 (ISPPRV_CDC_THR0 + (0x4) * 3)
397
398#define ISPPRV_REDGAMMA_TABLE_ADDR 0x0000
399#define ISPPRV_GREENGAMMA_TABLE_ADDR 0x0400
400#define ISPPRV_BLUEGAMMA_TABLE_ADDR 0x0800
401#define ISPPRV_NF_TABLE_ADDR 0x0C00
402#define ISPPRV_YENH_TABLE_ADDR 0x1000
403#define ISPPRV_CFA_TABLE_ADDR 0x1400
404
405#define ISPPRV_MAXOUTPUT_WIDTH 1280
406#define ISPPRV_MAXOUTPUT_WIDTH_ES2 3300
407#define ISPPRV_MAXOUTPUT_WIDTH_3630 4096
408#define ISPRSZ_MIN_OUTPUT 64
409#define ISPRSZ_MAX_OUTPUT 3312
410
411/* Resizer module register offset */
412#define ISPRSZ_PID (0x000)
413#define ISPRSZ_PCR (0x004)
414#define ISPRSZ_CNT (0x008)
415#define ISPRSZ_OUT_SIZE (0x00C)
416#define ISPRSZ_IN_START (0x010)
417#define ISPRSZ_IN_SIZE (0x014)
418#define ISPRSZ_SDR_INADD (0x018)
419#define ISPRSZ_SDR_INOFF (0x01C)
420#define ISPRSZ_SDR_OUTADD (0x020)
421#define ISPRSZ_SDR_OUTOFF (0x024)
422#define ISPRSZ_HFILT10 (0x028)
423#define ISPRSZ_HFILT32 (0x02C)
424#define ISPRSZ_HFILT54 (0x030)
425#define ISPRSZ_HFILT76 (0x034)
426#define ISPRSZ_HFILT98 (0x038)
427#define ISPRSZ_HFILT1110 (0x03C)
428#define ISPRSZ_HFILT1312 (0x040)
429#define ISPRSZ_HFILT1514 (0x044)
430#define ISPRSZ_HFILT1716 (0x048)
431#define ISPRSZ_HFILT1918 (0x04C)
432#define ISPRSZ_HFILT2120 (0x050)
433#define ISPRSZ_HFILT2322 (0x054)
434#define ISPRSZ_HFILT2524 (0x058)
435#define ISPRSZ_HFILT2726 (0x05C)
436#define ISPRSZ_HFILT2928 (0x060)
437#define ISPRSZ_HFILT3130 (0x064)
438#define ISPRSZ_VFILT10 (0x068)
439#define ISPRSZ_VFILT32 (0x06C)
440#define ISPRSZ_VFILT54 (0x070)
441#define ISPRSZ_VFILT76 (0x074)
442#define ISPRSZ_VFILT98 (0x078)
443#define ISPRSZ_VFILT1110 (0x07C)
444#define ISPRSZ_VFILT1312 (0x080)
445#define ISPRSZ_VFILT1514 (0x084)
446#define ISPRSZ_VFILT1716 (0x088)
447#define ISPRSZ_VFILT1918 (0x08C)
448#define ISPRSZ_VFILT2120 (0x090)
449#define ISPRSZ_VFILT2322 (0x094)
450#define ISPRSZ_VFILT2524 (0x098)
451#define ISPRSZ_VFILT2726 (0x09C)
452#define ISPRSZ_VFILT2928 (0x0A0)
453#define ISPRSZ_VFILT3130 (0x0A4)
454#define ISPRSZ_YENH (0x0A8)
455
456#define ISP_INT_CLR 0xFF113F11
457#define ISPPRV_PCR_EN 1
458#define ISPPRV_PCR_BUSY (1 << 1)
459#define ISPPRV_PCR_SOURCE (1 << 2)
460#define ISPPRV_PCR_ONESHOT (1 << 3)
461#define ISPPRV_PCR_WIDTH (1 << 4)
462#define ISPPRV_PCR_INVALAW (1 << 5)
463#define ISPPRV_PCR_DRKFEN (1 << 6)
464#define ISPPRV_PCR_DRKFCAP (1 << 7)
465#define ISPPRV_PCR_HMEDEN (1 << 8)
466#define ISPPRV_PCR_NFEN (1 << 9)
467#define ISPPRV_PCR_CFAEN (1 << 10)
468#define ISPPRV_PCR_CFAFMT_SHIFT 11
469#define ISPPRV_PCR_CFAFMT_MASK 0x7800
470#define ISPPRV_PCR_CFAFMT_BAYER (0 << 11)
471#define ISPPRV_PCR_CFAFMT_SONYVGA (1 << 11)
472#define ISPPRV_PCR_CFAFMT_RGBFOVEON (2 << 11)
473#define ISPPRV_PCR_CFAFMT_DNSPL (3 << 11)
474#define ISPPRV_PCR_CFAFMT_HONEYCOMB (4 << 11)
475#define ISPPRV_PCR_CFAFMT_RRGGBBFOVEON (5 << 11)
476#define ISPPRV_PCR_YNENHEN (1 << 15)
477#define ISPPRV_PCR_SUPEN (1 << 16)
478#define ISPPRV_PCR_YCPOS_SHIFT 17
479#define ISPPRV_PCR_YCPOS_YCrYCb (0 << 17)
480#define ISPPRV_PCR_YCPOS_YCbYCr (1 << 17)
481#define ISPPRV_PCR_YCPOS_CbYCrY (2 << 17)
482#define ISPPRV_PCR_YCPOS_CrYCbY (3 << 17)
483#define ISPPRV_PCR_RSZPORT (1 << 19)
484#define ISPPRV_PCR_SDRPORT (1 << 20)
485#define ISPPRV_PCR_SCOMP_EN (1 << 21)
486#define ISPPRV_PCR_SCOMP_SFT_SHIFT (22)
487#define ISPPRV_PCR_SCOMP_SFT_MASK (7 << 22)
488#define ISPPRV_PCR_GAMMA_BYPASS (1 << 26)
489#define ISPPRV_PCR_DCOREN (1 << 27)
490#define ISPPRV_PCR_DCCOUP (1 << 28)
491#define ISPPRV_PCR_DRK_FAIL (1 << 31)
492
493#define ISPPRV_HORZ_INFO_EPH_SHIFT 0
494#define ISPPRV_HORZ_INFO_EPH_MASK 0x3fff
495#define ISPPRV_HORZ_INFO_SPH_SHIFT 16
496#define ISPPRV_HORZ_INFO_SPH_MASK 0x3fff0
497
498#define ISPPRV_VERT_INFO_ELV_SHIFT 0
499#define ISPPRV_VERT_INFO_ELV_MASK 0x3fff
500#define ISPPRV_VERT_INFO_SLV_SHIFT 16
501#define ISPPRV_VERT_INFO_SLV_MASK 0x3fff0
502
503#define ISPPRV_AVE_EVENDIST_SHIFT 2
504#define ISPPRV_AVE_EVENDIST_1 0x0
505#define ISPPRV_AVE_EVENDIST_2 0x1
506#define ISPPRV_AVE_EVENDIST_3 0x2
507#define ISPPRV_AVE_EVENDIST_4 0x3
508#define ISPPRV_AVE_ODDDIST_SHIFT 4
509#define ISPPRV_AVE_ODDDIST_1 0x0
510#define ISPPRV_AVE_ODDDIST_2 0x1
511#define ISPPRV_AVE_ODDDIST_3 0x2
512#define ISPPRV_AVE_ODDDIST_4 0x3
513
514#define ISPPRV_HMED_THRESHOLD_SHIFT 0
515#define ISPPRV_HMED_EVENDIST (1 << 8)
516#define ISPPRV_HMED_ODDDIST (1 << 9)
517
518#define ISPPRV_WBGAIN_COEF0_SHIFT 0
519#define ISPPRV_WBGAIN_COEF1_SHIFT 8
520#define ISPPRV_WBGAIN_COEF2_SHIFT 16
521#define ISPPRV_WBGAIN_COEF3_SHIFT 24
522
523#define ISPPRV_WBSEL_COEF0 0x0
524#define ISPPRV_WBSEL_COEF1 0x1
525#define ISPPRV_WBSEL_COEF2 0x2
526#define ISPPRV_WBSEL_COEF3 0x3
527
528#define ISPPRV_WBSEL_N0_0_SHIFT 0
529#define ISPPRV_WBSEL_N0_1_SHIFT 2
530#define ISPPRV_WBSEL_N0_2_SHIFT 4
531#define ISPPRV_WBSEL_N0_3_SHIFT 6
532#define ISPPRV_WBSEL_N1_0_SHIFT 8
533#define ISPPRV_WBSEL_N1_1_SHIFT 10
534#define ISPPRV_WBSEL_N1_2_SHIFT 12
535#define ISPPRV_WBSEL_N1_3_SHIFT 14
536#define ISPPRV_WBSEL_N2_0_SHIFT 16
537#define ISPPRV_WBSEL_N2_1_SHIFT 18
538#define ISPPRV_WBSEL_N2_2_SHIFT 20
539#define ISPPRV_WBSEL_N2_3_SHIFT 22
540#define ISPPRV_WBSEL_N3_0_SHIFT 24
541#define ISPPRV_WBSEL_N3_1_SHIFT 26
542#define ISPPRV_WBSEL_N3_2_SHIFT 28
543#define ISPPRV_WBSEL_N3_3_SHIFT 30
544
545#define ISPPRV_CFA_GRADTH_HOR_SHIFT 0
546#define ISPPRV_CFA_GRADTH_VER_SHIFT 8
547
548#define ISPPRV_BLKADJOFF_B_SHIFT 0
549#define ISPPRV_BLKADJOFF_G_SHIFT 8
550#define ISPPRV_BLKADJOFF_R_SHIFT 16
551
552#define ISPPRV_RGB_MAT1_MTX_RR_SHIFT 0
553#define ISPPRV_RGB_MAT1_MTX_GR_SHIFT 16
554
555#define ISPPRV_RGB_MAT2_MTX_BR_SHIFT 0
556#define ISPPRV_RGB_MAT2_MTX_RG_SHIFT 16
557
558#define ISPPRV_RGB_MAT3_MTX_GG_SHIFT 0
559#define ISPPRV_RGB_MAT3_MTX_BG_SHIFT 16
560
561#define ISPPRV_RGB_MAT4_MTX_RB_SHIFT 0
562#define ISPPRV_RGB_MAT4_MTX_GB_SHIFT 16
563
564#define ISPPRV_RGB_MAT5_MTX_BB_SHIFT 0
565
566#define ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT 0
567#define ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT 16
568
569#define ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT 0
570
571#define ISPPRV_CSC0_RY_SHIFT 0
572#define ISPPRV_CSC0_GY_SHIFT 10
573#define ISPPRV_CSC0_BY_SHIFT 20
574
575#define ISPPRV_CSC1_RCB_SHIFT 0
576#define ISPPRV_CSC1_GCB_SHIFT 10
577#define ISPPRV_CSC1_BCB_SHIFT 20
578
579#define ISPPRV_CSC2_RCR_SHIFT 0
580#define ISPPRV_CSC2_GCR_SHIFT 10
581#define ISPPRV_CSC2_BCR_SHIFT 20
582
583#define ISPPRV_CSC_OFFSET_CR_SHIFT 0
584#define ISPPRV_CSC_OFFSET_CB_SHIFT 8
585#define ISPPRV_CSC_OFFSET_Y_SHIFT 16
586
587#define ISPPRV_CNT_BRT_BRT_SHIFT 0
588#define ISPPRV_CNT_BRT_CNT_SHIFT 8
589
590#define ISPPRV_CONTRAST_MAX 0x10
591#define ISPPRV_CONTRAST_MIN 0xFF
592#define ISPPRV_BRIGHT_MIN 0x00
593#define ISPPRV_BRIGHT_MAX 0xFF
594
595#define ISPPRV_CSUP_CSUPG_SHIFT 0
596#define ISPPRV_CSUP_THRES_SHIFT 8
597#define ISPPRV_CSUP_HPYF_SHIFT 16
598
599#define ISPPRV_SETUP_YC_MINC_SHIFT 0
600#define ISPPRV_SETUP_YC_MAXC_SHIFT 8
601#define ISPPRV_SETUP_YC_MINY_SHIFT 16
602#define ISPPRV_SETUP_YC_MAXY_SHIFT 24
603#define ISPPRV_YC_MAX 0xFF
604#define ISPPRV_YC_MIN 0x0
605
606/* Define bit fields within selected registers */
607#define ISP_REVISION_SHIFT 0
608
609#define ISP_SYSCONFIG_AUTOIDLE (1 << 0)
610#define ISP_SYSCONFIG_SOFTRESET (1 << 1)
611#define ISP_SYSCONFIG_MIDLEMODE_SHIFT 12
612#define ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY 0x0
613#define ISP_SYSCONFIG_MIDLEMODE_NOSTANBY 0x1
614#define ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x2
615
616#define ISP_SYSSTATUS_RESETDONE 0
617
618#define IRQ0ENABLE_CSIA_IRQ (1 << 0)
619#define IRQ0ENABLE_CSIC_IRQ (1 << 1)
620#define IRQ0ENABLE_CCP2_LCM_IRQ (1 << 3)
621#define IRQ0ENABLE_CCP2_LC0_IRQ (1 << 4)
622#define IRQ0ENABLE_CCP2_LC1_IRQ (1 << 5)
623#define IRQ0ENABLE_CCP2_LC2_IRQ (1 << 6)
624#define IRQ0ENABLE_CCP2_LC3_IRQ (1 << 7)
625#define IRQ0ENABLE_CSIB_IRQ (IRQ0ENABLE_CCP2_LCM_IRQ | \
626 IRQ0ENABLE_CCP2_LC0_IRQ | \
627 IRQ0ENABLE_CCP2_LC1_IRQ | \
628 IRQ0ENABLE_CCP2_LC2_IRQ | \
629 IRQ0ENABLE_CCP2_LC3_IRQ)
630
631#define IRQ0ENABLE_CCDC_VD0_IRQ (1 << 8)
632#define IRQ0ENABLE_CCDC_VD1_IRQ (1 << 9)
633#define IRQ0ENABLE_CCDC_VD2_IRQ (1 << 10)
634#define IRQ0ENABLE_CCDC_ERR_IRQ (1 << 11)
635#define IRQ0ENABLE_H3A_AF_DONE_IRQ (1 << 12)
636#define IRQ0ENABLE_H3A_AWB_DONE_IRQ (1 << 13)
637#define IRQ0ENABLE_HIST_DONE_IRQ (1 << 16)
638#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ (1 << 17)
639#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
640#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
641#define IRQ0ENABLE_PRV_DONE_IRQ (1 << 20)
642#define IRQ0ENABLE_RSZ_DONE_IRQ (1 << 24)
643#define IRQ0ENABLE_OVF_IRQ (1 << 25)
644#define IRQ0ENABLE_PING_IRQ (1 << 26)
645#define IRQ0ENABLE_PONG_IRQ (1 << 27)
646#define IRQ0ENABLE_MMU_ERR_IRQ (1 << 28)
647#define IRQ0ENABLE_OCP_ERR_IRQ (1 << 29)
648#define IRQ0ENABLE_SEC_ERR_IRQ (1 << 30)
649#define IRQ0ENABLE_HS_VS_IRQ (1 << 31)
650
651#define IRQ0STATUS_CSIA_IRQ (1 << 0)
652#define IRQ0STATUS_CSI2C_IRQ (1 << 1)
653#define IRQ0STATUS_CCP2_LCM_IRQ (1 << 3)
654#define IRQ0STATUS_CCP2_LC0_IRQ (1 << 4)
655#define IRQ0STATUS_CSIB_IRQ (IRQ0STATUS_CCP2_LCM_IRQ | \
656 IRQ0STATUS_CCP2_LC0_IRQ)
657
658#define IRQ0STATUS_CSIB_LC1_IRQ (1 << 5)
659#define IRQ0STATUS_CSIB_LC2_IRQ (1 << 6)
660#define IRQ0STATUS_CSIB_LC3_IRQ (1 << 7)
661#define IRQ0STATUS_CCDC_VD0_IRQ (1 << 8)
662#define IRQ0STATUS_CCDC_VD1_IRQ (1 << 9)
663#define IRQ0STATUS_CCDC_VD2_IRQ (1 << 10)
664#define IRQ0STATUS_CCDC_ERR_IRQ (1 << 11)
665#define IRQ0STATUS_H3A_AF_DONE_IRQ (1 << 12)
666#define IRQ0STATUS_H3A_AWB_DONE_IRQ (1 << 13)
667#define IRQ0STATUS_HIST_DONE_IRQ (1 << 16)
668#define IRQ0STATUS_CCDC_LSC_DONE_IRQ (1 << 17)
669#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
670#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
671#define IRQ0STATUS_PRV_DONE_IRQ (1 << 20)
672#define IRQ0STATUS_RSZ_DONE_IRQ (1 << 24)
673#define IRQ0STATUS_OVF_IRQ (1 << 25)
674#define IRQ0STATUS_PING_IRQ (1 << 26)
675#define IRQ0STATUS_PONG_IRQ (1 << 27)
676#define IRQ0STATUS_MMU_ERR_IRQ (1 << 28)
677#define IRQ0STATUS_OCP_ERR_IRQ (1 << 29)
678#define IRQ0STATUS_SEC_ERR_IRQ (1 << 30)
679#define IRQ0STATUS_HS_VS_IRQ (1 << 31)
680
681#define TCTRL_GRESET_LEN 0
682
683#define TCTRL_PSTRB_REPLAY_DELAY 0
684#define TCTRL_PSTRB_REPLAY_COUNTER_SHIFT 25
685
686#define ISPCTRL_PAR_SER_CLK_SEL_PARALLEL 0x0
687#define ISPCTRL_PAR_SER_CLK_SEL_CSIA 0x1
688#define ISPCTRL_PAR_SER_CLK_SEL_CSIB 0x2
689#define ISPCTRL_PAR_SER_CLK_SEL_CSIC 0x3
690#define ISPCTRL_PAR_SER_CLK_SEL_MASK 0x3
691
692#define ISPCTRL_PAR_BRIDGE_SHIFT 2
693#define ISPCTRL_PAR_BRIDGE_DISABLE (0x0 << 2)
694#define ISPCTRL_PAR_BRIDGE_LENDIAN (0x2 << 2)
695#define ISPCTRL_PAR_BRIDGE_BENDIAN (0x3 << 2)
696#define ISPCTRL_PAR_BRIDGE_MASK (0x3 << 2)
697
698#define ISPCTRL_PAR_CLK_POL_SHIFT 4
699#define ISPCTRL_PAR_CLK_POL_INV (1 << 4)
700#define ISPCTRL_PING_PONG_EN (1 << 5)
701#define ISPCTRL_SHIFT_SHIFT 6
702#define ISPCTRL_SHIFT_0 (0x0 << 6)
703#define ISPCTRL_SHIFT_2 (0x1 << 6)
704#define ISPCTRL_SHIFT_4 (0x2 << 6)
705#define ISPCTRL_SHIFT_MASK (0x3 << 6)
706
707#define ISPCTRL_CCDC_CLK_EN (1 << 8)
708#define ISPCTRL_SCMP_CLK_EN (1 << 9)
709#define ISPCTRL_H3A_CLK_EN (1 << 10)
710#define ISPCTRL_HIST_CLK_EN (1 << 11)
711#define ISPCTRL_PREV_CLK_EN (1 << 12)
712#define ISPCTRL_RSZ_CLK_EN (1 << 13)
713#define ISPCTRL_SYNC_DETECT_SHIFT 14
714#define ISPCTRL_SYNC_DETECT_HSFALL (0x0 << ISPCTRL_SYNC_DETECT_SHIFT)
715#define ISPCTRL_SYNC_DETECT_HSRISE (0x1 << ISPCTRL_SYNC_DETECT_SHIFT)
716#define ISPCTRL_SYNC_DETECT_VSFALL (0x2 << ISPCTRL_SYNC_DETECT_SHIFT)
717#define ISPCTRL_SYNC_DETECT_VSRISE (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
718#define ISPCTRL_SYNC_DETECT_MASK (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
719
720#define ISPCTRL_CCDC_RAM_EN (1 << 16)
721#define ISPCTRL_PREV_RAM_EN (1 << 17)
722#define ISPCTRL_SBL_RD_RAM_EN (1 << 18)
723#define ISPCTRL_SBL_WR1_RAM_EN (1 << 19)
724#define ISPCTRL_SBL_WR0_RAM_EN (1 << 20)
725#define ISPCTRL_SBL_AUTOIDLE (1 << 21)
726#define ISPCTRL_SBL_SHARED_WPORTC (1 << 26)
727#define ISPCTRL_SBL_SHARED_RPORTA (1 << 27)
728#define ISPCTRL_SBL_SHARED_RPORTB (1 << 28)
729#define ISPCTRL_JPEG_FLUSH (1 << 30)
730#define ISPCTRL_CCDC_FLUSH (1 << 31)
731
732#define ISPSECURE_SECUREMODE 0
733
734#define ISPTCTRL_CTRL_DIV_LOW 0x0
735#define ISPTCTRL_CTRL_DIV_HIGH 0x1
736#define ISPTCTRL_CTRL_DIV_BYPASS 0x1F
737
738#define ISPTCTRL_CTRL_DIVA_SHIFT 0
739#define ISPTCTRL_CTRL_DIVA_MASK (0x1F << ISPTCTRL_CTRL_DIVA_SHIFT)
740
741#define ISPTCTRL_CTRL_DIVB_SHIFT 5
742#define ISPTCTRL_CTRL_DIVB_MASK (0x1F << ISPTCTRL_CTRL_DIVB_SHIFT)
743
744#define ISPTCTRL_CTRL_DIVC_SHIFT 10
745#define ISPTCTRL_CTRL_DIVC_NOCLOCK (0x0 << 10)
746
747#define ISPTCTRL_CTRL_SHUTEN (1 << 21)
748#define ISPTCTRL_CTRL_PSTRBEN (1 << 22)
749#define ISPTCTRL_CTRL_STRBEN (1 << 23)
750#define ISPTCTRL_CTRL_SHUTPOL (1 << 24)
751#define ISPTCTRL_CTRL_STRBPSTRBPOL (1 << 26)
752
753#define ISPTCTRL_CTRL_INSEL_SHIFT 27
754#define ISPTCTRL_CTRL_INSEL_PARALLEL (0x0 << 27)
755#define ISPTCTRL_CTRL_INSEL_CSIA (0x1 << 27)
756#define ISPTCTRL_CTRL_INSEL_CSIB (0x2 << 27)
757
758#define ISPTCTRL_CTRL_GRESETEn (1 << 29)
759#define ISPTCTRL_CTRL_GRESETPOL (1 << 30)
760#define ISPTCTRL_CTRL_GRESETDIR (1 << 31)
761
762#define ISPTCTRL_FRAME_SHUT_SHIFT 0
763#define ISPTCTRL_FRAME_PSTRB_SHIFT 6
764#define ISPTCTRL_FRAME_STRB_SHIFT 12
765
766#define ISPCCDC_PID_PREV_SHIFT 0
767#define ISPCCDC_PID_CID_SHIFT 8
768#define ISPCCDC_PID_TID_SHIFT 16
769
770#define ISPCCDC_PCR_EN 1
771#define ISPCCDC_PCR_BUSY (1 << 1)
772
773#define ISPCCDC_SYN_MODE_VDHDOUT 0x1
774#define ISPCCDC_SYN_MODE_FLDOUT (1 << 1)
775#define ISPCCDC_SYN_MODE_VDPOL (1 << 2)
776#define ISPCCDC_SYN_MODE_HDPOL (1 << 3)
777#define ISPCCDC_SYN_MODE_FLDPOL (1 << 4)
778#define ISPCCDC_SYN_MODE_EXWEN (1 << 5)
779#define ISPCCDC_SYN_MODE_DATAPOL (1 << 6)
780#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7)
781#define ISPCCDC_SYN_MODE_DATSIZ_MASK (0x7 << 8)
782#define ISPCCDC_SYN_MODE_DATSIZ_8_16 (0x0 << 8)
783#define ISPCCDC_SYN_MODE_DATSIZ_12 (0x4 << 8)
784#define ISPCCDC_SYN_MODE_DATSIZ_11 (0x5 << 8)
785#define ISPCCDC_SYN_MODE_DATSIZ_10 (0x6 << 8)
786#define ISPCCDC_SYN_MODE_DATSIZ_8 (0x7 << 8)
787#define ISPCCDC_SYN_MODE_PACK8 (1 << 11)
788#define ISPCCDC_SYN_MODE_INPMOD_MASK (3 << 12)
789#define ISPCCDC_SYN_MODE_INPMOD_RAW (0 << 12)
790#define ISPCCDC_SYN_MODE_INPMOD_YCBCR16 (1 << 12)
791#define ISPCCDC_SYN_MODE_INPMOD_YCBCR8 (2 << 12)
792#define ISPCCDC_SYN_MODE_LPF (1 << 14)
793#define ISPCCDC_SYN_MODE_FLDSTAT (1 << 15)
794#define ISPCCDC_SYN_MODE_VDHDEN (1 << 16)
795#define ISPCCDC_SYN_MODE_WEN (1 << 17)
796#define ISPCCDC_SYN_MODE_VP2SDR (1 << 18)
797#define ISPCCDC_SYN_MODE_SDR2RSZ (1 << 19)
798
799#define ISPCCDC_HD_VD_WID_VDW_SHIFT 0
800#define ISPCCDC_HD_VD_WID_HDW_SHIFT 16
801
802#define ISPCCDC_PIX_LINES_HLPRF_SHIFT 0
803#define ISPCCDC_PIX_LINES_PPLN_SHIFT 16
804
805#define ISPCCDC_HORZ_INFO_NPH_SHIFT 0
806#define ISPCCDC_HORZ_INFO_NPH_MASK 0x00007fff
807#define ISPCCDC_HORZ_INFO_SPH_SHIFT 16
808#define ISPCCDC_HORZ_INFO_SPH_MASK 0x7fff0000
809
810#define ISPCCDC_VERT_START_SLV1_SHIFT 0
811#define ISPCCDC_VERT_START_SLV0_SHIFT 16
812#define ISPCCDC_VERT_START_SLV0_MASK 0x7fff0000
813
814#define ISPCCDC_VERT_LINES_NLV_SHIFT 0
815#define ISPCCDC_VERT_LINES_NLV_MASK 0x00007fff
816
817#define ISPCCDC_CULLING_CULV_SHIFT 0
818#define ISPCCDC_CULLING_CULHODD_SHIFT 16
819#define ISPCCDC_CULLING_CULHEVN_SHIFT 24
820
821#define ISPCCDC_HSIZE_OFF_SHIFT 0
822
823#define ISPCCDC_SDOFST_FINV (1 << 14)
824#define ISPCCDC_SDOFST_FOFST_1L 0
825#define ISPCCDC_SDOFST_FOFST_4L (3 << 12)
826#define ISPCCDC_SDOFST_LOFST3_SHIFT 0
827#define ISPCCDC_SDOFST_LOFST2_SHIFT 3
828#define ISPCCDC_SDOFST_LOFST1_SHIFT 6
829#define ISPCCDC_SDOFST_LOFST0_SHIFT 9
830#define EVENEVEN 1
831#define ODDEVEN 2
832#define EVENODD 3
833#define ODDODD 4
834
835#define ISPCCDC_CLAMP_OBGAIN_SHIFT 0
836#define ISPCCDC_CLAMP_OBST_SHIFT 10
837#define ISPCCDC_CLAMP_OBSLN_SHIFT 25
838#define ISPCCDC_CLAMP_OBSLEN_SHIFT 28
839#define ISPCCDC_CLAMP_CLAMPEN (1 << 31)
840
841#define ISPCCDC_COLPTN_R_Ye 0x0
842#define ISPCCDC_COLPTN_Gr_Cy 0x1
843#define ISPCCDC_COLPTN_Gb_G 0x2
844#define ISPCCDC_COLPTN_B_Mg 0x3
845#define ISPCCDC_COLPTN_CP0PLC0_SHIFT 0
846#define ISPCCDC_COLPTN_CP0PLC1_SHIFT 2
847#define ISPCCDC_COLPTN_CP0PLC2_SHIFT 4
848#define ISPCCDC_COLPTN_CP0PLC3_SHIFT 6
849#define ISPCCDC_COLPTN_CP1PLC0_SHIFT 8
850#define ISPCCDC_COLPTN_CP1PLC1_SHIFT 10
851#define ISPCCDC_COLPTN_CP1PLC2_SHIFT 12
852#define ISPCCDC_COLPTN_CP1PLC3_SHIFT 14
853#define ISPCCDC_COLPTN_CP2PLC0_SHIFT 16
854#define ISPCCDC_COLPTN_CP2PLC1_SHIFT 18
855#define ISPCCDC_COLPTN_CP2PLC2_SHIFT 20
856#define ISPCCDC_COLPTN_CP2PLC3_SHIFT 22
857#define ISPCCDC_COLPTN_CP3PLC0_SHIFT 24
858#define ISPCCDC_COLPTN_CP3PLC1_SHIFT 26
859#define ISPCCDC_COLPTN_CP3PLC2_SHIFT 28
860#define ISPCCDC_COLPTN_CP3PLC3_SHIFT 30
861
862#define ISPCCDC_BLKCMP_B_MG_SHIFT 0
863#define ISPCCDC_BLKCMP_GB_G_SHIFT 8
864#define ISPCCDC_BLKCMP_GR_CY_SHIFT 16
865#define ISPCCDC_BLKCMP_R_YE_SHIFT 24
866
867#define ISPCCDC_FPC_FPNUM_SHIFT 0
868#define ISPCCDC_FPC_FPCEN (1 << 15)
869#define ISPCCDC_FPC_FPERR (1 << 16)
870
871#define ISPCCDC_VDINT_1_SHIFT 0
872#define ISPCCDC_VDINT_1_MASK 0x00007fff
873#define ISPCCDC_VDINT_0_SHIFT 16
874#define ISPCCDC_VDINT_0_MASK 0x7fff0000
875
876#define ISPCCDC_ALAW_GWDI_12_3 (0x3 << 0)
877#define ISPCCDC_ALAW_GWDI_11_2 (0x4 << 0)
878#define ISPCCDC_ALAW_GWDI_10_1 (0x5 << 0)
879#define ISPCCDC_ALAW_GWDI_9_0 (0x6 << 0)
880#define ISPCCDC_ALAW_CCDTBL (1 << 3)
881
882#define ISPCCDC_REC656IF_R656ON 1
883#define ISPCCDC_REC656IF_ECCFVH (1 << 1)
884
885#define ISPCCDC_CFG_BW656 (1 << 5)
886#define ISPCCDC_CFG_FIDMD_SHIFT 6
887#define ISPCCDC_CFG_WENLOG (1 << 8)
888#define ISPCCDC_CFG_WENLOG_AND (0 << 8)
889#define ISPCCDC_CFG_WENLOG_OR (1 << 8)
890#define ISPCCDC_CFG_Y8POS (1 << 11)
891#define ISPCCDC_CFG_BSWD (1 << 12)
892#define ISPCCDC_CFG_MSBINVI (1 << 13)
893#define ISPCCDC_CFG_VDLC (1 << 15)
894
895#define ISPCCDC_FMTCFG_FMTEN 0x1
896#define ISPCCDC_FMTCFG_LNALT (1 << 1)
897#define ISPCCDC_FMTCFG_LNUM_SHIFT 2
898#define ISPCCDC_FMTCFG_PLEN_ODD_SHIFT 4
899#define ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT 8
900#define ISPCCDC_FMTCFG_VPIN_MASK 0x00007000
901#define ISPCCDC_FMTCFG_VPIN_12_3 (0x3 << 12)
902#define ISPCCDC_FMTCFG_VPIN_11_2 (0x4 << 12)
903#define ISPCCDC_FMTCFG_VPIN_10_1 (0x5 << 12)
904#define ISPCCDC_FMTCFG_VPIN_9_0 (0x6 << 12)
905#define ISPCCDC_FMTCFG_VPEN (1 << 15)
906
907#define ISPCCDC_FMTCFG_VPIF_FRQ_MASK 0x003f0000
908#define ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT 16
909#define ISPCCDC_FMTCFG_VPIF_FRQ_BY2 (0x0 << 16)
910#define ISPCCDC_FMTCFG_VPIF_FRQ_BY3 (0x1 << 16)
911#define ISPCCDC_FMTCFG_VPIF_FRQ_BY4 (0x2 << 16)
912#define ISPCCDC_FMTCFG_VPIF_FRQ_BY5 (0x3 << 16)
913#define ISPCCDC_FMTCFG_VPIF_FRQ_BY6 (0x4 << 16)
914
915#define ISPCCDC_FMT_HORZ_FMTLNH_SHIFT 0
916#define ISPCCDC_FMT_HORZ_FMTSPH_SHIFT 16
917
918#define ISPCCDC_FMT_VERT_FMTLNV_SHIFT 0
919#define ISPCCDC_FMT_VERT_FMTSLV_SHIFT 16
920
921#define ISPCCDC_FMT_HORZ_FMTSPH_MASK 0x1fff0000
922#define ISPCCDC_FMT_HORZ_FMTLNH_MASK 0x00001fff
923
924#define ISPCCDC_FMT_VERT_FMTSLV_MASK 0x1fff0000
925#define ISPCCDC_FMT_VERT_FMTLNV_MASK 0x00001fff
926
927#define ISPCCDC_VP_OUT_HORZ_ST_SHIFT 0
928#define ISPCCDC_VP_OUT_HORZ_NUM_SHIFT 4
929#define ISPCCDC_VP_OUT_VERT_NUM_SHIFT 17
930
931#define ISPRSZ_PID_PREV_SHIFT 0
932#define ISPRSZ_PID_CID_SHIFT 8
933#define ISPRSZ_PID_TID_SHIFT 16
934
935#define ISPRSZ_PCR_ENABLE (1 << 0)
936#define ISPRSZ_PCR_BUSY (1 << 1)
937#define ISPRSZ_PCR_ONESHOT (1 << 2)
938
939#define ISPRSZ_CNT_HRSZ_SHIFT 0
940#define ISPRSZ_CNT_HRSZ_MASK \
941 (0x3FF << ISPRSZ_CNT_HRSZ_SHIFT)
942#define ISPRSZ_CNT_VRSZ_SHIFT 10
943#define ISPRSZ_CNT_VRSZ_MASK \
944 (0x3FF << ISPRSZ_CNT_VRSZ_SHIFT)
945#define ISPRSZ_CNT_HSTPH_SHIFT 20
946#define ISPRSZ_CNT_HSTPH_MASK (0x7 << ISPRSZ_CNT_HSTPH_SHIFT)
947#define ISPRSZ_CNT_VSTPH_SHIFT 23
948#define ISPRSZ_CNT_VSTPH_MASK (0x7 << ISPRSZ_CNT_VSTPH_SHIFT)
949#define ISPRSZ_CNT_YCPOS (1 << 26)
950#define ISPRSZ_CNT_INPTYP (1 << 27)
951#define ISPRSZ_CNT_INPSRC (1 << 28)
952#define ISPRSZ_CNT_CBILIN (1 << 29)
953
954#define ISPRSZ_OUT_SIZE_HORZ_SHIFT 0
955#define ISPRSZ_OUT_SIZE_HORZ_MASK \
956 (0xFFF << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
957#define ISPRSZ_OUT_SIZE_VERT_SHIFT 16
958#define ISPRSZ_OUT_SIZE_VERT_MASK \
959 (0xFFF << ISPRSZ_OUT_SIZE_VERT_SHIFT)
960
961#define ISPRSZ_IN_START_HORZ_ST_SHIFT 0
962#define ISPRSZ_IN_START_HORZ_ST_MASK \
963 (0x1FFF << ISPRSZ_IN_START_HORZ_ST_SHIFT)
964#define ISPRSZ_IN_START_VERT_ST_SHIFT 16
965#define ISPRSZ_IN_START_VERT_ST_MASK \
966 (0x1FFF << ISPRSZ_IN_START_VERT_ST_SHIFT)
967
968#define ISPRSZ_IN_SIZE_HORZ_SHIFT 0
969#define ISPRSZ_IN_SIZE_HORZ_MASK \
970 (0x1FFF << ISPRSZ_IN_SIZE_HORZ_SHIFT)
971#define ISPRSZ_IN_SIZE_VERT_SHIFT 16
972#define ISPRSZ_IN_SIZE_VERT_MASK \
973 (0x1FFF << ISPRSZ_IN_SIZE_VERT_SHIFT)
974
975#define ISPRSZ_SDR_INADD_ADDR_SHIFT 0
976#define ISPRSZ_SDR_INADD_ADDR_MASK 0xFFFFFFFF
977
978#define ISPRSZ_SDR_INOFF_OFFSET_SHIFT 0
979#define ISPRSZ_SDR_INOFF_OFFSET_MASK \
980 (0xFFFF << ISPRSZ_SDR_INOFF_OFFSET_SHIFT)
981
982#define ISPRSZ_SDR_OUTADD_ADDR_SHIFT 0
983#define ISPRSZ_SDR_OUTADD_ADDR_MASK 0xFFFFFFFF
984
985
986#define ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT 0
987#define ISPRSZ_SDR_OUTOFF_OFFSET_MASK \
988 (0xFFFF << ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT)
989
990#define ISPRSZ_HFILT_COEF0_SHIFT 0
991#define ISPRSZ_HFILT_COEF0_MASK \
992 (0x3FF << ISPRSZ_HFILT_COEF0_SHIFT)
993#define ISPRSZ_HFILT_COEF1_SHIFT 16
994#define ISPRSZ_HFILT_COEF1_MASK \
995 (0x3FF << ISPRSZ_HFILT_COEF1_SHIFT)
996
997#define ISPRSZ_HFILT32_COEF2_SHIFT 0
998#define ISPRSZ_HFILT32_COEF2_MASK 0x3FF
999#define ISPRSZ_HFILT32_COEF3_SHIFT 16
1000#define ISPRSZ_HFILT32_COEF3_MASK 0x3FF0000
1001
1002#define ISPRSZ_HFILT54_COEF4_SHIFT 0
1003#define ISPRSZ_HFILT54_COEF4_MASK 0x3FF
1004#define ISPRSZ_HFILT54_COEF5_SHIFT 16
1005#define ISPRSZ_HFILT54_COEF5_MASK 0x3FF0000
1006
1007#define ISPRSZ_HFILT76_COEFF6_SHIFT 0
1008#define ISPRSZ_HFILT76_COEFF6_MASK 0x3FF
1009#define ISPRSZ_HFILT76_COEFF7_SHIFT 16
1010#define ISPRSZ_HFILT76_COEFF7_MASK 0x3FF0000
1011
1012#define ISPRSZ_HFILT98_COEFF8_SHIFT 0
1013#define ISPRSZ_HFILT98_COEFF8_MASK 0x3FF
1014#define ISPRSZ_HFILT98_COEFF9_SHIFT 16
1015#define ISPRSZ_HFILT98_COEFF9_MASK 0x3FF0000
1016
1017#define ISPRSZ_HFILT1110_COEF10_SHIFT 0
1018#define ISPRSZ_HFILT1110_COEF10_MASK 0x3FF
1019#define ISPRSZ_HFILT1110_COEF11_SHIFT 16
1020#define ISPRSZ_HFILT1110_COEF11_MASK 0x3FF0000
1021
1022#define ISPRSZ_HFILT1312_COEFF12_SHIFT 0
1023#define ISPRSZ_HFILT1312_COEFF12_MASK 0x3FF
1024#define ISPRSZ_HFILT1312_COEFF13_SHIFT 16
1025#define ISPRSZ_HFILT1312_COEFF13_MASK 0x3FF0000
1026
1027#define ISPRSZ_HFILT1514_COEFF14_SHIFT 0
1028#define ISPRSZ_HFILT1514_COEFF14_MASK 0x3FF
1029#define ISPRSZ_HFILT1514_COEFF15_SHIFT 16
1030#define ISPRSZ_HFILT1514_COEFF15_MASK 0x3FF0000
1031
1032#define ISPRSZ_HFILT1716_COEF16_SHIFT 0
1033#define ISPRSZ_HFILT1716_COEF16_MASK 0x3FF
1034#define ISPRSZ_HFILT1716_COEF17_SHIFT 16
1035#define ISPRSZ_HFILT1716_COEF17_MASK 0x3FF0000
1036
1037#define ISPRSZ_HFILT1918_COEF18_SHIFT 0
1038#define ISPRSZ_HFILT1918_COEF18_MASK 0x3FF
1039#define ISPRSZ_HFILT1918_COEF19_SHIFT 16
1040#define ISPRSZ_HFILT1918_COEF19_MASK 0x3FF0000
1041
1042#define ISPRSZ_HFILT2120_COEF20_SHIFT 0
1043#define ISPRSZ_HFILT2120_COEF20_MASK 0x3FF
1044#define ISPRSZ_HFILT2120_COEF21_SHIFT 16
1045#define ISPRSZ_HFILT2120_COEF21_MASK 0x3FF0000
1046
1047#define ISPRSZ_HFILT2322_COEF22_SHIFT 0
1048#define ISPRSZ_HFILT2322_COEF22_MASK 0x3FF
1049#define ISPRSZ_HFILT2322_COEF23_SHIFT 16
1050#define ISPRSZ_HFILT2322_COEF23_MASK 0x3FF0000
1051
1052#define ISPRSZ_HFILT2524_COEF24_SHIFT 0
1053#define ISPRSZ_HFILT2524_COEF24_MASK 0x3FF
1054#define ISPRSZ_HFILT2524_COEF25_SHIFT 16
1055#define ISPRSZ_HFILT2524_COEF25_MASK 0x3FF0000
1056
1057#define ISPRSZ_HFILT2726_COEF26_SHIFT 0
1058#define ISPRSZ_HFILT2726_COEF26_MASK 0x3FF
1059#define ISPRSZ_HFILT2726_COEF27_SHIFT 16
1060#define ISPRSZ_HFILT2726_COEF27_MASK 0x3FF0000
1061
1062#define ISPRSZ_HFILT2928_COEF28_SHIFT 0
1063#define ISPRSZ_HFILT2928_COEF28_MASK 0x3FF
1064#define ISPRSZ_HFILT2928_COEF29_SHIFT 16
1065#define ISPRSZ_HFILT2928_COEF29_MASK 0x3FF0000
1066
1067#define ISPRSZ_HFILT3130_COEF30_SHIFT 0
1068#define ISPRSZ_HFILT3130_COEF30_MASK 0x3FF
1069#define ISPRSZ_HFILT3130_COEF31_SHIFT 16
1070#define ISPRSZ_HFILT3130_COEF31_MASK 0x3FF0000
1071
1072#define ISPRSZ_VFILT_COEF0_SHIFT 0
1073#define ISPRSZ_VFILT_COEF0_MASK \
1074 (0x3FF << ISPRSZ_VFILT_COEF0_SHIFT)
1075#define ISPRSZ_VFILT_COEF1_SHIFT 16
1076#define ISPRSZ_VFILT_COEF1_MASK \
1077 (0x3FF << ISPRSZ_VFILT_COEF1_SHIFT)
1078
1079#define ISPRSZ_VFILT10_COEF0_SHIFT 0
1080#define ISPRSZ_VFILT10_COEF0_MASK 0x3FF
1081#define ISPRSZ_VFILT10_COEF1_SHIFT 16
1082#define ISPRSZ_VFILT10_COEF1_MASK 0x3FF0000
1083
1084#define ISPRSZ_VFILT32_COEF2_SHIFT 0
1085#define ISPRSZ_VFILT32_COEF2_MASK 0x3FF
1086#define ISPRSZ_VFILT32_COEF3_SHIFT 16
1087#define ISPRSZ_VFILT32_COEF3_MASK 0x3FF0000
1088
1089#define ISPRSZ_VFILT54_COEF4_SHIFT 0
1090#define ISPRSZ_VFILT54_COEF4_MASK 0x3FF
1091#define ISPRSZ_VFILT54_COEF5_SHIFT 16
1092#define ISPRSZ_VFILT54_COEF5_MASK 0x3FF0000
1093
1094#define ISPRSZ_VFILT76_COEFF6_SHIFT 0
1095#define ISPRSZ_VFILT76_COEFF6_MASK 0x3FF
1096#define ISPRSZ_VFILT76_COEFF7_SHIFT 16
1097#define ISPRSZ_VFILT76_COEFF7_MASK 0x3FF0000
1098
1099#define ISPRSZ_VFILT98_COEFF8_SHIFT 0
1100#define ISPRSZ_VFILT98_COEFF8_MASK 0x3FF
1101#define ISPRSZ_VFILT98_COEFF9_SHIFT 16
1102#define ISPRSZ_VFILT98_COEFF9_MASK 0x3FF0000
1103
1104#define ISPRSZ_VFILT1110_COEF10_SHIFT 0
1105#define ISPRSZ_VFILT1110_COEF10_MASK 0x3FF
1106#define ISPRSZ_VFILT1110_COEF11_SHIFT 16
1107#define ISPRSZ_VFILT1110_COEF11_MASK 0x3FF0000
1108
1109#define ISPRSZ_VFILT1312_COEFF12_SHIFT 0
1110#define ISPRSZ_VFILT1312_COEFF12_MASK 0x3FF
1111#define ISPRSZ_VFILT1312_COEFF13_SHIFT 16
1112#define ISPRSZ_VFILT1312_COEFF13_MASK 0x3FF0000
1113
1114#define ISPRSZ_VFILT1514_COEFF14_SHIFT 0
1115#define ISPRSZ_VFILT1514_COEFF14_MASK 0x3FF
1116#define ISPRSZ_VFILT1514_COEFF15_SHIFT 16
1117#define ISPRSZ_VFILT1514_COEFF15_MASK 0x3FF0000
1118
1119#define ISPRSZ_VFILT1716_COEF16_SHIFT 0
1120#define ISPRSZ_VFILT1716_COEF16_MASK 0x3FF
1121#define ISPRSZ_VFILT1716_COEF17_SHIFT 16
1122#define ISPRSZ_VFILT1716_COEF17_MASK 0x3FF0000
1123
1124#define ISPRSZ_VFILT1918_COEF18_SHIFT 0
1125#define ISPRSZ_VFILT1918_COEF18_MASK 0x3FF
1126#define ISPRSZ_VFILT1918_COEF19_SHIFT 16
1127#define ISPRSZ_VFILT1918_COEF19_MASK 0x3FF0000
1128
1129#define ISPRSZ_VFILT2120_COEF20_SHIFT 0
1130#define ISPRSZ_VFILT2120_COEF20_MASK 0x3FF
1131#define ISPRSZ_VFILT2120_COEF21_SHIFT 16
1132#define ISPRSZ_VFILT2120_COEF21_MASK 0x3FF0000
1133
1134#define ISPRSZ_VFILT2322_COEF22_SHIFT 0
1135#define ISPRSZ_VFILT2322_COEF22_MASK 0x3FF
1136#define ISPRSZ_VFILT2322_COEF23_SHIFT 16
1137#define ISPRSZ_VFILT2322_COEF23_MASK 0x3FF0000
1138
1139#define ISPRSZ_VFILT2524_COEF24_SHIFT 0
1140#define ISPRSZ_VFILT2524_COEF24_MASK 0x3FF
1141#define ISPRSZ_VFILT2524_COEF25_SHIFT 16
1142#define ISPRSZ_VFILT2524_COEF25_MASK 0x3FF0000
1143
1144#define ISPRSZ_VFILT2726_COEF26_SHIFT 0
1145#define ISPRSZ_VFILT2726_COEF26_MASK 0x3FF
1146#define ISPRSZ_VFILT2726_COEF27_SHIFT 16
1147#define ISPRSZ_VFILT2726_COEF27_MASK 0x3FF0000
1148
1149#define ISPRSZ_VFILT2928_COEF28_SHIFT 0
1150#define ISPRSZ_VFILT2928_COEF28_MASK 0x3FF
1151#define ISPRSZ_VFILT2928_COEF29_SHIFT 16
1152#define ISPRSZ_VFILT2928_COEF29_MASK 0x3FF0000
1153
1154#define ISPRSZ_VFILT3130_COEF30_SHIFT 0
1155#define ISPRSZ_VFILT3130_COEF30_MASK 0x3FF
1156#define ISPRSZ_VFILT3130_COEF31_SHIFT 16
1157#define ISPRSZ_VFILT3130_COEF31_MASK 0x3FF0000
1158
1159#define ISPRSZ_YENH_CORE_SHIFT 0
1160#define ISPRSZ_YENH_CORE_MASK \
1161 (0xFF << ISPRSZ_YENH_CORE_SHIFT)
1162#define ISPRSZ_YENH_SLOP_SHIFT 8
1163#define ISPRSZ_YENH_SLOP_MASK \
1164 (0xF << ISPRSZ_YENH_SLOP_SHIFT)
1165#define ISPRSZ_YENH_GAIN_SHIFT 12
1166#define ISPRSZ_YENH_GAIN_MASK \
1167 (0xF << ISPRSZ_YENH_GAIN_SHIFT)
1168#define ISPRSZ_YENH_ALGO_SHIFT 16
1169#define ISPRSZ_YENH_ALGO_MASK \
1170 (0x3 << ISPRSZ_YENH_ALGO_SHIFT)
1171
1172#define ISPH3A_PCR_AEW_ALAW_EN_SHIFT 1
1173#define ISPH3A_PCR_AF_MED_TH_SHIFT 3
1174#define ISPH3A_PCR_AF_RGBPOS_SHIFT 11
1175#define ISPH3A_PCR_AEW_AVE2LMT_SHIFT 22
1176#define ISPH3A_PCR_AEW_AVE2LMT_MASK 0xFFC00000
1177#define ISPH3A_PCR_BUSYAF (1 << 15)
1178#define ISPH3A_PCR_BUSYAEAWB (1 << 18)
1179
1180#define ISPH3A_AEWWIN1_WINHC_SHIFT 0
1181#define ISPH3A_AEWWIN1_WINHC_MASK 0x3F
1182#define ISPH3A_AEWWIN1_WINVC_SHIFT 6
1183#define ISPH3A_AEWWIN1_WINVC_MASK 0x1FC0
1184#define ISPH3A_AEWWIN1_WINW_SHIFT 13
1185#define ISPH3A_AEWWIN1_WINW_MASK 0xFE000
1186#define ISPH3A_AEWWIN1_WINH_SHIFT 24
1187#define ISPH3A_AEWWIN1_WINH_MASK 0x7F000000
1188
1189#define ISPH3A_AEWINSTART_WINSH_SHIFT 0
1190#define ISPH3A_AEWINSTART_WINSH_MASK 0x0FFF
1191#define ISPH3A_AEWINSTART_WINSV_SHIFT 16
1192#define ISPH3A_AEWINSTART_WINSV_MASK 0x0FFF0000
1193
1194#define ISPH3A_AEWINBLK_WINH_SHIFT 0
1195#define ISPH3A_AEWINBLK_WINH_MASK 0x7F
1196#define ISPH3A_AEWINBLK_WINSV_SHIFT 16
1197#define ISPH3A_AEWINBLK_WINSV_MASK 0x0FFF0000
1198
1199#define ISPH3A_AEWSUBWIN_AEWINCH_SHIFT 0
1200#define ISPH3A_AEWSUBWIN_AEWINCH_MASK 0x0F
1201#define ISPH3A_AEWSUBWIN_AEWINCV_SHIFT 8
1202#define ISPH3A_AEWSUBWIN_AEWINCV_MASK 0x0F00
1203
1204#define ISPHIST_PCR_ENABLE_SHIFT 0
1205#define ISPHIST_PCR_ENABLE_MASK 0x01
1206#define ISPHIST_PCR_ENABLE (1 << ISPHIST_PCR_ENABLE_SHIFT)
1207#define ISPHIST_PCR_BUSY 0x02
1208
1209#define ISPHIST_CNT_DATASIZE_SHIFT 8
1210#define ISPHIST_CNT_DATASIZE_MASK 0x0100
1211#define ISPHIST_CNT_CLEAR_SHIFT 7
1212#define ISPHIST_CNT_CLEAR_MASK 0x080
1213#define ISPHIST_CNT_CLEAR (1 << ISPHIST_CNT_CLEAR_SHIFT)
1214#define ISPHIST_CNT_CFA_SHIFT 6
1215#define ISPHIST_CNT_CFA_MASK 0x040
1216#define ISPHIST_CNT_BINS_SHIFT 4
1217#define ISPHIST_CNT_BINS_MASK 0x030
1218#define ISPHIST_CNT_SOURCE_SHIFT 3
1219#define ISPHIST_CNT_SOURCE_MASK 0x08
1220#define ISPHIST_CNT_SHIFT_SHIFT 0
1221#define ISPHIST_CNT_SHIFT_MASK 0x07
1222
1223#define ISPHIST_WB_GAIN_WG00_SHIFT 24
1224#define ISPHIST_WB_GAIN_WG00_MASK 0xFF000000
1225#define ISPHIST_WB_GAIN_WG01_SHIFT 16
1226#define ISPHIST_WB_GAIN_WG01_MASK 0xFF0000
1227#define ISPHIST_WB_GAIN_WG02_SHIFT 8
1228#define ISPHIST_WB_GAIN_WG02_MASK 0xFF00
1229#define ISPHIST_WB_GAIN_WG03_SHIFT 0
1230#define ISPHIST_WB_GAIN_WG03_MASK 0xFF
1231
1232#define ISPHIST_REG_START_END_MASK 0x3FFF
1233#define ISPHIST_REG_START_SHIFT 16
1234#define ISPHIST_REG_END_SHIFT 0
1235#define ISPHIST_REG_START_MASK (ISPHIST_REG_START_END_MASK << \
1236 ISPHIST_REG_START_SHIFT)
1237#define ISPHIST_REG_END_MASK (ISPHIST_REG_START_END_MASK << \
1238 ISPHIST_REG_END_SHIFT)
1239
1240#define ISPHIST_REG_MASK (ISPHIST_REG_START_MASK | \
1241 ISPHIST_REG_END_MASK)
1242
1243#define ISPHIST_ADDR_SHIFT 0
1244#define ISPHIST_ADDR_MASK 0x3FF
1245
1246#define ISPHIST_DATA_SHIFT 0
1247#define ISPHIST_DATA_MASK 0xFFFFF
1248
1249#define ISPHIST_RADD_SHIFT 0
1250#define ISPHIST_RADD_MASK 0xFFFFFFFF
1251
1252#define ISPHIST_RADD_OFF_SHIFT 0
1253#define ISPHIST_RADD_OFF_MASK 0xFFFF
1254
1255#define ISPHIST_HV_INFO_HSIZE_SHIFT 16
1256#define ISPHIST_HV_INFO_HSIZE_MASK 0x3FFF0000
1257#define ISPHIST_HV_INFO_VSIZE_SHIFT 0
1258#define ISPHIST_HV_INFO_VSIZE_MASK 0x3FFF
1259
1260#define ISPHIST_HV_INFO_MASK 0x3FFF3FFF
1261
1262#define ISPCCDC_LSC_ENABLE 1
1263#define ISPCCDC_LSC_BUSY (1 << 7)
1264#define ISPCCDC_LSC_GAIN_MODE_N_MASK 0x700
1265#define ISPCCDC_LSC_GAIN_MODE_N_SHIFT 8
1266#define ISPCCDC_LSC_GAIN_MODE_M_MASK 0x3800
1267#define ISPCCDC_LSC_GAIN_MODE_M_SHIFT 12
1268#define ISPCCDC_LSC_GAIN_FORMAT_MASK 0xE
1269#define ISPCCDC_LSC_GAIN_FORMAT_SHIFT 1
1270#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK (1<<6)
1271
1272#define ISPCCDC_LSC_INITIAL_X_MASK 0x3F
1273#define ISPCCDC_LSC_INITIAL_X_SHIFT 0
1274#define ISPCCDC_LSC_INITIAL_Y_MASK 0x3F0000
1275#define ISPCCDC_LSC_INITIAL_Y_SHIFT 16
1276
1277/* -----------------------------------------------------------------------------
1278 * CSI2 receiver registers (ES2.0)
1279 */
1280
1281#define ISPCSI2_REVISION (0x000)
1282#define ISPCSI2_SYSCONFIG (0x010)
1283#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
1284#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK \
1285 (0x3 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1286#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_FORCE \
1287 (0x0 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1288#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO \
1289 (0x1 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1290#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART \
1291 (0x2 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1292#define ISPCSI2_SYSCONFIG_SOFT_RESET (1 << 1)
1293#define ISPCSI2_SYSCONFIG_AUTO_IDLE (1 << 0)
1294
1295#define ISPCSI2_SYSSTATUS (0x014)
1296#define ISPCSI2_SYSSTATUS_RESET_DONE (1 << 0)
1297
1298#define ISPCSI2_IRQSTATUS (0x018)
1299#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ (1 << 14)
1300#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ (1 << 13)
1301#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 12)
1302#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ (1 << 11)
1303#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ (1 << 10)
1304#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ (1 << 9)
1305#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ (1 << 8)
1306#define ISPCSI2_IRQSTATUS_CONTEXT(n) (1 << (n))
1307
1308#define ISPCSI2_IRQENABLE (0x01c)
1309#define ISPCSI2_CTRL (0x040)
1310#define ISPCSI2_CTRL_VP_CLK_EN (1 << 15)
1311#define ISPCSI2_CTRL_VP_ONLY_EN (1 << 11)
1312#define ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT 8
1313#define ISPCSI2_CTRL_VP_OUT_CTRL_MASK \
1314 (3 << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT)
1315#define ISPCSI2_CTRL_DBG_EN (1 << 7)
1316#define ISPCSI2_CTRL_BURST_SIZE_SHIFT 5
1317#define ISPCSI2_CTRL_BURST_SIZE_MASK \
1318 (3 << ISPCSI2_CTRL_BURST_SIZE_SHIFT)
1319#define ISPCSI2_CTRL_FRAME (1 << 3)
1320#define ISPCSI2_CTRL_ECC_EN (1 << 2)
1321#define ISPCSI2_CTRL_SECURE (1 << 1)
1322#define ISPCSI2_CTRL_IF_EN (1 << 0)
1323
1324#define ISPCSI2_DBG_H (0x044)
1325#define ISPCSI2_GNQ (0x048)
1326#define ISPCSI2_PHY_CFG (0x050)
1327#define ISPCSI2_PHY_CFG_RESET_CTRL (1 << 30)
1328#define ISPCSI2_PHY_CFG_RESET_DONE (1 << 29)
1329#define ISPCSI2_PHY_CFG_PWR_CMD_SHIFT 27
1330#define ISPCSI2_PHY_CFG_PWR_CMD_MASK \
1331 (0x3 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1332#define ISPCSI2_PHY_CFG_PWR_CMD_OFF \
1333 (0x0 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1334#define ISPCSI2_PHY_CFG_PWR_CMD_ON \
1335 (0x1 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1336#define ISPCSI2_PHY_CFG_PWR_CMD_ULPW \
1337 (0x2 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1338#define ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT 25
1339#define ISPCSI2_PHY_CFG_PWR_STATUS_MASK \
1340 (0x3 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1341#define ISPCSI2_PHY_CFG_PWR_STATUS_OFF \
1342 (0x0 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1343#define ISPCSI2_PHY_CFG_PWR_STATUS_ON \
1344 (0x1 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1345#define ISPCSI2_PHY_CFG_PWR_STATUS_ULPW \
1346 (0x2 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1347#define ISPCSI2_PHY_CFG_PWR_AUTO (1 << 24)
1348
1349#define ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n) (3 + ((n) * 4))
1350#define ISPCSI2_PHY_CFG_DATA_POL_MASK(n) \
1351 (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1352#define ISPCSI2_PHY_CFG_DATA_POL_PN(n) \
1353 (0x0 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1354#define ISPCSI2_PHY_CFG_DATA_POL_NP(n) \
1355 (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1356
1357#define ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n) ((n) * 4)
1358#define ISPCSI2_PHY_CFG_DATA_POSITION_MASK(n) \
1359 (0x7 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1360#define ISPCSI2_PHY_CFG_DATA_POSITION_NC(n) \
1361 (0x0 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1362#define ISPCSI2_PHY_CFG_DATA_POSITION_1(n) \
1363 (0x1 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1364#define ISPCSI2_PHY_CFG_DATA_POSITION_2(n) \
1365 (0x2 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1366#define ISPCSI2_PHY_CFG_DATA_POSITION_3(n) \
1367 (0x3 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1368#define ISPCSI2_PHY_CFG_DATA_POSITION_4(n) \
1369 (0x4 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1370#define ISPCSI2_PHY_CFG_DATA_POSITION_5(n) \
1371 (0x5 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1372
1373#define ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT 3
1374#define ISPCSI2_PHY_CFG_CLOCK_POL_MASK \
1375 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1376#define ISPCSI2_PHY_CFG_CLOCK_POL_PN \
1377 (0x0 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1378#define ISPCSI2_PHY_CFG_CLOCK_POL_NP \
1379 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1380
1381#define ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT 0
1382#define ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK \
1383 (0x7 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1384#define ISPCSI2_PHY_CFG_CLOCK_POSITION_1 \
1385 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1386#define ISPCSI2_PHY_CFG_CLOCK_POSITION_2 \
1387 (0x2 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1388#define ISPCSI2_PHY_CFG_CLOCK_POSITION_3 \
1389 (0x3 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1390#define ISPCSI2_PHY_CFG_CLOCK_POSITION_4 \
1391 (0x4 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1392#define ISPCSI2_PHY_CFG_CLOCK_POSITION_5 \
1393 (0x5 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1394
1395#define ISPCSI2_PHY_IRQSTATUS (0x054)
1396#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT (1 << 26)
1397#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER (1 << 25)
1398#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5 (1 << 24)
1399#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4 (1 << 23)
1400#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3 (1 << 22)
1401#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2 (1 << 21)
1402#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1 (1 << 20)
1403#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5 (1 << 19)
1404#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4 (1 << 18)
1405#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3 (1 << 17)
1406#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2 (1 << 16)
1407#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1 (1 << 15)
1408#define ISPCSI2_PHY_IRQSTATUS_ERRESC5 (1 << 14)
1409#define ISPCSI2_PHY_IRQSTATUS_ERRESC4 (1 << 13)
1410#define ISPCSI2_PHY_IRQSTATUS_ERRESC3 (1 << 12)
1411#define ISPCSI2_PHY_IRQSTATUS_ERRESC2 (1 << 11)
1412#define ISPCSI2_PHY_IRQSTATUS_ERRESC1 (1 << 10)
1413#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5 (1 << 9)
1414#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4 (1 << 8)
1415#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3 (1 << 7)
1416#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2 (1 << 6)
1417#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1 (1 << 5)
1418#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5 (1 << 4)
1419#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4 (1 << 3)
1420#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3 (1 << 2)
1421#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2 (1 << 1)
1422#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1 1
1423
1424#define ISPCSI2_SHORT_PACKET (0x05c)
1425#define ISPCSI2_PHY_IRQENABLE (0x060)
1426#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT (1 << 26)
1427#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER (1 << 25)
1428#define ISPCSI2_PHY_IRQENABLE_STATEULPM5 (1 << 24)
1429#define ISPCSI2_PHY_IRQENABLE_STATEULPM4 (1 << 23)
1430#define ISPCSI2_PHY_IRQENABLE_STATEULPM3 (1 << 22)
1431#define ISPCSI2_PHY_IRQENABLE_STATEULPM2 (1 << 21)
1432#define ISPCSI2_PHY_IRQENABLE_STATEULPM1 (1 << 20)
1433#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 (1 << 19)
1434#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 (1 << 18)
1435#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 (1 << 17)
1436#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 (1 << 16)
1437#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 (1 << 15)
1438#define ISPCSI2_PHY_IRQENABLE_ERRESC5 (1 << 14)
1439#define ISPCSI2_PHY_IRQENABLE_ERRESC4 (1 << 13)
1440#define ISPCSI2_PHY_IRQENABLE_ERRESC3 (1 << 12)
1441#define ISPCSI2_PHY_IRQENABLE_ERRESC2 (1 << 11)
1442#define ISPCSI2_PHY_IRQENABLE_ERRESC1 (1 << 10)
1443#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 (1 << 9)
1444#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 (1 << 8)
1445#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 (1 << 7)
1446#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 (1 << 6)
1447#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 (1 << 5)
1448#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 (1 << 4)
1449#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 (1 << 3)
1450#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 (1 << 2)
1451#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 (1 << 1)
1452#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1 (1 << 0)
1453
1454#define ISPCSI2_DBG_P (0x068)
1455#define ISPCSI2_TIMING (0x06c)
1456#define ISPCSI2_TIMING_FORCE_RX_MODE_IO(n) (1 << ((16 * ((n) - 1)) + 15))
1457#define ISPCSI2_TIMING_STOP_STATE_X16_IO(n) (1 << ((16 * ((n) - 1)) + 14))
1458#define ISPCSI2_TIMING_STOP_STATE_X4_IO(n) (1 << ((16 * ((n) - 1)) + 13))
1459#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n) (16 * ((n) - 1))
1460#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(n) \
1461 (0x1fff << ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n))
1462
1463#define ISPCSI2_CTX_CTRL1(n) ((0x070) + 0x20 * (n))
1464#define ISPCSI2_CTX_CTRL1_COUNT_SHIFT 8
1465#define ISPCSI2_CTX_CTRL1_COUNT_MASK \
1466 (0xff << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
1467#define ISPCSI2_CTX_CTRL1_EOF_EN (1 << 7)
1468#define ISPCSI2_CTX_CTRL1_EOL_EN (1 << 6)
1469#define ISPCSI2_CTX_CTRL1_CS_EN (1 << 5)
1470#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK (1 << 4)
1471#define ISPCSI2_CTX_CTRL1_PING_PONG (1 << 3)
1472#define ISPCSI2_CTX_CTRL1_CTX_EN (1 << 0)
1473
1474#define ISPCSI2_CTX_CTRL2(n) ((0x074) + 0x20 * (n))
1475#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13
1476#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK \
1477 (0x3 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT)
1478#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11
1479#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK \
1480 (0x3 << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT)
1481#define ISPCSI2_CTX_CTRL2_DPCM_PRED (1 << 10)
1482#define ISPCSI2_CTX_CTRL2_FORMAT_SHIFT 0
1483#define ISPCSI2_CTX_CTRL2_FORMAT_MASK \
1484 (0x3ff << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT)
1485#define ISPCSI2_CTX_CTRL2_FRAME_SHIFT 16
1486#define ISPCSI2_CTX_CTRL2_FRAME_MASK \
1487 (0xffff << ISPCSI2_CTX_CTRL2_FRAME_SHIFT)
1488
1489#define ISPCSI2_CTX_DAT_OFST(n) ((0x078) + 0x20 * (n))
1490#define ISPCSI2_CTX_DAT_OFST_OFST_SHIFT 0
1491#define ISPCSI2_CTX_DAT_OFST_OFST_MASK \
1492 (0x1ffe0 << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT)
1493
1494#define ISPCSI2_CTX_DAT_PING_ADDR(n) ((0x07c) + 0x20 * (n))
1495#define ISPCSI2_CTX_DAT_PONG_ADDR(n) ((0x080) + 0x20 * (n))
1496#define ISPCSI2_CTX_IRQENABLE(n) ((0x084) + 0x20 * (n))
1497#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ (1 << 8)
1498#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ (1 << 7)
1499#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ (1 << 6)
1500#define ISPCSI2_CTX_IRQENABLE_CS_IRQ (1 << 5)
1501#define ISPCSI2_CTX_IRQENABLE_LE_IRQ (1 << 3)
1502#define ISPCSI2_CTX_IRQENABLE_LS_IRQ (1 << 2)
1503#define ISPCSI2_CTX_IRQENABLE_FE_IRQ (1 << 1)
1504#define ISPCSI2_CTX_IRQENABLE_FS_IRQ (1 << 0)
1505
1506#define ISPCSI2_CTX_IRQSTATUS(n) ((0x088) + 0x20 * (n))
1507#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 8)
1508#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ (1 << 7)
1509#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ (1 << 6)
1510#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ (1 << 5)
1511#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ (1 << 3)
1512#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ (1 << 2)
1513#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ (1 << 1)
1514#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ (1 << 0)
1515
1516#define ISPCSI2_CTX_CTRL3(n) ((0x08c) + 0x20 * (n))
1517#define ISPCSI2_CTX_CTRL3_ALPHA_SHIFT 5
1518#define ISPCSI2_CTX_CTRL3_ALPHA_MASK \
1519 (0x3fff << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT)
1520
1521/* This instance is for OMAP3630 only */
1522#define ISPCSI2_CTX_TRANSCODEH(n) (0x000 + 0x8 * (n))
1523#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT 16
1524#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_MASK \
1525 (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
1526#define ISPCSI2_CTX_TRANSCODEH_HSKIP_SHIFT 0
1527#define ISPCSI2_CTX_TRANSCODEH_HSKIP_MASK \
1528 (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
1529#define ISPCSI2_CTX_TRANSCODEV(n) (0x004 + 0x8 * (n))
1530#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT 16
1531#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_MASK \
1532 (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
1533#define ISPCSI2_CTX_TRANSCODEV_VSKIP_SHIFT 0
1534#define ISPCSI2_CTX_TRANSCODEV_VSKIP_MASK \
1535 (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
1536
1537/* -----------------------------------------------------------------------------
1538 * CSI PHY registers
1539 */
1540
1541#define ISPCSIPHY_REG0 (0x000)
1542#define ISPCSIPHY_REG0_THS_TERM_SHIFT 8
1543#define ISPCSIPHY_REG0_THS_TERM_MASK \
1544 (0xff << ISPCSIPHY_REG0_THS_TERM_SHIFT)
1545#define ISPCSIPHY_REG0_THS_SETTLE_SHIFT 0
1546#define ISPCSIPHY_REG0_THS_SETTLE_MASK \
1547 (0xff << ISPCSIPHY_REG0_THS_SETTLE_SHIFT)
1548
1549#define ISPCSIPHY_REG1 (0x004)
1550#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK (1 << 29)
1551/* This field is for OMAP3630 only */
1552#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS (1 << 25)
1553#define ISPCSIPHY_REG1_TCLK_TERM_SHIFT 18
1554#define ISPCSIPHY_REG1_TCLK_TERM_MASK \
1555 (0x7f << ISPCSIPHY_REG1_TCLK_TERM_SHIFT)
1556#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_SHIFT 10
1557#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_MASK \
1558 (0xff << ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN)
1559/* This field is for OMAP3430 only */
1560#define ISPCSIPHY_REG1_TCLK_MISS_SHIFT 8
1561#define ISPCSIPHY_REG1_TCLK_MISS_MASK \
1562 (0x3 << ISPCSIPHY_REG1_TCLK_MISS_SHIFT)
1563/* This field is for OMAP3630 only */
1564#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT 8
1565#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_MASK \
1566 (0x3 << ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT)
1567#define ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT 0
1568#define ISPCSIPHY_REG1_TCLK_SETTLE_MASK \
1569 (0xff << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT)
1570
1571/* This register is for OMAP3630 only */
1572#define ISPCSIPHY_REG2 (0x008)
1573#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT 30
1574#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_MASK \
1575 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT)
1576#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT 28
1577#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_MASK \
1578 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT)
1579#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT 26
1580#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_MASK \
1581 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT)
1582#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT 24
1583#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_MASK \
1584 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT)
1585#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT 0
1586#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_MASK \
1587 (0x7fffff << ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT)
1588
1589#endif /* OMAP3_ISP_REG_H */
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
new file mode 100644
index 000000000000..75d39b115d42
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -0,0 +1,1693 @@
1/*
2 * ispresizer.c
3 *
4 * TI OMAP3 ISP - Resizer module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/device.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispresizer.h"
34
35/*
36 * Resizer Constants
37 */
38#define MIN_RESIZE_VALUE 64
39#define MID_RESIZE_VALUE 512
40#define MAX_RESIZE_VALUE 1024
41
42#define MIN_IN_WIDTH 32
43#define MIN_IN_HEIGHT 32
44#define MAX_IN_WIDTH_MEMORY_MODE 4095
45#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES1 1280
46#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES2 4095
47#define MAX_IN_HEIGHT 4095
48
49#define MIN_OUT_WIDTH 16
50#define MIN_OUT_HEIGHT 2
51#define MAX_OUT_HEIGHT 4095
52
53/*
54 * Resizer Use Constraints
55 * "TRM ES3.1, table 12-46"
56 */
57#define MAX_4TAP_OUT_WIDTH_ES1 1280
58#define MAX_7TAP_OUT_WIDTH_ES1 640
59#define MAX_4TAP_OUT_WIDTH_ES2 3312
60#define MAX_7TAP_OUT_WIDTH_ES2 1650
61#define MAX_4TAP_OUT_WIDTH_3630 4096
62#define MAX_7TAP_OUT_WIDTH_3630 2048
63
64/*
65 * Constants for ratio calculation
66 */
67#define RESIZE_DIVISOR 256
68#define DEFAULT_PHASE 1
69
70/*
71 * Default (and only) configuration of filter coefficients.
72 * 7-tap mode is for scale factors 0.25x to 0.5x.
73 * 4-tap mode is for scale factors 0.5x to 4.0x.
74 * There shouldn't be any reason to recalculate these, EVER.
75 */
76static const struct isprsz_coef filter_coefs = {
77 /* For 8-phase 4-tap horizontal filter: */
78 {
79 0x0000, 0x0100, 0x0000, 0x0000,
80 0x03FA, 0x00F6, 0x0010, 0x0000,
81 0x03F9, 0x00DB, 0x002C, 0x0000,
82 0x03FB, 0x00B3, 0x0053, 0x03FF,
83 0x03FD, 0x0082, 0x0084, 0x03FD,
84 0x03FF, 0x0053, 0x00B3, 0x03FB,
85 0x0000, 0x002C, 0x00DB, 0x03F9,
86 0x0000, 0x0010, 0x00F6, 0x03FA
87 },
88 /* For 8-phase 4-tap vertical filter: */
89 {
90 0x0000, 0x0100, 0x0000, 0x0000,
91 0x03FA, 0x00F6, 0x0010, 0x0000,
92 0x03F9, 0x00DB, 0x002C, 0x0000,
93 0x03FB, 0x00B3, 0x0053, 0x03FF,
94 0x03FD, 0x0082, 0x0084, 0x03FD,
95 0x03FF, 0x0053, 0x00B3, 0x03FB,
96 0x0000, 0x002C, 0x00DB, 0x03F9,
97 0x0000, 0x0010, 0x00F6, 0x03FA
98 },
99 /* For 4-phase 7-tap horizontal filter: */
100 #define DUMMY 0
101 {
102 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
103 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
104 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
105 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
106 },
107 /* For 4-phase 7-tap vertical filter: */
108 {
109 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
110 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
111 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
112 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
113 }
114 /*
115 * The dummy padding is required in 7-tap mode because of how the
116 * registers are arranged physically.
117 */
118 #undef DUMMY
119};
120
121/*
122 * __resizer_get_format - helper function for getting resizer format
123 * @res : pointer to resizer private structure
124 * @pad : pad number
125 * @fh : V4L2 subdev file handle
126 * @which : wanted subdev format
127 * return zero
128 */
129static struct v4l2_mbus_framefmt *
130__resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
131 unsigned int pad, enum v4l2_subdev_format_whence which)
132{
133 if (which == V4L2_SUBDEV_FORMAT_TRY)
134 return v4l2_subdev_get_try_format(fh, pad);
135 else
136 return &res->formats[pad];
137}
138
139/*
140 * __resizer_get_crop - helper function for getting resizer crop rectangle
141 * @res : pointer to resizer private structure
142 * @fh : V4L2 subdev file handle
143 * @which : wanted subdev crop rectangle
144 */
145static struct v4l2_rect *
146__resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
147 enum v4l2_subdev_format_whence which)
148{
149 if (which == V4L2_SUBDEV_FORMAT_TRY)
150 return v4l2_subdev_get_try_crop(fh, RESZ_PAD_SINK);
151 else
152 return &res->crop.request;
153}
154
155/*
156 * resizer_set_filters - Set resizer filters
157 * @res: Device context.
158 * @h_coeff: horizontal coefficient
159 * @v_coeff: vertical coefficient
160 * Return none
161 */
162static void resizer_set_filters(struct isp_res_device *res, const u16 *h_coeff,
163 const u16 *v_coeff)
164{
165 struct isp_device *isp = to_isp_device(res);
166 u32 startaddr_h, startaddr_v, tmp_h, tmp_v;
167 int i;
168
169 startaddr_h = ISPRSZ_HFILT10;
170 startaddr_v = ISPRSZ_VFILT10;
171
172 for (i = 0; i < COEFF_CNT; i += 2) {
173 tmp_h = h_coeff[i] |
174 (h_coeff[i + 1] << ISPRSZ_HFILT_COEF1_SHIFT);
175 tmp_v = v_coeff[i] |
176 (v_coeff[i + 1] << ISPRSZ_VFILT_COEF1_SHIFT);
177 isp_reg_writel(isp, tmp_h, OMAP3_ISP_IOMEM_RESZ, startaddr_h);
178 isp_reg_writel(isp, tmp_v, OMAP3_ISP_IOMEM_RESZ, startaddr_v);
179 startaddr_h += 4;
180 startaddr_v += 4;
181 }
182}
183
184/*
185 * resizer_set_bilinear - Chrominance horizontal algorithm select
186 * @res: Device context.
187 * @type: Filtering interpolation type.
188 *
189 * Filtering that is same as luminance processing is
190 * intended only for downsampling, and bilinear interpolation
191 * is intended only for upsampling.
192 */
193static void resizer_set_bilinear(struct isp_res_device *res,
194 enum resizer_chroma_algo type)
195{
196 struct isp_device *isp = to_isp_device(res);
197
198 if (type == RSZ_BILINEAR)
199 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
200 ISPRSZ_CNT_CBILIN);
201 else
202 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
203 ISPRSZ_CNT_CBILIN);
204}
205
206/*
207 * resizer_set_ycpos - Luminance and chrominance order
208 * @res: Device context.
209 * @order: order type.
210 */
211static void resizer_set_ycpos(struct isp_res_device *res,
212 enum v4l2_mbus_pixelcode pixelcode)
213{
214 struct isp_device *isp = to_isp_device(res);
215
216 switch (pixelcode) {
217 case V4L2_MBUS_FMT_YUYV8_1X16:
218 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
219 ISPRSZ_CNT_YCPOS);
220 break;
221 case V4L2_MBUS_FMT_UYVY8_1X16:
222 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
223 ISPRSZ_CNT_YCPOS);
224 break;
225 default:
226 return;
227 }
228}
229
230/*
231 * resizer_set_phase - Setup horizontal and vertical starting phase
232 * @res: Device context.
233 * @h_phase: horizontal phase parameters.
234 * @v_phase: vertical phase parameters.
235 *
236 * Horizontal and vertical phase range is 0 to 7
237 */
238static void resizer_set_phase(struct isp_res_device *res, u32 h_phase,
239 u32 v_phase)
240{
241 struct isp_device *isp = to_isp_device(res);
242 u32 rgval = 0;
243
244 rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
245 ~(ISPRSZ_CNT_HSTPH_MASK | ISPRSZ_CNT_VSTPH_MASK);
246 rgval |= (h_phase << ISPRSZ_CNT_HSTPH_SHIFT) & ISPRSZ_CNT_HSTPH_MASK;
247 rgval |= (v_phase << ISPRSZ_CNT_VSTPH_SHIFT) & ISPRSZ_CNT_VSTPH_MASK;
248
249 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
250}
251
252/*
253 * resizer_set_luma - Setup luminance enhancer parameters
254 * @res: Device context.
255 * @luma: Structure for luminance enhancer parameters.
256 *
257 * Algorithm select:
258 * 0x0: Disable
259 * 0x1: [-1 2 -1]/2 high-pass filter
260 * 0x2: [-1 -2 6 -2 -1]/4 high-pass filter
261 *
262 * Maximum gain:
263 * The data is coded in U4Q4 representation.
264 *
265 * Slope:
266 * The data is coded in U4Q4 representation.
267 *
268 * Coring offset:
269 * The data is coded in U8Q0 representation.
270 *
271 * The new luminance value is computed as:
272 * Y += HPF(Y) x max(GAIN, (HPF(Y) - CORE) x SLOP + 8) >> 4.
273 */
274static void resizer_set_luma(struct isp_res_device *res,
275 struct resizer_luma_yenh *luma)
276{
277 struct isp_device *isp = to_isp_device(res);
278 u32 rgval = 0;
279
280 rgval = (luma->algo << ISPRSZ_YENH_ALGO_SHIFT)
281 & ISPRSZ_YENH_ALGO_MASK;
282 rgval |= (luma->gain << ISPRSZ_YENH_GAIN_SHIFT)
283 & ISPRSZ_YENH_GAIN_MASK;
284 rgval |= (luma->slope << ISPRSZ_YENH_SLOP_SHIFT)
285 & ISPRSZ_YENH_SLOP_MASK;
286 rgval |= (luma->core << ISPRSZ_YENH_CORE_SHIFT)
287 & ISPRSZ_YENH_CORE_MASK;
288
289 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_YENH);
290}
291
292/*
293 * resizer_set_source - Input source select
294 * @res: Device context.
295 * @source: Input source type
296 *
297 * If this field is set to RESIZER_INPUT_VP, the resizer input is fed from
298 * Preview/CCDC engine, otherwise from memory.
299 */
300static void resizer_set_source(struct isp_res_device *res,
301 enum resizer_input_entity source)
302{
303 struct isp_device *isp = to_isp_device(res);
304
305 if (source == RESIZER_INPUT_MEMORY)
306 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
307 ISPRSZ_CNT_INPSRC);
308 else
309 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
310 ISPRSZ_CNT_INPSRC);
311}
312
313/*
314 * resizer_set_ratio - Setup horizontal and vertical resizing value
315 * @res: Device context.
316 * @ratio: Structure for ratio parameters.
317 *
318 * Resizing range from 64 to 1024
319 */
320static void resizer_set_ratio(struct isp_res_device *res,
321 const struct resizer_ratio *ratio)
322{
323 struct isp_device *isp = to_isp_device(res);
324 const u16 *h_filter, *v_filter;
325 u32 rgval = 0;
326
327 rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
328 ~(ISPRSZ_CNT_HRSZ_MASK | ISPRSZ_CNT_VRSZ_MASK);
329 rgval |= ((ratio->horz - 1) << ISPRSZ_CNT_HRSZ_SHIFT)
330 & ISPRSZ_CNT_HRSZ_MASK;
331 rgval |= ((ratio->vert - 1) << ISPRSZ_CNT_VRSZ_SHIFT)
332 & ISPRSZ_CNT_VRSZ_MASK;
333 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
334
335 /* prepare horizontal filter coefficients */
336 if (ratio->horz > MID_RESIZE_VALUE)
337 h_filter = &filter_coefs.h_filter_coef_7tap[0];
338 else
339 h_filter = &filter_coefs.h_filter_coef_4tap[0];
340
341 /* prepare vertical filter coefficients */
342 if (ratio->vert > MID_RESIZE_VALUE)
343 v_filter = &filter_coefs.v_filter_coef_7tap[0];
344 else
345 v_filter = &filter_coefs.v_filter_coef_4tap[0];
346
347 resizer_set_filters(res, h_filter, v_filter);
348}
349
350/*
351 * resizer_set_dst_size - Setup the output height and width
352 * @res: Device context.
353 * @width: Output width.
354 * @height: Output height.
355 *
356 * Width :
357 * The value must be EVEN.
358 *
359 * Height:
360 * The number of bytes written to SDRAM must be
361 * a multiple of 16-bytes if the vertical resizing factor
362 * is greater than 1x (upsizing)
363 */
364static void resizer_set_output_size(struct isp_res_device *res,
365 u32 width, u32 height)
366{
367 struct isp_device *isp = to_isp_device(res);
368 u32 rgval = 0;
369
370 dev_dbg(isp->dev, "Output size[w/h]: %dx%d\n", width, height);
371 rgval = (width << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
372 & ISPRSZ_OUT_SIZE_HORZ_MASK;
373 rgval |= (height << ISPRSZ_OUT_SIZE_VERT_SHIFT)
374 & ISPRSZ_OUT_SIZE_VERT_MASK;
375 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_OUT_SIZE);
376}
377
378/*
379 * resizer_set_output_offset - Setup memory offset for the output lines.
380 * @res: Device context.
381 * @offset: Memory offset.
382 *
383 * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
384 * boundary; the 5 LSBs are read-only. For optimal use of SDRAM bandwidth,
385 * the SDRAM line offset must be set on a 256-byte boundary
386 */
387static void resizer_set_output_offset(struct isp_res_device *res, u32 offset)
388{
389 struct isp_device *isp = to_isp_device(res);
390
391 isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTOFF);
392}
393
394/*
395 * resizer_set_start - Setup vertical and horizontal start position
396 * @res: Device context.
397 * @left: Horizontal start position.
398 * @top: Vertical start position.
399 *
400 * Vertical start line:
401 * This field makes sense only when the resizer obtains its input
402 * from the preview engine/CCDC
403 *
404 * Horizontal start pixel:
405 * Pixels are coded on 16 bits for YUV and 8 bits for color separate data.
406 * When the resizer gets its input from SDRAM, this field must be set
407 * to <= 15 for YUV 16-bit data and <= 31 for 8-bit color separate data
408 */
409static void resizer_set_start(struct isp_res_device *res, u32 left, u32 top)
410{
411 struct isp_device *isp = to_isp_device(res);
412 u32 rgval = 0;
413
414 rgval = (left << ISPRSZ_IN_START_HORZ_ST_SHIFT)
415 & ISPRSZ_IN_START_HORZ_ST_MASK;
416 rgval |= (top << ISPRSZ_IN_START_VERT_ST_SHIFT)
417 & ISPRSZ_IN_START_VERT_ST_MASK;
418
419 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_START);
420}
421
422/*
423 * resizer_set_input_size - Setup the input size
424 * @res: Device context.
425 * @width: The range is 0 to 4095 pixels
426 * @height: The range is 0 to 4095 lines
427 */
428static void resizer_set_input_size(struct isp_res_device *res,
429 u32 width, u32 height)
430{
431 struct isp_device *isp = to_isp_device(res);
432 u32 rgval = 0;
433
434 dev_dbg(isp->dev, "Input size[w/h]: %dx%d\n", width, height);
435
436 rgval = (width << ISPRSZ_IN_SIZE_HORZ_SHIFT)
437 & ISPRSZ_IN_SIZE_HORZ_MASK;
438 rgval |= (height << ISPRSZ_IN_SIZE_VERT_SHIFT)
439 & ISPRSZ_IN_SIZE_VERT_MASK;
440
441 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_SIZE);
442}
443
444/*
445 * resizer_set_src_offs - Setup the memory offset for the input lines
446 * @res: Device context.
447 * @offset: Memory offset.
448 *
449 * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
450 * boundary; the 5 LSBs are read-only. This field must be programmed to be
451 * 0x0 if the resizer input is from preview engine/CCDC.
452 */
453static void resizer_set_input_offset(struct isp_res_device *res, u32 offset)
454{
455 struct isp_device *isp = to_isp_device(res);
456
457 isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INOFF);
458}
459
460/*
461 * resizer_set_intype - Input type select
462 * @res: Device context.
463 * @type: Pixel format type.
464 */
465static void resizer_set_intype(struct isp_res_device *res,
466 enum resizer_colors_type type)
467{
468 struct isp_device *isp = to_isp_device(res);
469
470 if (type == RSZ_COLOR8)
471 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
472 ISPRSZ_CNT_INPTYP);
473 else
474 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
475 ISPRSZ_CNT_INPTYP);
476}
477
478/*
479 * __resizer_set_inaddr - Helper function for set input address
480 * @res : pointer to resizer private data structure
481 * @addr: input address
482 * return none
483 */
484static void __resizer_set_inaddr(struct isp_res_device *res, u32 addr)
485{
486 struct isp_device *isp = to_isp_device(res);
487
488 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD);
489}
490
491/*
492 * The data rate at the horizontal resizer output must not exceed half the
493 * functional clock or 100 MP/s, whichever is lower. According to the TRM
494 * there's no similar requirement for the vertical resizer output. However
495 * experience showed that vertical upscaling by 4 leads to SBL overflows (with
496 * data rates at the resizer output exceeding 300 MP/s). Limiting the resizer
497 * output data rate to the functional clock or 200 MP/s, whichever is lower,
498 * seems to get rid of SBL overflows.
499 *
500 * The maximum data rate at the output of the horizontal resizer can thus be
501 * computed with
502 *
503 * max intermediate rate <= L3 clock * input height / output height
504 * max intermediate rate <= L3 clock / 2
505 *
506 * The maximum data rate at the resizer input is then
507 *
508 * max input rate <= max intermediate rate * input width / output width
509 *
510 * where the input width and height are the resizer input crop rectangle size.
511 * The TRM doesn't clearly explain if that's a maximum instant data rate or a
512 * maximum average data rate.
513 */
514void omap3isp_resizer_max_rate(struct isp_res_device *res,
515 unsigned int *max_rate)
516{
517 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
518 const struct v4l2_mbus_framefmt *ofmt = &res->formats[RESZ_PAD_SOURCE];
519 unsigned long limit = min(pipe->l3_ick, 200000000UL);
520 unsigned long clock;
521
522 clock = div_u64((u64)limit * res->crop.active.height, ofmt->height);
523 clock = min(clock, limit / 2);
524 *max_rate = div_u64((u64)clock * res->crop.active.width, ofmt->width);
525}
526
527/*
528 * When the resizer processes images from memory, the driver must slow down read
529 * requests on the input to at least comply with the internal data rate
530 * requirements. If the application real-time requirements can cope with slower
531 * processing, the resizer can be slowed down even more to put less pressure on
532 * the overall system.
533 *
534 * When the resizer processes images on the fly (either from the CCDC or the
535 * preview module), the same data rate requirements apply but they can't be
536 * enforced at the resizer level. The image input module (sensor, CCP2 or
537 * preview module) must not provide image data faster than the resizer can
538 * process.
539 *
540 * For live image pipelines, the data rate is set by the frame format, size and
541 * rate. The sensor output frame rate must not exceed the maximum resizer data
542 * rate.
543 *
544 * The resizer slows down read requests by inserting wait cycles in the SBL
545 * requests. The maximum number of 256-byte requests per second can be computed
546 * as (the data rate is multiplied by 2 to convert from pixels per second to
547 * bytes per second)
548 *
549 * request per second = data rate * 2 / 256
550 * cycles per request = cycles per second / requests per second
551 *
552 * The number of cycles per second is controlled by the L3 clock, leading to
553 *
554 * cycles per request = L3 frequency / 2 * 256 / data rate
555 */
556static void resizer_adjust_bandwidth(struct isp_res_device *res)
557{
558 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
559 struct isp_device *isp = to_isp_device(res);
560 unsigned long l3_ick = pipe->l3_ick;
561 struct v4l2_fract *timeperframe;
562 unsigned int cycles_per_frame;
563 unsigned int requests_per_frame;
564 unsigned int cycles_per_request;
565 unsigned int granularity;
566 unsigned int minimum;
567 unsigned int maximum;
568 unsigned int value;
569
570 if (res->input != RESIZER_INPUT_MEMORY) {
571 isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
572 ISPSBL_SDR_REQ_RSZ_EXP_MASK);
573 return;
574 }
575
576 switch (isp->revision) {
577 case ISP_REVISION_1_0:
578 case ISP_REVISION_2_0:
579 default:
580 granularity = 1024;
581 break;
582
583 case ISP_REVISION_15_0:
584 granularity = 32;
585 break;
586 }
587
588 /* Compute the minimum number of cycles per request, based on the
589 * pipeline maximum data rate. This is an absolute lower bound if we
590 * don't want SBL overflows, so round the value up.
591 */
592 cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
593 pipe->max_rate);
594 minimum = DIV_ROUND_UP(cycles_per_request, granularity);
595
596 /* Compute the maximum number of cycles per request, based on the
597 * requested frame rate. This is a soft upper bound to achieve a frame
598 * rate equal or higher than the requested value, so round the value
599 * down.
600 */
601 timeperframe = &pipe->max_timeperframe;
602
603 requests_per_frame = DIV_ROUND_UP(res->crop.active.width * 2, 256)
604 * res->crop.active.height;
605 cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
606 timeperframe->denominator);
607 cycles_per_request = cycles_per_frame / requests_per_frame;
608
609 maximum = cycles_per_request / granularity;
610
611 value = max(minimum, maximum);
612
613 dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
614 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
615 ISPSBL_SDR_REQ_RSZ_EXP_MASK,
616 value << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT);
617}
618
619/*
620 * omap3isp_resizer_busy - Checks if ISP resizer is busy.
621 *
622 * Returns busy field from ISPRSZ_PCR register.
623 */
624int omap3isp_resizer_busy(struct isp_res_device *res)
625{
626 struct isp_device *isp = to_isp_device(res);
627
628 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) &
629 ISPRSZ_PCR_BUSY;
630}
631
632/*
633 * resizer_set_inaddr - Sets the memory address of the input frame.
634 * @addr: 32bit memory address aligned on 32byte boundary.
635 */
636static void resizer_set_inaddr(struct isp_res_device *res, u32 addr)
637{
638 res->addr_base = addr;
639
640 /* This will handle crop settings in stream off state */
641 if (res->crop_offset)
642 addr += res->crop_offset & ~0x1f;
643
644 __resizer_set_inaddr(res, addr);
645}
646
647/*
648 * Configures the memory address to which the output frame is written.
649 * @addr: 32bit memory address aligned on 32byte boundary.
650 * Note: For SBL efficiency reasons the address should be on a 256-byte
651 * boundary.
652 */
653static void resizer_set_outaddr(struct isp_res_device *res, u32 addr)
654{
655 struct isp_device *isp = to_isp_device(res);
656
657 /*
658 * Set output address. This needs to be in its own function
659 * because it changes often.
660 */
661 isp_reg_writel(isp, addr << ISPRSZ_SDR_OUTADD_ADDR_SHIFT,
662 OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTADD);
663}
664
665/*
666 * resizer_print_status - Prints the values of the resizer module registers.
667 */
668#define RSZ_PRINT_REGISTER(isp, name)\
669 dev_dbg(isp->dev, "###RSZ " #name "=0x%08x\n", \
670 isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_##name))
671
672static void resizer_print_status(struct isp_res_device *res)
673{
674 struct isp_device *isp = to_isp_device(res);
675
676 dev_dbg(isp->dev, "-------------Resizer Register dump----------\n");
677
678 RSZ_PRINT_REGISTER(isp, PCR);
679 RSZ_PRINT_REGISTER(isp, CNT);
680 RSZ_PRINT_REGISTER(isp, OUT_SIZE);
681 RSZ_PRINT_REGISTER(isp, IN_START);
682 RSZ_PRINT_REGISTER(isp, IN_SIZE);
683 RSZ_PRINT_REGISTER(isp, SDR_INADD);
684 RSZ_PRINT_REGISTER(isp, SDR_INOFF);
685 RSZ_PRINT_REGISTER(isp, SDR_OUTADD);
686 RSZ_PRINT_REGISTER(isp, SDR_OUTOFF);
687 RSZ_PRINT_REGISTER(isp, YENH);
688
689 dev_dbg(isp->dev, "--------------------------------------------\n");
690}
691
692/*
693 * resizer_calc_ratios - Helper function for calculate resizer ratios
694 * @res: pointer to resizer private data structure
695 * @input: input frame size
696 * @output: output frame size
697 * @ratio : return calculated ratios
698 * return none
699 *
700 * The resizer uses a polyphase sample rate converter. The upsampling filter
701 * has a fixed number of phases that depend on the resizing ratio. As the ratio
702 * computation depends on the number of phases, we need to compute a first
703 * approximation and then refine it.
704 *
705 * The input/output/ratio relationship is given by the OMAP34xx TRM:
706 *
707 * - 8-phase, 4-tap mode (RSZ = 64 ~ 512)
708 * iw = (32 * sph + (ow - 1) * hrsz + 16) >> 8 + 7
709 * ih = (32 * spv + (oh - 1) * vrsz + 16) >> 8 + 4
710 * - 4-phase, 7-tap mode (RSZ = 513 ~ 1024)
711 * iw = (64 * sph + (ow - 1) * hrsz + 32) >> 8 + 7
712 * ih = (64 * spv + (oh - 1) * vrsz + 32) >> 8 + 7
713 *
714 * iw and ih are the input width and height after cropping. Those equations need
715 * to be satisfied exactly for the resizer to work correctly.
716 *
717 * Reverting the equations, we can compute the resizing ratios with
718 *
719 * - 8-phase, 4-tap mode
720 * hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1)
721 * vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1)
722 * - 4-phase, 7-tap mode
723 * hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1)
724 * vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1)
725 *
726 * The ratios are integer values, and must be rounded down to ensure that the
727 * cropped input size is not bigger than the uncropped input size. As the ratio
728 * in 7-tap mode is always smaller than the ratio in 4-tap mode, we can use the
729 * 7-tap mode equations to compute a ratio approximation.
730 *
731 * We first clamp the output size according to the hardware capabilitie to avoid
732 * auto-cropping the input more than required to satisfy the TRM equations. The
733 * minimum output size is achieved with a scaling factor of 1024. It is thus
734 * computed using the 7-tap equations.
735 *
736 * min ow = ((iw - 7) * 256 - 32 - 64 * sph) / 1024 + 1
737 * min oh = ((ih - 7) * 256 - 32 - 64 * spv) / 1024 + 1
738 *
739 * Similarly, the maximum output size is achieved with a scaling factor of 64
740 * and computed using the 4-tap equations.
741 *
742 * max ow = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / 64 + 1
743 * max oh = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1
744 *
745 * The additional +255 term compensates for the round down operation performed
746 * by the TRM equations when shifting the value right by 8 bits.
747 *
748 * We then compute and clamp the ratios (x1/4 ~ x4). Clamping the output size to
749 * the maximum value guarantees that the ratio value will never be smaller than
750 * the minimum, but it could still slightly exceed the maximum. Clamping the
751 * ratio will thus result in a resizing factor slightly larger than the
752 * requested value.
753 *
754 * To accomodate that, and make sure the TRM equations are satisfied exactly, we
755 * compute the input crop rectangle as the last step.
756 *
757 * As if the situation wasn't complex enough, the maximum output width depends
758 * on the vertical resizing ratio. Fortunately, the output height doesn't
759 * depend on the horizontal resizing ratio. We can then start by computing the
760 * output height and the vertical ratio, and then move to computing the output
761 * width and the horizontal ratio.
762 */
763static void resizer_calc_ratios(struct isp_res_device *res,
764 struct v4l2_rect *input,
765 struct v4l2_mbus_framefmt *output,
766 struct resizer_ratio *ratio)
767{
768 struct isp_device *isp = to_isp_device(res);
769 const unsigned int spv = DEFAULT_PHASE;
770 const unsigned int sph = DEFAULT_PHASE;
771 unsigned int upscaled_width;
772 unsigned int upscaled_height;
773 unsigned int min_width;
774 unsigned int min_height;
775 unsigned int max_width;
776 unsigned int max_height;
777 unsigned int width_alignment;
778
779 /*
780 * Clamp the output height based on the hardware capabilities and
781 * compute the vertical resizing ratio.
782 */
783 min_height = ((input->height - 7) * 256 - 32 - 64 * spv) / 1024 + 1;
784 min_height = max_t(unsigned int, min_height, MIN_OUT_HEIGHT);
785 max_height = ((input->height - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1;
786 max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
787 output->height = clamp(output->height, min_height, max_height);
788
789 ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv)
790 / (output->height - 1);
791 ratio->vert = clamp_t(unsigned int, ratio->vert,
792 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
793
794 if (ratio->vert <= MID_RESIZE_VALUE) {
795 upscaled_height = (output->height - 1) * ratio->vert
796 + 32 * spv + 16;
797 input->height = (upscaled_height >> 8) + 4;
798 } else {
799 upscaled_height = (output->height - 1) * ratio->vert
800 + 64 * spv + 32;
801 input->height = (upscaled_height >> 8) + 7;
802 }
803
804 /*
805 * Compute the minimum and maximum output widths based on the hardware
806 * capabilities. The maximum depends on the vertical resizing ratio.
807 */
808 min_width = ((input->width - 7) * 256 - 32 - 64 * sph) / 1024 + 1;
809 min_width = max_t(unsigned int, min_width, MIN_OUT_WIDTH);
810
811 if (ratio->vert <= MID_RESIZE_VALUE) {
812 switch (isp->revision) {
813 case ISP_REVISION_1_0:
814 max_width = MAX_4TAP_OUT_WIDTH_ES1;
815 break;
816
817 case ISP_REVISION_2_0:
818 default:
819 max_width = MAX_4TAP_OUT_WIDTH_ES2;
820 break;
821
822 case ISP_REVISION_15_0:
823 max_width = MAX_4TAP_OUT_WIDTH_3630;
824 break;
825 }
826 } else {
827 switch (isp->revision) {
828 case ISP_REVISION_1_0:
829 max_width = MAX_7TAP_OUT_WIDTH_ES1;
830 break;
831
832 case ISP_REVISION_2_0:
833 default:
834 max_width = MAX_7TAP_OUT_WIDTH_ES2;
835 break;
836
837 case ISP_REVISION_15_0:
838 max_width = MAX_7TAP_OUT_WIDTH_3630;
839 break;
840 }
841 }
842 max_width = min(((input->width - 7) * 256 + 255 - 16 - 32 * sph) / 64
843 + 1, max_width);
844
845 /*
846 * The output width must be even, and must be a multiple of 16 bytes
847 * when upscaling vertically. Clamp the output width to the valid range.
848 * Take the alignment into account (the maximum width in 7-tap mode on
849 * ES2 isn't a multiple of 8) and align the result up to make sure it
850 * won't be smaller than the minimum.
851 */
852 width_alignment = ratio->vert < 256 ? 8 : 2;
853 output->width = clamp(output->width, min_width,
854 max_width & ~(width_alignment - 1));
855 output->width = ALIGN(output->width, width_alignment);
856
857 ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph)
858 / (output->width - 1);
859 ratio->horz = clamp_t(unsigned int, ratio->horz,
860 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
861
862 if (ratio->horz <= MID_RESIZE_VALUE) {
863 upscaled_width = (output->width - 1) * ratio->horz
864 + 32 * sph + 16;
865 input->width = (upscaled_width >> 8) + 7;
866 } else {
867 upscaled_width = (output->width - 1) * ratio->horz
868 + 64 * sph + 32;
869 input->width = (upscaled_width >> 8) + 7;
870 }
871}
872
873/*
874 * resizer_set_crop_params - Setup hardware with cropping parameters
875 * @res : resizer private structure
876 * @crop_rect : current crop rectangle
877 * @ratio : resizer ratios
878 * return none
879 */
880static void resizer_set_crop_params(struct isp_res_device *res,
881 const struct v4l2_mbus_framefmt *input,
882 const struct v4l2_mbus_framefmt *output)
883{
884 resizer_set_ratio(res, &res->ratio);
885
886 /* Set chrominance horizontal algorithm */
887 if (res->ratio.horz >= RESIZE_DIVISOR)
888 resizer_set_bilinear(res, RSZ_THE_SAME);
889 else
890 resizer_set_bilinear(res, RSZ_BILINEAR);
891
892 resizer_adjust_bandwidth(res);
893
894 if (res->input == RESIZER_INPUT_MEMORY) {
895 /* Calculate additional offset for crop */
896 res->crop_offset = (res->crop.active.top * input->width +
897 res->crop.active.left) * 2;
898 /*
899 * Write lowest 4 bits of horizontal pixel offset (in pixels),
900 * vertical start must be 0.
901 */
902 resizer_set_start(res, (res->crop_offset / 2) & 0xf, 0);
903
904 /*
905 * Set start (read) address for cropping, in bytes.
906 * Lowest 5 bits must be zero.
907 */
908 __resizer_set_inaddr(res,
909 res->addr_base + (res->crop_offset & ~0x1f));
910 } else {
911 /*
912 * Set vertical start line and horizontal starting pixel.
913 * If the input is from CCDC/PREV, horizontal start field is
914 * in bytes (twice number of pixels).
915 */
916 resizer_set_start(res, res->crop.active.left * 2,
917 res->crop.active.top);
918 /* Input address and offset must be 0 for preview/ccdc input */
919 __resizer_set_inaddr(res, 0);
920 resizer_set_input_offset(res, 0);
921 }
922
923 /* Set the input size */
924 resizer_set_input_size(res, res->crop.active.width,
925 res->crop.active.height);
926}
927
928static void resizer_configure(struct isp_res_device *res)
929{
930 struct v4l2_mbus_framefmt *informat, *outformat;
931 struct resizer_luma_yenh luma = {0, 0, 0, 0};
932
933 resizer_set_source(res, res->input);
934
935 informat = &res->formats[RESZ_PAD_SINK];
936 outformat = &res->formats[RESZ_PAD_SOURCE];
937
938 /* RESZ_PAD_SINK */
939 if (res->input == RESIZER_INPUT_VP)
940 resizer_set_input_offset(res, 0);
941 else
942 resizer_set_input_offset(res, ALIGN(informat->width, 0x10) * 2);
943
944 /* YUV422 interleaved, default phase, no luma enhancement */
945 resizer_set_intype(res, RSZ_YUV422);
946 resizer_set_ycpos(res, informat->code);
947 resizer_set_phase(res, DEFAULT_PHASE, DEFAULT_PHASE);
948 resizer_set_luma(res, &luma);
949
950 /* RESZ_PAD_SOURCE */
951 resizer_set_output_offset(res, ALIGN(outformat->width * 2, 32));
952 resizer_set_output_size(res, outformat->width, outformat->height);
953
954 resizer_set_crop_params(res, informat, outformat);
955}
956
957/* -----------------------------------------------------------------------------
958 * Interrupt handling
959 */
960
961static void resizer_enable_oneshot(struct isp_res_device *res)
962{
963 struct isp_device *isp = to_isp_device(res);
964
965 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR,
966 ISPRSZ_PCR_ENABLE | ISPRSZ_PCR_ONESHOT);
967}
968
969void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res)
970{
971 /*
972 * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
973 * condition, the module was paused and now we have a buffer queued
974 * on the output again. Restart the pipeline if running in continuous
975 * mode.
976 */
977 if (res->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
978 res->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
979 resizer_enable_oneshot(res);
980 isp_video_dmaqueue_flags_clr(&res->video_out);
981 }
982}
983
984static void resizer_isr_buffer(struct isp_res_device *res)
985{
986 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
987 struct isp_buffer *buffer;
988 int restart = 0;
989
990 if (res->state == ISP_PIPELINE_STREAM_STOPPED)
991 return;
992
993 /* Complete the output buffer and, if reading from memory, the input
994 * buffer.
995 */
996 buffer = omap3isp_video_buffer_next(&res->video_out, res->error);
997 if (buffer != NULL) {
998 resizer_set_outaddr(res, buffer->isp_addr);
999 restart = 1;
1000 }
1001
1002 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1003
1004 if (res->input == RESIZER_INPUT_MEMORY) {
1005 buffer = omap3isp_video_buffer_next(&res->video_in, 0);
1006 if (buffer != NULL)
1007 resizer_set_inaddr(res, buffer->isp_addr);
1008 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
1009 }
1010
1011 if (res->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
1012 if (isp_pipeline_ready(pipe))
1013 omap3isp_pipeline_set_stream(pipe,
1014 ISP_PIPELINE_STREAM_SINGLESHOT);
1015 } else {
1016 /* If an underrun occurs, the video queue operation handler will
1017 * restart the resizer. Otherwise restart it immediately.
1018 */
1019 if (restart)
1020 resizer_enable_oneshot(res);
1021 }
1022
1023 res->error = 0;
1024}
1025
1026/*
1027 * omap3isp_resizer_isr - ISP resizer interrupt handler
1028 *
1029 * Manage the resizer video buffers and configure shadowed and busy-locked
1030 * registers.
1031 */
1032void omap3isp_resizer_isr(struct isp_res_device *res)
1033{
1034 struct v4l2_mbus_framefmt *informat, *outformat;
1035
1036 if (omap3isp_module_sync_is_stopping(&res->wait, &res->stopping))
1037 return;
1038
1039 if (res->applycrop) {
1040 outformat = __resizer_get_format(res, NULL, RESZ_PAD_SOURCE,
1041 V4L2_SUBDEV_FORMAT_ACTIVE);
1042 informat = __resizer_get_format(res, NULL, RESZ_PAD_SINK,
1043 V4L2_SUBDEV_FORMAT_ACTIVE);
1044 resizer_set_crop_params(res, informat, outformat);
1045 res->applycrop = 0;
1046 }
1047
1048 resizer_isr_buffer(res);
1049}
1050
1051/* -----------------------------------------------------------------------------
1052 * ISP video operations
1053 */
1054
1055static int resizer_video_queue(struct isp_video *video,
1056 struct isp_buffer *buffer)
1057{
1058 struct isp_res_device *res = &video->isp->isp_res;
1059
1060 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1061 resizer_set_inaddr(res, buffer->isp_addr);
1062
1063 /*
1064 * We now have a buffer queued on the output. Despite what the
1065 * TRM says, the resizer can't be restarted immediately.
1066 * Enabling it in one shot mode in the middle of a frame (or at
1067 * least asynchronously to the frame) results in the output
1068 * being shifted randomly left/right and up/down, as if the
1069 * hardware didn't synchronize itself to the beginning of the
1070 * frame correctly.
1071 *
1072 * Restart the resizer on the next sync interrupt if running in
1073 * continuous mode or when starting the stream.
1074 */
1075 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1076 resizer_set_outaddr(res, buffer->isp_addr);
1077
1078 return 0;
1079}
1080
1081static const struct isp_video_operations resizer_video_ops = {
1082 .queue = resizer_video_queue,
1083};
1084
1085/* -----------------------------------------------------------------------------
1086 * V4L2 subdev operations
1087 */
1088
1089/*
1090 * resizer_set_stream - Enable/Disable streaming on resizer subdev
1091 * @sd: ISP resizer V4L2 subdev
1092 * @enable: 1 == Enable, 0 == Disable
1093 *
1094 * The resizer hardware can't be enabled without a memory buffer to write to.
1095 * As the s_stream operation is called in response to a STREAMON call without
1096 * any buffer queued yet, just update the state field and return immediately.
1097 * The resizer will be enabled in resizer_video_queue().
1098 */
1099static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
1100{
1101 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1102 struct isp_video *video_out = &res->video_out;
1103 struct isp_device *isp = to_isp_device(res);
1104 struct device *dev = to_device(res);
1105
1106 if (res->state == ISP_PIPELINE_STREAM_STOPPED) {
1107 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1108 return 0;
1109
1110 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_RESIZER);
1111 resizer_configure(res);
1112 res->error = 0;
1113 resizer_print_status(res);
1114 }
1115
1116 switch (enable) {
1117 case ISP_PIPELINE_STREAM_CONTINUOUS:
1118 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
1119 if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
1120 resizer_enable_oneshot(res);
1121 isp_video_dmaqueue_flags_clr(video_out);
1122 }
1123 break;
1124
1125 case ISP_PIPELINE_STREAM_SINGLESHOT:
1126 if (res->input == RESIZER_INPUT_MEMORY)
1127 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_READ);
1128 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
1129
1130 resizer_enable_oneshot(res);
1131 break;
1132
1133 case ISP_PIPELINE_STREAM_STOPPED:
1134 if (omap3isp_module_sync_idle(&sd->entity, &res->wait,
1135 &res->stopping))
1136 dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
1137 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_RESIZER_READ |
1138 OMAP3_ISP_SBL_RESIZER_WRITE);
1139 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_RESIZER);
1140 isp_video_dmaqueue_flags_clr(video_out);
1141 break;
1142 }
1143
1144 res->state = enable;
1145 return 0;
1146}
1147
1148/*
1149 * resizer_g_crop - handle get crop subdev operation
1150 * @sd : pointer to v4l2 subdev structure
1151 * @pad : subdev pad
1152 * @crop : pointer to crop structure
1153 * @which : active or try format
1154 * return zero
1155 */
1156static int resizer_g_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1157 struct v4l2_subdev_crop *crop)
1158{
1159 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1160 struct v4l2_mbus_framefmt *format;
1161 struct resizer_ratio ratio;
1162
1163 /* Only sink pad has crop capability */
1164 if (crop->pad != RESZ_PAD_SINK)
1165 return -EINVAL;
1166
1167 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, crop->which);
1168 crop->rect = *__resizer_get_crop(res, fh, crop->which);
1169 resizer_calc_ratios(res, &crop->rect, format, &ratio);
1170
1171 return 0;
1172}
1173
1174/*
1175 * resizer_try_crop - mangles crop parameters.
1176 */
1177static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1178 const struct v4l2_mbus_framefmt *source,
1179 struct v4l2_rect *crop)
1180{
1181 const unsigned int spv = DEFAULT_PHASE;
1182 const unsigned int sph = DEFAULT_PHASE;
1183
1184 /* Crop rectangle is constrained to the output size so that zoom ratio
1185 * cannot exceed +/-4.0.
1186 */
1187 unsigned int min_width =
1188 ((32 * sph + (source->width - 1) * 64 + 16) >> 8) + 7;
1189 unsigned int min_height =
1190 ((32 * spv + (source->height - 1) * 64 + 16) >> 8) + 4;
1191 unsigned int max_width =
1192 ((64 * sph + (source->width - 1) * 1024 + 32) >> 8) + 7;
1193 unsigned int max_height =
1194 ((64 * spv + (source->height - 1) * 1024 + 32) >> 8) + 7;
1195
1196 crop->width = clamp_t(u32, crop->width, min_width, max_width);
1197 crop->height = clamp_t(u32, crop->height, min_height, max_height);
1198
1199 /* Crop can not go beyond of the input rectangle */
1200 crop->left = clamp_t(u32, crop->left, 0, sink->width - MIN_IN_WIDTH);
1201 crop->width = clamp_t(u32, crop->width, MIN_IN_WIDTH,
1202 sink->width - crop->left);
1203 crop->top = clamp_t(u32, crop->top, 0, sink->height - MIN_IN_HEIGHT);
1204 crop->height = clamp_t(u32, crop->height, MIN_IN_HEIGHT,
1205 sink->height - crop->top);
1206}
1207
1208/*
1209 * resizer_s_crop - handle set crop subdev operation
1210 * @sd : pointer to v4l2 subdev structure
1211 * @pad : subdev pad
1212 * @crop : pointer to crop structure
1213 * @which : active or try format
1214 * return -EINVAL or zero when succeed
1215 */
1216static int resizer_s_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1217 struct v4l2_subdev_crop *crop)
1218{
1219 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1220 struct isp_device *isp = to_isp_device(res);
1221 struct v4l2_mbus_framefmt *format_sink, *format_source;
1222 struct resizer_ratio ratio;
1223
1224 /* Only sink pad has crop capability */
1225 if (crop->pad != RESZ_PAD_SINK)
1226 return -EINVAL;
1227
1228 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1229 crop->which);
1230 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1231 crop->which);
1232
1233 dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__,
1234 crop->rect.left, crop->rect.top, crop->rect.width,
1235 crop->rect.height, crop->which);
1236
1237 dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__,
1238 format_sink->width, format_sink->height,
1239 format_source->width, format_source->height);
1240
1241 resizer_try_crop(format_sink, format_source, &crop->rect);
1242 *__resizer_get_crop(res, fh, crop->which) = crop->rect;
1243 resizer_calc_ratios(res, &crop->rect, format_source, &ratio);
1244
1245 if (crop->which == V4L2_SUBDEV_FORMAT_TRY)
1246 return 0;
1247
1248 res->ratio = ratio;
1249 res->crop.active = crop->rect;
1250
1251 /*
1252 * s_crop can be called while streaming is on. In this case
1253 * the crop values will be set in the next IRQ.
1254 */
1255 if (res->state != ISP_PIPELINE_STREAM_STOPPED)
1256 res->applycrop = 1;
1257
1258 return 0;
1259}
1260
1261/* resizer pixel formats */
1262static const unsigned int resizer_formats[] = {
1263 V4L2_MBUS_FMT_UYVY8_1X16,
1264 V4L2_MBUS_FMT_YUYV8_1X16,
1265};
1266
1267static unsigned int resizer_max_in_width(struct isp_res_device *res)
1268{
1269 struct isp_device *isp = to_isp_device(res);
1270
1271 if (res->input == RESIZER_INPUT_MEMORY) {
1272 return MAX_IN_WIDTH_MEMORY_MODE;
1273 } else {
1274 if (isp->revision == ISP_REVISION_1_0)
1275 return MAX_IN_WIDTH_ONTHEFLY_MODE_ES1;
1276 else
1277 return MAX_IN_WIDTH_ONTHEFLY_MODE_ES2;
1278 }
1279}
1280
1281/*
1282 * resizer_try_format - Handle try format by pad subdev method
1283 * @res : ISP resizer device
1284 * @fh : V4L2 subdev file handle
1285 * @pad : pad num
1286 * @fmt : pointer to v4l2 format structure
1287 * @which : wanted subdev format
1288 */
1289static void resizer_try_format(struct isp_res_device *res,
1290 struct v4l2_subdev_fh *fh, unsigned int pad,
1291 struct v4l2_mbus_framefmt *fmt,
1292 enum v4l2_subdev_format_whence which)
1293{
1294 struct v4l2_mbus_framefmt *format;
1295 struct resizer_ratio ratio;
1296 struct v4l2_rect crop;
1297
1298 switch (pad) {
1299 case RESZ_PAD_SINK:
1300 if (fmt->code != V4L2_MBUS_FMT_YUYV8_1X16 &&
1301 fmt->code != V4L2_MBUS_FMT_UYVY8_1X16)
1302 fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
1303
1304 fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH,
1305 resizer_max_in_width(res));
1306 fmt->height = clamp_t(u32, fmt->height, MIN_IN_HEIGHT,
1307 MAX_IN_HEIGHT);
1308 break;
1309
1310 case RESZ_PAD_SOURCE:
1311 format = __resizer_get_format(res, fh, RESZ_PAD_SINK, which);
1312 fmt->code = format->code;
1313
1314 crop = *__resizer_get_crop(res, fh, which);
1315 resizer_calc_ratios(res, &crop, fmt, &ratio);
1316 break;
1317 }
1318
1319 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1320 fmt->field = V4L2_FIELD_NONE;
1321}
1322
1323/*
1324 * resizer_enum_mbus_code - Handle pixel format enumeration
1325 * @sd : pointer to v4l2 subdev structure
1326 * @fh : V4L2 subdev file handle
1327 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1328 * return -EINVAL or zero on success
1329 */
1330static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
1331 struct v4l2_subdev_fh *fh,
1332 struct v4l2_subdev_mbus_code_enum *code)
1333{
1334 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1335 struct v4l2_mbus_framefmt *format;
1336
1337 if (code->pad == RESZ_PAD_SINK) {
1338 if (code->index >= ARRAY_SIZE(resizer_formats))
1339 return -EINVAL;
1340
1341 code->code = resizer_formats[code->index];
1342 } else {
1343 if (code->index != 0)
1344 return -EINVAL;
1345
1346 format = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1347 V4L2_SUBDEV_FORMAT_TRY);
1348 code->code = format->code;
1349 }
1350
1351 return 0;
1352}
1353
1354static int resizer_enum_frame_size(struct v4l2_subdev *sd,
1355 struct v4l2_subdev_fh *fh,
1356 struct v4l2_subdev_frame_size_enum *fse)
1357{
1358 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1359 struct v4l2_mbus_framefmt format;
1360
1361 if (fse->index != 0)
1362 return -EINVAL;
1363
1364 format.code = fse->code;
1365 format.width = 1;
1366 format.height = 1;
1367 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1368 fse->min_width = format.width;
1369 fse->min_height = format.height;
1370
1371 if (format.code != fse->code)
1372 return -EINVAL;
1373
1374 format.code = fse->code;
1375 format.width = -1;
1376 format.height = -1;
1377 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1378 fse->max_width = format.width;
1379 fse->max_height = format.height;
1380
1381 return 0;
1382}
1383
1384/*
1385 * resizer_get_format - Handle get format by pads subdev method
1386 * @sd : pointer to v4l2 subdev structure
1387 * @fh : V4L2 subdev file handle
1388 * @fmt : pointer to v4l2 subdev format structure
1389 * return -EINVAL or zero on sucess
1390 */
1391static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1392 struct v4l2_subdev_format *fmt)
1393{
1394 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1395 struct v4l2_mbus_framefmt *format;
1396
1397 format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
1398 if (format == NULL)
1399 return -EINVAL;
1400
1401 fmt->format = *format;
1402 return 0;
1403}
1404
1405/*
1406 * resizer_set_format - Handle set format by pads subdev method
1407 * @sd : pointer to v4l2 subdev structure
1408 * @fh : V4L2 subdev file handle
1409 * @fmt : pointer to v4l2 subdev format structure
1410 * return -EINVAL or zero on success
1411 */
1412static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1413 struct v4l2_subdev_format *fmt)
1414{
1415 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1416 struct v4l2_mbus_framefmt *format;
1417 struct v4l2_rect *crop;
1418
1419 format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
1420 if (format == NULL)
1421 return -EINVAL;
1422
1423 resizer_try_format(res, fh, fmt->pad, &fmt->format, fmt->which);
1424 *format = fmt->format;
1425
1426 if (fmt->pad == RESZ_PAD_SINK) {
1427 /* reset crop rectangle */
1428 crop = __resizer_get_crop(res, fh, fmt->which);
1429 crop->left = 0;
1430 crop->top = 0;
1431 crop->width = fmt->format.width;
1432 crop->height = fmt->format.height;
1433
1434 /* Propagate the format from sink to source */
1435 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1436 fmt->which);
1437 *format = fmt->format;
1438 resizer_try_format(res, fh, RESZ_PAD_SOURCE, format,
1439 fmt->which);
1440 }
1441
1442 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1443 /* Compute and store the active crop rectangle and resizer
1444 * ratios. format already points to the source pad active
1445 * format.
1446 */
1447 res->crop.active = res->crop.request;
1448 resizer_calc_ratios(res, &res->crop.active, format,
1449 &res->ratio);
1450 }
1451
1452 return 0;
1453}
1454
1455/*
1456 * resizer_init_formats - Initialize formats on all pads
1457 * @sd: ISP resizer V4L2 subdevice
1458 * @fh: V4L2 subdev file handle
1459 *
1460 * Initialize all pad formats with default values. If fh is not NULL, try
1461 * formats are initialized on the file handle. Otherwise active formats are
1462 * initialized on the device.
1463 */
1464static int resizer_init_formats(struct v4l2_subdev *sd,
1465 struct v4l2_subdev_fh *fh)
1466{
1467 struct v4l2_subdev_format format;
1468
1469 memset(&format, 0, sizeof(format));
1470 format.pad = RESZ_PAD_SINK;
1471 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1472 format.format.code = V4L2_MBUS_FMT_YUYV8_1X16;
1473 format.format.width = 4096;
1474 format.format.height = 4096;
1475 resizer_set_format(sd, fh, &format);
1476
1477 return 0;
1478}
1479
1480/* subdev video operations */
1481static const struct v4l2_subdev_video_ops resizer_v4l2_video_ops = {
1482 .s_stream = resizer_set_stream,
1483};
1484
1485/* subdev pad operations */
1486static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
1487 .enum_mbus_code = resizer_enum_mbus_code,
1488 .enum_frame_size = resizer_enum_frame_size,
1489 .get_fmt = resizer_get_format,
1490 .set_fmt = resizer_set_format,
1491 .get_crop = resizer_g_crop,
1492 .set_crop = resizer_s_crop,
1493};
1494
1495/* subdev operations */
1496static const struct v4l2_subdev_ops resizer_v4l2_ops = {
1497 .video = &resizer_v4l2_video_ops,
1498 .pad = &resizer_v4l2_pad_ops,
1499};
1500
1501/* subdev internal operations */
1502static const struct v4l2_subdev_internal_ops resizer_v4l2_internal_ops = {
1503 .open = resizer_init_formats,
1504};
1505
1506/* -----------------------------------------------------------------------------
1507 * Media entity operations
1508 */
1509
1510/*
1511 * resizer_link_setup - Setup resizer connections.
1512 * @entity : Pointer to media entity structure
1513 * @local : Pointer to local pad array
1514 * @remote : Pointer to remote pad array
1515 * @flags : Link flags
1516 * return -EINVAL or zero on success
1517 */
1518static int resizer_link_setup(struct media_entity *entity,
1519 const struct media_pad *local,
1520 const struct media_pad *remote, u32 flags)
1521{
1522 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1523 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1524
1525 switch (local->index | media_entity_type(remote->entity)) {
1526 case RESZ_PAD_SINK | MEDIA_ENT_T_DEVNODE:
1527 /* read from memory */
1528 if (flags & MEDIA_LNK_FL_ENABLED) {
1529 if (res->input == RESIZER_INPUT_VP)
1530 return -EBUSY;
1531 res->input = RESIZER_INPUT_MEMORY;
1532 } else {
1533 if (res->input == RESIZER_INPUT_MEMORY)
1534 res->input = RESIZER_INPUT_NONE;
1535 }
1536 break;
1537
1538 case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
1539 /* read from ccdc or previewer */
1540 if (flags & MEDIA_LNK_FL_ENABLED) {
1541 if (res->input == RESIZER_INPUT_MEMORY)
1542 return -EBUSY;
1543 res->input = RESIZER_INPUT_VP;
1544 } else {
1545 if (res->input == RESIZER_INPUT_VP)
1546 res->input = RESIZER_INPUT_NONE;
1547 }
1548 break;
1549
1550 case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1551 /* resizer always write to memory */
1552 break;
1553
1554 default:
1555 return -EINVAL;
1556 }
1557
1558 return 0;
1559}
1560
1561/* media operations */
1562static const struct media_entity_operations resizer_media_ops = {
1563 .link_setup = resizer_link_setup,
1564};
1565
1566/*
1567 * resizer_init_entities - Initialize resizer subdev and media entity.
1568 * @res : Pointer to resizer device structure
1569 * return -ENOMEM or zero on success
1570 */
1571static int resizer_init_entities(struct isp_res_device *res)
1572{
1573 struct v4l2_subdev *sd = &res->subdev;
1574 struct media_pad *pads = res->pads;
1575 struct media_entity *me = &sd->entity;
1576 int ret;
1577
1578 res->input = RESIZER_INPUT_NONE;
1579
1580 v4l2_subdev_init(sd, &resizer_v4l2_ops);
1581 sd->internal_ops = &resizer_v4l2_internal_ops;
1582 strlcpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name));
1583 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1584 v4l2_set_subdevdata(sd, res);
1585 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1586
1587 pads[RESZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1588 pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1589
1590 me->ops = &resizer_media_ops;
1591 ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0);
1592 if (ret < 0)
1593 return ret;
1594
1595 resizer_init_formats(sd, NULL);
1596
1597 res->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1598 res->video_in.ops = &resizer_video_ops;
1599 res->video_in.isp = to_isp_device(res);
1600 res->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
1601 res->video_in.bpl_alignment = 32;
1602 res->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1603 res->video_out.ops = &resizer_video_ops;
1604 res->video_out.isp = to_isp_device(res);
1605 res->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
1606 res->video_out.bpl_alignment = 32;
1607
1608 ret = omap3isp_video_init(&res->video_in, "resizer");
1609 if (ret < 0)
1610 return ret;
1611
1612 ret = omap3isp_video_init(&res->video_out, "resizer");
1613 if (ret < 0)
1614 return ret;
1615
1616 /* Connect the video nodes to the resizer subdev. */
1617 ret = media_entity_create_link(&res->video_in.video.entity, 0,
1618 &res->subdev.entity, RESZ_PAD_SINK, 0);
1619 if (ret < 0)
1620 return ret;
1621
1622 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
1623 &res->video_out.video.entity, 0, 0);
1624 if (ret < 0)
1625 return ret;
1626
1627 return 0;
1628}
1629
1630void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
1631{
1632 media_entity_cleanup(&res->subdev.entity);
1633
1634 v4l2_device_unregister_subdev(&res->subdev);
1635 omap3isp_video_unregister(&res->video_in);
1636 omap3isp_video_unregister(&res->video_out);
1637}
1638
1639int omap3isp_resizer_register_entities(struct isp_res_device *res,
1640 struct v4l2_device *vdev)
1641{
1642 int ret;
1643
1644 /* Register the subdev and video nodes. */
1645 ret = v4l2_device_register_subdev(vdev, &res->subdev);
1646 if (ret < 0)
1647 goto error;
1648
1649 ret = omap3isp_video_register(&res->video_in, vdev);
1650 if (ret < 0)
1651 goto error;
1652
1653 ret = omap3isp_video_register(&res->video_out, vdev);
1654 if (ret < 0)
1655 goto error;
1656
1657 return 0;
1658
1659error:
1660 omap3isp_resizer_unregister_entities(res);
1661 return ret;
1662}
1663
1664/* -----------------------------------------------------------------------------
1665 * ISP resizer initialization and cleanup
1666 */
1667
1668void omap3isp_resizer_cleanup(struct isp_device *isp)
1669{
1670}
1671
1672/*
1673 * isp_resizer_init - Resizer initialization.
1674 * @isp : Pointer to ISP device
1675 * return -ENOMEM or zero on success
1676 */
1677int omap3isp_resizer_init(struct isp_device *isp)
1678{
1679 struct isp_res_device *res = &isp->isp_res;
1680 int ret;
1681
1682 init_waitqueue_head(&res->wait);
1683 atomic_set(&res->stopping, 0);
1684 ret = resizer_init_entities(res);
1685 if (ret < 0)
1686 goto out;
1687
1688out:
1689 if (ret)
1690 omap3isp_resizer_cleanup(isp);
1691
1692 return ret;
1693}
diff --git a/drivers/media/video/omap3isp/ispresizer.h b/drivers/media/video/omap3isp/ispresizer.h
new file mode 100644
index 000000000000..76abc2e42126
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispresizer.h
@@ -0,0 +1,147 @@
1/*
2 * ispresizer.h
3 *
4 * TI OMAP3 ISP - Resizer module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_RESIZER_H
28#define OMAP3_ISP_RESIZER_H
29
30#include <linux/types.h>
31
32/*
33 * Constants for filter coefficents count
34 */
35#define COEFF_CNT 32
36
37/*
38 * struct isprsz_coef - Structure for resizer filter coeffcients.
39 * @h_filter_coef_4tap: Horizontal filter coefficients for 8-phase/4-tap
40 * mode (.5x-4x)
41 * @v_filter_coef_4tap: Vertical filter coefficients for 8-phase/4-tap
42 * mode (.5x-4x)
43 * @h_filter_coef_7tap: Horizontal filter coefficients for 4-phase/7-tap
44 * mode (.25x-.5x)
45 * @v_filter_coef_7tap: Vertical filter coefficients for 4-phase/7-tap
46 * mode (.25x-.5x)
47 */
48struct isprsz_coef {
49 u16 h_filter_coef_4tap[32];
50 u16 v_filter_coef_4tap[32];
51 /* Every 8th value is a dummy value in the following arrays: */
52 u16 h_filter_coef_7tap[32];
53 u16 v_filter_coef_7tap[32];
54};
55
56/* Chrominance horizontal algorithm */
57enum resizer_chroma_algo {
58 RSZ_THE_SAME = 0, /* Chrominance the same as Luminance */
59 RSZ_BILINEAR = 1, /* Chrominance uses bilinear interpolation */
60};
61
62/* Resizer input type select */
63enum resizer_colors_type {
64 RSZ_YUV422 = 0, /* YUV422 color is interleaved */
65 RSZ_COLOR8 = 1, /* Color separate data on 8 bits */
66};
67
68/*
69 * Structure for horizontal and vertical resizing value
70 */
71struct resizer_ratio {
72 u32 horz;
73 u32 vert;
74};
75
76/*
77 * Structure for luminance enhancer parameters.
78 */
79struct resizer_luma_yenh {
80 u8 algo; /* algorithm select. */
81 u8 gain; /* maximum gain. */
82 u8 slope; /* slope. */
83 u8 core; /* core offset. */
84};
85
86enum resizer_input_entity {
87 RESIZER_INPUT_NONE,
88 RESIZER_INPUT_VP, /* input video port - prev or ccdc */
89 RESIZER_INPUT_MEMORY,
90};
91
92/* Sink and source resizer pads */
93#define RESZ_PAD_SINK 0
94#define RESZ_PAD_SOURCE 1
95#define RESZ_PADS_NUM 2
96
97/*
98 * struct isp_res_device - OMAP3 ISP resizer module
99 * @crop.request: Crop rectangle requested by the user
100 * @crop.active: Active crop rectangle (based on hardware requirements)
101 */
102struct isp_res_device {
103 struct v4l2_subdev subdev;
104 struct media_pad pads[RESZ_PADS_NUM];
105 struct v4l2_mbus_framefmt formats[RESZ_PADS_NUM];
106
107 enum resizer_input_entity input;
108 struct isp_video video_in;
109 struct isp_video video_out;
110 unsigned int error;
111
112 u32 addr_base; /* stored source buffer address in memory mode */
113 u32 crop_offset; /* additional offset for crop in memory mode */
114 struct resizer_ratio ratio;
115 int pm_state;
116 unsigned int applycrop:1;
117 enum isp_pipeline_stream_state state;
118 wait_queue_head_t wait;
119 atomic_t stopping;
120
121 struct {
122 struct v4l2_rect request;
123 struct v4l2_rect active;
124 } crop;
125};
126
127struct isp_device;
128
129int omap3isp_resizer_init(struct isp_device *isp);
130void omap3isp_resizer_cleanup(struct isp_device *isp);
131
132int omap3isp_resizer_register_entities(struct isp_res_device *res,
133 struct v4l2_device *vdev);
134void omap3isp_resizer_unregister_entities(struct isp_res_device *res);
135void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res);
136void omap3isp_resizer_isr(struct isp_res_device *isp_res);
137
138void omap3isp_resizer_max_rate(struct isp_res_device *res,
139 unsigned int *max_rate);
140
141void omap3isp_resizer_suspend(struct isp_res_device *isp_res);
142
143void omap3isp_resizer_resume(struct isp_res_device *isp_res);
144
145int omap3isp_resizer_busy(struct isp_res_device *isp_res);
146
147#endif /* OMAP3_ISP_RESIZER_H */
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
new file mode 100644
index 000000000000..b44cb685236a
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -0,0 +1,1092 @@
1/*
2 * ispstat.c
3 *
4 * TI OMAP3 ISP - Statistics core
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/dma-mapping.h>
29#include <linux/slab.h>
30#include <linux/uaccess.h>
31
32#include "isp.h"
33
34#define IS_COHERENT_BUF(stat) ((stat)->dma_ch >= 0)
35
36/*
37 * MAGIC_SIZE must always be the greatest common divisor of
38 * AEWB_PACKET_SIZE and AF_PAXEL_SIZE.
39 */
40#define MAGIC_SIZE 16
41#define MAGIC_NUM 0x55
42
43/* HACK: AF module seems to be writing one more paxel data than it should. */
44#define AF_EXTRA_DATA OMAP3ISP_AF_PAXEL_SIZE
45
46/*
47 * HACK: H3A modules go to an invalid state after have a SBL overflow. It makes
48 * the next buffer to start to be written in the same point where the overflow
49 * occurred instead of the configured address. The only known way to make it to
50 * go back to a valid state is having a valid buffer processing. Of course it
51 * requires at least a doubled buffer size to avoid an access to invalid memory
52 * region. But it does not fix everything. It may happen more than one
53 * consecutive SBL overflows. In that case, it might be unpredictable how many
54 * buffers the allocated memory should fit. For that case, a recover
55 * configuration was created. It produces the minimum buffer size for each H3A
56 * module and decrease the change for more SBL overflows. This recover state
57 * will be enabled every time a SBL overflow occur. As the output buffer size
58 * isn't big, it's possible to have an extra size able to fit many recover
59 * buffers making it extreamily unlikely to have an access to invalid memory
60 * region.
61 */
62#define NUM_H3A_RECOVER_BUFS 10
63
64/*
65 * HACK: Because of HW issues the generic layer sometimes need to have
66 * different behaviour for different statistic modules.
67 */
68#define IS_H3A_AF(stat) ((stat) == &(stat)->isp->isp_af)
69#define IS_H3A_AEWB(stat) ((stat) == &(stat)->isp->isp_aewb)
70#define IS_H3A(stat) (IS_H3A_AF(stat) || IS_H3A_AEWB(stat))
71
72static void __isp_stat_buf_sync_magic(struct ispstat *stat,
73 struct ispstat_buffer *buf,
74 u32 buf_size, enum dma_data_direction dir,
75 void (*dma_sync)(struct device *,
76 dma_addr_t, unsigned long, size_t,
77 enum dma_data_direction))
78{
79 struct device *dev = stat->isp->dev;
80 struct page *pg;
81 dma_addr_t dma_addr;
82 u32 offset;
83
84 /* Initial magic words */
85 pg = vmalloc_to_page(buf->virt_addr);
86 dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
87 dma_sync(dev, dma_addr, 0, MAGIC_SIZE, dir);
88
89 /* Final magic words */
90 pg = vmalloc_to_page(buf->virt_addr + buf_size);
91 dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
92 offset = ((u32)buf->virt_addr + buf_size) & ~PAGE_MASK;
93 dma_sync(dev, dma_addr, offset, MAGIC_SIZE, dir);
94}
95
96static void isp_stat_buf_sync_magic_for_device(struct ispstat *stat,
97 struct ispstat_buffer *buf,
98 u32 buf_size,
99 enum dma_data_direction dir)
100{
101 if (IS_COHERENT_BUF(stat))
102 return;
103
104 __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
105 dma_sync_single_range_for_device);
106}
107
108static void isp_stat_buf_sync_magic_for_cpu(struct ispstat *stat,
109 struct ispstat_buffer *buf,
110 u32 buf_size,
111 enum dma_data_direction dir)
112{
113 if (IS_COHERENT_BUF(stat))
114 return;
115
116 __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
117 dma_sync_single_range_for_cpu);
118}
119
120static int isp_stat_buf_check_magic(struct ispstat *stat,
121 struct ispstat_buffer *buf)
122{
123 const u32 buf_size = IS_H3A_AF(stat) ?
124 buf->buf_size + AF_EXTRA_DATA : buf->buf_size;
125 u8 *w;
126 u8 *end;
127 int ret = -EINVAL;
128
129 isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
130
131 /* Checking initial magic numbers. They shouldn't be here anymore. */
132 for (w = buf->virt_addr, end = w + MAGIC_SIZE; w < end; w++)
133 if (likely(*w != MAGIC_NUM))
134 ret = 0;
135
136 if (ret) {
137 dev_dbg(stat->isp->dev, "%s: beginning magic check does not "
138 "match.\n", stat->subdev.name);
139 return ret;
140 }
141
142 /* Checking magic numbers at the end. They must be still here. */
143 for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE;
144 w < end; w++) {
145 if (unlikely(*w != MAGIC_NUM)) {
146 dev_dbg(stat->isp->dev, "%s: endding magic check does "
147 "not match.\n", stat->subdev.name);
148 return -EINVAL;
149 }
150 }
151
152 isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
153 DMA_FROM_DEVICE);
154
155 return 0;
156}
157
158static void isp_stat_buf_insert_magic(struct ispstat *stat,
159 struct ispstat_buffer *buf)
160{
161 const u32 buf_size = IS_H3A_AF(stat) ?
162 stat->buf_size + AF_EXTRA_DATA : stat->buf_size;
163
164 isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
165
166 /*
167 * Inserting MAGIC_NUM at the beginning and end of the buffer.
168 * buf->buf_size is set only after the buffer is queued. For now the
169 * right buf_size for the current configuration is pointed by
170 * stat->buf_size.
171 */
172 memset(buf->virt_addr, MAGIC_NUM, MAGIC_SIZE);
173 memset(buf->virt_addr + buf_size, MAGIC_NUM, MAGIC_SIZE);
174
175 isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
176 DMA_BIDIRECTIONAL);
177}
178
179static void isp_stat_buf_sync_for_device(struct ispstat *stat,
180 struct ispstat_buffer *buf)
181{
182 if (IS_COHERENT_BUF(stat))
183 return;
184
185 dma_sync_sg_for_device(stat->isp->dev, buf->iovm->sgt->sgl,
186 buf->iovm->sgt->nents, DMA_FROM_DEVICE);
187}
188
189static void isp_stat_buf_sync_for_cpu(struct ispstat *stat,
190 struct ispstat_buffer *buf)
191{
192 if (IS_COHERENT_BUF(stat))
193 return;
194
195 dma_sync_sg_for_cpu(stat->isp->dev, buf->iovm->sgt->sgl,
196 buf->iovm->sgt->nents, DMA_FROM_DEVICE);
197}
198
199static void isp_stat_buf_clear(struct ispstat *stat)
200{
201 int i;
202
203 for (i = 0; i < STAT_MAX_BUFS; i++)
204 stat->buf[i].empty = 1;
205}
206
207static struct ispstat_buffer *
208__isp_stat_buf_find(struct ispstat *stat, int look_empty)
209{
210 struct ispstat_buffer *found = NULL;
211 int i;
212
213 for (i = 0; i < STAT_MAX_BUFS; i++) {
214 struct ispstat_buffer *curr = &stat->buf[i];
215
216 /*
217 * Don't select the buffer which is being copied to
218 * userspace or used by the module.
219 */
220 if (curr == stat->locked_buf || curr == stat->active_buf)
221 continue;
222
223 /* Don't select uninitialised buffers if it's not required */
224 if (!look_empty && curr->empty)
225 continue;
226
227 /* Pick uninitialised buffer over anything else if look_empty */
228 if (curr->empty) {
229 found = curr;
230 break;
231 }
232
233 /* Choose the oldest buffer */
234 if (!found ||
235 (s32)curr->frame_number - (s32)found->frame_number < 0)
236 found = curr;
237 }
238
239 return found;
240}
241
242static inline struct ispstat_buffer *
243isp_stat_buf_find_oldest(struct ispstat *stat)
244{
245 return __isp_stat_buf_find(stat, 0);
246}
247
248static inline struct ispstat_buffer *
249isp_stat_buf_find_oldest_or_empty(struct ispstat *stat)
250{
251 return __isp_stat_buf_find(stat, 1);
252}
253
254static int isp_stat_buf_queue(struct ispstat *stat)
255{
256 if (!stat->active_buf)
257 return STAT_NO_BUF;
258
259 do_gettimeofday(&stat->active_buf->ts);
260
261 stat->active_buf->buf_size = stat->buf_size;
262 if (isp_stat_buf_check_magic(stat, stat->active_buf)) {
263 dev_dbg(stat->isp->dev, "%s: data wasn't properly written.\n",
264 stat->subdev.name);
265 return STAT_NO_BUF;
266 }
267 stat->active_buf->config_counter = stat->config_counter;
268 stat->active_buf->frame_number = stat->frame_number;
269 stat->active_buf->empty = 0;
270 stat->active_buf = NULL;
271
272 return STAT_BUF_DONE;
273}
274
275/* Get next free buffer to write the statistics to and mark it active. */
276static void isp_stat_buf_next(struct ispstat *stat)
277{
278 if (unlikely(stat->active_buf))
279 /* Overwriting unused active buffer */
280 dev_dbg(stat->isp->dev, "%s: new buffer requested without "
281 "queuing active one.\n",
282 stat->subdev.name);
283 else
284 stat->active_buf = isp_stat_buf_find_oldest_or_empty(stat);
285}
286
287static void isp_stat_buf_release(struct ispstat *stat)
288{
289 unsigned long flags;
290
291 isp_stat_buf_sync_for_device(stat, stat->locked_buf);
292 spin_lock_irqsave(&stat->isp->stat_lock, flags);
293 stat->locked_buf = NULL;
294 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
295}
296
297/* Get buffer to userspace. */
298static struct ispstat_buffer *isp_stat_buf_get(struct ispstat *stat,
299 struct omap3isp_stat_data *data)
300{
301 int rval = 0;
302 unsigned long flags;
303 struct ispstat_buffer *buf;
304
305 spin_lock_irqsave(&stat->isp->stat_lock, flags);
306
307 while (1) {
308 buf = isp_stat_buf_find_oldest(stat);
309 if (!buf) {
310 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
311 dev_dbg(stat->isp->dev, "%s: cannot find a buffer.\n",
312 stat->subdev.name);
313 return ERR_PTR(-EBUSY);
314 }
315 if (isp_stat_buf_check_magic(stat, buf)) {
316 dev_dbg(stat->isp->dev, "%s: current buffer has "
317 "corrupted data\n.", stat->subdev.name);
318 /* Mark empty because it doesn't have valid data. */
319 buf->empty = 1;
320 } else {
321 /* Buffer isn't corrupted. */
322 break;
323 }
324 }
325
326 stat->locked_buf = buf;
327
328 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
329
330 if (buf->buf_size > data->buf_size) {
331 dev_warn(stat->isp->dev, "%s: userspace's buffer size is "
332 "not enough.\n", stat->subdev.name);
333 isp_stat_buf_release(stat);
334 return ERR_PTR(-EINVAL);
335 }
336
337 isp_stat_buf_sync_for_cpu(stat, buf);
338
339 rval = copy_to_user(data->buf,
340 buf->virt_addr,
341 buf->buf_size);
342
343 if (rval) {
344 dev_info(stat->isp->dev,
345 "%s: failed copying %d bytes of stat data\n",
346 stat->subdev.name, rval);
347 buf = ERR_PTR(-EFAULT);
348 isp_stat_buf_release(stat);
349 }
350
351 return buf;
352}
353
354static void isp_stat_bufs_free(struct ispstat *stat)
355{
356 struct isp_device *isp = stat->isp;
357 int i;
358
359 for (i = 0; i < STAT_MAX_BUFS; i++) {
360 struct ispstat_buffer *buf = &stat->buf[i];
361
362 if (!IS_COHERENT_BUF(stat)) {
363 if (IS_ERR_OR_NULL((void *)buf->iommu_addr))
364 continue;
365 if (buf->iovm)
366 dma_unmap_sg(isp->dev, buf->iovm->sgt->sgl,
367 buf->iovm->sgt->nents,
368 DMA_FROM_DEVICE);
369 iommu_vfree(isp->iommu, buf->iommu_addr);
370 } else {
371 if (!buf->virt_addr)
372 continue;
373 dma_free_coherent(stat->isp->dev, stat->buf_alloc_size,
374 buf->virt_addr, buf->dma_addr);
375 }
376 buf->iommu_addr = 0;
377 buf->iovm = NULL;
378 buf->dma_addr = 0;
379 buf->virt_addr = NULL;
380 buf->empty = 1;
381 }
382
383 dev_dbg(stat->isp->dev, "%s: all buffers were freed.\n",
384 stat->subdev.name);
385
386 stat->buf_alloc_size = 0;
387 stat->active_buf = NULL;
388}
389
390static int isp_stat_bufs_alloc_iommu(struct ispstat *stat, unsigned int size)
391{
392 struct isp_device *isp = stat->isp;
393 int i;
394
395 stat->buf_alloc_size = size;
396
397 for (i = 0; i < STAT_MAX_BUFS; i++) {
398 struct ispstat_buffer *buf = &stat->buf[i];
399 struct iovm_struct *iovm;
400
401 WARN_ON(buf->dma_addr);
402 buf->iommu_addr = iommu_vmalloc(isp->iommu, 0, size,
403 IOMMU_FLAG);
404 if (IS_ERR((void *)buf->iommu_addr)) {
405 dev_err(stat->isp->dev,
406 "%s: Can't acquire memory for "
407 "buffer %d\n", stat->subdev.name, i);
408 isp_stat_bufs_free(stat);
409 return -ENOMEM;
410 }
411
412 iovm = find_iovm_area(isp->iommu, buf->iommu_addr);
413 if (!iovm ||
414 !dma_map_sg(isp->dev, iovm->sgt->sgl, iovm->sgt->nents,
415 DMA_FROM_DEVICE)) {
416 isp_stat_bufs_free(stat);
417 return -ENOMEM;
418 }
419 buf->iovm = iovm;
420
421 buf->virt_addr = da_to_va(stat->isp->iommu,
422 (u32)buf->iommu_addr);
423 buf->empty = 1;
424 dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
425 "iommu_addr=0x%08lx virt_addr=0x%08lx",
426 stat->subdev.name, i, buf->iommu_addr,
427 (unsigned long)buf->virt_addr);
428 }
429
430 return 0;
431}
432
433static int isp_stat_bufs_alloc_dma(struct ispstat *stat, unsigned int size)
434{
435 int i;
436
437 stat->buf_alloc_size = size;
438
439 for (i = 0; i < STAT_MAX_BUFS; i++) {
440 struct ispstat_buffer *buf = &stat->buf[i];
441
442 WARN_ON(buf->iommu_addr);
443 buf->virt_addr = dma_alloc_coherent(stat->isp->dev, size,
444 &buf->dma_addr, GFP_KERNEL | GFP_DMA);
445
446 if (!buf->virt_addr || !buf->dma_addr) {
447 dev_info(stat->isp->dev,
448 "%s: Can't acquire memory for "
449 "DMA buffer %d\n", stat->subdev.name, i);
450 isp_stat_bufs_free(stat);
451 return -ENOMEM;
452 }
453 buf->empty = 1;
454
455 dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
456 "dma_addr=0x%08lx virt_addr=0x%08lx\n",
457 stat->subdev.name, i, (unsigned long)buf->dma_addr,
458 (unsigned long)buf->virt_addr);
459 }
460
461 return 0;
462}
463
464static int isp_stat_bufs_alloc(struct ispstat *stat, u32 size)
465{
466 unsigned long flags;
467
468 spin_lock_irqsave(&stat->isp->stat_lock, flags);
469
470 BUG_ON(stat->locked_buf != NULL);
471
472 /* Are the old buffers big enough? */
473 if (stat->buf_alloc_size >= size) {
474 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
475 return 0;
476 }
477
478 if (stat->state != ISPSTAT_DISABLED || stat->buf_processing) {
479 dev_info(stat->isp->dev,
480 "%s: trying to allocate memory when busy\n",
481 stat->subdev.name);
482 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
483 return -EBUSY;
484 }
485
486 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
487
488 isp_stat_bufs_free(stat);
489
490 if (IS_COHERENT_BUF(stat))
491 return isp_stat_bufs_alloc_dma(stat, size);
492 else
493 return isp_stat_bufs_alloc_iommu(stat, size);
494}
495
496static void isp_stat_queue_event(struct ispstat *stat, int err)
497{
498 struct video_device *vdev = &stat->subdev.devnode;
499 struct v4l2_event event;
500 struct omap3isp_stat_event_status *status = (void *)event.u.data;
501
502 memset(&event, 0, sizeof(event));
503 if (!err) {
504 status->frame_number = stat->frame_number;
505 status->config_counter = stat->config_counter;
506 } else {
507 status->buf_err = 1;
508 }
509 event.type = stat->event_type;
510 v4l2_event_queue(vdev, &event);
511}
512
513
514/*
515 * omap3isp_stat_request_statistics - Request statistics.
516 * @data: Pointer to return statistics data.
517 *
518 * Returns 0 if successful.
519 */
520int omap3isp_stat_request_statistics(struct ispstat *stat,
521 struct omap3isp_stat_data *data)
522{
523 struct ispstat_buffer *buf;
524
525 if (stat->state != ISPSTAT_ENABLED) {
526 dev_dbg(stat->isp->dev, "%s: engine not enabled.\n",
527 stat->subdev.name);
528 return -EINVAL;
529 }
530
531 mutex_lock(&stat->ioctl_lock);
532 buf = isp_stat_buf_get(stat, data);
533 if (IS_ERR(buf)) {
534 mutex_unlock(&stat->ioctl_lock);
535 return PTR_ERR(buf);
536 }
537
538 data->ts = buf->ts;
539 data->config_counter = buf->config_counter;
540 data->frame_number = buf->frame_number;
541 data->buf_size = buf->buf_size;
542
543 buf->empty = 1;
544 isp_stat_buf_release(stat);
545 mutex_unlock(&stat->ioctl_lock);
546
547 return 0;
548}
549
550/*
551 * omap3isp_stat_config - Receives new statistic engine configuration.
552 * @new_conf: Pointer to config structure.
553 *
554 * Returns 0 if successful, -EINVAL if new_conf pointer is NULL, -ENOMEM if
555 * was unable to allocate memory for the buffer, or other errors if parameters
556 * are invalid.
557 */
558int omap3isp_stat_config(struct ispstat *stat, void *new_conf)
559{
560 int ret;
561 unsigned long irqflags;
562 struct ispstat_generic_config *user_cfg = new_conf;
563 u32 buf_size = user_cfg->buf_size;
564
565 if (!new_conf) {
566 dev_dbg(stat->isp->dev, "%s: configuration is NULL\n",
567 stat->subdev.name);
568 return -EINVAL;
569 }
570
571 mutex_lock(&stat->ioctl_lock);
572
573 dev_dbg(stat->isp->dev, "%s: configuring module with buffer "
574 "size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size);
575
576 ret = stat->ops->validate_params(stat, new_conf);
577 if (ret) {
578 mutex_unlock(&stat->ioctl_lock);
579 dev_dbg(stat->isp->dev, "%s: configuration values are "
580 "invalid.\n", stat->subdev.name);
581 return ret;
582 }
583
584 if (buf_size != user_cfg->buf_size)
585 dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size "
586 "request to 0x%08lx\n", stat->subdev.name,
587 (unsigned long)user_cfg->buf_size);
588
589 /*
590 * Hack: H3A modules may need a doubled buffer size to avoid access
591 * to a invalid memory address after a SBL overflow.
592 * The buffer size is always PAGE_ALIGNED.
593 * Hack 2: MAGIC_SIZE is added to buf_size so a magic word can be
594 * inserted at the end to data integrity check purpose.
595 * Hack 3: AF module writes one paxel data more than it should, so
596 * the buffer allocation must consider it to avoid invalid memory
597 * access.
598 * Hack 4: H3A need to allocate extra space for the recover state.
599 */
600 if (IS_H3A(stat)) {
601 buf_size = user_cfg->buf_size * 2 + MAGIC_SIZE;
602 if (IS_H3A_AF(stat))
603 /*
604 * Adding one extra paxel data size for each recover
605 * buffer + 2 regular ones.
606 */
607 buf_size += AF_EXTRA_DATA * (NUM_H3A_RECOVER_BUFS + 2);
608 if (stat->recover_priv) {
609 struct ispstat_generic_config *recover_cfg =
610 stat->recover_priv;
611 buf_size += recover_cfg->buf_size *
612 NUM_H3A_RECOVER_BUFS;
613 }
614 buf_size = PAGE_ALIGN(buf_size);
615 } else { /* Histogram */
616 buf_size = PAGE_ALIGN(user_cfg->buf_size + MAGIC_SIZE);
617 }
618
619 ret = isp_stat_bufs_alloc(stat, buf_size);
620 if (ret) {
621 mutex_unlock(&stat->ioctl_lock);
622 return ret;
623 }
624
625 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
626 stat->ops->set_params(stat, new_conf);
627 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
628
629 /*
630 * Returning the right future config_counter for this setup, so
631 * userspace can *know* when it has been applied.
632 */
633 user_cfg->config_counter = stat->config_counter + stat->inc_config;
634
635 /* Module has a valid configuration. */
636 stat->configured = 1;
637 dev_dbg(stat->isp->dev, "%s: module has been successfully "
638 "configured.\n", stat->subdev.name);
639
640 mutex_unlock(&stat->ioctl_lock);
641
642 return 0;
643}
644
645/*
646 * isp_stat_buf_process - Process statistic buffers.
647 * @buf_state: points out if buffer is ready to be processed. It's necessary
648 * because histogram needs to copy the data from internal memory
649 * before be able to process the buffer.
650 */
651static int isp_stat_buf_process(struct ispstat *stat, int buf_state)
652{
653 int ret = STAT_NO_BUF;
654
655 if (!atomic_add_unless(&stat->buf_err, -1, 0) &&
656 buf_state == STAT_BUF_DONE && stat->state == ISPSTAT_ENABLED) {
657 ret = isp_stat_buf_queue(stat);
658 isp_stat_buf_next(stat);
659 }
660
661 return ret;
662}
663
664int omap3isp_stat_pcr_busy(struct ispstat *stat)
665{
666 return stat->ops->busy(stat);
667}
668
669int omap3isp_stat_busy(struct ispstat *stat)
670{
671 return omap3isp_stat_pcr_busy(stat) | stat->buf_processing |
672 (stat->state != ISPSTAT_DISABLED);
673}
674
675/*
676 * isp_stat_pcr_enable - Disables/Enables statistic engines.
677 * @pcr_enable: 0/1 - Disables/Enables the engine.
678 *
679 * Must be called from ISP driver when the module is idle and synchronized
680 * with CCDC.
681 */
682static void isp_stat_pcr_enable(struct ispstat *stat, u8 pcr_enable)
683{
684 if ((stat->state != ISPSTAT_ENABLING &&
685 stat->state != ISPSTAT_ENABLED) && pcr_enable)
686 /* Userspace has disabled the module. Aborting. */
687 return;
688
689 stat->ops->enable(stat, pcr_enable);
690 if (stat->state == ISPSTAT_DISABLING && !pcr_enable)
691 stat->state = ISPSTAT_DISABLED;
692 else if (stat->state == ISPSTAT_ENABLING && pcr_enable)
693 stat->state = ISPSTAT_ENABLED;
694}
695
696void omap3isp_stat_suspend(struct ispstat *stat)
697{
698 unsigned long flags;
699
700 spin_lock_irqsave(&stat->isp->stat_lock, flags);
701
702 if (stat->state != ISPSTAT_DISABLED)
703 stat->ops->enable(stat, 0);
704 if (stat->state == ISPSTAT_ENABLED)
705 stat->state = ISPSTAT_SUSPENDED;
706
707 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
708}
709
710void omap3isp_stat_resume(struct ispstat *stat)
711{
712 /* Module will be re-enabled with its pipeline */
713 if (stat->state == ISPSTAT_SUSPENDED)
714 stat->state = ISPSTAT_ENABLING;
715}
716
717static void isp_stat_try_enable(struct ispstat *stat)
718{
719 unsigned long irqflags;
720
721 if (stat->priv == NULL)
722 /* driver wasn't initialised */
723 return;
724
725 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
726 if (stat->state == ISPSTAT_ENABLING && !stat->buf_processing &&
727 stat->buf_alloc_size) {
728 /*
729 * Userspace's requested to enable the engine but it wasn't yet.
730 * Let's do that now.
731 */
732 stat->update = 1;
733 isp_stat_buf_next(stat);
734 stat->ops->setup_regs(stat, stat->priv);
735 isp_stat_buf_insert_magic(stat, stat->active_buf);
736
737 /*
738 * H3A module has some hw issues which forces the driver to
739 * ignore next buffers even if it was disabled in the meantime.
740 * On the other hand, Histogram shouldn't ignore buffers anymore
741 * if it's being enabled.
742 */
743 if (!IS_H3A(stat))
744 atomic_set(&stat->buf_err, 0);
745
746 isp_stat_pcr_enable(stat, 1);
747 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
748 dev_dbg(stat->isp->dev, "%s: module is enabled.\n",
749 stat->subdev.name);
750 } else {
751 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
752 }
753}
754
755void omap3isp_stat_isr_frame_sync(struct ispstat *stat)
756{
757 isp_stat_try_enable(stat);
758}
759
760void omap3isp_stat_sbl_overflow(struct ispstat *stat)
761{
762 unsigned long irqflags;
763
764 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
765 /*
766 * Due to a H3A hw issue which prevents the next buffer to start from
767 * the correct memory address, 2 buffers must be ignored.
768 */
769 atomic_set(&stat->buf_err, 2);
770
771 /*
772 * If more than one SBL overflow happen in a row, H3A module may access
773 * invalid memory region.
774 * stat->sbl_ovl_recover is set to tell to the driver to temporarily use
775 * a soft configuration which helps to avoid consecutive overflows.
776 */
777 if (stat->recover_priv)
778 stat->sbl_ovl_recover = 1;
779 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
780}
781
782/*
783 * omap3isp_stat_enable - Disable/Enable statistic engine as soon as possible
784 * @enable: 0/1 - Disables/Enables the engine.
785 *
786 * Client should configure all the module registers before this.
787 * This function can be called from a userspace request.
788 */
789int omap3isp_stat_enable(struct ispstat *stat, u8 enable)
790{
791 unsigned long irqflags;
792
793 dev_dbg(stat->isp->dev, "%s: user wants to %s module.\n",
794 stat->subdev.name, enable ? "enable" : "disable");
795
796 /* Prevent enabling while configuring */
797 mutex_lock(&stat->ioctl_lock);
798
799 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
800
801 if (!stat->configured && enable) {
802 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
803 mutex_unlock(&stat->ioctl_lock);
804 dev_dbg(stat->isp->dev, "%s: cannot enable module as it's "
805 "never been successfully configured so far.\n",
806 stat->subdev.name);
807 return -EINVAL;
808 }
809
810 if (enable) {
811 if (stat->state == ISPSTAT_DISABLING)
812 /* Previous disabling request wasn't done yet */
813 stat->state = ISPSTAT_ENABLED;
814 else if (stat->state == ISPSTAT_DISABLED)
815 /* Module is now being enabled */
816 stat->state = ISPSTAT_ENABLING;
817 } else {
818 if (stat->state == ISPSTAT_ENABLING) {
819 /* Previous enabling request wasn't done yet */
820 stat->state = ISPSTAT_DISABLED;
821 } else if (stat->state == ISPSTAT_ENABLED) {
822 /* Module is now being disabled */
823 stat->state = ISPSTAT_DISABLING;
824 isp_stat_buf_clear(stat);
825 }
826 }
827
828 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
829 mutex_unlock(&stat->ioctl_lock);
830
831 return 0;
832}
833
834int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable)
835{
836 struct ispstat *stat = v4l2_get_subdevdata(subdev);
837
838 if (enable) {
839 /*
840 * Only set enable PCR bit if the module was previously
841 * enabled through ioct.
842 */
843 isp_stat_try_enable(stat);
844 } else {
845 unsigned long flags;
846 /* Disable PCR bit and config enable field */
847 omap3isp_stat_enable(stat, 0);
848 spin_lock_irqsave(&stat->isp->stat_lock, flags);
849 stat->ops->enable(stat, 0);
850 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
851
852 /*
853 * If module isn't busy, a new interrupt may come or not to
854 * set the state to DISABLED. As Histogram needs to read its
855 * internal memory to clear it, let interrupt handler
856 * responsible of changing state to DISABLED. If the last
857 * interrupt is coming, it's still safe as the handler will
858 * ignore the second time when state is already set to DISABLED.
859 * It's necessary to synchronize Histogram with streamoff, once
860 * the module may be considered idle before last SDMA transfer
861 * starts if we return here.
862 */
863 if (!omap3isp_stat_pcr_busy(stat))
864 omap3isp_stat_isr(stat);
865
866 dev_dbg(stat->isp->dev, "%s: module is being disabled\n",
867 stat->subdev.name);
868 }
869
870 return 0;
871}
872
873/*
874 * __stat_isr - Interrupt handler for statistic drivers
875 */
876static void __stat_isr(struct ispstat *stat, int from_dma)
877{
878 int ret = STAT_BUF_DONE;
879 int buf_processing;
880 unsigned long irqflags;
881 struct isp_pipeline *pipe;
882
883 /*
884 * stat->buf_processing must be set before disable module. It's
885 * necessary to not inform too early the buffers aren't busy in case
886 * of SDMA is going to be used.
887 */
888 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
889 if (stat->state == ISPSTAT_DISABLED) {
890 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
891 return;
892 }
893 buf_processing = stat->buf_processing;
894 stat->buf_processing = 1;
895 stat->ops->enable(stat, 0);
896
897 if (buf_processing && !from_dma) {
898 if (stat->state == ISPSTAT_ENABLED) {
899 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
900 dev_err(stat->isp->dev,
901 "%s: interrupt occurred when module was still "
902 "processing a buffer.\n", stat->subdev.name);
903 ret = STAT_NO_BUF;
904 goto out;
905 } else {
906 /*
907 * Interrupt handler was called from streamoff when
908 * the module wasn't busy anymore to ensure it is being
909 * disabled after process last buffer. If such buffer
910 * processing has already started, no need to do
911 * anything else.
912 */
913 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
914 return;
915 }
916 }
917 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
918
919 /* If it's busy we can't process this buffer anymore */
920 if (!omap3isp_stat_pcr_busy(stat)) {
921 if (!from_dma && stat->ops->buf_process)
922 /* Module still need to copy data to buffer. */
923 ret = stat->ops->buf_process(stat);
924 if (ret == STAT_BUF_WAITING_DMA)
925 /* Buffer is not ready yet */
926 return;
927
928 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
929
930 /*
931 * Histogram needs to read its internal memory to clear it
932 * before be disabled. For that reason, common statistic layer
933 * can return only after call stat's buf_process() operator.
934 */
935 if (stat->state == ISPSTAT_DISABLING) {
936 stat->state = ISPSTAT_DISABLED;
937 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
938 stat->buf_processing = 0;
939 return;
940 }
941 pipe = to_isp_pipeline(&stat->subdev.entity);
942 stat->frame_number = atomic_read(&pipe->frame_number);
943
944 /*
945 * Before this point, 'ret' stores the buffer's status if it's
946 * ready to be processed. Afterwards, it holds the status if
947 * it was processed successfully.
948 */
949 ret = isp_stat_buf_process(stat, ret);
950
951 if (likely(!stat->sbl_ovl_recover)) {
952 stat->ops->setup_regs(stat, stat->priv);
953 } else {
954 /*
955 * Using recover config to increase the chance to have
956 * a good buffer processing and make the H3A module to
957 * go back to a valid state.
958 */
959 stat->update = 1;
960 stat->ops->setup_regs(stat, stat->recover_priv);
961 stat->sbl_ovl_recover = 0;
962
963 /*
964 * Set 'update' in case of the module needs to use
965 * regular configuration after next buffer.
966 */
967 stat->update = 1;
968 }
969
970 isp_stat_buf_insert_magic(stat, stat->active_buf);
971
972 /*
973 * Hack: H3A modules may access invalid memory address or send
974 * corrupted data to userspace if more than 1 SBL overflow
975 * happens in a row without re-writing its buffer's start memory
976 * address in the meantime. Such situation is avoided if the
977 * module is not immediately re-enabled when the ISR misses the
978 * timing to process the buffer and to setup the registers.
979 * Because of that, pcr_enable(1) was moved to inside this 'if'
980 * block. But the next interruption will still happen as during
981 * pcr_enable(0) the module was busy.
982 */
983 isp_stat_pcr_enable(stat, 1);
984 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
985 } else {
986 /*
987 * If a SBL overflow occurs and the H3A driver misses the timing
988 * to process the buffer, stat->buf_err is set and won't be
989 * cleared now. So the next buffer will be correctly ignored.
990 * It's necessary due to a hw issue which makes the next H3A
991 * buffer to start from the memory address where the previous
992 * one stopped, instead of start where it was configured to.
993 * Do not "stat->buf_err = 0" here.
994 */
995
996 if (stat->ops->buf_process)
997 /*
998 * Driver may need to erase current data prior to
999 * process a new buffer. If it misses the timing, the
1000 * next buffer might be wrong. So should be ignored.
1001 * It happens only for Histogram.
1002 */
1003 atomic_set(&stat->buf_err, 1);
1004
1005 ret = STAT_NO_BUF;
1006 dev_dbg(stat->isp->dev, "%s: cannot process buffer, "
1007 "device is busy.\n", stat->subdev.name);
1008 }
1009
1010out:
1011 stat->buf_processing = 0;
1012 isp_stat_queue_event(stat, ret != STAT_BUF_DONE);
1013}
1014
1015void omap3isp_stat_isr(struct ispstat *stat)
1016{
1017 __stat_isr(stat, 0);
1018}
1019
1020void omap3isp_stat_dma_isr(struct ispstat *stat)
1021{
1022 __stat_isr(stat, 1);
1023}
1024
1025static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1026 const struct v4l2_subdev_ops *sd_ops)
1027{
1028 struct v4l2_subdev *subdev = &stat->subdev;
1029 struct media_entity *me = &subdev->entity;
1030
1031 v4l2_subdev_init(subdev, sd_ops);
1032 snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
1033 subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
1034 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1035 subdev->nevents = STAT_NEVENTS;
1036 v4l2_set_subdevdata(subdev, stat);
1037
1038 stat->pad.flags = MEDIA_PAD_FL_SINK;
1039 me->ops = NULL;
1040
1041 return media_entity_init(me, 1, &stat->pad, 0);
1042}
1043
1044int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
1045 struct v4l2_fh *fh,
1046 struct v4l2_event_subscription *sub)
1047{
1048 struct ispstat *stat = v4l2_get_subdevdata(subdev);
1049
1050 if (sub->type != stat->event_type)
1051 return -EINVAL;
1052
1053 return v4l2_event_subscribe(fh, sub);
1054}
1055
1056int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
1057 struct v4l2_fh *fh,
1058 struct v4l2_event_subscription *sub)
1059{
1060 return v4l2_event_unsubscribe(fh, sub);
1061}
1062
1063void omap3isp_stat_unregister_entities(struct ispstat *stat)
1064{
1065 media_entity_cleanup(&stat->subdev.entity);
1066 v4l2_device_unregister_subdev(&stat->subdev);
1067}
1068
1069int omap3isp_stat_register_entities(struct ispstat *stat,
1070 struct v4l2_device *vdev)
1071{
1072 return v4l2_device_register_subdev(vdev, &stat->subdev);
1073}
1074
1075int omap3isp_stat_init(struct ispstat *stat, const char *name,
1076 const struct v4l2_subdev_ops *sd_ops)
1077{
1078 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
1079 if (!stat->buf)
1080 return -ENOMEM;
1081 isp_stat_buf_clear(stat);
1082 mutex_init(&stat->ioctl_lock);
1083 atomic_set(&stat->buf_err, 0);
1084
1085 return isp_stat_init_entities(stat, name, sd_ops);
1086}
1087
1088void omap3isp_stat_free(struct ispstat *stat)
1089{
1090 isp_stat_bufs_free(stat);
1091 kfree(stat->buf);
1092}
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/video/omap3isp/ispstat.h
new file mode 100644
index 000000000000..820950c9ef46
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispstat.h
@@ -0,0 +1,169 @@
1/*
2 * ispstat.h
3 *
4 * TI OMAP3 ISP - Statistics core
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_STAT_H
29#define OMAP3_ISP_STAT_H
30
31#include <linux/types.h>
32#include <linux/omap3isp.h>
33#include <plat/dma.h>
34#include <media/v4l2-event.h>
35
36#include "isp.h"
37#include "ispvideo.h"
38
39#define STAT_MAX_BUFS 5
40#define STAT_NEVENTS 8
41
42#define STAT_BUF_DONE 0 /* Buffer is ready */
43#define STAT_NO_BUF 1 /* An error has occurred */
44#define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */
45
46struct ispstat;
47
48struct ispstat_buffer {
49 unsigned long iommu_addr;
50 struct iovm_struct *iovm;
51 void *virt_addr;
52 dma_addr_t dma_addr;
53 struct timeval ts;
54 u32 buf_size;
55 u32 frame_number;
56 u16 config_counter;
57 u8 empty;
58};
59
60struct ispstat_ops {
61 /*
62 * Validate new params configuration.
63 * new_conf->buf_size value must be changed to the exact buffer size
64 * necessary for the new configuration if it's smaller.
65 */
66 int (*validate_params)(struct ispstat *stat, void *new_conf);
67
68 /*
69 * Save new params configuration.
70 * stat->priv->buf_size value must be set to the exact buffer size for
71 * the new configuration.
72 * stat->update is set to 1 if new configuration is different than
73 * current one.
74 */
75 void (*set_params)(struct ispstat *stat, void *new_conf);
76
77 /* Apply stored configuration. */
78 void (*setup_regs)(struct ispstat *stat, void *priv);
79
80 /* Enable/Disable module. */
81 void (*enable)(struct ispstat *stat, int enable);
82
83 /* Verify is module is busy. */
84 int (*busy)(struct ispstat *stat);
85
86 /* Used for specific operations during generic buf process task. */
87 int (*buf_process)(struct ispstat *stat);
88};
89
90enum ispstat_state_t {
91 ISPSTAT_DISABLED = 0,
92 ISPSTAT_DISABLING,
93 ISPSTAT_ENABLED,
94 ISPSTAT_ENABLING,
95 ISPSTAT_SUSPENDED,
96};
97
98struct ispstat {
99 struct v4l2_subdev subdev;
100 struct media_pad pad; /* sink pad */
101
102 /* Control */
103 unsigned configured:1;
104 unsigned update:1;
105 unsigned buf_processing:1;
106 unsigned sbl_ovl_recover:1;
107 u8 inc_config;
108 atomic_t buf_err;
109 enum ispstat_state_t state; /* enabling/disabling state */
110 struct omap_dma_channel_params dma_config;
111 struct isp_device *isp;
112 void *priv; /* pointer to priv config struct */
113 void *recover_priv; /* pointer to recover priv configuration */
114 struct mutex ioctl_lock; /* serialize private ioctl */
115
116 const struct ispstat_ops *ops;
117
118 /* Buffer */
119 u8 wait_acc_frames;
120 u16 config_counter;
121 u32 frame_number;
122 u32 buf_size;
123 u32 buf_alloc_size;
124 int dma_ch;
125 unsigned long event_type;
126 struct ispstat_buffer *buf;
127 struct ispstat_buffer *active_buf;
128 struct ispstat_buffer *locked_buf;
129};
130
131struct ispstat_generic_config {
132 /*
133 * Fields must be in the same order as in:
134 * - isph3a_aewb_config
135 * - isph3a_af_config
136 * - isphist_config
137 */
138 u32 buf_size;
139 u16 config_counter;
140};
141
142int omap3isp_stat_config(struct ispstat *stat, void *new_conf);
143int omap3isp_stat_request_statistics(struct ispstat *stat,
144 struct omap3isp_stat_data *data);
145int omap3isp_stat_init(struct ispstat *stat, const char *name,
146 const struct v4l2_subdev_ops *sd_ops);
147void omap3isp_stat_free(struct ispstat *stat);
148int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
149 struct v4l2_fh *fh,
150 struct v4l2_event_subscription *sub);
151int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
152 struct v4l2_fh *fh,
153 struct v4l2_event_subscription *sub);
154int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
155
156int omap3isp_stat_busy(struct ispstat *stat);
157int omap3isp_stat_pcr_busy(struct ispstat *stat);
158void omap3isp_stat_suspend(struct ispstat *stat);
159void omap3isp_stat_resume(struct ispstat *stat);
160int omap3isp_stat_enable(struct ispstat *stat, u8 enable);
161void omap3isp_stat_sbl_overflow(struct ispstat *stat);
162void omap3isp_stat_isr(struct ispstat *stat);
163void omap3isp_stat_isr_frame_sync(struct ispstat *stat);
164void omap3isp_stat_dma_isr(struct ispstat *stat);
165int omap3isp_stat_register_entities(struct ispstat *stat,
166 struct v4l2_device *vdev);
167void omap3isp_stat_unregister_entities(struct ispstat *stat);
168
169#endif /* OMAP3_ISP_STAT_H */
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
new file mode 100644
index 000000000000..a0bb5db9cb8a
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -0,0 +1,1255 @@
1/*
2 * ispvideo.c
3 *
4 * TI OMAP3 ISP - Generic video node
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <asm/cacheflush.h>
27#include <linux/clk.h>
28#include <linux/mm.h>
29#include <linux/pagemap.h>
30#include <linux/scatterlist.h>
31#include <linux/sched.h>
32#include <linux/slab.h>
33#include <linux/vmalloc.h>
34#include <media/v4l2-dev.h>
35#include <media/v4l2-ioctl.h>
36#include <plat/iommu.h>
37#include <plat/iovmm.h>
38#include <plat/omap-pm.h>
39
40#include "ispvideo.h"
41#include "isp.h"
42
43
44/* -----------------------------------------------------------------------------
45 * Helper functions
46 */
47
48static struct isp_format_info formats[] = {
49 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
50 V4L2_MBUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, },
51 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
52 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
53 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
54 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 10, },
55 { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
56 V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 10, },
57 { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
58 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 10, },
59 { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
60 V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 10, },
61 { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
62 V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 12, },
63 { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
64 V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 12, },
65 { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
66 V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 12, },
67 { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
68 V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 12, },
69 { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
70 V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, },
71 { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
72 V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, },
73};
74
75const struct isp_format_info *
76omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
77{
78 unsigned int i;
79
80 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
81 if (formats[i].code == code)
82 return &formats[i];
83 }
84
85 return NULL;
86}
87
88/*
89 * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
90 * @video: ISP video instance
91 * @mbus: v4l2_mbus_framefmt format (input)
92 * @pix: v4l2_pix_format format (output)
93 *
94 * Fill the output pix structure with information from the input mbus format.
95 * The bytesperline and sizeimage fields are computed from the requested bytes
96 * per line value in the pix format and information from the video instance.
97 *
98 * Return the number of padding bytes at end of line.
99 */
100static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
101 const struct v4l2_mbus_framefmt *mbus,
102 struct v4l2_pix_format *pix)
103{
104 unsigned int bpl = pix->bytesperline;
105 unsigned int min_bpl;
106 unsigned int i;
107
108 memset(pix, 0, sizeof(*pix));
109 pix->width = mbus->width;
110 pix->height = mbus->height;
111
112 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
113 if (formats[i].code == mbus->code)
114 break;
115 }
116
117 if (WARN_ON(i == ARRAY_SIZE(formats)))
118 return 0;
119
120 min_bpl = pix->width * ALIGN(formats[i].bpp, 8) / 8;
121
122 /* Clamp the requested bytes per line value. If the maximum bytes per
123 * line value is zero, the module doesn't support user configurable line
124 * sizes. Override the requested value with the minimum in that case.
125 */
126 if (video->bpl_max)
127 bpl = clamp(bpl, min_bpl, video->bpl_max);
128 else
129 bpl = min_bpl;
130
131 if (!video->bpl_zero_padding || bpl != min_bpl)
132 bpl = ALIGN(bpl, video->bpl_alignment);
133
134 pix->pixelformat = formats[i].pixelformat;
135 pix->bytesperline = bpl;
136 pix->sizeimage = pix->bytesperline * pix->height;
137 pix->colorspace = mbus->colorspace;
138 pix->field = mbus->field;
139
140 return bpl - min_bpl;
141}
142
143static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix,
144 struct v4l2_mbus_framefmt *mbus)
145{
146 unsigned int i;
147
148 memset(mbus, 0, sizeof(*mbus));
149 mbus->width = pix->width;
150 mbus->height = pix->height;
151
152 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
153 if (formats[i].pixelformat == pix->pixelformat)
154 break;
155 }
156
157 if (WARN_ON(i == ARRAY_SIZE(formats)))
158 return;
159
160 mbus->code = formats[i].code;
161 mbus->colorspace = pix->colorspace;
162 mbus->field = pix->field;
163}
164
165static struct v4l2_subdev *
166isp_video_remote_subdev(struct isp_video *video, u32 *pad)
167{
168 struct media_pad *remote;
169
170 remote = media_entity_remote_source(&video->pad);
171
172 if (remote == NULL ||
173 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
174 return NULL;
175
176 if (pad)
177 *pad = remote->index;
178
179 return media_entity_to_v4l2_subdev(remote->entity);
180}
181
182/* Return a pointer to the ISP video instance at the far end of the pipeline. */
183static struct isp_video *
184isp_video_far_end(struct isp_video *video)
185{
186 struct media_entity_graph graph;
187 struct media_entity *entity = &video->video.entity;
188 struct media_device *mdev = entity->parent;
189 struct isp_video *far_end = NULL;
190
191 mutex_lock(&mdev->graph_mutex);
192 media_entity_graph_walk_start(&graph, entity);
193
194 while ((entity = media_entity_graph_walk_next(&graph))) {
195 if (entity == &video->video.entity)
196 continue;
197
198 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
199 continue;
200
201 far_end = to_isp_video(media_entity_to_video_device(entity));
202 if (far_end->type != video->type)
203 break;
204
205 far_end = NULL;
206 }
207
208 mutex_unlock(&mdev->graph_mutex);
209 return far_end;
210}
211
212/*
213 * Validate a pipeline by checking both ends of all links for format
214 * discrepancies.
215 *
216 * Compute the minimum time per frame value as the maximum of time per frame
217 * limits reported by every block in the pipeline.
218 *
219 * Return 0 if all formats match, or -EPIPE if at least one link is found with
220 * different formats on its two ends.
221 */
222static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
223{
224 struct isp_device *isp = pipe->output->isp;
225 struct v4l2_subdev_format fmt_source;
226 struct v4l2_subdev_format fmt_sink;
227 struct media_pad *pad;
228 struct v4l2_subdev *subdev;
229 int ret;
230
231 pipe->max_rate = pipe->l3_ick;
232
233 subdev = isp_video_remote_subdev(pipe->output, NULL);
234 if (subdev == NULL)
235 return -EPIPE;
236
237 while (1) {
238 /* Retrieve the sink format */
239 pad = &subdev->entity.pads[0];
240 if (!(pad->flags & MEDIA_PAD_FL_SINK))
241 break;
242
243 fmt_sink.pad = pad->index;
244 fmt_sink.which = V4L2_SUBDEV_FORMAT_ACTIVE;
245 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_sink);
246 if (ret < 0 && ret != -ENOIOCTLCMD)
247 return -EPIPE;
248
249 /* Update the maximum frame rate */
250 if (subdev == &isp->isp_res.subdev)
251 omap3isp_resizer_max_rate(&isp->isp_res,
252 &pipe->max_rate);
253
254 /* Check ccdc maximum data rate when data comes from sensor
255 * TODO: Include ccdc rate in pipe->max_rate and compare the
256 * total pipe rate with the input data rate from sensor.
257 */
258 if (subdev == &isp->isp_ccdc.subdev && pipe->input == NULL) {
259 unsigned int rate = UINT_MAX;
260
261 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
262 if (isp->isp_ccdc.vpcfg.pixelclk > rate)
263 return -ENOSPC;
264 }
265
266 /* Retrieve the source format */
267 pad = media_entity_remote_source(pad);
268 if (pad == NULL ||
269 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
270 break;
271
272 subdev = media_entity_to_v4l2_subdev(pad->entity);
273
274 fmt_source.pad = pad->index;
275 fmt_source.which = V4L2_SUBDEV_FORMAT_ACTIVE;
276 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_source);
277 if (ret < 0 && ret != -ENOIOCTLCMD)
278 return -EPIPE;
279
280 /* Check if the two ends match */
281 if (fmt_source.format.code != fmt_sink.format.code ||
282 fmt_source.format.width != fmt_sink.format.width ||
283 fmt_source.format.height != fmt_sink.format.height)
284 return -EPIPE;
285 }
286
287 return 0;
288}
289
290static int
291__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
292{
293 struct v4l2_subdev_format fmt;
294 struct v4l2_subdev *subdev;
295 u32 pad;
296 int ret;
297
298 subdev = isp_video_remote_subdev(video, &pad);
299 if (subdev == NULL)
300 return -EINVAL;
301
302 mutex_lock(&video->mutex);
303
304 fmt.pad = pad;
305 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
306 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
307 if (ret == -ENOIOCTLCMD)
308 ret = -EINVAL;
309
310 mutex_unlock(&video->mutex);
311
312 if (ret)
313 return ret;
314
315 format->type = video->type;
316 return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
317}
318
319static int
320isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
321{
322 struct v4l2_format format;
323 int ret;
324
325 memcpy(&format, &vfh->format, sizeof(format));
326 ret = __isp_video_get_format(video, &format);
327 if (ret < 0)
328 return ret;
329
330 if (vfh->format.fmt.pix.pixelformat != format.fmt.pix.pixelformat ||
331 vfh->format.fmt.pix.height != format.fmt.pix.height ||
332 vfh->format.fmt.pix.width != format.fmt.pix.width ||
333 vfh->format.fmt.pix.bytesperline != format.fmt.pix.bytesperline ||
334 vfh->format.fmt.pix.sizeimage != format.fmt.pix.sizeimage)
335 return -EINVAL;
336
337 return ret;
338}
339
340/* -----------------------------------------------------------------------------
341 * IOMMU management
342 */
343
344#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
345
346/*
347 * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list
348 * @dev: Device pointer specific to the OMAP3 ISP.
349 * @sglist: Pointer to source Scatter gather list to allocate.
350 * @sglen: Number of elements of the scatter-gatter list.
351 *
352 * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if
353 * we ran out of memory.
354 */
355static dma_addr_t
356ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
357{
358 struct sg_table *sgt;
359 u32 da;
360
361 sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
362 if (sgt == NULL)
363 return -ENOMEM;
364
365 sgt->sgl = (struct scatterlist *)sglist;
366 sgt->nents = sglen;
367 sgt->orig_nents = sglen;
368
369 da = iommu_vmap(isp->iommu, 0, sgt, IOMMU_FLAG);
370 if (IS_ERR_VALUE(da))
371 kfree(sgt);
372
373 return da;
374}
375
376/*
377 * ispmmu_vunmap - Unmap a device address from the ISP MMU
378 * @dev: Device pointer specific to the OMAP3 ISP.
379 * @da: Device address generated from a ispmmu_vmap call.
380 */
381static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
382{
383 struct sg_table *sgt;
384
385 sgt = iommu_vunmap(isp->iommu, (u32)da);
386 kfree(sgt);
387}
388
389/* -----------------------------------------------------------------------------
390 * Video queue operations
391 */
392
393static void isp_video_queue_prepare(struct isp_video_queue *queue,
394 unsigned int *nbuffers, unsigned int *size)
395{
396 struct isp_video_fh *vfh =
397 container_of(queue, struct isp_video_fh, queue);
398 struct isp_video *video = vfh->video;
399
400 *size = vfh->format.fmt.pix.sizeimage;
401 if (*size == 0)
402 return;
403
404 *nbuffers = min(*nbuffers, video->capture_mem / PAGE_ALIGN(*size));
405}
406
407static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
408{
409 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
410 struct isp_buffer *buffer = to_isp_buffer(buf);
411 struct isp_video *video = vfh->video;
412
413 if (buffer->isp_addr) {
414 ispmmu_vunmap(video->isp, buffer->isp_addr);
415 buffer->isp_addr = 0;
416 }
417}
418
419static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
420{
421 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
422 struct isp_buffer *buffer = to_isp_buffer(buf);
423 struct isp_video *video = vfh->video;
424 unsigned long addr;
425
426 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
427 if (IS_ERR_VALUE(addr))
428 return -EIO;
429
430 if (!IS_ALIGNED(addr, 32)) {
431 dev_dbg(video->isp->dev, "Buffer address must be "
432 "aligned to 32 bytes boundary.\n");
433 ispmmu_vunmap(video->isp, buffer->isp_addr);
434 return -EINVAL;
435 }
436
437 buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
438 buffer->isp_addr = addr;
439 return 0;
440}
441
442/*
443 * isp_video_buffer_queue - Add buffer to streaming queue
444 * @buf: Video buffer
445 *
446 * In memory-to-memory mode, start streaming on the pipeline if buffers are
447 * queued on both the input and the output, if the pipeline isn't already busy.
448 * If the pipeline is busy, it will be restarted in the output module interrupt
449 * handler.
450 */
451static void isp_video_buffer_queue(struct isp_video_buffer *buf)
452{
453 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
454 struct isp_buffer *buffer = to_isp_buffer(buf);
455 struct isp_video *video = vfh->video;
456 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
457 enum isp_pipeline_state state;
458 unsigned long flags;
459 unsigned int empty;
460 unsigned int start;
461
462 empty = list_empty(&video->dmaqueue);
463 list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
464
465 if (empty) {
466 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
467 state = ISP_PIPELINE_QUEUE_OUTPUT;
468 else
469 state = ISP_PIPELINE_QUEUE_INPUT;
470
471 spin_lock_irqsave(&pipe->lock, flags);
472 pipe->state |= state;
473 video->ops->queue(video, buffer);
474 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
475
476 start = isp_pipeline_ready(pipe);
477 if (start)
478 pipe->state |= ISP_PIPELINE_STREAM;
479 spin_unlock_irqrestore(&pipe->lock, flags);
480
481 if (start)
482 omap3isp_pipeline_set_stream(pipe,
483 ISP_PIPELINE_STREAM_SINGLESHOT);
484 }
485}
486
487static const struct isp_video_queue_operations isp_video_queue_ops = {
488 .queue_prepare = &isp_video_queue_prepare,
489 .buffer_prepare = &isp_video_buffer_prepare,
490 .buffer_queue = &isp_video_buffer_queue,
491 .buffer_cleanup = &isp_video_buffer_cleanup,
492};
493
494/*
495 * omap3isp_video_buffer_next - Complete the current buffer and return the next
496 * @video: ISP video object
497 * @error: Whether an error occured during capture
498 *
499 * Remove the current video buffer from the DMA queue and fill its timestamp,
500 * field count and state fields before waking up its completion handler.
501 *
502 * The buffer state is set to VIDEOBUF_DONE if no error occured (@error is 0)
503 * or VIDEOBUF_ERROR otherwise (@error is non-zero).
504 *
505 * The DMA queue is expected to contain at least one buffer.
506 *
507 * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is
508 * empty.
509 */
510struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video,
511 unsigned int error)
512{
513 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
514 struct isp_video_queue *queue = video->queue;
515 enum isp_pipeline_state state;
516 struct isp_video_buffer *buf;
517 unsigned long flags;
518 struct timespec ts;
519
520 spin_lock_irqsave(&queue->irqlock, flags);
521 if (WARN_ON(list_empty(&video->dmaqueue))) {
522 spin_unlock_irqrestore(&queue->irqlock, flags);
523 return NULL;
524 }
525
526 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
527 irqlist);
528 list_del(&buf->irqlist);
529 spin_unlock_irqrestore(&queue->irqlock, flags);
530
531 ktime_get_ts(&ts);
532 buf->vbuf.timestamp.tv_sec = ts.tv_sec;
533 buf->vbuf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
534
535 /* Do frame number propagation only if this is the output video node.
536 * Frame number either comes from the CSI receivers or it gets
537 * incremented here if H3A is not active.
538 * Note: There is no guarantee that the output buffer will finish
539 * first, so the input number might lag behind by 1 in some cases.
540 */
541 if (video == pipe->output && !pipe->do_propagation)
542 buf->vbuf.sequence = atomic_inc_return(&pipe->frame_number);
543 else
544 buf->vbuf.sequence = atomic_read(&pipe->frame_number);
545
546 buf->state = error ? ISP_BUF_STATE_ERROR : ISP_BUF_STATE_DONE;
547
548 wake_up(&buf->wait);
549
550 if (list_empty(&video->dmaqueue)) {
551 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
552 state = ISP_PIPELINE_QUEUE_OUTPUT
553 | ISP_PIPELINE_STREAM;
554 else
555 state = ISP_PIPELINE_QUEUE_INPUT
556 | ISP_PIPELINE_STREAM;
557
558 spin_lock_irqsave(&pipe->lock, flags);
559 pipe->state &= ~state;
560 if (video->pipe.stream_state == ISP_PIPELINE_STREAM_CONTINUOUS)
561 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
562 spin_unlock_irqrestore(&pipe->lock, flags);
563 return NULL;
564 }
565
566 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
567 spin_lock_irqsave(&pipe->lock, flags);
568 pipe->state &= ~ISP_PIPELINE_STREAM;
569 spin_unlock_irqrestore(&pipe->lock, flags);
570 }
571
572 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
573 irqlist);
574 buf->state = ISP_BUF_STATE_ACTIVE;
575 return to_isp_buffer(buf);
576}
577
578/*
579 * omap3isp_video_resume - Perform resume operation on the buffers
580 * @video: ISP video object
581 * @continuous: Pipeline is in single shot mode if 0 or continous mode otherwise
582 *
583 * This function is intended to be used on suspend/resume scenario. It
584 * requests video queue layer to discard buffers marked as DONE if it's in
585 * continuous mode and requests ISP modules to queue again the ACTIVE buffer
586 * if there's any.
587 */
588void omap3isp_video_resume(struct isp_video *video, int continuous)
589{
590 struct isp_buffer *buf = NULL;
591
592 if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
593 omap3isp_video_queue_discard_done(video->queue);
594
595 if (!list_empty(&video->dmaqueue)) {
596 buf = list_first_entry(&video->dmaqueue,
597 struct isp_buffer, buffer.irqlist);
598 video->ops->queue(video, buf);
599 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
600 } else {
601 if (continuous)
602 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
603 }
604}
605
606/* -----------------------------------------------------------------------------
607 * V4L2 ioctls
608 */
609
610static int
611isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
612{
613 struct isp_video *video = video_drvdata(file);
614
615 strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
616 strlcpy(cap->card, video->video.name, sizeof(cap->card));
617 strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
618 cap->version = ISP_VIDEO_DRIVER_VERSION;
619
620 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
621 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
622 else
623 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
624
625 return 0;
626}
627
628static int
629isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
630{
631 struct isp_video_fh *vfh = to_isp_video_fh(fh);
632 struct isp_video *video = video_drvdata(file);
633
634 if (format->type != video->type)
635 return -EINVAL;
636
637 mutex_lock(&video->mutex);
638 *format = vfh->format;
639 mutex_unlock(&video->mutex);
640
641 return 0;
642}
643
644static int
645isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
646{
647 struct isp_video_fh *vfh = to_isp_video_fh(fh);
648 struct isp_video *video = video_drvdata(file);
649 struct v4l2_mbus_framefmt fmt;
650
651 if (format->type != video->type)
652 return -EINVAL;
653
654 mutex_lock(&video->mutex);
655
656 /* Fill the bytesperline and sizeimage fields by converting to media bus
657 * format and back to pixel format.
658 */
659 isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
660 isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
661
662 vfh->format = *format;
663
664 mutex_unlock(&video->mutex);
665 return 0;
666}
667
668static int
669isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
670{
671 struct isp_video *video = video_drvdata(file);
672 struct v4l2_subdev_format fmt;
673 struct v4l2_subdev *subdev;
674 u32 pad;
675 int ret;
676
677 if (format->type != video->type)
678 return -EINVAL;
679
680 subdev = isp_video_remote_subdev(video, &pad);
681 if (subdev == NULL)
682 return -EINVAL;
683
684 isp_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
685
686 fmt.pad = pad;
687 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
688 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
689 if (ret)
690 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
691
692 isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
693 return 0;
694}
695
696static int
697isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
698{
699 struct isp_video *video = video_drvdata(file);
700 struct v4l2_subdev *subdev;
701 int ret;
702
703 subdev = isp_video_remote_subdev(video, NULL);
704 if (subdev == NULL)
705 return -EINVAL;
706
707 mutex_lock(&video->mutex);
708 ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
709 mutex_unlock(&video->mutex);
710
711 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
712}
713
714static int
715isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
716{
717 struct isp_video *video = video_drvdata(file);
718 struct v4l2_subdev_format format;
719 struct v4l2_subdev *subdev;
720 u32 pad;
721 int ret;
722
723 subdev = isp_video_remote_subdev(video, &pad);
724 if (subdev == NULL)
725 return -EINVAL;
726
727 /* Try the get crop operation first and fallback to get format if not
728 * implemented.
729 */
730 ret = v4l2_subdev_call(subdev, video, g_crop, crop);
731 if (ret != -ENOIOCTLCMD)
732 return ret;
733
734 format.pad = pad;
735 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
736 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
737 if (ret < 0)
738 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
739
740 crop->c.left = 0;
741 crop->c.top = 0;
742 crop->c.width = format.format.width;
743 crop->c.height = format.format.height;
744
745 return 0;
746}
747
748static int
749isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
750{
751 struct isp_video *video = video_drvdata(file);
752 struct v4l2_subdev *subdev;
753 int ret;
754
755 subdev = isp_video_remote_subdev(video, NULL);
756 if (subdev == NULL)
757 return -EINVAL;
758
759 mutex_lock(&video->mutex);
760 ret = v4l2_subdev_call(subdev, video, s_crop, crop);
761 mutex_unlock(&video->mutex);
762
763 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
764}
765
766static int
767isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
768{
769 struct isp_video_fh *vfh = to_isp_video_fh(fh);
770 struct isp_video *video = video_drvdata(file);
771
772 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
773 video->type != a->type)
774 return -EINVAL;
775
776 memset(a, 0, sizeof(*a));
777 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
778 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
779 a->parm.output.timeperframe = vfh->timeperframe;
780
781 return 0;
782}
783
784static int
785isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
786{
787 struct isp_video_fh *vfh = to_isp_video_fh(fh);
788 struct isp_video *video = video_drvdata(file);
789
790 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
791 video->type != a->type)
792 return -EINVAL;
793
794 if (a->parm.output.timeperframe.denominator == 0)
795 a->parm.output.timeperframe.denominator = 1;
796
797 vfh->timeperframe = a->parm.output.timeperframe;
798
799 return 0;
800}
801
802static int
803isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
804{
805 struct isp_video_fh *vfh = to_isp_video_fh(fh);
806
807 return omap3isp_video_queue_reqbufs(&vfh->queue, rb);
808}
809
810static int
811isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
812{
813 struct isp_video_fh *vfh = to_isp_video_fh(fh);
814
815 return omap3isp_video_queue_querybuf(&vfh->queue, b);
816}
817
818static int
819isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
820{
821 struct isp_video_fh *vfh = to_isp_video_fh(fh);
822
823 return omap3isp_video_queue_qbuf(&vfh->queue, b);
824}
825
826static int
827isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
828{
829 struct isp_video_fh *vfh = to_isp_video_fh(fh);
830
831 return omap3isp_video_queue_dqbuf(&vfh->queue, b,
832 file->f_flags & O_NONBLOCK);
833}
834
835/*
836 * Stream management
837 *
838 * Every ISP pipeline has a single input and a single output. The input can be
839 * either a sensor or a video node. The output is always a video node.
840 *
841 * As every pipeline has an output video node, the ISP video objects at the
842 * pipeline output stores the pipeline state. It tracks the streaming state of
843 * both the input and output, as well as the availability of buffers.
844 *
845 * In sensor-to-memory mode, frames are always available at the pipeline input.
846 * Starting the sensor usually requires I2C transfers and must be done in
847 * interruptible context. The pipeline is started and stopped synchronously
848 * to the stream on/off commands. All modules in the pipeline will get their
849 * subdev set stream handler called. The module at the end of the pipeline must
850 * delay starting the hardware until buffers are available at its output.
851 *
852 * In memory-to-memory mode, starting/stopping the stream requires
853 * synchronization between the input and output. ISP modules can't be stopped
854 * in the middle of a frame, and at least some of the modules seem to become
855 * busy as soon as they're started, even if they don't receive a frame start
856 * event. For that reason frames need to be processed in single-shot mode. The
857 * driver needs to wait until a frame is completely processed and written to
858 * memory before restarting the pipeline for the next frame. Pipelined
859 * processing might be possible but requires more testing.
860 *
861 * Stream start must be delayed until buffers are available at both the input
862 * and output. The pipeline must be started in the videobuf queue callback with
863 * the buffers queue spinlock held. The modules subdev set stream operation must
864 * not sleep.
865 */
866static int
867isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
868{
869 struct isp_video_fh *vfh = to_isp_video_fh(fh);
870 struct isp_video *video = video_drvdata(file);
871 enum isp_pipeline_state state;
872 struct isp_pipeline *pipe;
873 struct isp_video *far_end;
874 unsigned long flags;
875 int ret;
876
877 if (type != video->type)
878 return -EINVAL;
879
880 mutex_lock(&video->stream_lock);
881
882 if (video->streaming) {
883 mutex_unlock(&video->stream_lock);
884 return -EBUSY;
885 }
886
887 /* Start streaming on the pipeline. No link touching an entity in the
888 * pipeline can be activated or deactivated once streaming is started.
889 */
890 pipe = video->video.entity.pipe
891 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
892 media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
893
894 /* Verify that the currently configured format matches the output of
895 * the connected subdev.
896 */
897 ret = isp_video_check_format(video, vfh);
898 if (ret < 0)
899 goto error;
900
901 video->bpl_padding = ret;
902 video->bpl_value = vfh->format.fmt.pix.bytesperline;
903
904 /* Find the ISP video node connected at the far end of the pipeline and
905 * update the pipeline.
906 */
907 far_end = isp_video_far_end(video);
908
909 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
910 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
911 pipe->input = far_end;
912 pipe->output = video;
913 } else {
914 if (far_end == NULL) {
915 ret = -EPIPE;
916 goto error;
917 }
918
919 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
920 pipe->input = video;
921 pipe->output = far_end;
922 }
923
924 if (video->isp->pdata->set_constraints)
925 video->isp->pdata->set_constraints(video->isp, true);
926 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
927
928 /* Validate the pipeline and update its state. */
929 ret = isp_video_validate_pipeline(pipe);
930 if (ret < 0)
931 goto error;
932
933 spin_lock_irqsave(&pipe->lock, flags);
934 pipe->state &= ~ISP_PIPELINE_STREAM;
935 pipe->state |= state;
936 spin_unlock_irqrestore(&pipe->lock, flags);
937
938 /* Set the maximum time per frame as the value requested by userspace.
939 * This is a soft limit that can be overridden if the hardware doesn't
940 * support the request limit.
941 */
942 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
943 pipe->max_timeperframe = vfh->timeperframe;
944
945 video->queue = &vfh->queue;
946 INIT_LIST_HEAD(&video->dmaqueue);
947 atomic_set(&pipe->frame_number, -1);
948
949 ret = omap3isp_video_queue_streamon(&vfh->queue);
950 if (ret < 0)
951 goto error;
952
953 /* In sensor-to-memory mode, the stream can be started synchronously
954 * to the stream on command. In memory-to-memory mode, it will be
955 * started when buffers are queued on both the input and output.
956 */
957 if (pipe->input == NULL) {
958 ret = omap3isp_pipeline_set_stream(pipe,
959 ISP_PIPELINE_STREAM_CONTINUOUS);
960 if (ret < 0)
961 goto error;
962 spin_lock_irqsave(&video->queue->irqlock, flags);
963 if (list_empty(&video->dmaqueue))
964 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
965 spin_unlock_irqrestore(&video->queue->irqlock, flags);
966 }
967
968error:
969 if (ret < 0) {
970 omap3isp_video_queue_streamoff(&vfh->queue);
971 if (video->isp->pdata->set_constraints)
972 video->isp->pdata->set_constraints(video->isp, false);
973 media_entity_pipeline_stop(&video->video.entity);
974 video->queue = NULL;
975 }
976
977 if (!ret)
978 video->streaming = 1;
979
980 mutex_unlock(&video->stream_lock);
981 return ret;
982}
983
984static int
985isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
986{
987 struct isp_video_fh *vfh = to_isp_video_fh(fh);
988 struct isp_video *video = video_drvdata(file);
989 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
990 enum isp_pipeline_state state;
991 unsigned int streaming;
992 unsigned long flags;
993
994 if (type != video->type)
995 return -EINVAL;
996
997 mutex_lock(&video->stream_lock);
998
999 /* Make sure we're not streaming yet. */
1000 mutex_lock(&vfh->queue.lock);
1001 streaming = vfh->queue.streaming;
1002 mutex_unlock(&vfh->queue.lock);
1003
1004 if (!streaming)
1005 goto done;
1006
1007 /* Update the pipeline state. */
1008 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1009 state = ISP_PIPELINE_STREAM_OUTPUT
1010 | ISP_PIPELINE_QUEUE_OUTPUT;
1011 else
1012 state = ISP_PIPELINE_STREAM_INPUT
1013 | ISP_PIPELINE_QUEUE_INPUT;
1014
1015 spin_lock_irqsave(&pipe->lock, flags);
1016 pipe->state &= ~state;
1017 spin_unlock_irqrestore(&pipe->lock, flags);
1018
1019 /* Stop the stream. */
1020 omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
1021 omap3isp_video_queue_streamoff(&vfh->queue);
1022 video->queue = NULL;
1023 video->streaming = 0;
1024
1025 if (video->isp->pdata->set_constraints)
1026 video->isp->pdata->set_constraints(video->isp, false);
1027 media_entity_pipeline_stop(&video->video.entity);
1028
1029done:
1030 mutex_unlock(&video->stream_lock);
1031 return 0;
1032}
1033
1034static int
1035isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
1036{
1037 if (input->index > 0)
1038 return -EINVAL;
1039
1040 strlcpy(input->name, "camera", sizeof(input->name));
1041 input->type = V4L2_INPUT_TYPE_CAMERA;
1042
1043 return 0;
1044}
1045
1046static int
1047isp_video_g_input(struct file *file, void *fh, unsigned int *input)
1048{
1049 *input = 0;
1050
1051 return 0;
1052}
1053
1054static int
1055isp_video_s_input(struct file *file, void *fh, unsigned int input)
1056{
1057 return input == 0 ? 0 : -EINVAL;
1058}
1059
1060static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
1061 .vidioc_querycap = isp_video_querycap,
1062 .vidioc_g_fmt_vid_cap = isp_video_get_format,
1063 .vidioc_s_fmt_vid_cap = isp_video_set_format,
1064 .vidioc_try_fmt_vid_cap = isp_video_try_format,
1065 .vidioc_g_fmt_vid_out = isp_video_get_format,
1066 .vidioc_s_fmt_vid_out = isp_video_set_format,
1067 .vidioc_try_fmt_vid_out = isp_video_try_format,
1068 .vidioc_cropcap = isp_video_cropcap,
1069 .vidioc_g_crop = isp_video_get_crop,
1070 .vidioc_s_crop = isp_video_set_crop,
1071 .vidioc_g_parm = isp_video_get_param,
1072 .vidioc_s_parm = isp_video_set_param,
1073 .vidioc_reqbufs = isp_video_reqbufs,
1074 .vidioc_querybuf = isp_video_querybuf,
1075 .vidioc_qbuf = isp_video_qbuf,
1076 .vidioc_dqbuf = isp_video_dqbuf,
1077 .vidioc_streamon = isp_video_streamon,
1078 .vidioc_streamoff = isp_video_streamoff,
1079 .vidioc_enum_input = isp_video_enum_input,
1080 .vidioc_g_input = isp_video_g_input,
1081 .vidioc_s_input = isp_video_s_input,
1082};
1083
1084/* -----------------------------------------------------------------------------
1085 * V4L2 file operations
1086 */
1087
1088static int isp_video_open(struct file *file)
1089{
1090 struct isp_video *video = video_drvdata(file);
1091 struct isp_video_fh *handle;
1092 int ret = 0;
1093
1094 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
1095 if (handle == NULL)
1096 return -ENOMEM;
1097
1098 v4l2_fh_init(&handle->vfh, &video->video);
1099 v4l2_fh_add(&handle->vfh);
1100
1101 /* If this is the first user, initialise the pipeline. */
1102 if (omap3isp_get(video->isp) == NULL) {
1103 ret = -EBUSY;
1104 goto done;
1105 }
1106
1107 ret = omap3isp_pipeline_pm_use(&video->video.entity, 1);
1108 if (ret < 0) {
1109 omap3isp_put(video->isp);
1110 goto done;
1111 }
1112
1113 omap3isp_video_queue_init(&handle->queue, video->type,
1114 &isp_video_queue_ops, video->isp->dev,
1115 sizeof(struct isp_buffer));
1116
1117 memset(&handle->format, 0, sizeof(handle->format));
1118 handle->format.type = video->type;
1119 handle->timeperframe.denominator = 1;
1120
1121 handle->video = video;
1122 file->private_data = &handle->vfh;
1123
1124done:
1125 if (ret < 0) {
1126 v4l2_fh_del(&handle->vfh);
1127 kfree(handle);
1128 }
1129
1130 return ret;
1131}
1132
1133static int isp_video_release(struct file *file)
1134{
1135 struct isp_video *video = video_drvdata(file);
1136 struct v4l2_fh *vfh = file->private_data;
1137 struct isp_video_fh *handle = to_isp_video_fh(vfh);
1138
1139 /* Disable streaming and free the buffers queue resources. */
1140 isp_video_streamoff(file, vfh, video->type);
1141
1142 mutex_lock(&handle->queue.lock);
1143 omap3isp_video_queue_cleanup(&handle->queue);
1144 mutex_unlock(&handle->queue.lock);
1145
1146 omap3isp_pipeline_pm_use(&video->video.entity, 0);
1147
1148 /* Release the file handle. */
1149 v4l2_fh_del(vfh);
1150 kfree(handle);
1151 file->private_data = NULL;
1152
1153 omap3isp_put(video->isp);
1154
1155 return 0;
1156}
1157
1158static unsigned int isp_video_poll(struct file *file, poll_table *wait)
1159{
1160 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1161 struct isp_video_queue *queue = &vfh->queue;
1162
1163 return omap3isp_video_queue_poll(queue, file, wait);
1164}
1165
1166static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
1167{
1168 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1169
1170 return omap3isp_video_queue_mmap(&vfh->queue, vma);
1171}
1172
1173static struct v4l2_file_operations isp_video_fops = {
1174 .owner = THIS_MODULE,
1175 .unlocked_ioctl = video_ioctl2,
1176 .open = isp_video_open,
1177 .release = isp_video_release,
1178 .poll = isp_video_poll,
1179 .mmap = isp_video_mmap,
1180};
1181
1182/* -----------------------------------------------------------------------------
1183 * ISP video core
1184 */
1185
1186static const struct isp_video_operations isp_video_dummy_ops = {
1187};
1188
1189int omap3isp_video_init(struct isp_video *video, const char *name)
1190{
1191 const char *direction;
1192 int ret;
1193
1194 switch (video->type) {
1195 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1196 direction = "output";
1197 video->pad.flags = MEDIA_PAD_FL_SINK;
1198 break;
1199 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1200 direction = "input";
1201 video->pad.flags = MEDIA_PAD_FL_SOURCE;
1202 break;
1203
1204 default:
1205 return -EINVAL;
1206 }
1207
1208 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
1209 if (ret < 0)
1210 return ret;
1211
1212 mutex_init(&video->mutex);
1213 atomic_set(&video->active, 0);
1214
1215 spin_lock_init(&video->pipe.lock);
1216 mutex_init(&video->stream_lock);
1217
1218 /* Initialize the video device. */
1219 if (video->ops == NULL)
1220 video->ops = &isp_video_dummy_ops;
1221
1222 video->video.fops = &isp_video_fops;
1223 snprintf(video->video.name, sizeof(video->video.name),
1224 "OMAP3 ISP %s %s", name, direction);
1225 video->video.vfl_type = VFL_TYPE_GRABBER;
1226 video->video.release = video_device_release_empty;
1227 video->video.ioctl_ops = &isp_video_ioctl_ops;
1228 video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
1229
1230 video_set_drvdata(&video->video, video);
1231
1232 return 0;
1233}
1234
1235int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1236{
1237 int ret;
1238
1239 video->video.v4l2_dev = vdev;
1240
1241 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
1242 if (ret < 0)
1243 printk(KERN_ERR "%s: could not register video device (%d)\n",
1244 __func__, ret);
1245
1246 return ret;
1247}
1248
1249void omap3isp_video_unregister(struct isp_video *video)
1250{
1251 if (video_is_registered(&video->video)) {
1252 media_entity_cleanup(&video->video.entity);
1253 video_unregister_device(&video->video);
1254 }
1255}
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
new file mode 100644
index 000000000000..524a1acd0906
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispvideo.h
@@ -0,0 +1,202 @@
1/*
2 * ispvideo.h
3 *
4 * TI OMAP3 ISP - Generic video node
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#ifndef OMAP3_ISP_VIDEO_H
27#define OMAP3_ISP_VIDEO_H
28
29#include <linux/v4l2-mediabus.h>
30#include <linux/version.h>
31#include <media/media-entity.h>
32#include <media/v4l2-dev.h>
33#include <media/v4l2-fh.h>
34
35#include "ispqueue.h"
36
37#define ISP_VIDEO_DRIVER_NAME "ispvideo"
38#define ISP_VIDEO_DRIVER_VERSION KERNEL_VERSION(0, 0, 1)
39
40struct isp_device;
41struct isp_video;
42struct v4l2_mbus_framefmt;
43struct v4l2_pix_format;
44
45/*
46 * struct isp_format_info - ISP media bus format information
47 * @code: V4L2 media bus format code
48 * @truncated: V4L2 media bus format code for the same format truncated to 10
49 * bits. Identical to @code if the format is 10 bits wide or less.
50 * @uncompressed: V4L2 media bus format code for the corresponding uncompressed
51 * format. Identical to @code if the format is not DPCM compressed.
52 * @pixelformat: V4L2 pixel format FCC identifier
53 * @bpp: Bits per pixel
54 */
55struct isp_format_info {
56 enum v4l2_mbus_pixelcode code;
57 enum v4l2_mbus_pixelcode truncated;
58 enum v4l2_mbus_pixelcode uncompressed;
59 u32 pixelformat;
60 unsigned int bpp;
61};
62
63enum isp_pipeline_stream_state {
64 ISP_PIPELINE_STREAM_STOPPED = 0,
65 ISP_PIPELINE_STREAM_CONTINUOUS = 1,
66 ISP_PIPELINE_STREAM_SINGLESHOT = 2,
67};
68
69enum isp_pipeline_state {
70 /* The stream has been started on the input video node. */
71 ISP_PIPELINE_STREAM_INPUT = 1,
72 /* The stream has been started on the output video node. */
73 ISP_PIPELINE_STREAM_OUTPUT = 2,
74 /* At least one buffer is queued on the input video node. */
75 ISP_PIPELINE_QUEUE_INPUT = 4,
76 /* At least one buffer is queued on the output video node. */
77 ISP_PIPELINE_QUEUE_OUTPUT = 8,
78 /* The input entity is idle, ready to be started. */
79 ISP_PIPELINE_IDLE_INPUT = 16,
80 /* The output entity is idle, ready to be started. */
81 ISP_PIPELINE_IDLE_OUTPUT = 32,
82 /* The pipeline is currently streaming. */
83 ISP_PIPELINE_STREAM = 64,
84};
85
86struct isp_pipeline {
87 struct media_pipeline pipe;
88 spinlock_t lock; /* Pipeline state and queue flags */
89 unsigned int state;
90 enum isp_pipeline_stream_state stream_state;
91 struct isp_video *input;
92 struct isp_video *output;
93 unsigned long l3_ick;
94 unsigned int max_rate;
95 atomic_t frame_number;
96 bool do_propagation; /* of frame number */
97 struct v4l2_fract max_timeperframe;
98};
99
100#define to_isp_pipeline(__e) \
101 container_of((__e)->pipe, struct isp_pipeline, pipe)
102
103static inline int isp_pipeline_ready(struct isp_pipeline *pipe)
104{
105 return pipe->state == (ISP_PIPELINE_STREAM_INPUT |
106 ISP_PIPELINE_STREAM_OUTPUT |
107 ISP_PIPELINE_QUEUE_INPUT |
108 ISP_PIPELINE_QUEUE_OUTPUT |
109 ISP_PIPELINE_IDLE_INPUT |
110 ISP_PIPELINE_IDLE_OUTPUT);
111}
112
113/*
114 * struct isp_buffer - ISP buffer
115 * @buffer: ISP video buffer
116 * @isp_addr: MMU mapped address (a.k.a. device address) of the buffer.
117 */
118struct isp_buffer {
119 struct isp_video_buffer buffer;
120 dma_addr_t isp_addr;
121};
122
123#define to_isp_buffer(buf) container_of(buf, struct isp_buffer, buffer)
124
125enum isp_video_dmaqueue_flags {
126 /* Set if DMA queue becomes empty when ISP_PIPELINE_STREAM_CONTINUOUS */
127 ISP_VIDEO_DMAQUEUE_UNDERRUN = (1 << 0),
128 /* Set when queuing buffer to an empty DMA queue */
129 ISP_VIDEO_DMAQUEUE_QUEUED = (1 << 1),
130};
131
132#define isp_video_dmaqueue_flags_clr(video) \
133 ({ (video)->dmaqueue_flags = 0; })
134
135/*
136 * struct isp_video_operations - ISP video operations
137 * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF
138 * if there was no buffer previously queued.
139 */
140struct isp_video_operations {
141 int(*queue)(struct isp_video *video, struct isp_buffer *buffer);
142};
143
144struct isp_video {
145 struct video_device video;
146 enum v4l2_buf_type type;
147 struct media_pad pad;
148
149 struct mutex mutex; /* format and crop settings */
150 atomic_t active;
151
152 struct isp_device *isp;
153
154 unsigned int capture_mem;
155 unsigned int bpl_alignment; /* alignment value */
156 unsigned int bpl_zero_padding; /* whether the alignment is optional */
157 unsigned int bpl_max; /* maximum bytes per line value */
158 unsigned int bpl_value; /* bytes per line value */
159 unsigned int bpl_padding; /* padding at end of line */
160
161 /* Entity video node streaming */
162 unsigned int streaming:1;
163
164 /* Pipeline state */
165 struct isp_pipeline pipe;
166 struct mutex stream_lock; /* pipeline and stream states */
167
168 /* Video buffers queue */
169 struct isp_video_queue *queue;
170 struct list_head dmaqueue;
171 enum isp_video_dmaqueue_flags dmaqueue_flags;
172
173 const struct isp_video_operations *ops;
174};
175
176#define to_isp_video(vdev) container_of(vdev, struct isp_video, video)
177
178struct isp_video_fh {
179 struct v4l2_fh vfh;
180 struct isp_video *video;
181 struct isp_video_queue queue;
182 struct v4l2_format format;
183 struct v4l2_fract timeperframe;
184};
185
186#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh)
187#define isp_video_queue_to_isp_video_fh(q) \
188 container_of(q, struct isp_video_fh, queue)
189
190int omap3isp_video_init(struct isp_video *video, const char *name);
191int omap3isp_video_register(struct isp_video *video,
192 struct v4l2_device *vdev);
193void omap3isp_video_unregister(struct isp_video *video);
194struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video,
195 unsigned int error);
196void omap3isp_video_resume(struct isp_video *video, int continuous);
197struct media_pad *omap3isp_video_remote_pad(struct isp_video *video);
198
199const struct isp_format_info *
200omap3isp_video_format_info(enum v4l2_mbus_pixelcode code);
201
202#endif /* OMAP3_ISP_VIDEO_H */
diff --git a/drivers/media/video/omap3isp/luma_enhance_table.h b/drivers/media/video/omap3isp/luma_enhance_table.h
new file mode 100644
index 000000000000..098b45e2280f
--- /dev/null
+++ b/drivers/media/video/omap3isp/luma_enhance_table.h
@@ -0,0 +1,42 @@
1/*
2 * luma_enhance_table.h
3 *
4 * TI OMAP3 ISP - Luminance enhancement table
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
271047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
281047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
291047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
301047552, 1047552, 1047552, 1047552, 1048575, 1047551, 1046527, 1045503,
311044479, 1043455, 1042431, 1041407, 1040383, 1039359, 1038335, 1037311,
321036287, 1035263, 1034239, 1033215, 1032191, 1031167, 1030143, 1028096,
331028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096,
341028096, 1028100, 1032196, 1036292, 1040388, 1044484, 0, 0,
35 0, 5, 5125, 10245, 15365, 20485, 25605, 30720,
36 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720,
37 30720, 30720, 31743, 30719, 29695, 28671, 27647, 26623,
38 25599, 24575, 23551, 22527, 21503, 20479, 19455, 18431,
39 17407, 16383, 15359, 14335, 13311, 12287, 11263, 10239,
40 9215, 8191, 7167, 6143, 5119, 4095, 3071, 1024,
41 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
42 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024
diff --git a/drivers/media/video/omap3isp/noise_filter_table.h b/drivers/media/video/omap3isp/noise_filter_table.h
new file mode 100644
index 000000000000..d50451a4a242
--- /dev/null
+++ b/drivers/media/video/omap3isp/noise_filter_table.h
@@ -0,0 +1,30 @@
1/*
2 * noise_filter_table.h
3 *
4 * TI OMAP3 ISP - Noise filter table
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
2716, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2816, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2931, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
3031, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
index cf93de988068..fe8e3ebd9ce4 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/video/ov6650.c
@@ -207,7 +207,7 @@ static enum v4l2_mbus_pixelcode ov6650_codes[] = {
207 V4L2_MBUS_FMT_YVYU8_2X8, 207 V4L2_MBUS_FMT_YVYU8_2X8,
208 V4L2_MBUS_FMT_VYUY8_2X8, 208 V4L2_MBUS_FMT_VYUY8_2X8,
209 V4L2_MBUS_FMT_SBGGR8_1X8, 209 V4L2_MBUS_FMT_SBGGR8_1X8,
210 V4L2_MBUS_FMT_GREY8_1X8, 210 V4L2_MBUS_FMT_Y8_1X8,
211}; 211};
212 212
213static const struct v4l2_queryctrl ov6650_controls[] = { 213static const struct v4l2_queryctrl ov6650_controls[] = {
@@ -800,7 +800,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
800 800
801 /* select color matrix configuration for given color encoding */ 801 /* select color matrix configuration for given color encoding */
802 switch (code) { 802 switch (code) {
803 case V4L2_MBUS_FMT_GREY8_1X8: 803 case V4L2_MBUS_FMT_Y8_1X8:
804 dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); 804 dev_dbg(&client->dev, "pixel format GREY8_1X8\n");
805 coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; 805 coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP;
806 coma_set |= COMA_BW; 806 coma_set |= COMA_BW;
@@ -846,7 +846,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
846 } 846 }
847 priv->code = code; 847 priv->code = code;
848 848
849 if (code == V4L2_MBUS_FMT_GREY8_1X8 || 849 if (code == V4L2_MBUS_FMT_Y8_1X8 ||
850 code == V4L2_MBUS_FMT_SBGGR8_1X8) { 850 code == V4L2_MBUS_FMT_SBGGR8_1X8) {
851 coml_mask = COML_ONE_CHANNEL; 851 coml_mask = COML_ONE_CHANNEL;
852 coml_set = 0; 852 coml_set = 0;
@@ -936,8 +936,8 @@ static int ov6650_try_fmt(struct v4l2_subdev *sd,
936 936
937 switch (mf->code) { 937 switch (mf->code) {
938 case V4L2_MBUS_FMT_Y10_1X10: 938 case V4L2_MBUS_FMT_Y10_1X10:
939 mf->code = V4L2_MBUS_FMT_GREY8_1X8; 939 mf->code = V4L2_MBUS_FMT_Y8_1X8;
940 case V4L2_MBUS_FMT_GREY8_1X8: 940 case V4L2_MBUS_FMT_Y8_1X8:
941 case V4L2_MBUS_FMT_YVYU8_2X8: 941 case V4L2_MBUS_FMT_YVYU8_2X8:
942 case V4L2_MBUS_FMT_YUYV8_2X8: 942 case V4L2_MBUS_FMT_YUYV8_2X8:
943 case V4L2_MBUS_FMT_VYUY8_2X8: 943 case V4L2_MBUS_FMT_VYUY8_2X8:
diff --git a/drivers/media/video/ov9740.c b/drivers/media/video/ov9740.c
new file mode 100644
index 000000000000..4d4ee4faca69
--- /dev/null
+++ b/drivers/media/video/ov9740.c
@@ -0,0 +1,1009 @@
1/*
2 * OmniVision OV9740 Camera Driver
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
5 *
6 * Based on ov9640 camera driver.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16#include <linux/slab.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h>
19
20#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev)
21
22/* General Status Registers */
23#define OV9740_MODEL_ID_HI 0x0000
24#define OV9740_MODEL_ID_LO 0x0001
25#define OV9740_REVISION_NUMBER 0x0002
26#define OV9740_MANUFACTURER_ID 0x0003
27#define OV9740_SMIA_VERSION 0x0004
28
29/* General Setup Registers */
30#define OV9740_MODE_SELECT 0x0100
31#define OV9740_IMAGE_ORT 0x0101
32#define OV9740_SOFTWARE_RESET 0x0103
33#define OV9740_GRP_PARAM_HOLD 0x0104
34#define OV9740_MSK_CORRUP_FM 0x0105
35
36/* Timing Setting */
37#define OV9740_FRM_LENGTH_LN_HI 0x0340 /* VTS */
38#define OV9740_FRM_LENGTH_LN_LO 0x0341 /* VTS */
39#define OV9740_LN_LENGTH_PCK_HI 0x0342 /* HTS */
40#define OV9740_LN_LENGTH_PCK_LO 0x0343 /* HTS */
41#define OV9740_X_ADDR_START_HI 0x0344
42#define OV9740_X_ADDR_START_LO 0x0345
43#define OV9740_Y_ADDR_START_HI 0x0346
44#define OV9740_Y_ADDR_START_LO 0x0347
45#define OV9740_X_ADDR_END_HI 0x0348
46#define OV9740_X_ADDR_END_LO 0x0349
47#define OV9740_Y_ADDR_END_HI 0x034A
48#define OV9740_Y_ADDR_END_LO 0x034B
49#define OV9740_X_OUTPUT_SIZE_HI 0x034C
50#define OV9740_X_OUTPUT_SIZE_LO 0x034D
51#define OV9740_Y_OUTPUT_SIZE_HI 0x034E
52#define OV9740_Y_OUTPUT_SIZE_LO 0x034F
53
54/* IO Control Registers */
55#define OV9740_IO_CREL00 0x3002
56#define OV9740_IO_CREL01 0x3004
57#define OV9740_IO_CREL02 0x3005
58#define OV9740_IO_OUTPUT_SEL01 0x3026
59#define OV9740_IO_OUTPUT_SEL02 0x3027
60
61/* AWB Registers */
62#define OV9740_AWB_MANUAL_CTRL 0x3406
63
64/* Analog Control Registers */
65#define OV9740_ANALOG_CTRL01 0x3601
66#define OV9740_ANALOG_CTRL02 0x3602
67#define OV9740_ANALOG_CTRL03 0x3603
68#define OV9740_ANALOG_CTRL04 0x3604
69#define OV9740_ANALOG_CTRL10 0x3610
70#define OV9740_ANALOG_CTRL12 0x3612
71#define OV9740_ANALOG_CTRL20 0x3620
72#define OV9740_ANALOG_CTRL21 0x3621
73#define OV9740_ANALOG_CTRL22 0x3622
74#define OV9740_ANALOG_CTRL30 0x3630
75#define OV9740_ANALOG_CTRL31 0x3631
76#define OV9740_ANALOG_CTRL32 0x3632
77#define OV9740_ANALOG_CTRL33 0x3633
78
79/* Sensor Control */
80#define OV9740_SENSOR_CTRL03 0x3703
81#define OV9740_SENSOR_CTRL04 0x3704
82#define OV9740_SENSOR_CTRL05 0x3705
83#define OV9740_SENSOR_CTRL07 0x3707
84
85/* Timing Control */
86#define OV9740_TIMING_CTRL17 0x3817
87#define OV9740_TIMING_CTRL19 0x3819
88#define OV9740_TIMING_CTRL33 0x3833
89#define OV9740_TIMING_CTRL35 0x3835
90
91/* Banding Filter */
92#define OV9740_AEC_MAXEXPO_60_H 0x3A02
93#define OV9740_AEC_MAXEXPO_60_L 0x3A03
94#define OV9740_AEC_B50_STEP_HI 0x3A08
95#define OV9740_AEC_B50_STEP_LO 0x3A09
96#define OV9740_AEC_B60_STEP_HI 0x3A0A
97#define OV9740_AEC_B60_STEP_LO 0x3A0B
98#define OV9740_AEC_CTRL0D 0x3A0D
99#define OV9740_AEC_CTRL0E 0x3A0E
100#define OV9740_AEC_MAXEXPO_50_H 0x3A14
101#define OV9740_AEC_MAXEXPO_50_L 0x3A15
102
103/* AEC/AGC Control */
104#define OV9740_AEC_ENABLE 0x3503
105#define OV9740_GAIN_CEILING_01 0x3A18
106#define OV9740_GAIN_CEILING_02 0x3A19
107#define OV9740_AEC_HI_THRESHOLD 0x3A11
108#define OV9740_AEC_3A1A 0x3A1A
109#define OV9740_AEC_CTRL1B_WPT2 0x3A1B
110#define OV9740_AEC_CTRL0F_WPT 0x3A0F
111#define OV9740_AEC_CTRL10_BPT 0x3A10
112#define OV9740_AEC_CTRL1E_BPT2 0x3A1E
113#define OV9740_AEC_LO_THRESHOLD 0x3A1F
114
115/* BLC Control */
116#define OV9740_BLC_AUTO_ENABLE 0x4002
117#define OV9740_BLC_MODE 0x4005
118
119/* VFIFO */
120#define OV9740_VFIFO_READ_START_HI 0x4608
121#define OV9740_VFIFO_READ_START_LO 0x4609
122
123/* DVP Control */
124#define OV9740_DVP_VSYNC_CTRL02 0x4702
125#define OV9740_DVP_VSYNC_MODE 0x4704
126#define OV9740_DVP_VSYNC_CTRL06 0x4706
127
128/* PLL Setting */
129#define OV9740_PLL_MODE_CTRL01 0x3104
130#define OV9740_PRE_PLL_CLK_DIV 0x0305
131#define OV9740_PLL_MULTIPLIER 0x0307
132#define OV9740_VT_SYS_CLK_DIV 0x0303
133#define OV9740_VT_PIX_CLK_DIV 0x0301
134#define OV9740_PLL_CTRL3010 0x3010
135#define OV9740_VFIFO_CTRL00 0x460E
136
137/* ISP Control */
138#define OV9740_ISP_CTRL00 0x5000
139#define OV9740_ISP_CTRL01 0x5001
140#define OV9740_ISP_CTRL03 0x5003
141#define OV9740_ISP_CTRL05 0x5005
142#define OV9740_ISP_CTRL12 0x5012
143#define OV9740_ISP_CTRL19 0x5019
144#define OV9740_ISP_CTRL1A 0x501A
145#define OV9740_ISP_CTRL1E 0x501E
146#define OV9740_ISP_CTRL1F 0x501F
147#define OV9740_ISP_CTRL20 0x5020
148#define OV9740_ISP_CTRL21 0x5021
149
150/* AWB */
151#define OV9740_AWB_CTRL00 0x5180
152#define OV9740_AWB_CTRL01 0x5181
153#define OV9740_AWB_CTRL02 0x5182
154#define OV9740_AWB_CTRL03 0x5183
155#define OV9740_AWB_ADV_CTRL01 0x5184
156#define OV9740_AWB_ADV_CTRL02 0x5185
157#define OV9740_AWB_ADV_CTRL03 0x5186
158#define OV9740_AWB_ADV_CTRL04 0x5187
159#define OV9740_AWB_ADV_CTRL05 0x5188
160#define OV9740_AWB_ADV_CTRL06 0x5189
161#define OV9740_AWB_ADV_CTRL07 0x518A
162#define OV9740_AWB_ADV_CTRL08 0x518B
163#define OV9740_AWB_ADV_CTRL09 0x518C
164#define OV9740_AWB_ADV_CTRL10 0x518D
165#define OV9740_AWB_ADV_CTRL11 0x518E
166#define OV9740_AWB_CTRL0F 0x518F
167#define OV9740_AWB_CTRL10 0x5190
168#define OV9740_AWB_CTRL11 0x5191
169#define OV9740_AWB_CTRL12 0x5192
170#define OV9740_AWB_CTRL13 0x5193
171#define OV9740_AWB_CTRL14 0x5194
172
173/* MIPI Control */
174#define OV9740_MIPI_CTRL00 0x4800
175#define OV9740_MIPI_3837 0x3837
176#define OV9740_MIPI_CTRL01 0x4801
177#define OV9740_MIPI_CTRL03 0x4803
178#define OV9740_MIPI_CTRL05 0x4805
179#define OV9740_VFIFO_RD_CTRL 0x4601
180#define OV9740_MIPI_CTRL_3012 0x3012
181#define OV9740_SC_CMMM_MIPI_CTR 0x3014
182
183/* supported resolutions */
184enum {
185 OV9740_VGA,
186 OV9740_720P,
187};
188
189struct ov9740_resolution {
190 unsigned int width;
191 unsigned int height;
192};
193
194static struct ov9740_resolution ov9740_resolutions[] = {
195 [OV9740_VGA] = {
196 .width = 640,
197 .height = 480,
198 },
199 [OV9740_720P] = {
200 .width = 1280,
201 .height = 720,
202 },
203};
204
205/* Misc. structures */
206struct ov9740_reg {
207 u16 reg;
208 u8 val;
209};
210
211struct ov9740_priv {
212 struct v4l2_subdev subdev;
213
214 int ident;
215 u16 model;
216 u8 revision;
217 u8 manid;
218 u8 smiaver;
219
220 bool flag_vflip;
221 bool flag_hflip;
222};
223
224static const struct ov9740_reg ov9740_defaults[] = {
225 /* Banding Filter */
226 { OV9740_AEC_B50_STEP_HI, 0x00 },
227 { OV9740_AEC_B50_STEP_LO, 0xe8 },
228 { OV9740_AEC_CTRL0E, 0x03 },
229 { OV9740_AEC_MAXEXPO_50_H, 0x15 },
230 { OV9740_AEC_MAXEXPO_50_L, 0xc6 },
231 { OV9740_AEC_B60_STEP_HI, 0x00 },
232 { OV9740_AEC_B60_STEP_LO, 0xc0 },
233 { OV9740_AEC_CTRL0D, 0x04 },
234 { OV9740_AEC_MAXEXPO_60_H, 0x18 },
235 { OV9740_AEC_MAXEXPO_60_L, 0x20 },
236
237 /* LC */
238 { 0x5842, 0x02 }, { 0x5843, 0x5e }, { 0x5844, 0x04 }, { 0x5845, 0x32 },
239 { 0x5846, 0x03 }, { 0x5847, 0x29 }, { 0x5848, 0x02 }, { 0x5849, 0xcc },
240
241 /* Un-documented OV9740 registers */
242 { 0x5800, 0x29 }, { 0x5801, 0x25 }, { 0x5802, 0x20 }, { 0x5803, 0x21 },
243 { 0x5804, 0x26 }, { 0x5805, 0x2e }, { 0x5806, 0x11 }, { 0x5807, 0x0c },
244 { 0x5808, 0x09 }, { 0x5809, 0x0a }, { 0x580A, 0x0e }, { 0x580B, 0x16 },
245 { 0x580C, 0x06 }, { 0x580D, 0x02 }, { 0x580E, 0x00 }, { 0x580F, 0x00 },
246 { 0x5810, 0x04 }, { 0x5811, 0x0a }, { 0x5812, 0x05 }, { 0x5813, 0x02 },
247 { 0x5814, 0x00 }, { 0x5815, 0x00 }, { 0x5816, 0x03 }, { 0x5817, 0x09 },
248 { 0x5818, 0x0f }, { 0x5819, 0x0a }, { 0x581A, 0x07 }, { 0x581B, 0x08 },
249 { 0x581C, 0x0b }, { 0x581D, 0x14 }, { 0x581E, 0x28 }, { 0x581F, 0x23 },
250 { 0x5820, 0x1d }, { 0x5821, 0x1e }, { 0x5822, 0x24 }, { 0x5823, 0x2a },
251 { 0x5824, 0x4f }, { 0x5825, 0x6f }, { 0x5826, 0x5f }, { 0x5827, 0x7f },
252 { 0x5828, 0x9f }, { 0x5829, 0x5f }, { 0x582A, 0x8f }, { 0x582B, 0x9e },
253 { 0x582C, 0x8f }, { 0x582D, 0x9f }, { 0x582E, 0x4f }, { 0x582F, 0x87 },
254 { 0x5830, 0x86 }, { 0x5831, 0x97 }, { 0x5832, 0xae }, { 0x5833, 0x3f },
255 { 0x5834, 0x8e }, { 0x5835, 0x7c }, { 0x5836, 0x7e }, { 0x5837, 0xaf },
256 { 0x5838, 0x8f }, { 0x5839, 0x8f }, { 0x583A, 0x9f }, { 0x583B, 0x7f },
257 { 0x583C, 0x5f },
258
259 /* Y Gamma */
260 { 0x5480, 0x07 }, { 0x5481, 0x18 }, { 0x5482, 0x2c }, { 0x5483, 0x4e },
261 { 0x5484, 0x5e }, { 0x5485, 0x6b }, { 0x5486, 0x77 }, { 0x5487, 0x82 },
262 { 0x5488, 0x8c }, { 0x5489, 0x95 }, { 0x548A, 0xa4 }, { 0x548B, 0xb1 },
263 { 0x548C, 0xc6 }, { 0x548D, 0xd8 }, { 0x548E, 0xe9 },
264
265 /* UV Gamma */
266 { 0x5490, 0x0f }, { 0x5491, 0xff }, { 0x5492, 0x0d }, { 0x5493, 0x05 },
267 { 0x5494, 0x07 }, { 0x5495, 0x1a }, { 0x5496, 0x04 }, { 0x5497, 0x01 },
268 { 0x5498, 0x03 }, { 0x5499, 0x53 }, { 0x549A, 0x02 }, { 0x549B, 0xeb },
269 { 0x549C, 0x02 }, { 0x549D, 0xa0 }, { 0x549E, 0x02 }, { 0x549F, 0x67 },
270 { 0x54A0, 0x02 }, { 0x54A1, 0x3b }, { 0x54A2, 0x02 }, { 0x54A3, 0x18 },
271 { 0x54A4, 0x01 }, { 0x54A5, 0xe7 }, { 0x54A6, 0x01 }, { 0x54A7, 0xc3 },
272 { 0x54A8, 0x01 }, { 0x54A9, 0x94 }, { 0x54AA, 0x01 }, { 0x54AB, 0x72 },
273 { 0x54AC, 0x01 }, { 0x54AD, 0x57 },
274
275 /* AWB */
276 { OV9740_AWB_CTRL00, 0xf0 },
277 { OV9740_AWB_CTRL01, 0x00 },
278 { OV9740_AWB_CTRL02, 0x41 },
279 { OV9740_AWB_CTRL03, 0x42 },
280 { OV9740_AWB_ADV_CTRL01, 0x8a },
281 { OV9740_AWB_ADV_CTRL02, 0x61 },
282 { OV9740_AWB_ADV_CTRL03, 0xce },
283 { OV9740_AWB_ADV_CTRL04, 0xa8 },
284 { OV9740_AWB_ADV_CTRL05, 0x17 },
285 { OV9740_AWB_ADV_CTRL06, 0x1f },
286 { OV9740_AWB_ADV_CTRL07, 0x27 },
287 { OV9740_AWB_ADV_CTRL08, 0x41 },
288 { OV9740_AWB_ADV_CTRL09, 0x34 },
289 { OV9740_AWB_ADV_CTRL10, 0xf0 },
290 { OV9740_AWB_ADV_CTRL11, 0x10 },
291 { OV9740_AWB_CTRL0F, 0xff },
292 { OV9740_AWB_CTRL10, 0x00 },
293 { OV9740_AWB_CTRL11, 0xff },
294 { OV9740_AWB_CTRL12, 0x00 },
295 { OV9740_AWB_CTRL13, 0xff },
296 { OV9740_AWB_CTRL14, 0x00 },
297
298 /* CIP */
299 { 0x530D, 0x12 },
300
301 /* CMX */
302 { 0x5380, 0x01 }, { 0x5381, 0x00 }, { 0x5382, 0x00 }, { 0x5383, 0x17 },
303 { 0x5384, 0x00 }, { 0x5385, 0x01 }, { 0x5386, 0x00 }, { 0x5387, 0x00 },
304 { 0x5388, 0x00 }, { 0x5389, 0xe0 }, { 0x538A, 0x00 }, { 0x538B, 0x20 },
305 { 0x538C, 0x00 }, { 0x538D, 0x00 }, { 0x538E, 0x00 }, { 0x538F, 0x16 },
306 { 0x5390, 0x00 }, { 0x5391, 0x9c }, { 0x5392, 0x00 }, { 0x5393, 0xa0 },
307 { 0x5394, 0x18 },
308
309 /* 50/60 Detection */
310 { 0x3C0A, 0x9c }, { 0x3C0B, 0x3f },
311
312 /* Output Select */
313 { OV9740_IO_OUTPUT_SEL01, 0x00 },
314 { OV9740_IO_OUTPUT_SEL02, 0x00 },
315 { OV9740_IO_CREL00, 0x00 },
316 { OV9740_IO_CREL01, 0x00 },
317 { OV9740_IO_CREL02, 0x00 },
318
319 /* AWB Control */
320 { OV9740_AWB_MANUAL_CTRL, 0x00 },
321
322 /* Analog Control */
323 { OV9740_ANALOG_CTRL03, 0xaa },
324 { OV9740_ANALOG_CTRL32, 0x2f },
325 { OV9740_ANALOG_CTRL20, 0x66 },
326 { OV9740_ANALOG_CTRL21, 0xc0 },
327 { OV9740_ANALOG_CTRL31, 0x52 },
328 { OV9740_ANALOG_CTRL33, 0x50 },
329 { OV9740_ANALOG_CTRL30, 0xca },
330 { OV9740_ANALOG_CTRL04, 0x0c },
331 { OV9740_ANALOG_CTRL01, 0x40 },
332 { OV9740_ANALOG_CTRL02, 0x16 },
333 { OV9740_ANALOG_CTRL10, 0xa1 },
334 { OV9740_ANALOG_CTRL12, 0x24 },
335 { OV9740_ANALOG_CTRL22, 0x9f },
336
337 /* Sensor Control */
338 { OV9740_SENSOR_CTRL03, 0x42 },
339 { OV9740_SENSOR_CTRL04, 0x10 },
340 { OV9740_SENSOR_CTRL05, 0x45 },
341 { OV9740_SENSOR_CTRL07, 0x14 },
342
343 /* Timing Control */
344 { OV9740_TIMING_CTRL33, 0x04 },
345 { OV9740_TIMING_CTRL35, 0x02 },
346 { OV9740_TIMING_CTRL19, 0x6e },
347 { OV9740_TIMING_CTRL17, 0x94 },
348
349 /* AEC/AGC Control */
350 { OV9740_AEC_ENABLE, 0x10 },
351 { OV9740_GAIN_CEILING_01, 0x00 },
352 { OV9740_GAIN_CEILING_02, 0x7f },
353 { OV9740_AEC_HI_THRESHOLD, 0xa0 },
354 { OV9740_AEC_3A1A, 0x05 },
355 { OV9740_AEC_CTRL1B_WPT2, 0x50 },
356 { OV9740_AEC_CTRL0F_WPT, 0x50 },
357 { OV9740_AEC_CTRL10_BPT, 0x4c },
358 { OV9740_AEC_CTRL1E_BPT2, 0x4c },
359 { OV9740_AEC_LO_THRESHOLD, 0x26 },
360
361 /* BLC Control */
362 { OV9740_BLC_AUTO_ENABLE, 0x45 },
363 { OV9740_BLC_MODE, 0x18 },
364
365 /* DVP Control */
366 { OV9740_DVP_VSYNC_CTRL02, 0x04 },
367 { OV9740_DVP_VSYNC_MODE, 0x00 },
368 { OV9740_DVP_VSYNC_CTRL06, 0x08 },
369
370 /* PLL Setting */
371 { OV9740_PLL_MODE_CTRL01, 0x20 },
372 { OV9740_PRE_PLL_CLK_DIV, 0x03 },
373 { OV9740_PLL_MULTIPLIER, 0x4c },
374 { OV9740_VT_SYS_CLK_DIV, 0x01 },
375 { OV9740_VT_PIX_CLK_DIV, 0x08 },
376 { OV9740_PLL_CTRL3010, 0x01 },
377 { OV9740_VFIFO_CTRL00, 0x82 },
378
379 /* Timing Setting */
380 /* VTS */
381 { OV9740_FRM_LENGTH_LN_HI, 0x03 },
382 { OV9740_FRM_LENGTH_LN_LO, 0x07 },
383 /* HTS */
384 { OV9740_LN_LENGTH_PCK_HI, 0x06 },
385 { OV9740_LN_LENGTH_PCK_LO, 0x62 },
386
387 /* MIPI Control */
388 { OV9740_MIPI_CTRL00, 0x44 },
389 { OV9740_MIPI_3837, 0x01 },
390 { OV9740_MIPI_CTRL01, 0x0f },
391 { OV9740_MIPI_CTRL03, 0x05 },
392 { OV9740_MIPI_CTRL05, 0x10 },
393 { OV9740_VFIFO_RD_CTRL, 0x16 },
394 { OV9740_MIPI_CTRL_3012, 0x70 },
395 { OV9740_SC_CMMM_MIPI_CTR, 0x01 },
396};
397
398static const struct ov9740_reg ov9740_regs_vga[] = {
399 { OV9740_X_ADDR_START_HI, 0x00 },
400 { OV9740_X_ADDR_START_LO, 0xa0 },
401 { OV9740_Y_ADDR_START_HI, 0x00 },
402 { OV9740_Y_ADDR_START_LO, 0x00 },
403 { OV9740_X_ADDR_END_HI, 0x04 },
404 { OV9740_X_ADDR_END_LO, 0x63 },
405 { OV9740_Y_ADDR_END_HI, 0x02 },
406 { OV9740_Y_ADDR_END_LO, 0xd3 },
407 { OV9740_X_OUTPUT_SIZE_HI, 0x02 },
408 { OV9740_X_OUTPUT_SIZE_LO, 0x80 },
409 { OV9740_Y_OUTPUT_SIZE_HI, 0x01 },
410 { OV9740_Y_OUTPUT_SIZE_LO, 0xe0 },
411 { OV9740_ISP_CTRL1E, 0x03 },
412 { OV9740_ISP_CTRL1F, 0xc0 },
413 { OV9740_ISP_CTRL20, 0x02 },
414 { OV9740_ISP_CTRL21, 0xd0 },
415 { OV9740_VFIFO_READ_START_HI, 0x01 },
416 { OV9740_VFIFO_READ_START_LO, 0x40 },
417 { OV9740_ISP_CTRL00, 0xff },
418 { OV9740_ISP_CTRL01, 0xff },
419 { OV9740_ISP_CTRL03, 0xff },
420};
421
422static const struct ov9740_reg ov9740_regs_720p[] = {
423 { OV9740_X_ADDR_START_HI, 0x00 },
424 { OV9740_X_ADDR_START_LO, 0x00 },
425 { OV9740_Y_ADDR_START_HI, 0x00 },
426 { OV9740_Y_ADDR_START_LO, 0x00 },
427 { OV9740_X_ADDR_END_HI, 0x05 },
428 { OV9740_X_ADDR_END_LO, 0x03 },
429 { OV9740_Y_ADDR_END_HI, 0x02 },
430 { OV9740_Y_ADDR_END_LO, 0xd3 },
431 { OV9740_X_OUTPUT_SIZE_HI, 0x05 },
432 { OV9740_X_OUTPUT_SIZE_LO, 0x00 },
433 { OV9740_Y_OUTPUT_SIZE_HI, 0x02 },
434 { OV9740_Y_OUTPUT_SIZE_LO, 0xd0 },
435 { OV9740_ISP_CTRL1E, 0x05 },
436 { OV9740_ISP_CTRL1F, 0x00 },
437 { OV9740_ISP_CTRL20, 0x02 },
438 { OV9740_ISP_CTRL21, 0xd0 },
439 { OV9740_VFIFO_READ_START_HI, 0x02 },
440 { OV9740_VFIFO_READ_START_LO, 0x30 },
441 { OV9740_ISP_CTRL00, 0xff },
442 { OV9740_ISP_CTRL01, 0xef },
443 { OV9740_ISP_CTRL03, 0xff },
444};
445
446static enum v4l2_mbus_pixelcode ov9740_codes[] = {
447 V4L2_MBUS_FMT_YUYV8_2X8,
448};
449
450static const struct v4l2_queryctrl ov9740_controls[] = {
451 {
452 .id = V4L2_CID_VFLIP,
453 .type = V4L2_CTRL_TYPE_BOOLEAN,
454 .name = "Flip Vertically",
455 .minimum = 0,
456 .maximum = 1,
457 .step = 1,
458 .default_value = 0,
459 },
460 {
461 .id = V4L2_CID_HFLIP,
462 .type = V4L2_CTRL_TYPE_BOOLEAN,
463 .name = "Flip Horizontally",
464 .minimum = 0,
465 .maximum = 1,
466 .step = 1,
467 .default_value = 0,
468 },
469};
470
471/* read a register */
472static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
473{
474 int ret;
475 struct i2c_msg msg[] = {
476 {
477 .addr = client->addr,
478 .flags = 0,
479 .len = 2,
480 .buf = (u8 *)&reg,
481 },
482 {
483 .addr = client->addr,
484 .flags = I2C_M_RD,
485 .len = 1,
486 .buf = val,
487 },
488 };
489
490 reg = swab16(reg);
491
492 ret = i2c_transfer(client->adapter, msg, 2);
493 if (ret < 0) {
494 dev_err(&client->dev, "Failed reading register 0x%04x!\n", reg);
495 return ret;
496 }
497
498 return 0;
499}
500
501/* write a register */
502static int ov9740_reg_write(struct i2c_client *client, u16 reg, u8 val)
503{
504 struct i2c_msg msg;
505 struct {
506 u16 reg;
507 u8 val;
508 } __packed buf;
509 int ret;
510
511 reg = swab16(reg);
512
513 buf.reg = reg;
514 buf.val = val;
515
516 msg.addr = client->addr;
517 msg.flags = 0;
518 msg.len = 3;
519 msg.buf = (u8 *)&buf;
520
521 ret = i2c_transfer(client->adapter, &msg, 1);
522 if (ret < 0) {
523 dev_err(&client->dev, "Failed writing register 0x%04x!\n", reg);
524 return ret;
525 }
526
527 return 0;
528}
529
530
531/* Read a register, alter its bits, write it back */
532static int ov9740_reg_rmw(struct i2c_client *client, u16 reg, u8 set, u8 unset)
533{
534 u8 val;
535 int ret;
536
537 ret = ov9740_reg_read(client, reg, &val);
538 if (ret < 0) {
539 dev_err(&client->dev,
540 "[Read]-Modify-Write of register %02x failed!\n", reg);
541 return ret;
542 }
543
544 val |= set;
545 val &= ~unset;
546
547 ret = ov9740_reg_write(client, reg, val);
548 if (ret < 0) {
549 dev_err(&client->dev,
550 "Read-Modify-[Write] of register %02x failed!\n", reg);
551 return ret;
552 }
553
554 return 0;
555}
556
557static int ov9740_reg_write_array(struct i2c_client *client,
558 const struct ov9740_reg *regarray,
559 int regarraylen)
560{
561 int i;
562 int ret;
563
564 for (i = 0; i < regarraylen; i++) {
565 ret = ov9740_reg_write(client,
566 regarray[i].reg, regarray[i].val);
567 if (ret < 0)
568 return ret;
569 }
570
571 return 0;
572}
573
574/* Start/Stop streaming from the device */
575static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
576{
577 struct i2c_client *client = v4l2_get_subdevdata(sd);
578 struct ov9740_priv *priv = to_ov9740(sd);
579 int ret;
580
581 /* Program orientation register. */
582 if (priv->flag_vflip)
583 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x2, 0);
584 else
585 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x2);
586 if (ret < 0)
587 return ret;
588
589 if (priv->flag_hflip)
590 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x1, 0);
591 else
592 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x1);
593 if (ret < 0)
594 return ret;
595
596 if (enable) {
597 dev_dbg(&client->dev, "Enabling Streaming\n");
598 /* Start Streaming */
599 ret = ov9740_reg_write(client, OV9740_MODE_SELECT, 0x01);
600
601 } else {
602 dev_dbg(&client->dev, "Disabling Streaming\n");
603 /* Software Reset */
604 ret = ov9740_reg_write(client, OV9740_SOFTWARE_RESET, 0x01);
605 if (!ret)
606 /* Setting Streaming to Standby */
607 ret = ov9740_reg_write(client, OV9740_MODE_SELECT,
608 0x00);
609 }
610
611 return ret;
612}
613
614/* Alter bus settings on camera side */
615static int ov9740_set_bus_param(struct soc_camera_device *icd,
616 unsigned long flags)
617{
618 return 0;
619}
620
621/* Request bus settings on camera side */
622static unsigned long ov9740_query_bus_param(struct soc_camera_device *icd)
623{
624 struct soc_camera_link *icl = to_soc_camera_link(icd);
625
626 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
627 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
628 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
629
630 return soc_camera_apply_sensor_flags(icl, flags);
631}
632
633/* Get status of additional camera capabilities */
634static int ov9740_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
635{
636 struct ov9740_priv *priv = to_ov9740(sd);
637
638 switch (ctrl->id) {
639 case V4L2_CID_VFLIP:
640 ctrl->value = priv->flag_vflip;
641 break;
642 case V4L2_CID_HFLIP:
643 ctrl->value = priv->flag_hflip;
644 break;
645 default:
646 return -EINVAL;
647 }
648
649 return 0;
650}
651
652/* Set status of additional camera capabilities */
653static int ov9740_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
654{
655 struct ov9740_priv *priv = to_ov9740(sd);
656
657 switch (ctrl->id) {
658 case V4L2_CID_VFLIP:
659 priv->flag_vflip = ctrl->value;
660 break;
661 case V4L2_CID_HFLIP:
662 priv->flag_hflip = ctrl->value;
663 break;
664 default:
665 return -EINVAL;
666 }
667
668 return 0;
669}
670
671/* Get chip identification */
672static int ov9740_g_chip_ident(struct v4l2_subdev *sd,
673 struct v4l2_dbg_chip_ident *id)
674{
675 struct ov9740_priv *priv = to_ov9740(sd);
676
677 id->ident = priv->ident;
678 id->revision = priv->revision;
679
680 return 0;
681}
682
683#ifdef CONFIG_VIDEO_ADV_DEBUG
684static int ov9740_get_register(struct v4l2_subdev *sd,
685 struct v4l2_dbg_register *reg)
686{
687 struct i2c_client *client = v4l2_get_subdevdata(sd);
688 int ret;
689 u8 val;
690
691 if (reg->reg & ~0xffff)
692 return -EINVAL;
693
694 reg->size = 2;
695
696 ret = ov9740_reg_read(client, reg->reg, &val);
697 if (ret)
698 return ret;
699
700 reg->val = (__u64)val;
701
702 return ret;
703}
704
705static int ov9740_set_register(struct v4l2_subdev *sd,
706 struct v4l2_dbg_register *reg)
707{
708 struct i2c_client *client = v4l2_get_subdevdata(sd);
709
710 if (reg->reg & ~0xffff || reg->val & ~0xff)
711 return -EINVAL;
712
713 return ov9740_reg_write(client, reg->reg, reg->val);
714}
715#endif
716
717/* select nearest higher resolution for capture */
718static void ov9740_res_roundup(u32 *width, u32 *height)
719{
720 int i;
721
722 for (i = 0; i < ARRAY_SIZE(ov9740_resolutions); i++)
723 if ((ov9740_resolutions[i].width >= *width) &&
724 (ov9740_resolutions[i].height >= *height)) {
725 *width = ov9740_resolutions[i].width;
726 *height = ov9740_resolutions[i].height;
727 return;
728 }
729
730 *width = ov9740_resolutions[OV9740_720P].width;
731 *height = ov9740_resolutions[OV9740_720P].height;
732}
733
734/* Setup registers according to resolution and color encoding */
735static int ov9740_set_res(struct i2c_client *client, u32 width)
736{
737 int ret;
738
739 /* select register configuration for given resolution */
740 if (width == ov9740_resolutions[OV9740_VGA].width) {
741 dev_dbg(&client->dev, "Setting image size to 640x480\n");
742 ret = ov9740_reg_write_array(client, ov9740_regs_vga,
743 ARRAY_SIZE(ov9740_regs_vga));
744 } else if (width == ov9740_resolutions[OV9740_720P].width) {
745 dev_dbg(&client->dev, "Setting image size to 1280x720\n");
746 ret = ov9740_reg_write_array(client, ov9740_regs_720p,
747 ARRAY_SIZE(ov9740_regs_720p));
748 } else {
749 dev_err(&client->dev, "Failed to select resolution!\n");
750 return -EINVAL;
751 }
752
753 return ret;
754}
755
756/* set the format we will capture in */
757static int ov9740_s_fmt(struct v4l2_subdev *sd,
758 struct v4l2_mbus_framefmt *mf)
759{
760 struct i2c_client *client = v4l2_get_subdevdata(sd);
761 enum v4l2_colorspace cspace;
762 enum v4l2_mbus_pixelcode code = mf->code;
763 int ret;
764
765 ov9740_res_roundup(&mf->width, &mf->height);
766
767 switch (code) {
768 case V4L2_MBUS_FMT_YUYV8_2X8:
769 cspace = V4L2_COLORSPACE_SRGB;
770 break;
771 default:
772 return -EINVAL;
773 }
774
775 ret = ov9740_reg_write_array(client, ov9740_defaults,
776 ARRAY_SIZE(ov9740_defaults));
777 if (ret < 0)
778 return ret;
779
780 ret = ov9740_set_res(client, mf->width);
781 if (ret < 0)
782 return ret;
783
784 mf->code = code;
785 mf->colorspace = cspace;
786
787 return ret;
788}
789
790static int ov9740_try_fmt(struct v4l2_subdev *sd,
791 struct v4l2_mbus_framefmt *mf)
792{
793 ov9740_res_roundup(&mf->width, &mf->height);
794
795 mf->field = V4L2_FIELD_NONE;
796 mf->code = V4L2_MBUS_FMT_YUYV8_2X8;
797 mf->colorspace = V4L2_COLORSPACE_SRGB;
798
799 return 0;
800}
801
802static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
803 enum v4l2_mbus_pixelcode *code)
804{
805 if (index >= ARRAY_SIZE(ov9740_codes))
806 return -EINVAL;
807
808 *code = ov9740_codes[index];
809
810 return 0;
811}
812
813static int ov9740_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
814{
815 a->bounds.left = 0;
816 a->bounds.top = 0;
817 a->bounds.width = ov9740_resolutions[OV9740_720P].width;
818 a->bounds.height = ov9740_resolutions[OV9740_720P].height;
819 a->defrect = a->bounds;
820 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
821 a->pixelaspect.numerator = 1;
822 a->pixelaspect.denominator = 1;
823
824 return 0;
825}
826
827static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
828{
829 a->c.left = 0;
830 a->c.top = 0;
831 a->c.width = ov9740_resolutions[OV9740_720P].width;
832 a->c.height = ov9740_resolutions[OV9740_720P].height;
833 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
834
835 return 0;
836}
837
838static int ov9740_video_probe(struct soc_camera_device *icd,
839 struct i2c_client *client)
840{
841 struct v4l2_subdev *sd = i2c_get_clientdata(client);
842 struct ov9740_priv *priv = to_ov9740(sd);
843 u8 modelhi, modello;
844 int ret;
845
846 /*
847 * We must have a parent by now. And it cannot be a wrong one.
848 * So this entire test is completely redundant.
849 */
850 if (!icd->dev.parent ||
851 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
852 dev_err(&client->dev, "Parent missing or invalid!\n");
853 ret = -ENODEV;
854 goto err;
855 }
856
857 /*
858 * check and show product ID and manufacturer ID
859 */
860 ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi);
861 if (ret < 0)
862 goto err;
863
864 ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello);
865 if (ret < 0)
866 goto err;
867
868 priv->model = (modelhi << 8) | modello;
869
870 ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision);
871 if (ret < 0)
872 goto err;
873
874 ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid);
875 if (ret < 0)
876 goto err;
877
878 ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver);
879 if (ret < 0)
880 goto err;
881
882 if (priv->model != 0x9740) {
883 ret = -ENODEV;
884 goto err;
885 }
886
887 priv->ident = V4L2_IDENT_OV9740;
888
889 dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, "
890 "Manufacturer 0x%02x, SMIA Version 0x%02x\n",
891 priv->model, priv->revision, priv->manid, priv->smiaver);
892
893err:
894 return ret;
895}
896
897static struct soc_camera_ops ov9740_ops = {
898 .set_bus_param = ov9740_set_bus_param,
899 .query_bus_param = ov9740_query_bus_param,
900 .controls = ov9740_controls,
901 .num_controls = ARRAY_SIZE(ov9740_controls),
902};
903
904static struct v4l2_subdev_core_ops ov9740_core_ops = {
905 .g_ctrl = ov9740_g_ctrl,
906 .s_ctrl = ov9740_s_ctrl,
907 .g_chip_ident = ov9740_g_chip_ident,
908#ifdef CONFIG_VIDEO_ADV_DEBUG
909 .g_register = ov9740_get_register,
910 .s_register = ov9740_set_register,
911#endif
912
913};
914
915static struct v4l2_subdev_video_ops ov9740_video_ops = {
916 .s_stream = ov9740_s_stream,
917 .s_mbus_fmt = ov9740_s_fmt,
918 .try_mbus_fmt = ov9740_try_fmt,
919 .enum_mbus_fmt = ov9740_enum_fmt,
920 .cropcap = ov9740_cropcap,
921 .g_crop = ov9740_g_crop,
922};
923
924static struct v4l2_subdev_ops ov9740_subdev_ops = {
925 .core = &ov9740_core_ops,
926 .video = &ov9740_video_ops,
927};
928
929/*
930 * i2c_driver function
931 */
932static int ov9740_probe(struct i2c_client *client,
933 const struct i2c_device_id *did)
934{
935 struct ov9740_priv *priv;
936 struct soc_camera_device *icd = client->dev.platform_data;
937 struct soc_camera_link *icl;
938 int ret;
939
940 if (!icd) {
941 dev_err(&client->dev, "Missing soc-camera data!\n");
942 return -EINVAL;
943 }
944
945 icl = to_soc_camera_link(icd);
946 if (!icl) {
947 dev_err(&client->dev, "Missing platform_data for driver\n");
948 return -EINVAL;
949 }
950
951 priv = kzalloc(sizeof(struct ov9740_priv), GFP_KERNEL);
952 if (!priv) {
953 dev_err(&client->dev, "Failed to allocate private data!\n");
954 return -ENOMEM;
955 }
956
957 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
958
959 icd->ops = &ov9740_ops;
960
961 ret = ov9740_video_probe(icd, client);
962 if (ret < 0) {
963 icd->ops = NULL;
964 kfree(priv);
965 }
966
967 return ret;
968}
969
970static int ov9740_remove(struct i2c_client *client)
971{
972 struct ov9740_priv *priv = i2c_get_clientdata(client);
973
974 kfree(priv);
975
976 return 0;
977}
978
979static const struct i2c_device_id ov9740_id[] = {
980 { "ov9740", 0 },
981 { }
982};
983MODULE_DEVICE_TABLE(i2c, ov9740_id);
984
985static struct i2c_driver ov9740_i2c_driver = {
986 .driver = {
987 .name = "ov9740",
988 },
989 .probe = ov9740_probe,
990 .remove = ov9740_remove,
991 .id_table = ov9740_id,
992};
993
994static int __init ov9740_module_init(void)
995{
996 return i2c_add_driver(&ov9740_i2c_driver);
997}
998
999static void __exit ov9740_module_exit(void)
1000{
1001 i2c_del_driver(&ov9740_i2c_driver);
1002}
1003
1004module_init(ov9740_module_init);
1005module_exit(ov9740_module_exit);
1006
1007MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740");
1008MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
1009MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 2222da8d0ca6..c514d0b9ffdc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -99,9 +99,27 @@ static const struct routing_scheme routing_defgv = {
99 .cnt = ARRAY_SIZE(routing_schemegv), 99 .cnt = ARRAY_SIZE(routing_schemegv),
100}; 100};
101 101
102/* Specific to grabster av400 device */
103static const struct routing_scheme_item routing_schemeav400[] = {
104 [PVR2_CVAL_INPUT_COMPOSITE] = {
105 .vid = CX25840_COMPOSITE1,
106 .aud = CX25840_AUDIO_SERIAL,
107 },
108 [PVR2_CVAL_INPUT_SVIDEO] = {
109 .vid = (CX25840_SVIDEO_LUMA2|CX25840_SVIDEO_CHROMA4),
110 .aud = CX25840_AUDIO_SERIAL,
111 },
112};
113
114static const struct routing_scheme routing_defav400 = {
115 .def = routing_schemeav400,
116 .cnt = ARRAY_SIZE(routing_schemeav400),
117};
118
102static const struct routing_scheme *routing_schemes[] = { 119static const struct routing_scheme *routing_schemes[] = {
103 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, 120 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
104 [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv, 121 [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
122 [PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
105}; 123};
106 124
107void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) 125void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 3092abfd66a2..e799331389b1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -157,6 +157,28 @@ static const struct pvr2_device_desc pvr2_device_gotview_2d = {
157 157
158 158
159/*------------------------------------------------------------------------*/ 159/*------------------------------------------------------------------------*/
160/* Terratec Grabster AV400 */
161
162static const struct pvr2_device_client_desc pvr2_cli_av400[] = {
163 { .module_id = PVR2_CLIENT_ID_CX25840 },
164};
165
166static const struct pvr2_device_desc pvr2_device_av400 = {
167 .description = "Terratec Grabster AV400",
168 .shortname = "av400",
169 .flag_is_experimental = 1,
170 .client_table.lst = pvr2_cli_av400,
171 .client_table.cnt = ARRAY_SIZE(pvr2_cli_av400),
172 .flag_has_cx25840 = !0,
173 .flag_has_analogtuner = 0,
174 .flag_has_composite = !0,
175 .flag_has_svideo = !0,
176 .signal_routing_scheme = PVR2_ROUTING_SCHEME_AV400,
177};
178
179
180
181/*------------------------------------------------------------------------*/
160/* OnAir Creator */ 182/* OnAir Creator */
161 183
162#ifdef CONFIG_VIDEO_PVRUSB2_DVB 184#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -517,6 +539,8 @@ struct usb_device_id pvr2_device_table[] = {
517 .driver_info = (kernel_ulong_t)&pvr2_device_750xx}, 539 .driver_info = (kernel_ulong_t)&pvr2_device_750xx},
518 { USB_DEVICE(0x2040, 0x7501), 540 { USB_DEVICE(0x2040, 0x7501),
519 .driver_info = (kernel_ulong_t)&pvr2_device_751xx}, 541 .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
542 { USB_DEVICE(0x0ccd, 0x0039),
543 .driver_info = (kernel_ulong_t)&pvr2_device_av400},
520 { } 544 { }
521}; 545};
522 546
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 66ad516bdfd9..9d0dd08f57f8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -499,31 +499,35 @@ static int ctrl_cropt_max_get(struct pvr2_ctrl *cptr, int *top)
499 return 0; 499 return 0;
500} 500}
501 501
502static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *val) 502static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *width)
503{ 503{
504 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; 504 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
505 int stat = pvr2_hdw_check_cropcap(cptr->hdw); 505 int stat, bleftend, cleft;
506
507 stat = pvr2_hdw_check_cropcap(cptr->hdw);
506 if (stat != 0) { 508 if (stat != 0) {
507 return stat; 509 return stat;
508 } 510 }
509 *val = 0; 511 bleftend = cap->bounds.left+cap->bounds.width;
510 if (cap->bounds.width > cptr->hdw->cropl_val) { 512 cleft = cptr->hdw->cropl_val;
511 *val = cap->bounds.width - cptr->hdw->cropl_val; 513
512 } 514 *width = cleft < bleftend ? bleftend-cleft : 0;
513 return 0; 515 return 0;
514} 516}
515 517
516static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *val) 518static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *height)
517{ 519{
518 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; 520 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
519 int stat = pvr2_hdw_check_cropcap(cptr->hdw); 521 int stat, btopend, ctop;
522
523 stat = pvr2_hdw_check_cropcap(cptr->hdw);
520 if (stat != 0) { 524 if (stat != 0) {
521 return stat; 525 return stat;
522 } 526 }
523 *val = 0; 527 btopend = cap->bounds.top+cap->bounds.height;
524 if (cap->bounds.height > cptr->hdw->cropt_val) { 528 ctop = cptr->hdw->cropt_val;
525 *val = cap->bounds.height - cptr->hdw->cropt_val; 529
526 } 530 *height = ctop < btopend ? btopend-ctop : 0;
527 return 0; 531 return 0;
528} 532}
529 533
@@ -1114,6 +1118,7 @@ static const struct pvr2_ctl_info control_defs[] = {
1114 .internal_id = PVR2_CID_CROPW, 1118 .internal_id = PVR2_CID_CROPW,
1115 .default_value = 720, 1119 .default_value = 720,
1116 DEFREF(cropw), 1120 DEFREF(cropw),
1121 DEFINT(0, 864),
1117 .get_max_value = ctrl_cropw_max_get, 1122 .get_max_value = ctrl_cropw_max_get,
1118 .get_def_value = ctrl_get_cropcapdw, 1123 .get_def_value = ctrl_get_cropcapdw,
1119 }, { 1124 }, {
@@ -1122,6 +1127,7 @@ static const struct pvr2_ctl_info control_defs[] = {
1122 .internal_id = PVR2_CID_CROPH, 1127 .internal_id = PVR2_CID_CROPH,
1123 .default_value = 480, 1128 .default_value = 480,
1124 DEFREF(croph), 1129 DEFREF(croph),
1130 DEFINT(0, 576),
1125 .get_max_value = ctrl_croph_max_get, 1131 .get_max_value = ctrl_croph_max_get,
1126 .get_def_value = ctrl_get_cropcapdh, 1132 .get_def_value = ctrl_get_cropcapdh,
1127 }, { 1133 }, {
@@ -2027,6 +2033,8 @@ static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
2027 hdw->decoder_client_id); 2033 hdw->decoder_client_id);
2028 memset(&fmt, 0, sizeof(fmt)); 2034 memset(&fmt, 0, sizeof(fmt));
2029 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 2035 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
2036 fmt.fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
2037 fmt.fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
2030 v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, 2038 v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
2031 vbi, s_sliced_fmt, &fmt.fmt.sliced); 2039 vbi, s_sliced_fmt, &fmt.fmt.sliced);
2032} 2040}
@@ -2842,15 +2850,23 @@ static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
2842 PVR2_TRACE_ERROR_LEGS, 2850 PVR2_TRACE_ERROR_LEGS,
2843 "WARNING: Failed to identify any viable standards"); 2851 "WARNING: Failed to identify any viable standards");
2844 } 2852 }
2853
2854 /* Set up the dynamic control for this standard */
2845 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL); 2855 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2846 hdw->std_enum_names[0] = "none"; 2856 if (hdw->std_enum_names) {
2847 for (idx = 0; idx < std_cnt; idx++) { 2857 hdw->std_enum_names[0] = "none";
2848 hdw->std_enum_names[idx+1] = 2858 for (idx = 0; idx < std_cnt; idx++)
2849 newstd[idx].name; 2859 hdw->std_enum_names[idx+1] = newstd[idx].name;
2850 } 2860 hdw->std_info_enum.def.type_enum.value_names =
2851 // Set up the dynamic control for this standard 2861 hdw->std_enum_names;
2852 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names; 2862 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2853 hdw->std_info_enum.def.type_enum.count = std_cnt+1; 2863 } else {
2864 pvr2_trace(
2865 PVR2_TRACE_ERROR_LEGS,
2866 "WARNING: Failed to alloc memory for names");
2867 hdw->std_info_enum.def.type_enum.value_names = NULL;
2868 hdw->std_info_enum.def.type_enum.count = 0;
2869 }
2854 hdw->std_defs = newstd; 2870 hdw->std_defs = newstd;
2855 hdw->std_enum_cnt = std_cnt+1; 2871 hdw->std_enum_cnt = std_cnt+1;
2856 hdw->std_enum_cur = 0; 2872 hdw->std_enum_cur = 0;
@@ -3165,6 +3181,19 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
3165 struct pvr2_ctrl *cptr; 3181 struct pvr2_ctrl *cptr;
3166 int disruptive_change; 3182 int disruptive_change;
3167 3183
3184 if (hdw->input_dirty && hdw->state_pathway_ok &&
3185 (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
3186 PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
3187 hdw->pathway_state)) {
3188 /* Change of mode being asked for... */
3189 hdw->state_pathway_ok = 0;
3190 trace_stbit("state_pathway_ok", hdw->state_pathway_ok);
3191 }
3192 if (!hdw->state_pathway_ok) {
3193 /* Can't commit anything until pathway is ok. */
3194 return 0;
3195 }
3196
3168 /* Handle some required side effects when the video standard is 3197 /* Handle some required side effects when the video standard is
3169 changed.... */ 3198 changed.... */
3170 if (hdw->std_dirty) { 3199 if (hdw->std_dirty) {
@@ -3199,18 +3228,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
3199 } 3228 }
3200 } 3229 }
3201 3230
3202 if (hdw->input_dirty && hdw->state_pathway_ok &&
3203 (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
3204 PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
3205 hdw->pathway_state)) {
3206 /* Change of mode being asked for... */
3207 hdw->state_pathway_ok = 0;
3208 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
3209 }
3210 if (!hdw->state_pathway_ok) {
3211 /* Can't commit anything until pathway is ok. */
3212 return 0;
3213 }
3214 /* The broadcast decoder can only scale down, so if 3231 /* The broadcast decoder can only scale down, so if
3215 * res_*_dirty && crop window < output format ==> enlarge crop. 3232 * res_*_dirty && crop window < output format ==> enlarge crop.
3216 * 3233 *
@@ -5159,8 +5176,7 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
5159 using v4l2-subdev - therefore we can't support that AT ALL right 5176 using v4l2-subdev - therefore we can't support that AT ALL right
5160 now. (Of course, no sub-drivers seem to implement it either. 5177 now. (Of course, no sub-drivers seem to implement it either.
5161 But now it's a a chicken and egg problem...) */ 5178 But now it's a a chicken and egg problem...) */
5162 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, 5179 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, vtp);
5163 &hdw->tuner_signal_info);
5164 pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll" 5180 pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll"
5165 " type=%u strength=%u audio=0x%x cap=0x%x" 5181 " type=%u strength=%u audio=0x%x cap=0x%x"
5166 " low=%u hi=%u", 5182 " low=%u hi=%u",
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 451ecd485f97..e72d5103e778 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -578,7 +578,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
578 switch (hdw->ir_scheme_active) { 578 switch (hdw->ir_scheme_active) {
579 case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */ 579 case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */
580 case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */ 580 case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */
581 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 581 init_data->ir_codes = RC_MAP_HAUPPAUGE;
582 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; 582 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
583 init_data->type = RC_TYPE_RC5; 583 init_data->type = RC_TYPE_RC5;
584 init_data->name = hdw->hdw_desc->description; 584 init_data->name = hdw->hdw_desc->description;
@@ -593,7 +593,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
593 break; 593 break;
594 case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */ 594 case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */
595 case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */ 595 case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */
596 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 596 init_data->ir_codes = RC_MAP_HAUPPAUGE;
597 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 597 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
598 init_data->type = RC_TYPE_RC5; 598 init_data->type = RC_TYPE_RC5;
599 init_data->name = hdw->hdw_desc->description; 599 init_data->name = hdw->hdw_desc->description;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 281806b2df62..6ef1335b2858 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -324,36 +324,45 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
324 } 324 }
325 sfp->item_last = cip; 325 sfp->item_last = cip;
326 326
327 sysfs_attr_init(&cip->attr_name.attr);
327 cip->attr_name.attr.name = "name"; 328 cip->attr_name.attr.name = "name";
328 cip->attr_name.attr.mode = S_IRUGO; 329 cip->attr_name.attr.mode = S_IRUGO;
329 cip->attr_name.show = show_name; 330 cip->attr_name.show = show_name;
330 331
332 sysfs_attr_init(&cip->attr_type.attr);
331 cip->attr_type.attr.name = "type"; 333 cip->attr_type.attr.name = "type";
332 cip->attr_type.attr.mode = S_IRUGO; 334 cip->attr_type.attr.mode = S_IRUGO;
333 cip->attr_type.show = show_type; 335 cip->attr_type.show = show_type;
334 336
337 sysfs_attr_init(&cip->attr_min.attr);
335 cip->attr_min.attr.name = "min_val"; 338 cip->attr_min.attr.name = "min_val";
336 cip->attr_min.attr.mode = S_IRUGO; 339 cip->attr_min.attr.mode = S_IRUGO;
337 cip->attr_min.show = show_min; 340 cip->attr_min.show = show_min;
338 341
342 sysfs_attr_init(&cip->attr_max.attr);
339 cip->attr_max.attr.name = "max_val"; 343 cip->attr_max.attr.name = "max_val";
340 cip->attr_max.attr.mode = S_IRUGO; 344 cip->attr_max.attr.mode = S_IRUGO;
341 cip->attr_max.show = show_max; 345 cip->attr_max.show = show_max;
342 346
347 sysfs_attr_init(&cip->attr_def.attr);
343 cip->attr_def.attr.name = "def_val"; 348 cip->attr_def.attr.name = "def_val";
344 cip->attr_def.attr.mode = S_IRUGO; 349 cip->attr_def.attr.mode = S_IRUGO;
345 cip->attr_def.show = show_def; 350 cip->attr_def.show = show_def;
346 351
352 sysfs_attr_init(&cip->attr_val.attr);
347 cip->attr_val.attr.name = "cur_val"; 353 cip->attr_val.attr.name = "cur_val";
348 cip->attr_val.attr.mode = S_IRUGO; 354 cip->attr_val.attr.mode = S_IRUGO;
349 355
356 sysfs_attr_init(&cip->attr_custom.attr);
350 cip->attr_custom.attr.name = "custom_val"; 357 cip->attr_custom.attr.name = "custom_val";
351 cip->attr_custom.attr.mode = S_IRUGO; 358 cip->attr_custom.attr.mode = S_IRUGO;
352 359
360 sysfs_attr_init(&cip->attr_enum.attr);
353 cip->attr_enum.attr.name = "enum_val"; 361 cip->attr_enum.attr.name = "enum_val";
354 cip->attr_enum.attr.mode = S_IRUGO; 362 cip->attr_enum.attr.mode = S_IRUGO;
355 cip->attr_enum.show = show_enum; 363 cip->attr_enum.show = show_enum;
356 364
365 sysfs_attr_init(&cip->attr_bits.attr);
357 cip->attr_bits.attr.name = "bit_val"; 366 cip->attr_bits.attr.name = "bit_val";
358 cip->attr_bits.attr.mode = S_IRUGO; 367 cip->attr_bits.attr.mode = S_IRUGO;
359 cip->attr_bits.show = show_bits; 368 cip->attr_bits.show = show_bits;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 58617fc656c2..38761142a4d9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -795,12 +795,10 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
795 case VIDIOC_S_CROP: 795 case VIDIOC_S_CROP:
796 { 796 {
797 struct v4l2_crop *crop = (struct v4l2_crop *)arg; 797 struct v4l2_crop *crop = (struct v4l2_crop *)arg;
798 struct v4l2_cropcap cap;
799 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 798 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
800 ret = -EINVAL; 799 ret = -EINVAL;
801 break; 800 break;
802 } 801 }
803 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
804 ret = pvr2_ctrl_set_value( 802 ret = pvr2_ctrl_set_value(
805 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), 803 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
806 crop->c.left); 804 crop->c.left);
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index bd1519a4ecb4..780af5f81642 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -151,8 +151,6 @@ static int pwc_video_close(struct file *file);
151static ssize_t pwc_video_read(struct file *file, char __user *buf, 151static ssize_t pwc_video_read(struct file *file, char __user *buf,
152 size_t count, loff_t *ppos); 152 size_t count, loff_t *ppos);
153static unsigned int pwc_video_poll(struct file *file, poll_table *wait); 153static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
154static long pwc_video_ioctl(struct file *file,
155 unsigned int ioctlnr, unsigned long arg);
156static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); 154static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
157 155
158static const struct v4l2_file_operations pwc_fops = { 156static const struct v4l2_file_operations pwc_fops = {
@@ -162,7 +160,7 @@ static const struct v4l2_file_operations pwc_fops = {
162 .read = pwc_video_read, 160 .read = pwc_video_read,
163 .poll = pwc_video_poll, 161 .poll = pwc_video_poll,
164 .mmap = pwc_video_mmap, 162 .mmap = pwc_video_mmap,
165 .unlocked_ioctl = pwc_video_ioctl, 163 .unlocked_ioctl = video_ioctl2,
166}; 164};
167static struct video_device pwc_template = { 165static struct video_device pwc_template = {
168 .name = "Philips Webcam", /* Filled in later */ 166 .name = "Philips Webcam", /* Filled in later */
@@ -1098,7 +1096,6 @@ static int pwc_video_open(struct file *file)
1098 return -EBUSY; 1096 return -EBUSY;
1099 } 1097 }
1100 1098
1101 mutex_lock(&pdev->modlock);
1102 pwc_construct(pdev); /* set min/max sizes correct */ 1099 pwc_construct(pdev); /* set min/max sizes correct */
1103 if (!pdev->usb_init) { 1100 if (!pdev->usb_init) {
1104 PWC_DEBUG_OPEN("Doing first time initialization.\n"); 1101 PWC_DEBUG_OPEN("Doing first time initialization.\n");
@@ -1130,7 +1127,6 @@ static int pwc_video_open(struct file *file)
1130 if (i < 0) { 1127 if (i < 0) {
1131 PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n"); 1128 PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n");
1132 pwc_free_buffers(pdev); 1129 pwc_free_buffers(pdev);
1133 mutex_unlock(&pdev->modlock);
1134 return i; 1130 return i;
1135 } 1131 }
1136 1132
@@ -1171,7 +1167,6 @@ static int pwc_video_open(struct file *file)
1171 if (i) { 1167 if (i) {
1172 PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n"); 1168 PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n");
1173 pwc_free_buffers(pdev); 1169 pwc_free_buffers(pdev);
1174 mutex_unlock(&pdev->modlock);
1175 return i; 1170 return i;
1176 } 1171 }
1177 1172
@@ -1181,7 +1176,6 @@ static int pwc_video_open(struct file *file)
1181 1176
1182 pdev->vopen++; 1177 pdev->vopen++;
1183 file->private_data = vdev; 1178 file->private_data = vdev;
1184 mutex_unlock(&pdev->modlock);
1185 PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); 1179 PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
1186 return 0; 1180 return 0;
1187} 1181}
@@ -1210,7 +1204,6 @@ static int pwc_video_close(struct file *file)
1210 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); 1204 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
1211 1205
1212 pdev = video_get_drvdata(vdev); 1206 pdev = video_get_drvdata(vdev);
1213 mutex_lock(&pdev->modlock);
1214 if (pdev->vopen == 0) 1207 if (pdev->vopen == 0)
1215 PWC_DEBUG_MODULE("video_close() called on closed device?\n"); 1208 PWC_DEBUG_MODULE("video_close() called on closed device?\n");
1216 1209
@@ -1248,7 +1241,6 @@ static int pwc_video_close(struct file *file)
1248 if (device_hint[hint].pdev == pdev) 1241 if (device_hint[hint].pdev == pdev)
1249 device_hint[hint].pdev = NULL; 1242 device_hint[hint].pdev = NULL;
1250 } 1243 }
1251 mutex_unlock(&pdev->modlock);
1252 1244
1253 return 0; 1245 return 0;
1254} 1246}
@@ -1283,7 +1275,6 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1283 if (pdev == NULL) 1275 if (pdev == NULL)
1284 return -EFAULT; 1276 return -EFAULT;
1285 1277
1286 mutex_lock(&pdev->modlock);
1287 if (pdev->error_status) { 1278 if (pdev->error_status) {
1288 rv = -pdev->error_status; /* Something happened, report what. */ 1279 rv = -pdev->error_status; /* Something happened, report what. */
1289 goto err_out; 1280 goto err_out;
@@ -1318,8 +1309,10 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1318 rv = -ERESTARTSYS; 1309 rv = -ERESTARTSYS;
1319 goto err_out; 1310 goto err_out;
1320 } 1311 }
1312 mutex_unlock(&pdev->modlock);
1321 schedule(); 1313 schedule();
1322 set_current_state(TASK_INTERRUPTIBLE); 1314 set_current_state(TASK_INTERRUPTIBLE);
1315 mutex_lock(&pdev->modlock);
1323 } 1316 }
1324 remove_wait_queue(&pdev->frameq, &wait); 1317 remove_wait_queue(&pdev->frameq, &wait);
1325 set_current_state(TASK_RUNNING); 1318 set_current_state(TASK_RUNNING);
@@ -1352,10 +1345,8 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1352 pdev->image_read_pos = 0; 1345 pdev->image_read_pos = 0;
1353 pwc_next_image(pdev); 1346 pwc_next_image(pdev);
1354 } 1347 }
1355 mutex_unlock(&pdev->modlock);
1356 return count; 1348 return count;
1357err_out: 1349err_out:
1358 mutex_unlock(&pdev->modlock);
1359 return rv; 1350 return rv;
1360} 1351}
1361 1352
@@ -1372,9 +1363,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1372 return -EFAULT; 1363 return -EFAULT;
1373 1364
1374 /* Start the stream (if not already started) */ 1365 /* Start the stream (if not already started) */
1375 mutex_lock(&pdev->modlock);
1376 ret = pwc_isoc_init(pdev); 1366 ret = pwc_isoc_init(pdev);
1377 mutex_unlock(&pdev->modlock);
1378 if (ret) 1367 if (ret)
1379 return ret; 1368 return ret;
1380 1369
@@ -1387,25 +1376,6 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1387 return 0; 1376 return 0;
1388} 1377}
1389 1378
1390static long pwc_video_ioctl(struct file *file,
1391 unsigned int cmd, unsigned long arg)
1392{
1393 struct video_device *vdev = file->private_data;
1394 struct pwc_device *pdev;
1395 long r = -ENODEV;
1396
1397 if (!vdev)
1398 goto out;
1399 pdev = video_get_drvdata(vdev);
1400
1401 mutex_lock(&pdev->modlock);
1402 if (!pdev->unplugged)
1403 r = video_usercopy(file, cmd, arg, pwc_video_do_ioctl);
1404 mutex_unlock(&pdev->modlock);
1405out:
1406 return r;
1407}
1408
1409static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 1379static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1410{ 1380{
1411 struct video_device *vdev = file->private_data; 1381 struct video_device *vdev = file->private_data;
@@ -1754,6 +1724,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1754 } 1724 }
1755 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); 1725 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1756 pdev->vdev->parent = &intf->dev; 1726 pdev->vdev->parent = &intf->dev;
1727 pdev->vdev->lock = &pdev->modlock;
1728 pdev->vdev->ioctl_ops = &pwc_ioctl_ops;
1757 strcpy(pdev->vdev->name, name); 1729 strcpy(pdev->vdev->name, name);
1758 video_set_drvdata(pdev->vdev, pdev); 1730 video_set_drvdata(pdev->vdev, pdev);
1759 1731
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 8ca4d22b4384..aa87e462a958 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -341,604 +341,555 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
341 341
342} 342}
343 343
344long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) 344static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
345{ 345{
346 struct video_device *vdev = video_devdata(file); 346 struct video_device *vdev = video_devdata(file);
347 struct pwc_device *pdev; 347 struct pwc_device *pdev = video_drvdata(file);
348 DECLARE_WAITQUEUE(wait, current); 348
349 349 strcpy(cap->driver, PWC_NAME);
350 if (vdev == NULL) 350 strlcpy(cap->card, vdev->name, sizeof(cap->card));
351 return -EFAULT; 351 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
352 pdev = video_get_drvdata(vdev); 352 cap->version = PWC_VERSION_CODE;
353 if (pdev == NULL) 353 cap->capabilities =
354 return -EFAULT; 354 V4L2_CAP_VIDEO_CAPTURE |
355 V4L2_CAP_STREAMING |
356 V4L2_CAP_READWRITE;
357 return 0;
358}
355 359
356#ifdef CONFIG_USB_PWC_DEBUG 360static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
357 if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) { 361{
358 v4l_printk_ioctl(cmd); 362 if (i->index) /* Only one INPUT is supported */
359 printk("\n"); 363 return -EINVAL;
360 }
361#endif
362
363
364 switch (cmd) {
365 /* V4L2 Layer */
366 case VIDIOC_QUERYCAP:
367 {
368 struct v4l2_capability *cap = arg;
369
370 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\
371 "try to use the v4l2 layer\n");
372 strcpy(cap->driver,PWC_NAME);
373 strlcpy(cap->card, vdev->name, sizeof(cap->card));
374 usb_make_path(pdev->udev,cap->bus_info,sizeof(cap->bus_info));
375 cap->version = PWC_VERSION_CODE;
376 cap->capabilities =
377 V4L2_CAP_VIDEO_CAPTURE |
378 V4L2_CAP_STREAMING |
379 V4L2_CAP_READWRITE;
380 return 0;
381 }
382 364
383 case VIDIOC_ENUMINPUT: 365 strcpy(i->name, "usb");
384 { 366 return 0;
385 struct v4l2_input *i = arg; 367}
386 368
387 if ( i->index ) /* Only one INPUT is supported */ 369static int pwc_g_input(struct file *file, void *fh, unsigned int *i)
388 return -EINVAL; 370{
371 *i = 0;
372 return 0;
373}
389 374
390 memset(i, 0, sizeof(struct v4l2_input)); 375static int pwc_s_input(struct file *file, void *fh, unsigned int i)
391 strcpy(i->name, "usb"); 376{
392 return 0; 377 return i ? -EINVAL : 0;
393 } 378}
394 379
395 case VIDIOC_G_INPUT: 380static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
396 { 381{
397 int *i = arg; 382 int i;
398 *i = 0; /* Only one INPUT is supported */
399 return 0;
400 }
401 case VIDIOC_S_INPUT:
402 {
403 int *i = arg;
404 383
405 if ( *i ) { /* Only one INPUT is supported */ 384 for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) {
406 PWC_DEBUG_IOCTL("Only one input source is"\ 385 if (pwc_controls[i].id == c->id) {
407 " supported with this webcam.\n"); 386 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
408 return -EINVAL; 387 memcpy(c, &pwc_controls[i], sizeof(struct v4l2_queryctrl));
409 }
410 return 0; 388 return 0;
411 } 389 }
390 }
391 return -EINVAL;
392}
412 393
413 /* TODO: */ 394static int pwc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
414 case VIDIOC_QUERYCTRL: 395{
415 { 396 struct pwc_device *pdev = video_drvdata(file);
416 struct v4l2_queryctrl *c = arg; 397 int ret;
417 int i;
418
419 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id);
420 for (i=0; i<sizeof(pwc_controls)/sizeof(struct v4l2_queryctrl); i++) {
421 if (pwc_controls[i].id == c->id) {
422 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
423 memcpy(c,&pwc_controls[i],sizeof(struct v4l2_queryctrl));
424 return 0;
425 }
426 }
427 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n");
428 398
399 switch (c->id) {
400 case V4L2_CID_BRIGHTNESS:
401 c->value = pwc_get_brightness(pdev);
402 if (c->value < 0)
429 return -EINVAL; 403 return -EINVAL;
430 } 404 return 0;
431 case VIDIOC_G_CTRL: 405 case V4L2_CID_CONTRAST:
432 { 406 c->value = pwc_get_contrast(pdev);
433 struct v4l2_control *c = arg; 407 if (c->value < 0)
434 int ret;
435
436 switch (c->id)
437 {
438 case V4L2_CID_BRIGHTNESS:
439 c->value = pwc_get_brightness(pdev);
440 if (c->value<0)
441 return -EINVAL;
442 return 0;
443 case V4L2_CID_CONTRAST:
444 c->value = pwc_get_contrast(pdev);
445 if (c->value<0)
446 return -EINVAL;
447 return 0;
448 case V4L2_CID_SATURATION:
449 ret = pwc_get_saturation(pdev, &c->value);
450 if (ret<0)
451 return -EINVAL;
452 return 0;
453 case V4L2_CID_GAMMA:
454 c->value = pwc_get_gamma(pdev);
455 if (c->value<0)
456 return -EINVAL;
457 return 0;
458 case V4L2_CID_RED_BALANCE:
459 ret = pwc_get_red_gain(pdev, &c->value);
460 if (ret<0)
461 return -EINVAL;
462 c->value >>= 8;
463 return 0;
464 case V4L2_CID_BLUE_BALANCE:
465 ret = pwc_get_blue_gain(pdev, &c->value);
466 if (ret<0)
467 return -EINVAL;
468 c->value >>= 8;
469 return 0;
470 case V4L2_CID_AUTO_WHITE_BALANCE:
471 ret = pwc_get_awb(pdev);
472 if (ret<0)
473 return -EINVAL;
474 c->value = (ret == PWC_WB_MANUAL)?0:1;
475 return 0;
476 case V4L2_CID_GAIN:
477 ret = pwc_get_agc(pdev, &c->value);
478 if (ret<0)
479 return -EINVAL;
480 c->value >>= 8;
481 return 0;
482 case V4L2_CID_AUTOGAIN:
483 ret = pwc_get_agc(pdev, &c->value);
484 if (ret<0)
485 return -EINVAL;
486 c->value = (c->value < 0)?1:0;
487 return 0;
488 case V4L2_CID_EXPOSURE:
489 ret = pwc_get_shutter_speed(pdev, &c->value);
490 if (ret<0)
491 return -EINVAL;
492 return 0;
493 case V4L2_CID_PRIVATE_COLOUR_MODE:
494 ret = pwc_get_colour_mode(pdev, &c->value);
495 if (ret < 0)
496 return -EINVAL;
497 return 0;
498 case V4L2_CID_PRIVATE_AUTOCONTOUR:
499 ret = pwc_get_contour(pdev, &c->value);
500 if (ret < 0)
501 return -EINVAL;
502 c->value=(c->value == -1?1:0);
503 return 0;
504 case V4L2_CID_PRIVATE_CONTOUR:
505 ret = pwc_get_contour(pdev, &c->value);
506 if (ret < 0)
507 return -EINVAL;
508 c->value >>= 10;
509 return 0;
510 case V4L2_CID_PRIVATE_BACKLIGHT:
511 ret = pwc_get_backlight(pdev, &c->value);
512 if (ret < 0)
513 return -EINVAL;
514 return 0;
515 case V4L2_CID_PRIVATE_FLICKERLESS:
516 ret = pwc_get_flicker(pdev, &c->value);
517 if (ret < 0)
518 return -EINVAL;
519 c->value=(c->value?1:0);
520 return 0;
521 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
522 ret = pwc_get_dynamic_noise(pdev, &c->value);
523 if (ret < 0)
524 return -EINVAL;
525 return 0;
526
527 case V4L2_CID_PRIVATE_SAVE_USER:
528 case V4L2_CID_PRIVATE_RESTORE_USER:
529 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
530 return -EINVAL;
531 }
532 return -EINVAL; 408 return -EINVAL;
533 } 409 return 0;
534 case VIDIOC_S_CTRL: 410 case V4L2_CID_SATURATION:
535 { 411 ret = pwc_get_saturation(pdev, &c->value);
536 struct v4l2_control *c = arg; 412 if (ret < 0)
537 int ret;
538
539 switch (c->id)
540 {
541 case V4L2_CID_BRIGHTNESS:
542 c->value <<= 9;
543 ret = pwc_set_brightness(pdev, c->value);
544 if (ret<0)
545 return -EINVAL;
546 return 0;
547 case V4L2_CID_CONTRAST:
548 c->value <<= 10;
549 ret = pwc_set_contrast(pdev, c->value);
550 if (ret<0)
551 return -EINVAL;
552 return 0;
553 case V4L2_CID_SATURATION:
554 ret = pwc_set_saturation(pdev, c->value);
555 if (ret<0)
556 return -EINVAL;
557 return 0;
558 case V4L2_CID_GAMMA:
559 c->value <<= 11;
560 ret = pwc_set_gamma(pdev, c->value);
561 if (ret<0)
562 return -EINVAL;
563 return 0;
564 case V4L2_CID_RED_BALANCE:
565 c->value <<= 8;
566 ret = pwc_set_red_gain(pdev, c->value);
567 if (ret<0)
568 return -EINVAL;
569 return 0;
570 case V4L2_CID_BLUE_BALANCE:
571 c->value <<= 8;
572 ret = pwc_set_blue_gain(pdev, c->value);
573 if (ret<0)
574 return -EINVAL;
575 return 0;
576 case V4L2_CID_AUTO_WHITE_BALANCE:
577 c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO;
578 ret = pwc_set_awb(pdev, c->value);
579 if (ret<0)
580 return -EINVAL;
581 return 0;
582 case V4L2_CID_EXPOSURE:
583 c->value <<= 8;
584 ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value);
585 if (ret<0)
586 return -EINVAL;
587 return 0;
588 case V4L2_CID_AUTOGAIN:
589 /* autogain off means nothing without a gain */
590 if (c->value == 0)
591 return 0;
592 ret = pwc_set_agc(pdev, c->value, 0);
593 if (ret<0)
594 return -EINVAL;
595 return 0;
596 case V4L2_CID_GAIN:
597 c->value <<= 8;
598 ret = pwc_set_agc(pdev, 0, c->value);
599 if (ret<0)
600 return -EINVAL;
601 return 0;
602 case V4L2_CID_PRIVATE_SAVE_USER:
603 if (pwc_save_user(pdev))
604 return -EINVAL;
605 return 0;
606 case V4L2_CID_PRIVATE_RESTORE_USER:
607 if (pwc_restore_user(pdev))
608 return -EINVAL;
609 return 0;
610 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
611 if (pwc_restore_factory(pdev))
612 return -EINVAL;
613 return 0;
614 case V4L2_CID_PRIVATE_COLOUR_MODE:
615 ret = pwc_set_colour_mode(pdev, c->value);
616 if (ret < 0)
617 return -EINVAL;
618 return 0;
619 case V4L2_CID_PRIVATE_AUTOCONTOUR:
620 c->value=(c->value == 1)?-1:0;
621 ret = pwc_set_contour(pdev, c->value);
622 if (ret < 0)
623 return -EINVAL;
624 return 0;
625 case V4L2_CID_PRIVATE_CONTOUR:
626 c->value <<= 10;
627 ret = pwc_set_contour(pdev, c->value);
628 if (ret < 0)
629 return -EINVAL;
630 return 0;
631 case V4L2_CID_PRIVATE_BACKLIGHT:
632 ret = pwc_set_backlight(pdev, c->value);
633 if (ret < 0)
634 return -EINVAL;
635 return 0;
636 case V4L2_CID_PRIVATE_FLICKERLESS:
637 ret = pwc_set_flicker(pdev, c->value);
638 if (ret < 0)
639 return -EINVAL;
640 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
641 ret = pwc_set_dynamic_noise(pdev, c->value);
642 if (ret < 0)
643 return -EINVAL;
644 return 0;
645
646 }
647 return -EINVAL; 413 return -EINVAL;
648 } 414 return 0;
415 case V4L2_CID_GAMMA:
416 c->value = pwc_get_gamma(pdev);
417 if (c->value < 0)
418 return -EINVAL;
419 return 0;
420 case V4L2_CID_RED_BALANCE:
421 ret = pwc_get_red_gain(pdev, &c->value);
422 if (ret < 0)
423 return -EINVAL;
424 c->value >>= 8;
425 return 0;
426 case V4L2_CID_BLUE_BALANCE:
427 ret = pwc_get_blue_gain(pdev, &c->value);
428 if (ret < 0)
429 return -EINVAL;
430 c->value >>= 8;
431 return 0;
432 case V4L2_CID_AUTO_WHITE_BALANCE:
433 ret = pwc_get_awb(pdev);
434 if (ret < 0)
435 return -EINVAL;
436 c->value = (ret == PWC_WB_MANUAL) ? 0 : 1;
437 return 0;
438 case V4L2_CID_GAIN:
439 ret = pwc_get_agc(pdev, &c->value);
440 if (ret < 0)
441 return -EINVAL;
442 c->value >>= 8;
443 return 0;
444 case V4L2_CID_AUTOGAIN:
445 ret = pwc_get_agc(pdev, &c->value);
446 if (ret < 0)
447 return -EINVAL;
448 c->value = (c->value < 0) ? 1 : 0;
449 return 0;
450 case V4L2_CID_EXPOSURE:
451 ret = pwc_get_shutter_speed(pdev, &c->value);
452 if (ret < 0)
453 return -EINVAL;
454 return 0;
455 case V4L2_CID_PRIVATE_COLOUR_MODE:
456 ret = pwc_get_colour_mode(pdev, &c->value);
457 if (ret < 0)
458 return -EINVAL;
459 return 0;
460 case V4L2_CID_PRIVATE_AUTOCONTOUR:
461 ret = pwc_get_contour(pdev, &c->value);
462 if (ret < 0)
463 return -EINVAL;
464 c->value = (c->value == -1 ? 1 : 0);
465 return 0;
466 case V4L2_CID_PRIVATE_CONTOUR:
467 ret = pwc_get_contour(pdev, &c->value);
468 if (ret < 0)
469 return -EINVAL;
470 c->value >>= 10;
471 return 0;
472 case V4L2_CID_PRIVATE_BACKLIGHT:
473 ret = pwc_get_backlight(pdev, &c->value);
474 if (ret < 0)
475 return -EINVAL;
476 return 0;
477 case V4L2_CID_PRIVATE_FLICKERLESS:
478 ret = pwc_get_flicker(pdev, &c->value);
479 if (ret < 0)
480 return -EINVAL;
481 c->value = (c->value ? 1 : 0);
482 return 0;
483 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
484 ret = pwc_get_dynamic_noise(pdev, &c->value);
485 if (ret < 0)
486 return -EINVAL;
487 return 0;
649 488
650 case VIDIOC_ENUM_FMT: 489 case V4L2_CID_PRIVATE_SAVE_USER:
651 { 490 case V4L2_CID_PRIVATE_RESTORE_USER:
652 struct v4l2_fmtdesc *f = arg; 491 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
653 int index; 492 return -EINVAL;
654 493 }
655 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 494 return -EINVAL;
656 return -EINVAL; 495}
657
658 /* We only support two format: the raw format, and YUV */
659 index = f->index;
660 memset(f,0,sizeof(struct v4l2_fmtdesc));
661 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
662 f->index = index;
663 switch(index)
664 {
665 case 0:
666 /* RAW format */
667 f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2;
668 f->flags = V4L2_FMT_FLAG_COMPRESSED;
669 strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description));
670 break;
671 case 1:
672 f->pixelformat = V4L2_PIX_FMT_YUV420;
673 strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description));
674 break;
675 default:
676 return -EINVAL;
677 }
678 return 0;
679 }
680 496
681 case VIDIOC_G_FMT: 497static int pwc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
682 { 498{
683 struct v4l2_format *f = arg; 499 struct pwc_device *pdev = video_drvdata(file);
500 int ret;
501
502 switch (c->id) {
503 case V4L2_CID_BRIGHTNESS:
504 c->value <<= 9;
505 ret = pwc_set_brightness(pdev, c->value);
506 if (ret < 0)
507 return -EINVAL;
508 return 0;
509 case V4L2_CID_CONTRAST:
510 c->value <<= 10;
511 ret = pwc_set_contrast(pdev, c->value);
512 if (ret < 0)
513 return -EINVAL;
514 return 0;
515 case V4L2_CID_SATURATION:
516 ret = pwc_set_saturation(pdev, c->value);
517 if (ret < 0)
518 return -EINVAL;
519 return 0;
520 case V4L2_CID_GAMMA:
521 c->value <<= 11;
522 ret = pwc_set_gamma(pdev, c->value);
523 if (ret < 0)
524 return -EINVAL;
525 return 0;
526 case V4L2_CID_RED_BALANCE:
527 c->value <<= 8;
528 ret = pwc_set_red_gain(pdev, c->value);
529 if (ret < 0)
530 return -EINVAL;
531 return 0;
532 case V4L2_CID_BLUE_BALANCE:
533 c->value <<= 8;
534 ret = pwc_set_blue_gain(pdev, c->value);
535 if (ret < 0)
536 return -EINVAL;
537 return 0;
538 case V4L2_CID_AUTO_WHITE_BALANCE:
539 c->value = (c->value == 0) ? PWC_WB_MANUAL : PWC_WB_AUTO;
540 ret = pwc_set_awb(pdev, c->value);
541 if (ret < 0)
542 return -EINVAL;
543 return 0;
544 case V4L2_CID_EXPOSURE:
545 c->value <<= 8;
546 ret = pwc_set_shutter_speed(pdev, c->value ? 0 : 1, c->value);
547 if (ret < 0)
548 return -EINVAL;
549 return 0;
550 case V4L2_CID_AUTOGAIN:
551 /* autogain off means nothing without a gain */
552 if (c->value == 0)
553 return 0;
554 ret = pwc_set_agc(pdev, c->value, 0);
555 if (ret < 0)
556 return -EINVAL;
557 return 0;
558 case V4L2_CID_GAIN:
559 c->value <<= 8;
560 ret = pwc_set_agc(pdev, 0, c->value);
561 if (ret < 0)
562 return -EINVAL;
563 return 0;
564 case V4L2_CID_PRIVATE_SAVE_USER:
565 if (pwc_save_user(pdev))
566 return -EINVAL;
567 return 0;
568 case V4L2_CID_PRIVATE_RESTORE_USER:
569 if (pwc_restore_user(pdev))
570 return -EINVAL;
571 return 0;
572 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
573 if (pwc_restore_factory(pdev))
574 return -EINVAL;
575 return 0;
576 case V4L2_CID_PRIVATE_COLOUR_MODE:
577 ret = pwc_set_colour_mode(pdev, c->value);
578 if (ret < 0)
579 return -EINVAL;
580 return 0;
581 case V4L2_CID_PRIVATE_AUTOCONTOUR:
582 c->value = (c->value == 1) ? -1 : 0;
583 ret = pwc_set_contour(pdev, c->value);
584 if (ret < 0)
585 return -EINVAL;
586 return 0;
587 case V4L2_CID_PRIVATE_CONTOUR:
588 c->value <<= 10;
589 ret = pwc_set_contour(pdev, c->value);
590 if (ret < 0)
591 return -EINVAL;
592 return 0;
593 case V4L2_CID_PRIVATE_BACKLIGHT:
594 ret = pwc_set_backlight(pdev, c->value);
595 if (ret < 0)
596 return -EINVAL;
597 return 0;
598 case V4L2_CID_PRIVATE_FLICKERLESS:
599 ret = pwc_set_flicker(pdev, c->value);
600 if (ret < 0)
601 return -EINVAL;
602 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
603 ret = pwc_set_dynamic_noise(pdev, c->value);
604 if (ret < 0)
605 return -EINVAL;
606 return 0;
684 607
685 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y); 608 }
686 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 609 return -EINVAL;
687 return -EINVAL; 610}
688 611
689 pwc_vidioc_fill_fmt(pdev, f); 612static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
613{
614 struct pwc_device *pdev = video_drvdata(file);
615
616 /* We only support two format: the raw format, and YUV */
617 switch (f->index) {
618 case 0:
619 /* RAW format */
620 f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2;
621 f->flags = V4L2_FMT_FLAG_COMPRESSED;
622 strlcpy(f->description, "Raw Philips Webcam", sizeof(f->description));
623 break;
624 case 1:
625 f->pixelformat = V4L2_PIX_FMT_YUV420;
626 strlcpy(f->description, "4:2:0, planar, Y-Cb-Cr", sizeof(f->description));
627 break;
628 default:
629 return -EINVAL;
630 }
631 return 0;
632}
690 633
691 return 0; 634static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
692 } 635{
636 struct pwc_device *pdev = video_drvdata(file);
693 637
694 case VIDIOC_TRY_FMT: 638 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
695 return pwc_vidioc_try_fmt(pdev, arg); 639 pdev->image.x, pdev->image.y);
640 pwc_vidioc_fill_fmt(pdev, f);
641 return 0;
642}
696 643
697 case VIDIOC_S_FMT: 644static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
698 return pwc_vidioc_set_fmt(pdev, arg); 645{
646 struct pwc_device *pdev = video_drvdata(file);
699 647
700 case VIDIOC_G_STD: 648 return pwc_vidioc_try_fmt(pdev, f);
701 { 649}
702 v4l2_std_id *std = arg;
703 *std = V4L2_STD_UNKNOWN;
704 return 0;
705 }
706 650
707 case VIDIOC_S_STD: 651static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
708 { 652{
709 v4l2_std_id *std = arg; 653 struct pwc_device *pdev = video_drvdata(file);
710 if (*std != V4L2_STD_UNKNOWN)
711 return -EINVAL;
712 return 0;
713 }
714 654
715 case VIDIOC_ENUMSTD: 655 return pwc_vidioc_set_fmt(pdev, f);
716 { 656}
717 struct v4l2_standard *std = arg;
718 if (std->index != 0)
719 return -EINVAL;
720 std->id = V4L2_STD_UNKNOWN;
721 strlcpy(std->name, "webcam", sizeof(std->name));
722 return 0;
723 }
724 657
725 case VIDIOC_REQBUFS: 658static int pwc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
726 { 659{
727 struct v4l2_requestbuffers *rb = arg; 660 int nbuffers;
728 int nbuffers;
729 661
730 PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count); 662 PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n", rb->count);
731 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 663 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
732 return -EINVAL; 664 return -EINVAL;
733 if (rb->memory != V4L2_MEMORY_MMAP) 665 if (rb->memory != V4L2_MEMORY_MMAP)
734 return -EINVAL; 666 return -EINVAL;
735 667
736 nbuffers = rb->count; 668 nbuffers = rb->count;
737 if (nbuffers < 2) 669 if (nbuffers < 2)
738 nbuffers = 2; 670 nbuffers = 2;
739 else if (nbuffers > pwc_mbufs) 671 else if (nbuffers > pwc_mbufs)
740 nbuffers = pwc_mbufs; 672 nbuffers = pwc_mbufs;
741 /* Force to use our # of buffers */ 673 /* Force to use our # of buffers */
742 rb->count = pwc_mbufs; 674 rb->count = pwc_mbufs;
743 return 0; 675 return 0;
744 } 676}
745 677
746 case VIDIOC_QUERYBUF: 678static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
747 { 679{
748 struct v4l2_buffer *buf = arg; 680 struct pwc_device *pdev = video_drvdata(file);
749 int index; 681 int index;
750 682
751 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index); 683 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n", buf->index);
752 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 684 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
753 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n"); 685 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n");
754 return -EINVAL; 686 return -EINVAL;
755 } 687 }
756 if (buf->memory != V4L2_MEMORY_MMAP) { 688 index = buf->index;
757 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n"); 689 if (index < 0 || index >= pwc_mbufs) {
758 return -EINVAL; 690 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
759 } 691 return -EINVAL;
760 index = buf->index; 692 }
761 if (index < 0 || index >= pwc_mbufs) {
762 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
763 return -EINVAL;
764 }
765 693
766 memset(buf, 0, sizeof(struct v4l2_buffer)); 694 buf->m.offset = index * pdev->len_per_image;
767 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 695 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
768 buf->index = index; 696 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
769 buf->m.offset = index * pdev->len_per_image; 697 else
770 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) 698 buf->bytesused = pdev->view.size;
771 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); 699 buf->field = V4L2_FIELD_NONE;
772 else 700 buf->memory = V4L2_MEMORY_MMAP;
773 buf->bytesused = pdev->view.size; 701 /*buf->flags = V4L2_BUF_FLAG_MAPPED;*/
774 buf->field = V4L2_FIELD_NONE; 702 buf->length = pdev->len_per_image;
775 buf->memory = V4L2_MEMORY_MMAP;
776 //buf->flags = V4L2_BUF_FLAG_MAPPED;
777 buf->length = pdev->len_per_image;
778
779 PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index);
780 PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset);
781 PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused);
782 703
783 return 0; 704 PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n", buf->index);
784 } 705 PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n", buf->m.offset);
706 PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n", buf->bytesused);
785 707
786 case VIDIOC_QBUF: 708 return 0;
787 { 709}
788 struct v4l2_buffer *buf = arg;
789 710
790 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index); 711static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
791 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 712{
792 return -EINVAL; 713 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n", buf->index);
793 if (buf->memory != V4L2_MEMORY_MMAP) 714 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
794 return -EINVAL; 715 return -EINVAL;
795 if (buf->index >= pwc_mbufs) 716 if (buf->memory != V4L2_MEMORY_MMAP)
796 return -EINVAL; 717 return -EINVAL;
718 if (buf->index >= pwc_mbufs)
719 return -EINVAL;
797 720
798 buf->flags |= V4L2_BUF_FLAG_QUEUED; 721 buf->flags |= V4L2_BUF_FLAG_QUEUED;
799 buf->flags &= ~V4L2_BUF_FLAG_DONE; 722 buf->flags &= ~V4L2_BUF_FLAG_DONE;
800 723
801 return 0; 724 return 0;
802 } 725}
803 726
804 case VIDIOC_DQBUF: 727static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
805 { 728{
806 struct v4l2_buffer *buf = arg; 729 DECLARE_WAITQUEUE(wait, current);
807 int ret; 730 struct pwc_device *pdev = video_drvdata(file);
731 int ret;
808 732
809 PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); 733 PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n");
810 734
811 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 735 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
812 return -EINVAL; 736 return -EINVAL;
813 737
814 /* Add ourselves to the frame wait-queue. 738 add_wait_queue(&pdev->frameq, &wait);
815 739 while (pdev->full_frames == NULL) {
816 FIXME: needs auditing for safety. 740 if (pdev->error_status) {
817 QUESTION: In what respect? I think that using the 741 remove_wait_queue(&pdev->frameq, &wait);
818 frameq is safe now. 742 set_current_state(TASK_RUNNING);
819 */ 743 return -pdev->error_status;
820 add_wait_queue(&pdev->frameq, &wait); 744 }
821 while (pdev->full_frames == NULL) {
822 if (pdev->error_status) {
823 remove_wait_queue(&pdev->frameq, &wait);
824 set_current_state(TASK_RUNNING);
825 return -pdev->error_status;
826 }
827 745
828 if (signal_pending(current)) { 746 if (signal_pending(current)) {
829 remove_wait_queue(&pdev->frameq, &wait);
830 set_current_state(TASK_RUNNING);
831 return -ERESTARTSYS;
832 }
833 schedule();
834 set_current_state(TASK_INTERRUPTIBLE);
835 }
836 remove_wait_queue(&pdev->frameq, &wait); 747 remove_wait_queue(&pdev->frameq, &wait);
837 set_current_state(TASK_RUNNING); 748 set_current_state(TASK_RUNNING);
749 return -ERESTARTSYS;
750 }
751 mutex_unlock(&pdev->modlock);
752 schedule();
753 set_current_state(TASK_INTERRUPTIBLE);
754 mutex_lock(&pdev->modlock);
755 }
756 remove_wait_queue(&pdev->frameq, &wait);
757 set_current_state(TASK_RUNNING);
838 758
839 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n"); 759 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n");
840 /* Decompress data in pdev->images[pdev->fill_image] */ 760 /* Decompress data in pdev->images[pdev->fill_image] */
841 ret = pwc_handle_frame(pdev); 761 ret = pwc_handle_frame(pdev);
842 if (ret) 762 if (ret)
843 return -EFAULT; 763 return -EFAULT;
844 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); 764 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n");
845 765
846 buf->index = pdev->fill_image; 766 buf->index = pdev->fill_image;
847 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) 767 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
848 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); 768 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
849 else 769 else
850 buf->bytesused = pdev->view.size; 770 buf->bytesused = pdev->view.size;
851 buf->flags = V4L2_BUF_FLAG_MAPPED; 771 buf->flags = V4L2_BUF_FLAG_MAPPED;
852 buf->field = V4L2_FIELD_NONE; 772 buf->field = V4L2_FIELD_NONE;
853 do_gettimeofday(&buf->timestamp); 773 do_gettimeofday(&buf->timestamp);
854 buf->sequence = 0; 774 buf->sequence = 0;
855 buf->memory = V4L2_MEMORY_MMAP; 775 buf->memory = V4L2_MEMORY_MMAP;
856 buf->m.offset = pdev->fill_image * pdev->len_per_image; 776 buf->m.offset = pdev->fill_image * pdev->len_per_image;
857 buf->length = pdev->len_per_image; 777 buf->length = pdev->len_per_image;
858 pwc_next_image(pdev); 778 pwc_next_image(pdev);
859 779
860 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index); 780 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n", buf->index);
861 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length); 781 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n", buf->length);
862 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset); 782 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n", buf->m.offset);
863 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused); 783 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n", buf->bytesused);
864 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n"); 784 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n");
865 return 0; 785 return 0;
866 786
867 } 787}
868 788
869 case VIDIOC_STREAMON: 789static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
870 { 790{
871 return pwc_isoc_init(pdev); 791 struct pwc_device *pdev = video_drvdata(file);
872 }
873 792
874 case VIDIOC_STREAMOFF: 793 return pwc_isoc_init(pdev);
875 { 794}
876 pwc_isoc_cleanup(pdev);
877 return 0;
878 }
879 795
880 case VIDIOC_ENUM_FRAMESIZES: 796static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
881 { 797{
882 struct v4l2_frmsizeenum *fsize = arg; 798 struct pwc_device *pdev = video_drvdata(file);
883 unsigned int i = 0, index = fsize->index;
884
885 if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
886 for (i = 0; i < PSZ_MAX; i++) {
887 if (pdev->image_mask & (1UL << i)) {
888 if (!index--) {
889 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
890 fsize->discrete.width = pwc_image_sizes[i].x;
891 fsize->discrete.height = pwc_image_sizes[i].y;
892 return 0;
893 }
894 }
895 }
896 } else if (fsize->index == 0 &&
897 ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
898 (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
899
900 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
901 fsize->discrete.width = pdev->abs_max.x;
902 fsize->discrete.height = pdev->abs_max.y;
903 return 0;
904 }
905 return -EINVAL;
906 }
907 799
908 case VIDIOC_ENUM_FRAMEINTERVALS: 800 pwc_isoc_cleanup(pdev);
909 { 801 return 0;
910 struct v4l2_frmivalenum *fival = arg; 802}
911 int size = -1; 803
912 unsigned int i; 804static int pwc_enum_framesizes(struct file *file, void *fh,
913 805 struct v4l2_frmsizeenum *fsize)
914 for (i = 0; i < PSZ_MAX; i++) { 806{
915 if (pwc_image_sizes[i].x == fival->width && 807 struct pwc_device *pdev = video_drvdata(file);
916 pwc_image_sizes[i].y == fival->height) { 808 unsigned int i = 0, index = fsize->index;
917 size = i; 809
918 break; 810 if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
811 for (i = 0; i < PSZ_MAX; i++) {
812 if (pdev->image_mask & (1UL << i)) {
813 if (!index--) {
814 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
815 fsize->discrete.width = pwc_image_sizes[i].x;
816 fsize->discrete.height = pwc_image_sizes[i].y;
817 return 0;
919 } 818 }
920 } 819 }
820 }
821 } else if (fsize->index == 0 &&
822 ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
823 (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
824
825 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
826 fsize->discrete.width = pdev->abs_max.x;
827 fsize->discrete.height = pdev->abs_max.y;
828 return 0;
829 }
830 return -EINVAL;
831}
921 832
922 /* TODO: Support raw format */ 833static int pwc_enum_frameintervals(struct file *file, void *fh,
923 if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) { 834 struct v4l2_frmivalenum *fival)
924 return -EINVAL; 835{
925 } 836 struct pwc_device *pdev = video_drvdata(file);
837 int size = -1;
838 unsigned int i;
839
840 for (i = 0; i < PSZ_MAX; i++) {
841 if (pwc_image_sizes[i].x == fival->width &&
842 pwc_image_sizes[i].y == fival->height) {
843 size = i;
844 break;
845 }
846 }
926 847
927 i = pwc_get_fps(pdev, fival->index, size); 848 /* TODO: Support raw format */
928 if (!i) 849 if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420)
929 return -EINVAL; 850 return -EINVAL;
930 851
931 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 852 i = pwc_get_fps(pdev, fival->index, size);
932 fival->discrete.numerator = 1; 853 if (!i)
933 fival->discrete.denominator = i; 854 return -EINVAL;
934 855
935 return 0; 856 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
936 } 857 fival->discrete.numerator = 1;
858 fival->discrete.denominator = i;
937 859
938 default:
939 return pwc_ioctl(pdev, cmd, arg);
940 } /* ..switch */
941 return 0; 860 return 0;
942} 861}
943 862
863static long pwc_default(struct file *file, void *fh, bool valid_prio,
864 int cmd, void *arg)
865{
866 struct pwc_device *pdev = video_drvdata(file);
867
868 return pwc_ioctl(pdev, cmd, arg);
869}
870
871const struct v4l2_ioctl_ops pwc_ioctl_ops = {
872 .vidioc_querycap = pwc_querycap,
873 .vidioc_enum_input = pwc_enum_input,
874 .vidioc_g_input = pwc_g_input,
875 .vidioc_s_input = pwc_s_input,
876 .vidioc_enum_fmt_vid_cap = pwc_enum_fmt_vid_cap,
877 .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap,
878 .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap,
879 .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap,
880 .vidioc_queryctrl = pwc_queryctrl,
881 .vidioc_g_ctrl = pwc_g_ctrl,
882 .vidioc_s_ctrl = pwc_s_ctrl,
883 .vidioc_reqbufs = pwc_reqbufs,
884 .vidioc_querybuf = pwc_querybuf,
885 .vidioc_qbuf = pwc_qbuf,
886 .vidioc_dqbuf = pwc_dqbuf,
887 .vidioc_streamon = pwc_streamon,
888 .vidioc_streamoff = pwc_streamoff,
889 .vidioc_enum_framesizes = pwc_enum_framesizes,
890 .vidioc_enum_frameintervals = pwc_enum_frameintervals,
891 .vidioc_default = pwc_default,
892};
893
894
944/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ 895/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 16bbc6df9b07..e947766337d6 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -339,8 +339,7 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power);
339/* Private ioctl()s; see pwc-ioctl.h */ 339/* Private ioctl()s; see pwc-ioctl.h */
340extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); 340extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
341 341
342/** Functions in pwc-v4l.c */ 342extern const struct v4l2_ioctl_ops pwc_ioctl_ops;
343extern long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
344 343
345/** pwc-uncompress.c */ 344/** pwc-uncompress.c */
346/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ 345/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 2f500809f53d..95f8b4e11e46 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -27,13 +27,13 @@
27#include <media/v4l2-device.h> 27#include <media/v4l2-device.h>
28#include <media/v4l2-ioctl.h> 28#include <media/v4l2-ioctl.h>
29#include <media/v4l2-mem2mem.h> 29#include <media/v4l2-mem2mem.h>
30#include <media/videobuf-core.h> 30#include <media/videobuf2-core.h>
31#include <media/videobuf-dma-contig.h> 31#include <media/videobuf2-dma-contig.h>
32 32
33#include "fimc-core.h" 33#include "fimc-core.h"
34 34
35static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc, 35static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
36 struct s3c_fimc_isp_info *isp_info) 36 struct s5p_fimc_isp_info *isp_info)
37{ 37{
38 struct i2c_adapter *i2c_adap; 38 struct i2c_adapter *i2c_adap;
39 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; 39 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
@@ -86,19 +86,19 @@ static void fimc_subdev_unregister(struct fimc_dev *fimc)
86static int fimc_subdev_attach(struct fimc_dev *fimc, int index) 86static int fimc_subdev_attach(struct fimc_dev *fimc, int index)
87{ 87{
88 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; 88 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
89 struct s3c_platform_fimc *pdata = fimc->pdata; 89 struct s5p_platform_fimc *pdata = fimc->pdata;
90 struct s3c_fimc_isp_info *isp_info; 90 struct s5p_fimc_isp_info *isp_info;
91 struct v4l2_subdev *sd; 91 struct v4l2_subdev *sd;
92 int i; 92 int i;
93 93
94 for (i = 0; i < FIMC_MAX_CAMIF_CLIENTS; ++i) { 94 for (i = 0; i < pdata->num_clients; ++i) {
95 isp_info = pdata->isp_info[i]; 95 isp_info = &pdata->isp_info[i];
96 96
97 if (!isp_info || (index >= 0 && i != index)) 97 if (index >= 0 && i != index)
98 continue; 98 continue;
99 99
100 sd = fimc_subdev_register(fimc, isp_info); 100 sd = fimc_subdev_register(fimc, isp_info);
101 if (sd) { 101 if (!IS_ERR_OR_NULL(sd)) {
102 vid_cap->sd = sd; 102 vid_cap->sd = sd;
103 vid_cap->input_index = i; 103 vid_cap->input_index = i;
104 104
@@ -113,60 +113,42 @@ static int fimc_subdev_attach(struct fimc_dev *fimc, int index)
113 return -ENODEV; 113 return -ENODEV;
114} 114}
115 115
116static int fimc_isp_subdev_init(struct fimc_dev *fimc, int index) 116static int fimc_isp_subdev_init(struct fimc_dev *fimc, unsigned int index)
117{ 117{
118 struct s3c_fimc_isp_info *isp_info; 118 struct s5p_fimc_isp_info *isp_info;
119 struct s5p_platform_fimc *pdata = fimc->pdata;
119 int ret; 120 int ret;
120 121
121 ret = fimc_subdev_attach(fimc, index); 122 if (index >= pdata->num_clients)
122 if (ret) 123 return -EINVAL;
123 return ret;
124 124
125 isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index]; 125 isp_info = &pdata->isp_info[index];
126 ret = fimc_hw_set_camera_polarity(fimc, isp_info);
127 if (!ret) {
128 ret = v4l2_subdev_call(fimc->vid_cap.sd, core,
129 s_power, 1);
130 if (!ret)
131 return ret;
132 }
133 126
134 fimc_subdev_unregister(fimc); 127 if (isp_info->clk_frequency)
135 err("ISP initialization failed: %d", ret); 128 clk_set_rate(fimc->clock[CLK_CAM], isp_info->clk_frequency);
136 return ret;
137}
138 129
139/* 130 ret = clk_enable(fimc->clock[CLK_CAM]);
140 * At least one buffer on the pending_buf_q queue is required. 131 if (ret)
141 * Locking: The caller holds fimc->slock spinlock. 132 return ret;
142 */
143int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
144 struct fimc_vid_buffer *fimc_vb)
145{
146 struct fimc_vid_cap *cap = &fimc->vid_cap;
147 struct fimc_ctx *ctx = cap->ctx;
148 int ret = 0;
149 133
150 BUG_ON(!fimc || !fimc_vb); 134 ret = fimc_subdev_attach(fimc, index);
135 if (ret)
136 return ret;
151 137
152 ret = fimc_prepare_addr(ctx, fimc_vb, &ctx->d_frame, 138 ret = fimc_hw_set_camera_polarity(fimc, isp_info);
153 &fimc_vb->paddr);
154 if (ret) 139 if (ret)
155 return ret; 140 return ret;
156 141
157 if (test_bit(ST_CAPT_STREAM, &fimc->state)) { 142 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 1);
158 fimc_pending_queue_add(cap, fimc_vb); 143 if (!ret)
159 } else { 144 return ret;
160 /* Setup the buffer directly for processing. */ 145
161 int buf_id = (cap->reqbufs_count == 1) ? -1 : cap->buf_index; 146 /* enabling power failed so unregister subdev */
162 fimc_hw_set_output_addr(fimc, &fimc_vb->paddr, buf_id); 147 fimc_subdev_unregister(fimc);
163 148
164 fimc_vb->index = cap->buf_index; 149 v4l2_err(&fimc->vid_cap.v4l2_dev, "ISP initialization failed: %d\n",
165 active_queue_add(cap, fimc_vb); 150 ret);
166 151
167 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
168 cap->buf_index = 0;
169 }
170 return ret; 152 return ret;
171} 153}
172 154
@@ -174,7 +156,7 @@ static int fimc_stop_capture(struct fimc_dev *fimc)
174{ 156{
175 unsigned long flags; 157 unsigned long flags;
176 struct fimc_vid_cap *cap; 158 struct fimc_vid_cap *cap;
177 int ret; 159 struct fimc_vid_buffer *buf;
178 160
179 cap = &fimc->vid_cap; 161 cap = &fimc->vid_cap;
180 162
@@ -187,24 +169,224 @@ static int fimc_stop_capture(struct fimc_dev *fimc)
187 spin_unlock_irqrestore(&fimc->slock, flags); 169 spin_unlock_irqrestore(&fimc->slock, flags);
188 170
189 wait_event_timeout(fimc->irq_queue, 171 wait_event_timeout(fimc->irq_queue,
190 test_bit(ST_CAPT_SHUT, &fimc->state), 172 !test_bit(ST_CAPT_SHUT, &fimc->state),
191 FIMC_SHUTDOWN_TIMEOUT); 173 FIMC_SHUTDOWN_TIMEOUT);
192 174
193 ret = v4l2_subdev_call(cap->sd, video, s_stream, 0); 175 v4l2_subdev_call(cap->sd, video, s_stream, 0);
194 if (ret)
195 v4l2_err(&fimc->vid_cap.v4l2_dev, "s_stream(0) failed\n");
196 176
197 spin_lock_irqsave(&fimc->slock, flags); 177 spin_lock_irqsave(&fimc->slock, flags);
198 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND | 178 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND |
199 1 << ST_CAPT_STREAM); 179 1 << ST_CAPT_SHUT | 1 << ST_CAPT_STREAM);
200 180
201 fimc->vid_cap.active_buf_cnt = 0; 181 fimc->vid_cap.active_buf_cnt = 0;
182
183 /* Release buffers that were enqueued in the driver by videobuf2. */
184 while (!list_empty(&cap->pending_buf_q)) {
185 buf = pending_queue_pop(cap);
186 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
187 }
188
189 while (!list_empty(&cap->active_buf_q)) {
190 buf = active_queue_pop(cap);
191 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
192 }
193
202 spin_unlock_irqrestore(&fimc->slock, flags); 194 spin_unlock_irqrestore(&fimc->slock, flags);
203 195
204 dbg("state: 0x%lx", fimc->state); 196 dbg("state: 0x%lx", fimc->state);
205 return 0; 197 return 0;
206} 198}
207 199
200static int start_streaming(struct vb2_queue *q)
201{
202 struct fimc_ctx *ctx = q->drv_priv;
203 struct fimc_dev *fimc = ctx->fimc_dev;
204 struct s5p_fimc_isp_info *isp_info;
205 int ret;
206
207 fimc_hw_reset(fimc);
208
209 ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
210 if (ret && ret != -ENOIOCTLCMD)
211 return ret;
212
213 ret = fimc_prepare_config(ctx, ctx->state);
214 if (ret)
215 return ret;
216
217 isp_info = &fimc->pdata->isp_info[fimc->vid_cap.input_index];
218 fimc_hw_set_camera_type(fimc, isp_info);
219 fimc_hw_set_camera_source(fimc, isp_info);
220 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
221
222 if (ctx->state & FIMC_PARAMS) {
223 ret = fimc_set_scaler_info(ctx);
224 if (ret) {
225 err("Scaler setup error");
226 return ret;
227 }
228 fimc_hw_set_input_path(ctx);
229 fimc_hw_set_prescaler(ctx);
230 fimc_hw_set_mainscaler(ctx);
231 fimc_hw_set_target_format(ctx);
232 fimc_hw_set_rotation(ctx);
233 fimc_hw_set_effect(ctx);
234 }
235
236 fimc_hw_set_output_path(ctx);
237 fimc_hw_set_out_dma(ctx);
238
239 INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
240 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
241 fimc->vid_cap.active_buf_cnt = 0;
242 fimc->vid_cap.frame_count = 0;
243 fimc->vid_cap.buf_index = 0;
244
245 set_bit(ST_CAPT_PEND, &fimc->state);
246
247 return 0;
248}
249
250static int stop_streaming(struct vb2_queue *q)
251{
252 struct fimc_ctx *ctx = q->drv_priv;
253 struct fimc_dev *fimc = ctx->fimc_dev;
254
255 if (!fimc_capture_active(fimc))
256 return -EINVAL;
257
258 return fimc_stop_capture(fimc);
259}
260
261static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
262{
263 if (!fr || plane >= fr->fmt->memplanes)
264 return 0;
265
266 dbg("%s: w: %d. h: %d. depth[%d]: %d",
267 __func__, fr->width, fr->height, plane, fr->fmt->depth[plane]);
268
269 return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
270
271}
272
273static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
274 unsigned int *num_planes, unsigned long sizes[],
275 void *allocators[])
276{
277 struct fimc_ctx *ctx = vq->drv_priv;
278 struct fimc_fmt *fmt = ctx->d_frame.fmt;
279 int i;
280
281 if (!fmt)
282 return -EINVAL;
283
284 *num_planes = fmt->memplanes;
285
286 dbg("%s, buffer count=%d, plane count=%d",
287 __func__, *num_buffers, *num_planes);
288
289 for (i = 0; i < fmt->memplanes; i++) {
290 sizes[i] = get_plane_size(&ctx->d_frame, i);
291 dbg("plane: %u, plane_size: %lu", i, sizes[i]);
292 allocators[i] = ctx->fimc_dev->alloc_ctx;
293 }
294
295 return 0;
296}
297
298static int buffer_init(struct vb2_buffer *vb)
299{
300 /* TODO: */
301 return 0;
302}
303
304static int buffer_prepare(struct vb2_buffer *vb)
305{
306 struct vb2_queue *vq = vb->vb2_queue;
307 struct fimc_ctx *ctx = vq->drv_priv;
308 struct v4l2_device *v4l2_dev = &ctx->fimc_dev->m2m.v4l2_dev;
309 int i;
310
311 if (!ctx->d_frame.fmt || vq->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
312 return -EINVAL;
313
314 for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) {
315 unsigned long size = get_plane_size(&ctx->d_frame, i);
316
317 if (vb2_plane_size(vb, i) < size) {
318 v4l2_err(v4l2_dev, "User buffer too small (%ld < %ld)\n",
319 vb2_plane_size(vb, i), size);
320 return -EINVAL;
321 }
322
323 vb2_set_plane_payload(vb, i, size);
324 }
325
326 return 0;
327}
328
329static void buffer_queue(struct vb2_buffer *vb)
330{
331 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
332 struct fimc_dev *fimc = ctx->fimc_dev;
333 struct fimc_vid_buffer *buf
334 = container_of(vb, struct fimc_vid_buffer, vb);
335 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
336 unsigned long flags;
337 int min_bufs;
338
339 spin_lock_irqsave(&fimc->slock, flags);
340 fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);
341
342 if (!test_bit(ST_CAPT_STREAM, &fimc->state)
343 && vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
344 /* Setup the buffer directly for processing. */
345 int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
346 vid_cap->buf_index;
347
348 fimc_hw_set_output_addr(fimc, &buf->paddr, buf_id);
349 buf->index = vid_cap->buf_index;
350 active_queue_add(vid_cap, buf);
351
352 if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
353 vid_cap->buf_index = 0;
354 } else {
355 fimc_pending_queue_add(vid_cap, buf);
356 }
357
358 min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
359
360 if (vid_cap->active_buf_cnt >= min_bufs &&
361 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state))
362 fimc_activate_capture(ctx);
363
364 spin_unlock_irqrestore(&fimc->slock, flags);
365}
366
367static void fimc_lock(struct vb2_queue *vq)
368{
369 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
370 mutex_lock(&ctx->fimc_dev->lock);
371}
372
373static void fimc_unlock(struct vb2_queue *vq)
374{
375 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
376 mutex_unlock(&ctx->fimc_dev->lock);
377}
378
379static struct vb2_ops fimc_capture_qops = {
380 .queue_setup = queue_setup,
381 .buf_prepare = buffer_prepare,
382 .buf_queue = buffer_queue,
383 .buf_init = buffer_init,
384 .wait_prepare = fimc_unlock,
385 .wait_finish = fimc_lock,
386 .start_streaming = start_streaming,
387 .stop_streaming = stop_streaming,
388};
389
208static int fimc_capture_open(struct file *file) 390static int fimc_capture_open(struct file *file)
209{ 391{
210 struct fimc_dev *fimc = video_drvdata(file); 392 struct fimc_dev *fimc = video_drvdata(file);
@@ -216,44 +398,36 @@ static int fimc_capture_open(struct file *file)
216 if (fimc_m2m_active(fimc)) 398 if (fimc_m2m_active(fimc))
217 return -EBUSY; 399 return -EBUSY;
218 400
219 if (mutex_lock_interruptible(&fimc->lock))
220 return -ERESTARTSYS;
221
222 if (++fimc->vid_cap.refcnt == 1) { 401 if (++fimc->vid_cap.refcnt == 1) {
223 ret = fimc_isp_subdev_init(fimc, -1); 402 ret = fimc_isp_subdev_init(fimc, 0);
224 if (ret) { 403 if (ret) {
225 fimc->vid_cap.refcnt--; 404 fimc->vid_cap.refcnt--;
226 ret = -EIO; 405 return -EIO;
227 } 406 }
228 } 407 }
229 408
230 file->private_data = fimc->vid_cap.ctx; 409 file->private_data = fimc->vid_cap.ctx;
231 410
232 mutex_unlock(&fimc->lock); 411 return 0;
233 return ret;
234} 412}
235 413
236static int fimc_capture_close(struct file *file) 414static int fimc_capture_close(struct file *file)
237{ 415{
238 struct fimc_dev *fimc = video_drvdata(file); 416 struct fimc_dev *fimc = video_drvdata(file);
239 417
240 if (mutex_lock_interruptible(&fimc->lock))
241 return -ERESTARTSYS;
242
243 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); 418 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
244 419
245 if (--fimc->vid_cap.refcnt == 0) { 420 if (--fimc->vid_cap.refcnt == 0) {
246 fimc_stop_capture(fimc); 421 fimc_stop_capture(fimc);
247 422 vb2_queue_release(&fimc->vid_cap.vbq);
248 videobuf_stop(&fimc->vid_cap.vbq);
249 videobuf_mmap_free(&fimc->vid_cap.vbq);
250 423
251 v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n"); 424 v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n");
425
252 v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); 426 v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0);
427 clk_disable(fimc->clock[CLK_CAM]);
253 fimc_subdev_unregister(fimc); 428 fimc_subdev_unregister(fimc);
254 } 429 }
255 430
256 mutex_unlock(&fimc->lock);
257 return 0; 431 return 0;
258} 432}
259 433
@@ -262,32 +436,16 @@ static unsigned int fimc_capture_poll(struct file *file,
262{ 436{
263 struct fimc_ctx *ctx = file->private_data; 437 struct fimc_ctx *ctx = file->private_data;
264 struct fimc_dev *fimc = ctx->fimc_dev; 438 struct fimc_dev *fimc = ctx->fimc_dev;
265 struct fimc_vid_cap *cap = &fimc->vid_cap;
266 int ret;
267
268 if (mutex_lock_interruptible(&fimc->lock))
269 return POLLERR;
270 439
271 ret = videobuf_poll_stream(file, &cap->vbq, wait); 440 return vb2_poll(&fimc->vid_cap.vbq, file, wait);
272 mutex_unlock(&fimc->lock);
273
274 return ret;
275} 441}
276 442
277static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) 443static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
278{ 444{
279 struct fimc_ctx *ctx = file->private_data; 445 struct fimc_ctx *ctx = file->private_data;
280 struct fimc_dev *fimc = ctx->fimc_dev; 446 struct fimc_dev *fimc = ctx->fimc_dev;
281 struct fimc_vid_cap *cap = &fimc->vid_cap;
282 int ret;
283
284 if (mutex_lock_interruptible(&fimc->lock))
285 return -ERESTARTSYS;
286 447
287 ret = videobuf_mmap_mapper(&cap->vbq, vma); 448 return vb2_mmap(&fimc->vid_cap.vbq, vma);
288 mutex_unlock(&fimc->lock);
289
290 return ret;
291} 449}
292 450
293/* video device file operations */ 451/* video device file operations */
@@ -310,7 +468,8 @@ static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
310 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1); 468 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
311 cap->bus_info[0] = 0; 469 cap->bus_info[0] = 0;
312 cap->version = KERNEL_VERSION(1, 0, 0); 470 cap->version = KERNEL_VERSION(1, 0, 0);
313 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; 471 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
472 V4L2_CAP_VIDEO_CAPTURE_MPLANE;
314 473
315 return 0; 474 return 0;
316} 475}
@@ -351,57 +510,52 @@ static int sync_capture_fmt(struct fimc_ctx *ctx)
351 return 0; 510 return 0;
352} 511}
353 512
354static int fimc_cap_s_fmt(struct file *file, void *priv, 513static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
355 struct v4l2_format *f) 514 struct v4l2_format *f)
356{ 515{
357 struct fimc_ctx *ctx = priv; 516 struct fimc_ctx *ctx = priv;
358 struct fimc_dev *fimc = ctx->fimc_dev; 517 struct fimc_dev *fimc = ctx->fimc_dev;
359 struct fimc_frame *frame; 518 struct fimc_frame *frame;
360 struct v4l2_pix_format *pix; 519 struct v4l2_pix_format_mplane *pix;
361 int ret; 520 int ret;
521 int i;
362 522
363 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 523 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
364 return -EINVAL; 524 return -EINVAL;
365 525
366 ret = fimc_vidioc_try_fmt(file, priv, f); 526 ret = fimc_vidioc_try_fmt_mplane(file, priv, f);
367 if (ret) 527 if (ret)
368 return ret; 528 return ret;
369 529
370 if (mutex_lock_interruptible(&fimc->lock)) 530 if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc))
371 return -ERESTARTSYS; 531 return -EBUSY;
372
373 if (fimc_capture_active(fimc)) {
374 ret = -EBUSY;
375 goto sf_unlock;
376 }
377 532
378 frame = &ctx->d_frame; 533 frame = &ctx->d_frame;
379 534
380 pix = &f->fmt.pix; 535 pix = &f->fmt.pix_mp;
381 frame->fmt = find_format(f, FMT_FLAGS_M2M | FMT_FLAGS_CAM); 536 frame->fmt = find_format(f, FMT_FLAGS_M2M | FMT_FLAGS_CAM);
382 if (!frame->fmt) { 537 if (!frame->fmt) {
383 err("fimc target format not found\n"); 538 err("fimc target format not found\n");
384 ret = -EINVAL; 539 return -EINVAL;
385 goto sf_unlock;
386 } 540 }
387 541
542 for (i = 0; i < frame->fmt->colplanes; i++)
543 frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height;
544
388 /* Output DMA frame pixel size and offsets. */ 545 /* Output DMA frame pixel size and offsets. */
389 frame->f_width = pix->bytesperline * 8 / frame->fmt->depth; 546 frame->f_width = pix->plane_fmt[0].bytesperline * 8
547 / frame->fmt->depth[0];
390 frame->f_height = pix->height; 548 frame->f_height = pix->height;
391 frame->width = pix->width; 549 frame->width = pix->width;
392 frame->height = pix->height; 550 frame->height = pix->height;
393 frame->o_width = pix->width; 551 frame->o_width = pix->width;
394 frame->o_height = pix->height; 552 frame->o_height = pix->height;
395 frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3;
396 frame->offs_h = 0; 553 frame->offs_h = 0;
397 frame->offs_v = 0; 554 frame->offs_v = 0;
398 555
399 ret = sync_capture_fmt(ctx);
400
401 ctx->state |= (FIMC_PARAMS | FIMC_DST_FMT); 556 ctx->state |= (FIMC_PARAMS | FIMC_DST_FMT);
402 557
403sf_unlock: 558 ret = sync_capture_fmt(ctx);
404 mutex_unlock(&fimc->lock);
405 return ret; 559 return ret;
406} 560}
407 561
@@ -409,15 +563,13 @@ static int fimc_cap_enum_input(struct file *file, void *priv,
409 struct v4l2_input *i) 563 struct v4l2_input *i)
410{ 564{
411 struct fimc_ctx *ctx = priv; 565 struct fimc_ctx *ctx = priv;
412 struct s3c_platform_fimc *pldata = ctx->fimc_dev->pdata; 566 struct s5p_platform_fimc *pldata = ctx->fimc_dev->pdata;
413 struct s3c_fimc_isp_info *isp_info; 567 struct s5p_fimc_isp_info *isp_info;
414 568
415 if (i->index >= FIMC_MAX_CAMIF_CLIENTS) 569 if (i->index >= pldata->num_clients)
416 return -EINVAL; 570 return -EINVAL;
417 571
418 isp_info = pldata->isp_info[i->index]; 572 isp_info = &pldata->isp_info[i->index];
419 if (isp_info == NULL)
420 return -EINVAL;
421 573
422 i->type = V4L2_INPUT_TYPE_CAMERA; 574 i->type = V4L2_INPUT_TYPE_CAMERA;
423 strncpy(i->name, isp_info->board_info->type, 32); 575 strncpy(i->name, isp_info->board_info->type, 32);
@@ -429,34 +581,27 @@ static int fimc_cap_s_input(struct file *file, void *priv,
429{ 581{
430 struct fimc_ctx *ctx = priv; 582 struct fimc_ctx *ctx = priv;
431 struct fimc_dev *fimc = ctx->fimc_dev; 583 struct fimc_dev *fimc = ctx->fimc_dev;
432 struct s3c_platform_fimc *pdata = fimc->pdata; 584 struct s5p_platform_fimc *pdata = fimc->pdata;
433 int ret;
434 585
435 if (fimc_capture_active(ctx->fimc_dev)) 586 if (fimc_capture_active(ctx->fimc_dev))
436 return -EBUSY; 587 return -EBUSY;
437 588
438 if (mutex_lock_interruptible(&fimc->lock)) 589 if (i >= pdata->num_clients)
439 return -ERESTARTSYS; 590 return -EINVAL;
440 591
441 if (i >= FIMC_MAX_CAMIF_CLIENTS || !pdata->isp_info[i]) {
442 ret = -EINVAL;
443 goto si_unlock;
444 }
445 592
446 if (fimc->vid_cap.sd) { 593 if (fimc->vid_cap.sd) {
447 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); 594 int ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0);
448 if (ret) 595 if (ret)
449 err("s_power failed: %d", ret); 596 err("s_power failed: %d", ret);
597
598 clk_disable(fimc->clock[CLK_CAM]);
450 } 599 }
451 600
452 /* Release the attached sensor subdevice. */ 601 /* Release the attached sensor subdevice. */
453 fimc_subdev_unregister(fimc); 602 fimc_subdev_unregister(fimc);
454 603
455 ret = fimc_isp_subdev_init(fimc, i); 604 return fimc_isp_subdev_init(fimc, i);
456
457si_unlock:
458 mutex_unlock(&fimc->lock);
459 return ret;
460} 605}
461 606
462static int fimc_cap_g_input(struct file *file, void *priv, 607static int fimc_cap_g_input(struct file *file, void *priv,
@@ -470,66 +615,20 @@ static int fimc_cap_g_input(struct file *file, void *priv,
470} 615}
471 616
472static int fimc_cap_streamon(struct file *file, void *priv, 617static int fimc_cap_streamon(struct file *file, void *priv,
473 enum v4l2_buf_type type) 618 enum v4l2_buf_type type)
474{ 619{
475 struct s3c_fimc_isp_info *isp_info;
476 struct fimc_ctx *ctx = priv; 620 struct fimc_ctx *ctx = priv;
477 struct fimc_dev *fimc = ctx->fimc_dev; 621 struct fimc_dev *fimc = ctx->fimc_dev;
478 int ret = -EBUSY;
479
480 if (mutex_lock_interruptible(&fimc->lock))
481 return -ERESTARTSYS;
482 622
483 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd) 623 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd)
484 goto s_unlock; 624 return -EBUSY;
485 625
486 if (!(ctx->state & FIMC_DST_FMT)) { 626 if (!(ctx->state & FIMC_DST_FMT)) {
487 v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n"); 627 v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n");
488 ret = -EINVAL; 628 return -EINVAL;
489 goto s_unlock;
490 }
491
492 ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
493 if (ret && ret != -ENOIOCTLCMD)
494 goto s_unlock;
495
496 ret = fimc_prepare_config(ctx, ctx->state);
497 if (ret)
498 goto s_unlock;
499
500 isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index];
501 fimc_hw_set_camera_type(fimc, isp_info);
502 fimc_hw_set_camera_source(fimc, isp_info);
503 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
504
505 if (ctx->state & FIMC_PARAMS) {
506 ret = fimc_set_scaler_info(ctx);
507 if (ret) {
508 err("Scaler setup error");
509 goto s_unlock;
510 }
511 fimc_hw_set_input_path(ctx);
512 fimc_hw_set_scaler(ctx);
513 fimc_hw_set_target_format(ctx);
514 fimc_hw_set_rotation(ctx);
515 fimc_hw_set_effect(ctx);
516 } 629 }
517 630
518 fimc_hw_set_output_path(ctx); 631 return vb2_streamon(&fimc->vid_cap.vbq, type);
519 fimc_hw_set_out_dma(ctx);
520
521 INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
522 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
523 fimc->vid_cap.active_buf_cnt = 0;
524 fimc->vid_cap.frame_count = 0;
525 fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc);
526
527 set_bit(ST_CAPT_PEND, &fimc->state);
528 ret = videobuf_streamon(&fimc->vid_cap.vbq);
529
530s_unlock:
531 mutex_unlock(&fimc->lock);
532 return ret;
533} 632}
534 633
535static int fimc_cap_streamoff(struct file *file, void *priv, 634static int fimc_cap_streamoff(struct file *file, void *priv,
@@ -537,46 +636,22 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
537{ 636{
538 struct fimc_ctx *ctx = priv; 637 struct fimc_ctx *ctx = priv;
539 struct fimc_dev *fimc = ctx->fimc_dev; 638 struct fimc_dev *fimc = ctx->fimc_dev;
540 struct fimc_vid_cap *cap = &fimc->vid_cap;
541 unsigned long flags;
542 int ret;
543
544 spin_lock_irqsave(&fimc->slock, flags);
545 if (!fimc_capture_running(fimc) && !fimc_capture_pending(fimc)) {
546 spin_unlock_irqrestore(&fimc->slock, flags);
547 dbg("state: 0x%lx", fimc->state);
548 return -EINVAL;
549 }
550 spin_unlock_irqrestore(&fimc->slock, flags);
551 639
552 if (mutex_lock_interruptible(&fimc->lock)) 640 return vb2_streamoff(&fimc->vid_cap.vbq, type);
553 return -ERESTARTSYS;
554
555 fimc_stop_capture(fimc);
556 ret = videobuf_streamoff(&cap->vbq);
557 mutex_unlock(&fimc->lock);
558 return ret;
559} 641}
560 642
561static int fimc_cap_reqbufs(struct file *file, void *priv, 643static int fimc_cap_reqbufs(struct file *file, void *priv,
562 struct v4l2_requestbuffers *reqbufs) 644 struct v4l2_requestbuffers *reqbufs)
563{ 645{
564 struct fimc_ctx *ctx = priv; 646 struct fimc_ctx *ctx = priv;
565 struct fimc_dev *fimc = ctx->fimc_dev; 647 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
566 struct fimc_vid_cap *cap = &fimc->vid_cap;
567 int ret; 648 int ret;
568 649
569 if (fimc_capture_active(ctx->fimc_dev))
570 return -EBUSY;
571 650
572 if (mutex_lock_interruptible(&fimc->lock)) 651 ret = vb2_reqbufs(&cap->vbq, reqbufs);
573 return -ERESTARTSYS;
574
575 ret = videobuf_reqbufs(&cap->vbq, reqbufs);
576 if (!ret) 652 if (!ret)
577 cap->reqbufs_count = reqbufs->count; 653 cap->reqbufs_count = reqbufs->count;
578 654
579 mutex_unlock(&fimc->lock);
580 return ret; 655 return ret;
581} 656}
582 657
@@ -586,43 +661,23 @@ static int fimc_cap_querybuf(struct file *file, void *priv,
586 struct fimc_ctx *ctx = priv; 661 struct fimc_ctx *ctx = priv;
587 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; 662 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
588 663
589 if (fimc_capture_active(ctx->fimc_dev)) 664 return vb2_querybuf(&cap->vbq, buf);
590 return -EBUSY;
591
592 return videobuf_querybuf(&cap->vbq, buf);
593} 665}
594 666
595static int fimc_cap_qbuf(struct file *file, void *priv, 667static int fimc_cap_qbuf(struct file *file, void *priv,
596 struct v4l2_buffer *buf) 668 struct v4l2_buffer *buf)
597{ 669{
598 struct fimc_ctx *ctx = priv; 670 struct fimc_ctx *ctx = priv;
599 struct fimc_dev *fimc = ctx->fimc_dev; 671 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
600 struct fimc_vid_cap *cap = &fimc->vid_cap; 672 return vb2_qbuf(&cap->vbq, buf);
601 int ret;
602
603 if (mutex_lock_interruptible(&fimc->lock))
604 return -ERESTARTSYS;
605
606 ret = videobuf_qbuf(&cap->vbq, buf);
607
608 mutex_unlock(&fimc->lock);
609 return ret;
610} 673}
611 674
612static int fimc_cap_dqbuf(struct file *file, void *priv, 675static int fimc_cap_dqbuf(struct file *file, void *priv,
613 struct v4l2_buffer *buf) 676 struct v4l2_buffer *buf)
614{ 677{
615 struct fimc_ctx *ctx = priv; 678 struct fimc_ctx *ctx = priv;
616 int ret; 679 return vb2_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf,
617
618 if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
619 return -ERESTARTSYS;
620
621 ret = videobuf_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf,
622 file->f_flags & O_NONBLOCK); 680 file->f_flags & O_NONBLOCK);
623
624 mutex_unlock(&ctx->fimc_dev->lock);
625 return ret;
626} 681}
627 682
628static int fimc_cap_s_ctrl(struct file *file, void *priv, 683static int fimc_cap_s_ctrl(struct file *file, void *priv,
@@ -631,9 +686,6 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
631 struct fimc_ctx *ctx = priv; 686 struct fimc_ctx *ctx = priv;
632 int ret = -EINVAL; 687 int ret = -EINVAL;
633 688
634 if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
635 return -ERESTARTSYS;
636
637 /* Allow any controls but 90/270 rotation while streaming */ 689 /* Allow any controls but 90/270 rotation while streaming */
638 if (!fimc_capture_active(ctx->fimc_dev) || 690 if (!fimc_capture_active(ctx->fimc_dev) ||
639 ctrl->id != V4L2_CID_ROTATE || 691 ctrl->id != V4L2_CID_ROTATE ||
@@ -648,8 +700,6 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
648 if (ret == -EINVAL) 700 if (ret == -EINVAL)
649 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, 701 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
650 core, s_ctrl, ctrl); 702 core, s_ctrl, ctrl);
651
652 mutex_unlock(&ctx->fimc_dev->lock);
653 return ret; 703 return ret;
654} 704}
655 705
@@ -658,22 +708,18 @@ static int fimc_cap_cropcap(struct file *file, void *fh,
658{ 708{
659 struct fimc_frame *f; 709 struct fimc_frame *f;
660 struct fimc_ctx *ctx = fh; 710 struct fimc_ctx *ctx = fh;
661 struct fimc_dev *fimc = ctx->fimc_dev;
662 711
663 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 712 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
664 return -EINVAL; 713 return -EINVAL;
665 714
666 if (mutex_lock_interruptible(&fimc->lock))
667 return -ERESTARTSYS;
668
669 f = &ctx->s_frame; 715 f = &ctx->s_frame;
716
670 cr->bounds.left = 0; 717 cr->bounds.left = 0;
671 cr->bounds.top = 0; 718 cr->bounds.top = 0;
672 cr->bounds.width = f->o_width; 719 cr->bounds.width = f->o_width;
673 cr->bounds.height = f->o_height; 720 cr->bounds.height = f->o_height;
674 cr->defrect = cr->bounds; 721 cr->defrect = cr->bounds;
675 722
676 mutex_unlock(&fimc->lock);
677 return 0; 723 return 0;
678} 724}
679 725
@@ -681,19 +727,14 @@ static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
681{ 727{
682 struct fimc_frame *f; 728 struct fimc_frame *f;
683 struct fimc_ctx *ctx = file->private_data; 729 struct fimc_ctx *ctx = file->private_data;
684 struct fimc_dev *fimc = ctx->fimc_dev;
685
686
687 if (mutex_lock_interruptible(&fimc->lock))
688 return -ERESTARTSYS;
689 730
690 f = &ctx->s_frame; 731 f = &ctx->s_frame;
732
691 cr->c.left = f->offs_h; 733 cr->c.left = f->offs_h;
692 cr->c.top = f->offs_v; 734 cr->c.top = f->offs_v;
693 cr->c.width = f->width; 735 cr->c.width = f->width;
694 cr->c.height = f->height; 736 cr->c.height = f->height;
695 737
696 mutex_unlock(&fimc->lock);
697 return 0; 738 return 0;
698} 739}
699 740
@@ -712,41 +753,38 @@ static int fimc_cap_s_crop(struct file *file, void *fh,
712 if (ret) 753 if (ret)
713 return ret; 754 return ret;
714 755
715 if (mutex_lock_interruptible(&fimc->lock))
716 return -ERESTARTSYS;
717
718 if (!(ctx->state & FIMC_DST_FMT)) { 756 if (!(ctx->state & FIMC_DST_FMT)) {
719 v4l2_err(&fimc->vid_cap.v4l2_dev, 757 v4l2_err(&fimc->vid_cap.v4l2_dev,
720 "Capture color format not set\n"); 758 "Capture color format not set\n");
721 goto sc_unlock; 759 return -EINVAL; /* TODO: make sure this is the right value */
722 } 760 }
723 761
724 f = &ctx->s_frame; 762 f = &ctx->s_frame;
725 /* Check for the pixel scaling ratio when cropping input image. */ 763 /* Check for the pixel scaling ratio when cropping input image. */
726 ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); 764 ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height,
765 ctx->d_frame.width, ctx->d_frame.height,
766 ctx->rotation);
727 if (ret) { 767 if (ret) {
728 v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range"); 768 v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range\n");
729 } else { 769 return ret;
730 ret = 0;
731 f->offs_h = cr->c.left;
732 f->offs_v = cr->c.top;
733 f->width = cr->c.width;
734 f->height = cr->c.height;
735 } 770 }
736 771
737sc_unlock: 772 f->offs_h = cr->c.left;
738 mutex_unlock(&fimc->lock); 773 f->offs_v = cr->c.top;
739 return ret; 774 f->width = cr->c.width;
775 f->height = cr->c.height;
776
777 return 0;
740} 778}
741 779
742 780
743static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { 781static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
744 .vidioc_querycap = fimc_vidioc_querycap_capture, 782 .vidioc_querycap = fimc_vidioc_querycap_capture,
745 783
746 .vidioc_enum_fmt_vid_cap = fimc_vidioc_enum_fmt, 784 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane,
747 .vidioc_try_fmt_vid_cap = fimc_vidioc_try_fmt, 785 .vidioc_try_fmt_vid_cap_mplane = fimc_vidioc_try_fmt_mplane,
748 .vidioc_s_fmt_vid_cap = fimc_cap_s_fmt, 786 .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
749 .vidioc_g_fmt_vid_cap = fimc_vidioc_g_fmt, 787 .vidioc_g_fmt_vid_cap_mplane = fimc_vidioc_g_fmt_mplane,
750 788
751 .vidioc_reqbufs = fimc_cap_reqbufs, 789 .vidioc_reqbufs = fimc_cap_reqbufs,
752 .vidioc_querybuf = fimc_cap_querybuf, 790 .vidioc_querybuf = fimc_cap_querybuf,
@@ -770,6 +808,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
770 .vidioc_g_input = fimc_cap_g_input, 808 .vidioc_g_input = fimc_cap_g_input,
771}; 809};
772 810
811/* fimc->lock must be already initialized */
773int fimc_register_capture_device(struct fimc_dev *fimc) 812int fimc_register_capture_device(struct fimc_dev *fimc)
774{ 813{
775 struct v4l2_device *v4l2_dev = &fimc->vid_cap.v4l2_dev; 814 struct v4l2_device *v4l2_dev = &fimc->vid_cap.v4l2_dev;
@@ -777,6 +816,8 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
777 struct fimc_vid_cap *vid_cap; 816 struct fimc_vid_cap *vid_cap;
778 struct fimc_ctx *ctx; 817 struct fimc_ctx *ctx;
779 struct v4l2_format f; 818 struct v4l2_format f;
819 struct fimc_frame *fr;
820 struct vb2_queue *q;
780 int ret; 821 int ret;
781 822
782 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 823 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
@@ -788,8 +829,12 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
788 ctx->out_path = FIMC_DMA; 829 ctx->out_path = FIMC_DMA;
789 ctx->state = FIMC_CTX_CAP; 830 ctx->state = FIMC_CTX_CAP;
790 831
791 f.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; 832 /* Default format of the output frames */
792 ctx->d_frame.fmt = find_format(&f, FMT_FLAGS_M2M); 833 f.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
834 fr = &ctx->d_frame;
835 fr->fmt = find_format(&f, FMT_FLAGS_M2M);
836 fr->width = fr->f_width = fr->o_width = 640;
837 fr->height = fr->f_height = fr->o_height = 480;
793 838
794 if (!v4l2_dev->name[0]) 839 if (!v4l2_dev->name[0])
795 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), 840 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
@@ -812,6 +857,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
812 vfd->ioctl_ops = &fimc_capture_ioctl_ops; 857 vfd->ioctl_ops = &fimc_capture_ioctl_ops;
813 vfd->minor = -1; 858 vfd->minor = -1;
814 vfd->release = video_device_release; 859 vfd->release = video_device_release;
860 vfd->lock = &fimc->lock;
815 video_set_drvdata(vfd, fimc); 861 video_set_drvdata(vfd, fimc);
816 862
817 vid_cap = &fimc->vid_cap; 863 vid_cap = &fimc->vid_cap;
@@ -819,7 +865,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
819 vid_cap->active_buf_cnt = 0; 865 vid_cap->active_buf_cnt = 0;
820 vid_cap->reqbufs_count = 0; 866 vid_cap->reqbufs_count = 0;
821 vid_cap->refcnt = 0; 867 vid_cap->refcnt = 0;
822 /* The default color format for image sensor. */ 868 /* Default color format for image sensor */
823 vid_cap->fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; 869 vid_cap->fmt.code = V4L2_MBUS_FMT_YUYV8_2X8;
824 870
825 INIT_LIST_HEAD(&vid_cap->pending_buf_q); 871 INIT_LIST_HEAD(&vid_cap->pending_buf_q);
@@ -827,10 +873,16 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
827 spin_lock_init(&ctx->slock); 873 spin_lock_init(&ctx->slock);
828 vid_cap->ctx = ctx; 874 vid_cap->ctx = ctx;
829 875
830 videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, 876 q = &fimc->vid_cap.vbq;
831 vid_cap->v4l2_dev.dev, &fimc->irqlock, 877 memset(q, 0, sizeof(*q));
832 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, 878 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
833 sizeof(struct fimc_vid_buffer), (void *)ctx, NULL); 879 q->io_modes = VB2_MMAP | VB2_USERPTR;
880 q->drv_priv = fimc->vid_cap.ctx;
881 q->ops = &fimc_capture_qops;
882 q->mem_ops = &vb2_dma_contig_memops;
883 q->buf_struct_size = sizeof(struct fimc_vid_buffer);
884
885 vb2_queue_init(q);
834 886
835 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); 887 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
836 if (ret) { 888 if (ret) {
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 817aa66627f6..6c919b38a3d8 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -25,114 +25,141 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <media/v4l2-ioctl.h> 27#include <media/v4l2-ioctl.h>
28#include <media/videobuf-dma-contig.h> 28#include <media/videobuf2-core.h>
29#include <media/videobuf2-dma-contig.h>
29 30
30#include "fimc-core.h" 31#include "fimc-core.h"
31 32
32static char *fimc_clock_name[NUM_FIMC_CLOCKS] = { "sclk_fimc", "fimc" }; 33static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
34 "sclk_fimc", "fimc", "sclk_cam"
35};
33 36
34static struct fimc_fmt fimc_formats[] = { 37static struct fimc_fmt fimc_formats[] = {
35 { 38 {
36 .name = "RGB565", 39 .name = "RGB565",
37 .fourcc = V4L2_PIX_FMT_RGB565X, 40 .fourcc = V4L2_PIX_FMT_RGB565X,
38 .depth = 16, 41 .depth = { 16 },
39 .color = S5P_FIMC_RGB565, 42 .color = S5P_FIMC_RGB565,
40 .buff_cnt = 1, 43 .memplanes = 1,
41 .planes_cnt = 1, 44 .colplanes = 1,
42 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_BE, 45 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_BE,
43 .flags = FMT_FLAGS_M2M, 46 .flags = FMT_FLAGS_M2M,
47 }, {
48 .name = "BGR666",
49 .fourcc = V4L2_PIX_FMT_BGR666,
50 .depth = { 32 },
51 .color = S5P_FIMC_RGB666,
52 .memplanes = 1,
53 .colplanes = 1,
54 .flags = FMT_FLAGS_M2M,
55 }, {
56 .name = "XRGB-8-8-8-8, 32 bpp",
57 .fourcc = V4L2_PIX_FMT_RGB32,
58 .depth = { 32 },
59 .color = S5P_FIMC_RGB888,
60 .memplanes = 1,
61 .colplanes = 1,
62 .flags = FMT_FLAGS_M2M,
63 }, {
64 .name = "YUV 4:2:2 packed, YCbYCr",
65 .fourcc = V4L2_PIX_FMT_YUYV,
66 .depth = { 16 },
67 .color = S5P_FIMC_YCBYCR422,
68 .memplanes = 1,
69 .colplanes = 1,
70 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
71 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
44 }, { 72 }, {
45 .name = "BGR666", 73 .name = "YUV 4:2:2 packed, CbYCrY",
46 .fourcc = V4L2_PIX_FMT_BGR666, 74 .fourcc = V4L2_PIX_FMT_UYVY,
47 .depth = 32, 75 .depth = { 16 },
48 .color = S5P_FIMC_RGB666, 76 .color = S5P_FIMC_CBYCRY422,
49 .buff_cnt = 1, 77 .memplanes = 1,
50 .planes_cnt = 1, 78 .colplanes = 1,
51 .flags = FMT_FLAGS_M2M, 79 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
80 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
52 }, { 81 }, {
53 .name = "XRGB-8-8-8-8, 32 bpp", 82 .name = "YUV 4:2:2 packed, CrYCbY",
54 .fourcc = V4L2_PIX_FMT_RGB32, 83 .fourcc = V4L2_PIX_FMT_VYUY,
55 .depth = 32, 84 .depth = { 16 },
56 .color = S5P_FIMC_RGB888, 85 .color = S5P_FIMC_CRYCBY422,
57 .buff_cnt = 1, 86 .memplanes = 1,
58 .planes_cnt = 1, 87 .colplanes = 1,
59 .flags = FMT_FLAGS_M2M, 88 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
89 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
60 }, { 90 }, {
61 .name = "YUV 4:2:2 packed, YCbYCr", 91 .name = "YUV 4:2:2 packed, YCrYCb",
62 .fourcc = V4L2_PIX_FMT_YUYV, 92 .fourcc = V4L2_PIX_FMT_YVYU,
63 .depth = 16, 93 .depth = { 16 },
64 .color = S5P_FIMC_YCBYCR422, 94 .color = S5P_FIMC_YCRYCB422,
65 .buff_cnt = 1, 95 .memplanes = 1,
66 .planes_cnt = 1, 96 .colplanes = 1,
67 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, 97 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
68 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, 98 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
69 }, { 99 }, {
70 .name = "YUV 4:2:2 packed, CbYCrY", 100 .name = "YUV 4:2:2 planar, Y/Cb/Cr",
71 .fourcc = V4L2_PIX_FMT_UYVY, 101 .fourcc = V4L2_PIX_FMT_YUV422P,
72 .depth = 16, 102 .depth = { 12 },
73 .color = S5P_FIMC_CBYCRY422, 103 .color = S5P_FIMC_YCBYCR422,
74 .buff_cnt = 1, 104 .memplanes = 1,
75 .planes_cnt = 1, 105 .colplanes = 3,
76 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, 106 .flags = FMT_FLAGS_M2M,
77 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
78 }, { 107 }, {
79 .name = "YUV 4:2:2 packed, CrYCbY", 108 .name = "YUV 4:2:2 planar, Y/CbCr",
80 .fourcc = V4L2_PIX_FMT_VYUY, 109 .fourcc = V4L2_PIX_FMT_NV16,
81 .depth = 16, 110 .depth = { 16 },
82 .color = S5P_FIMC_CRYCBY422, 111 .color = S5P_FIMC_YCBYCR422,
83 .buff_cnt = 1, 112 .memplanes = 1,
84 .planes_cnt = 1, 113 .colplanes = 2,
85 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, 114 .flags = FMT_FLAGS_M2M,
86 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
87 }, { 115 }, {
88 .name = "YUV 4:2:2 packed, YCrYCb", 116 .name = "YUV 4:2:2 planar, Y/CrCb",
89 .fourcc = V4L2_PIX_FMT_YVYU, 117 .fourcc = V4L2_PIX_FMT_NV61,
90 .depth = 16, 118 .depth = { 16 },
91 .color = S5P_FIMC_YCRYCB422, 119 .color = S5P_FIMC_YCRYCB422,
92 .buff_cnt = 1, 120 .memplanes = 1,
93 .planes_cnt = 1, 121 .colplanes = 2,
94 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, 122 .flags = FMT_FLAGS_M2M,
95 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
96 }, { 123 }, {
97 .name = "YUV 4:2:2 planar, Y/Cb/Cr", 124 .name = "YUV 4:2:0 planar, YCbCr",
98 .fourcc = V4L2_PIX_FMT_YUV422P, 125 .fourcc = V4L2_PIX_FMT_YUV420,
99 .depth = 12, 126 .depth = { 12 },
100 .color = S5P_FIMC_YCBCR422, 127 .color = S5P_FIMC_YCBCR420,
101 .buff_cnt = 1, 128 .memplanes = 1,
102 .planes_cnt = 3, 129 .colplanes = 3,
103 .flags = FMT_FLAGS_M2M, 130 .flags = FMT_FLAGS_M2M,
104 }, { 131 }, {
105 .name = "YUV 4:2:2 planar, Y/CbCr", 132 .name = "YUV 4:2:0 planar, Y/CbCr",
106 .fourcc = V4L2_PIX_FMT_NV16, 133 .fourcc = V4L2_PIX_FMT_NV12,
107 .depth = 16, 134 .depth = { 12 },
108 .color = S5P_FIMC_YCBCR422, 135 .color = S5P_FIMC_YCBCR420,
109 .buff_cnt = 1, 136 .memplanes = 1,
110 .planes_cnt = 2, 137 .colplanes = 2,
111 .flags = FMT_FLAGS_M2M, 138 .flags = FMT_FLAGS_M2M,
112 }, { 139 }, {
113 .name = "YUV 4:2:2 planar, Y/CrCb", 140 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr",
114 .fourcc = V4L2_PIX_FMT_NV61, 141 .fourcc = V4L2_PIX_FMT_NV12M,
115 .depth = 16, 142 .color = S5P_FIMC_YCBCR420,
116 .color = S5P_FIMC_RGB565, 143 .depth = { 8, 4 },
117 .buff_cnt = 1, 144 .memplanes = 2,
118 .planes_cnt = 2, 145 .colplanes = 2,
119 .flags = FMT_FLAGS_M2M, 146 .flags = FMT_FLAGS_M2M,
120 }, { 147 }, {
121 .name = "YUV 4:2:0 planar, YCbCr", 148 .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr",
122 .fourcc = V4L2_PIX_FMT_YUV420, 149 .fourcc = V4L2_PIX_FMT_YUV420M,
123 .depth = 12, 150 .color = S5P_FIMC_YCBCR420,
124 .color = S5P_FIMC_YCBCR420, 151 .depth = { 8, 2, 2 },
125 .buff_cnt = 1, 152 .memplanes = 3,
126 .planes_cnt = 3, 153 .colplanes = 3,
127 .flags = FMT_FLAGS_M2M, 154 .flags = FMT_FLAGS_M2M,
128 }, { 155 }, {
129 .name = "YUV 4:2:0 planar, Y/CbCr", 156 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled",
130 .fourcc = V4L2_PIX_FMT_NV12, 157 .fourcc = V4L2_PIX_FMT_NV12MT,
131 .depth = 12, 158 .color = S5P_FIMC_YCBCR420,
132 .color = S5P_FIMC_YCBCR420, 159 .depth = { 8, 4 },
133 .buff_cnt = 1, 160 .memplanes = 2,
134 .planes_cnt = 2, 161 .colplanes = 2,
135 .flags = FMT_FLAGS_M2M, 162 .flags = FMT_FLAGS_M2M,
136 }, 163 },
137}; 164};
138 165
@@ -173,24 +200,21 @@ static struct v4l2_queryctrl *get_ctrl(int id)
173 return NULL; 200 return NULL;
174} 201}
175 202
176int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) 203int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot)
177{ 204{
178 if (r->width > f->width) { 205 int tx, ty;
179 if (f->width > (r->width * SCALER_MAX_HRATIO))
180 return -EINVAL;
181 } else {
182 if ((f->width * SCALER_MAX_HRATIO) < r->width)
183 return -EINVAL;
184 }
185 206
186 if (r->height > f->height) { 207 if (rot == 90 || rot == 270) {
187 if (f->height > (r->height * SCALER_MAX_VRATIO)) 208 ty = dw;
188 return -EINVAL; 209 tx = dh;
189 } else { 210 } else {
190 if ((f->height * SCALER_MAX_VRATIO) < r->height) 211 tx = dw;
191 return -EINVAL; 212 ty = dh;
192 } 213 }
193 214
215 if ((sw >= SCALER_MAX_HRATIO * tx) || (sh >= SCALER_MAX_VRATIO * ty))
216 return -EINVAL;
217
194 return 0; 218 return 0;
195} 219}
196 220
@@ -221,6 +245,7 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
221 struct fimc_scaler *sc = &ctx->scaler; 245 struct fimc_scaler *sc = &ctx->scaler;
222 struct fimc_frame *s_frame = &ctx->s_frame; 246 struct fimc_frame *s_frame = &ctx->s_frame;
223 struct fimc_frame *d_frame = &ctx->d_frame; 247 struct fimc_frame *d_frame = &ctx->d_frame;
248 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
224 int tx, ty, sx, sy; 249 int tx, ty, sx, sy;
225 int ret; 250 int ret;
226 251
@@ -259,8 +284,14 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
259 sc->pre_dst_width = sx / sc->pre_hratio; 284 sc->pre_dst_width = sx / sc->pre_hratio;
260 sc->pre_dst_height = sy / sc->pre_vratio; 285 sc->pre_dst_height = sy / sc->pre_vratio;
261 286
262 sc->main_hratio = (sx << 8) / (tx << sc->hfactor); 287 if (variant->has_mainscaler_ext) {
263 sc->main_vratio = (sy << 8) / (ty << sc->vfactor); 288 sc->main_hratio = (sx << 14) / (tx << sc->hfactor);
289 sc->main_vratio = (sy << 14) / (ty << sc->vfactor);
290 } else {
291 sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
292 sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
293
294 }
264 295
265 sc->scaleup_h = (tx >= sx) ? 1 : 0; 296 sc->scaleup_h = (tx >= sx) ? 1 : 0;
266 sc->scaleup_v = (ty >= sy) ? 1 : 0; 297 sc->scaleup_v = (ty >= sy) ? 1 : 0;
@@ -276,14 +307,65 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
276 return 0; 307 return 0;
277} 308}
278 309
279static void fimc_capture_handler(struct fimc_dev *fimc) 310static void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
311{
312 struct vb2_buffer *src_vb, *dst_vb;
313 struct fimc_dev *fimc = ctx->fimc_dev;
314
315 if (!ctx || !ctx->m2m_ctx)
316 return;
317
318 src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
319 dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
320
321 if (src_vb && dst_vb) {
322 v4l2_m2m_buf_done(src_vb, vb_state);
323 v4l2_m2m_buf_done(dst_vb, vb_state);
324 v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx);
325 }
326}
327
328/* Complete the transaction which has been scheduled for execution. */
329static void fimc_m2m_shutdown(struct fimc_ctx *ctx)
330{
331 struct fimc_dev *fimc = ctx->fimc_dev;
332 int ret;
333
334 if (!fimc_m2m_pending(fimc))
335 return;
336
337 fimc_ctx_state_lock_set(FIMC_CTX_SHUT, ctx);
338
339 ret = wait_event_timeout(fimc->irq_queue,
340 !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
341 FIMC_SHUTDOWN_TIMEOUT);
342 /*
343 * In case of a timeout the buffers are not released in the interrupt
344 * handler so return them here with the error flag set, if there are
345 * any on the queue.
346 */
347 if (ret == 0)
348 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
349}
350
351static int stop_streaming(struct vb2_queue *q)
352{
353 struct fimc_ctx *ctx = q->drv_priv;
354
355 fimc_m2m_shutdown(ctx);
356
357 return 0;
358}
359
360static void fimc_capture_irq_handler(struct fimc_dev *fimc)
280{ 361{
281 struct fimc_vid_cap *cap = &fimc->vid_cap; 362 struct fimc_vid_cap *cap = &fimc->vid_cap;
282 struct fimc_vid_buffer *v_buf = NULL; 363 struct fimc_vid_buffer *v_buf;
283 364
284 if (!list_empty(&cap->active_buf_q)) { 365 if (!list_empty(&cap->active_buf_q) &&
366 test_bit(ST_CAPT_RUN, &fimc->state)) {
285 v_buf = active_queue_pop(cap); 367 v_buf = active_queue_pop(cap);
286 fimc_buf_finish(fimc, v_buf); 368 vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
287 } 369 }
288 370
289 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) { 371 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
@@ -297,13 +379,6 @@ static void fimc_capture_handler(struct fimc_dev *fimc)
297 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index); 379 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
298 v_buf->index = cap->buf_index; 380 v_buf->index = cap->buf_index;
299 381
300 dbg("hw ptr: %d, sw ptr: %d",
301 fimc_hw_get_frame_index(fimc), cap->buf_index);
302
303 spin_lock(&fimc->irqlock);
304 v_buf->vb.state = VIDEOBUF_ACTIVE;
305 spin_unlock(&fimc->irqlock);
306
307 /* Move the buffer to the capture active queue */ 382 /* Move the buffer to the capture active queue */
308 active_queue_add(cap, v_buf); 383 active_queue_add(cap, v_buf);
309 384
@@ -312,77 +387,79 @@ static void fimc_capture_handler(struct fimc_dev *fimc)
312 387
313 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS) 388 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
314 cap->buf_index = 0; 389 cap->buf_index = 0;
390 }
315 391
316 } else if (test_and_clear_bit(ST_CAPT_STREAM, &fimc->state) && 392 if (cap->active_buf_cnt == 0) {
317 cap->active_buf_cnt <= 1) { 393 clear_bit(ST_CAPT_RUN, &fimc->state);
318 fimc_deactivate_capture(fimc); 394
395 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
396 cap->buf_index = 0;
397 } else {
398 set_bit(ST_CAPT_RUN, &fimc->state);
319 } 399 }
320 400
321 dbg("frame: %d, active_buf_cnt= %d", 401 dbg("frame: %d, active_buf_cnt: %d",
322 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt); 402 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
323} 403}
324 404
325static irqreturn_t fimc_isr(int irq, void *priv) 405static irqreturn_t fimc_isr(int irq, void *priv)
326{ 406{
327 struct fimc_vid_buffer *src_buf, *dst_buf;
328 struct fimc_ctx *ctx;
329 struct fimc_dev *fimc = priv; 407 struct fimc_dev *fimc = priv;
408 struct fimc_vid_cap *cap = &fimc->vid_cap;
409 struct fimc_ctx *ctx;
330 410
331 BUG_ON(!fimc);
332 fimc_hw_clear_irq(fimc); 411 fimc_hw_clear_irq(fimc);
333 412
334 spin_lock(&fimc->slock);
335
336 if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { 413 if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) {
337 ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); 414 ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev);
338 if (!ctx || !ctx->m2m_ctx) 415 if (ctx != NULL) {
339 goto isr_unlock; 416 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
340 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 417
341 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 418 spin_lock(&ctx->slock);
342 if (src_buf && dst_buf) { 419 if (ctx->state & FIMC_CTX_SHUT) {
343 spin_lock(&fimc->irqlock); 420 ctx->state &= ~FIMC_CTX_SHUT;
344 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE; 421 wake_up(&fimc->irq_queue);
345 wake_up(&src_buf->vb.done); 422 }
346 wake_up(&dst_buf->vb.done); 423 spin_unlock(&ctx->slock);
347 spin_unlock(&fimc->irqlock);
348 v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx);
349 } 424 }
350 goto isr_unlock;
351 425
426 return IRQ_HANDLED;
352 } 427 }
353 428
354 if (test_bit(ST_CAPT_RUN, &fimc->state)) 429 spin_lock(&fimc->slock);
355 fimc_capture_handler(fimc);
356 430
357 if (test_and_clear_bit(ST_CAPT_PEND, &fimc->state)) { 431 if (test_bit(ST_CAPT_PEND, &fimc->state)) {
358 set_bit(ST_CAPT_RUN, &fimc->state); 432 fimc_capture_irq_handler(fimc);
359 wake_up(&fimc->irq_queue); 433
434 if (cap->active_buf_cnt == 1) {
435 fimc_deactivate_capture(fimc);
436 clear_bit(ST_CAPT_STREAM, &fimc->state);
437 }
360 } 438 }
361 439
362isr_unlock:
363 spin_unlock(&fimc->slock); 440 spin_unlock(&fimc->slock);
364 return IRQ_HANDLED; 441 return IRQ_HANDLED;
365} 442}
366 443
367/* The color format (planes_cnt, buff_cnt) must be already configured. */ 444/* The color format (colplanes, memplanes) must be already configured. */
368int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, 445int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
369 struct fimc_frame *frame, struct fimc_addr *paddr) 446 struct fimc_frame *frame, struct fimc_addr *paddr)
370{ 447{
371 int ret = 0; 448 int ret = 0;
372 u32 pix_size; 449 u32 pix_size;
373 450
374 if (buf == NULL || frame == NULL) 451 if (vb == NULL || frame == NULL)
375 return -EINVAL; 452 return -EINVAL;
376 453
377 pix_size = frame->width * frame->height; 454 pix_size = frame->width * frame->height;
378 455
379 dbg("buff_cnt= %d, planes_cnt= %d, frame->size= %d, pix_size= %d", 456 dbg("memplanes= %d, colplanes= %d, pix_size= %d",
380 frame->fmt->buff_cnt, frame->fmt->planes_cnt, 457 frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
381 frame->size, pix_size); 458
459 paddr->y = vb2_dma_contig_plane_paddr(vb, 0);
382 460
383 if (frame->fmt->buff_cnt == 1) { 461 if (frame->fmt->memplanes == 1) {
384 paddr->y = videobuf_to_dma_contig(&buf->vb); 462 switch (frame->fmt->colplanes) {
385 switch (frame->fmt->planes_cnt) {
386 case 1: 463 case 1:
387 paddr->cb = 0; 464 paddr->cb = 0;
388 paddr->cr = 0; 465 paddr->cr = 0;
@@ -405,6 +482,12 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf,
405 default: 482 default:
406 return -EINVAL; 483 return -EINVAL;
407 } 484 }
485 } else {
486 if (frame->fmt->memplanes >= 2)
487 paddr->cb = vb2_dma_contig_plane_paddr(vb, 1);
488
489 if (frame->fmt->memplanes == 3)
490 paddr->cr = vb2_dma_contig_plane_paddr(vb, 2);
408 } 491 }
409 492
410 dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d", 493 dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
@@ -423,34 +506,34 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx)
423 /* Set order for 1 plane input formats. */ 506 /* Set order for 1 plane input formats. */
424 switch (ctx->s_frame.fmt->color) { 507 switch (ctx->s_frame.fmt->color) {
425 case S5P_FIMC_YCRYCB422: 508 case S5P_FIMC_YCRYCB422:
426 ctx->in_order_1p = S5P_FIMC_IN_YCRYCB; 509 ctx->in_order_1p = S5P_MSCTRL_ORDER422_CBYCRY;
427 break; 510 break;
428 case S5P_FIMC_CBYCRY422: 511 case S5P_FIMC_CBYCRY422:
429 ctx->in_order_1p = S5P_FIMC_IN_CBYCRY; 512 ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCRYCB;
430 break; 513 break;
431 case S5P_FIMC_CRYCBY422: 514 case S5P_FIMC_CRYCBY422:
432 ctx->in_order_1p = S5P_FIMC_IN_CRYCBY; 515 ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCBYCR;
433 break; 516 break;
434 case S5P_FIMC_YCBYCR422: 517 case S5P_FIMC_YCBYCR422:
435 default: 518 default:
436 ctx->in_order_1p = S5P_FIMC_IN_YCBYCR; 519 ctx->in_order_1p = S5P_MSCTRL_ORDER422_CRYCBY;
437 break; 520 break;
438 } 521 }
439 dbg("ctx->in_order_1p= %d", ctx->in_order_1p); 522 dbg("ctx->in_order_1p= %d", ctx->in_order_1p);
440 523
441 switch (ctx->d_frame.fmt->color) { 524 switch (ctx->d_frame.fmt->color) {
442 case S5P_FIMC_YCRYCB422: 525 case S5P_FIMC_YCRYCB422:
443 ctx->out_order_1p = S5P_FIMC_OUT_YCRYCB; 526 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CBYCRY;
444 break; 527 break;
445 case S5P_FIMC_CBYCRY422: 528 case S5P_FIMC_CBYCRY422:
446 ctx->out_order_1p = S5P_FIMC_OUT_CBYCRY; 529 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCRYCB;
447 break; 530 break;
448 case S5P_FIMC_CRYCBY422: 531 case S5P_FIMC_CRYCBY422:
449 ctx->out_order_1p = S5P_FIMC_OUT_CRYCBY; 532 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCBYCR;
450 break; 533 break;
451 case S5P_FIMC_YCBYCR422: 534 case S5P_FIMC_YCBYCR422:
452 default: 535 default:
453 ctx->out_order_1p = S5P_FIMC_OUT_YCBYCR; 536 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CRYCBY;
454 break; 537 break;
455 } 538 }
456 dbg("ctx->out_order_1p= %d", ctx->out_order_1p); 539 dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
@@ -459,10 +542,14 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx)
459static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) 542static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
460{ 543{
461 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; 544 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
545 u32 i, depth = 0;
546
547 for (i = 0; i < f->fmt->colplanes; i++)
548 depth += f->fmt->depth[i];
462 549
463 f->dma_offset.y_h = f->offs_h; 550 f->dma_offset.y_h = f->offs_h;
464 if (!variant->pix_hoff) 551 if (!variant->pix_hoff)
465 f->dma_offset.y_h *= (f->fmt->depth >> 3); 552 f->dma_offset.y_h *= (depth >> 3);
466 553
467 f->dma_offset.y_v = f->offs_v; 554 f->dma_offset.y_v = f->offs_v;
468 555
@@ -473,7 +560,7 @@ static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
473 f->dma_offset.cr_v = f->offs_v; 560 f->dma_offset.cr_v = f->offs_v;
474 561
475 if (!variant->pix_hoff) { 562 if (!variant->pix_hoff) {
476 if (f->fmt->planes_cnt == 3) { 563 if (f->fmt->colplanes == 3) {
477 f->dma_offset.cb_h >>= 1; 564 f->dma_offset.cb_h >>= 1;
478 f->dma_offset.cr_h >>= 1; 565 f->dma_offset.cr_h >>= 1;
479 } 566 }
@@ -499,7 +586,7 @@ static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
499int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) 586int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
500{ 587{
501 struct fimc_frame *s_frame, *d_frame; 588 struct fimc_frame *s_frame, *d_frame;
502 struct fimc_vid_buffer *buf = NULL; 589 struct vb2_buffer *vb = NULL;
503 int ret = 0; 590 int ret = 0;
504 591
505 s_frame = &ctx->s_frame; 592 s_frame = &ctx->s_frame;
@@ -522,15 +609,15 @@ int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
522 ctx->scaler.enabled = 1; 609 ctx->scaler.enabled = 1;
523 610
524 if (flags & FIMC_SRC_ADDR) { 611 if (flags & FIMC_SRC_ADDR) {
525 buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 612 vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
526 ret = fimc_prepare_addr(ctx, buf, s_frame, &s_frame->paddr); 613 ret = fimc_prepare_addr(ctx, vb, s_frame, &s_frame->paddr);
527 if (ret) 614 if (ret)
528 return ret; 615 return ret;
529 } 616 }
530 617
531 if (flags & FIMC_DST_ADDR) { 618 if (flags & FIMC_DST_ADDR) {
532 buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 619 vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
533 ret = fimc_prepare_addr(ctx, buf, d_frame, &d_frame->paddr); 620 ret = fimc_prepare_addr(ctx, vb, d_frame, &d_frame->paddr);
534 } 621 }
535 622
536 return ret; 623 return ret;
@@ -553,26 +640,28 @@ static void fimc_dma_run(void *priv)
553 640
554 ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR); 641 ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR);
555 ret = fimc_prepare_config(ctx, ctx->state); 642 ret = fimc_prepare_config(ctx, ctx->state);
556 if (ret) { 643 if (ret)
557 err("Wrong parameters");
558 goto dma_unlock; 644 goto dma_unlock;
559 } 645
560 /* Reconfigure hardware if the context has changed. */ 646 /* Reconfigure hardware if the context has changed. */
561 if (fimc->m2m.ctx != ctx) { 647 if (fimc->m2m.ctx != ctx) {
562 ctx->state |= FIMC_PARAMS; 648 ctx->state |= FIMC_PARAMS;
563 fimc->m2m.ctx = ctx; 649 fimc->m2m.ctx = ctx;
564 } 650 }
565 651
652 spin_lock(&fimc->slock);
566 fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr); 653 fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr);
567 654
568 if (ctx->state & FIMC_PARAMS) { 655 if (ctx->state & FIMC_PARAMS) {
569 fimc_hw_set_input_path(ctx); 656 fimc_hw_set_input_path(ctx);
570 fimc_hw_set_in_dma(ctx); 657 fimc_hw_set_in_dma(ctx);
571 if (fimc_set_scaler_info(ctx)) { 658 ret = fimc_set_scaler_info(ctx);
572 err("Scaler setup error"); 659 if (ret) {
660 spin_unlock(&fimc->slock);
573 goto dma_unlock; 661 goto dma_unlock;
574 } 662 }
575 fimc_hw_set_scaler(ctx); 663 fimc_hw_set_prescaler(ctx);
664 fimc_hw_set_mainscaler(ctx);
576 fimc_hw_set_target_format(ctx); 665 fimc_hw_set_target_format(ctx);
577 fimc_hw_set_rotation(ctx); 666 fimc_hw_set_rotation(ctx);
578 fimc_hw_set_effect(ctx); 667 fimc_hw_set_effect(ctx);
@@ -587,8 +676,10 @@ static void fimc_dma_run(void *priv)
587 676
588 fimc_activate_capture(ctx); 677 fimc_activate_capture(ctx);
589 678
590 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP); 679 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
680 FIMC_SRC_FMT | FIMC_DST_FMT);
591 fimc_hw_activate_input_dma(fimc, true); 681 fimc_hw_activate_input_dma(fimc, true);
682 spin_unlock(&fimc->slock);
592 683
593dma_unlock: 684dma_unlock:
594 spin_unlock_irqrestore(&ctx->slock, flags); 685 spin_unlock_irqrestore(&ctx->slock, flags);
@@ -596,109 +687,84 @@ dma_unlock:
596 687
597static void fimc_job_abort(void *priv) 688static void fimc_job_abort(void *priv)
598{ 689{
599 /* Nothing done in job_abort. */ 690 fimc_m2m_shutdown(priv);
600} 691}
601 692
602static void fimc_buf_release(struct videobuf_queue *vq, 693static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
603 struct videobuf_buffer *vb) 694 unsigned int *num_planes, unsigned long sizes[],
695 void *allocators[])
604{ 696{
605 videobuf_dma_contig_free(vq, vb); 697 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
606 vb->state = VIDEOBUF_NEEDS_INIT; 698 struct fimc_frame *f;
607} 699 int i;
608 700
609static int fimc_buf_setup(struct videobuf_queue *vq, unsigned int *count, 701 f = ctx_get_frame(ctx, vq->type);
610 unsigned int *size) 702 if (IS_ERR(f))
611{ 703 return PTR_ERR(f);
612 struct fimc_ctx *ctx = vq->priv_data;
613 struct fimc_frame *frame;
614 704
615 frame = ctx_get_frame(ctx, vq->type); 705 /*
616 if (IS_ERR(frame)) 706 * Return number of non-contigous planes (plane buffers)
617 return PTR_ERR(frame); 707 * depending on the configured color format.
708 */
709 if (f->fmt)
710 *num_planes = f->fmt->memplanes;
711
712 for (i = 0; i < f->fmt->memplanes; i++) {
713 sizes[i] = (f->width * f->height * f->fmt->depth[i]) >> 3;
714 allocators[i] = ctx->fimc_dev->alloc_ctx;
715 }
716
717 if (*num_buffers == 0)
718 *num_buffers = 1;
618 719
619 *size = (frame->width * frame->height * frame->fmt->depth) >> 3;
620 if (0 == *count)
621 *count = 1;
622 return 0; 720 return 0;
623} 721}
624 722
625static int fimc_buf_prepare(struct videobuf_queue *vq, 723static int fimc_buf_prepare(struct vb2_buffer *vb)
626 struct videobuf_buffer *vb, enum v4l2_field field)
627{ 724{
628 struct fimc_ctx *ctx = vq->priv_data; 725 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
629 struct v4l2_device *v4l2_dev = &ctx->fimc_dev->m2m.v4l2_dev;
630 struct fimc_frame *frame; 726 struct fimc_frame *frame;
631 int ret; 727 int i;
632 728
633 frame = ctx_get_frame(ctx, vq->type); 729 frame = ctx_get_frame(ctx, vb->vb2_queue->type);
634 if (IS_ERR(frame)) 730 if (IS_ERR(frame))
635 return PTR_ERR(frame); 731 return PTR_ERR(frame);
636 732
637 if (vb->baddr) { 733 for (i = 0; i < frame->fmt->memplanes; i++)
638 if (vb->bsize < frame->size) { 734 vb2_set_plane_payload(vb, i, frame->payload[i]);
639 v4l2_err(v4l2_dev,
640 "User-provided buffer too small (%d < %d)\n",
641 vb->bsize, frame->size);
642 WARN_ON(1);
643 return -EINVAL;
644 }
645 } else if (vb->state != VIDEOBUF_NEEDS_INIT
646 && vb->bsize < frame->size) {
647 return -EINVAL;
648 }
649
650 vb->width = frame->width;
651 vb->height = frame->height;
652 vb->bytesperline = (frame->width * frame->fmt->depth) >> 3;
653 vb->size = frame->size;
654 vb->field = field;
655
656 if (VIDEOBUF_NEEDS_INIT == vb->state) {
657 ret = videobuf_iolock(vq, vb, NULL);
658 if (ret) {
659 v4l2_err(v4l2_dev, "Iolock failed\n");
660 fimc_buf_release(vq, vb);
661 return ret;
662 }
663 }
664 vb->state = VIDEOBUF_PREPARED;
665 735
666 return 0; 736 return 0;
667} 737}
668 738
669static void fimc_buf_queue(struct videobuf_queue *vq, 739static void fimc_buf_queue(struct vb2_buffer *vb)
670 struct videobuf_buffer *vb)
671{ 740{
672 struct fimc_ctx *ctx = vq->priv_data; 741 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
673 struct fimc_dev *fimc = ctx->fimc_dev;
674 struct fimc_vid_cap *cap = &fimc->vid_cap;
675 unsigned long flags;
676 742
677 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state); 743 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
678 744
679 if ((ctx->state & FIMC_CTX_M2M) && ctx->m2m_ctx) { 745 if (ctx->m2m_ctx)
680 v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb); 746 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
681 } else if (ctx->state & FIMC_CTX_CAP) { 747}
682 spin_lock_irqsave(&fimc->slock, flags);
683 fimc_vid_cap_buf_queue(fimc, (struct fimc_vid_buffer *)vb);
684 748
685 dbg("fimc->cap.active_buf_cnt: %d", 749static void fimc_lock(struct vb2_queue *vq)
686 fimc->vid_cap.active_buf_cnt); 750{
751 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
752 mutex_lock(&ctx->fimc_dev->lock);
753}
687 754
688 if (cap->active_buf_cnt >= cap->reqbufs_count || 755static void fimc_unlock(struct vb2_queue *vq)
689 cap->active_buf_cnt >= FIMC_MAX_OUT_BUFS) { 756{
690 if (!test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) 757 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
691 fimc_activate_capture(ctx); 758 mutex_unlock(&ctx->fimc_dev->lock);
692 }
693 spin_unlock_irqrestore(&fimc->slock, flags);
694 }
695} 759}
696 760
697struct videobuf_queue_ops fimc_qops = { 761struct vb2_ops fimc_qops = {
698 .buf_setup = fimc_buf_setup, 762 .queue_setup = fimc_queue_setup,
699 .buf_prepare = fimc_buf_prepare, 763 .buf_prepare = fimc_buf_prepare,
700 .buf_queue = fimc_buf_queue, 764 .buf_queue = fimc_buf_queue,
701 .buf_release = fimc_buf_release, 765 .wait_prepare = fimc_unlock,
766 .wait_finish = fimc_lock,
767 .stop_streaming = stop_streaming,
702}; 768};
703 769
704static int fimc_m2m_querycap(struct file *file, void *priv, 770static int fimc_m2m_querycap(struct file *file, void *priv,
@@ -712,12 +778,13 @@ static int fimc_m2m_querycap(struct file *file, void *priv,
712 cap->bus_info[0] = 0; 778 cap->bus_info[0] = 0;
713 cap->version = KERNEL_VERSION(1, 0, 0); 779 cap->version = KERNEL_VERSION(1, 0, 0);
714 cap->capabilities = V4L2_CAP_STREAMING | 780 cap->capabilities = V4L2_CAP_STREAMING |
715 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT; 781 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
782 V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
716 783
717 return 0; 784 return 0;
718} 785}
719 786
720int fimc_vidioc_enum_fmt(struct file *file, void *priv, 787int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
721 struct v4l2_fmtdesc *f) 788 struct v4l2_fmtdesc *f)
722{ 789{
723 struct fimc_fmt *fmt; 790 struct fimc_fmt *fmt;
@@ -732,25 +799,39 @@ int fimc_vidioc_enum_fmt(struct file *file, void *priv,
732 return 0; 799 return 0;
733} 800}
734 801
735int fimc_vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) 802int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv,
803 struct v4l2_format *f)
736{ 804{
737 struct fimc_ctx *ctx = priv; 805 struct fimc_ctx *ctx = priv;
738 struct fimc_dev *fimc = ctx->fimc_dev;
739 struct fimc_frame *frame; 806 struct fimc_frame *frame;
807 struct v4l2_pix_format_mplane *pixm;
808 int i;
740 809
741 frame = ctx_get_frame(ctx, f->type); 810 frame = ctx_get_frame(ctx, f->type);
742 if (IS_ERR(frame)) 811 if (IS_ERR(frame))
743 return PTR_ERR(frame); 812 return PTR_ERR(frame);
744 813
745 if (mutex_lock_interruptible(&fimc->lock)) 814 pixm = &f->fmt.pix_mp;
746 return -ERESTARTSYS; 815
816 pixm->width = frame->width;
817 pixm->height = frame->height;
818 pixm->field = V4L2_FIELD_NONE;
819 pixm->pixelformat = frame->fmt->fourcc;
820 pixm->colorspace = V4L2_COLORSPACE_JPEG;
821 pixm->num_planes = frame->fmt->memplanes;
822
823 for (i = 0; i < pixm->num_planes; ++i) {
824 int bpl = frame->o_width;
747 825
748 f->fmt.pix.width = frame->width; 826 if (frame->fmt->colplanes == 1) /* packed formats */
749 f->fmt.pix.height = frame->height; 827 bpl = (bpl * frame->fmt->depth[0]) / 8;
750 f->fmt.pix.field = V4L2_FIELD_NONE; 828
751 f->fmt.pix.pixelformat = frame->fmt->fourcc; 829 pixm->plane_fmt[i].bytesperline = bpl;
830
831 pixm->plane_fmt[i].sizeimage = (frame->o_width *
832 frame->o_height * frame->fmt->depth[i]) / 8;
833 }
752 834
753 mutex_unlock(&fimc->lock);
754 return 0; 835 return 0;
755} 836}
756 837
@@ -785,42 +866,40 @@ struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,
785} 866}
786 867
787 868
788int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 869int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
870 struct v4l2_format *f)
789{ 871{
790 struct fimc_ctx *ctx = priv; 872 struct fimc_ctx *ctx = priv;
791 struct fimc_dev *fimc = ctx->fimc_dev; 873 struct fimc_dev *fimc = ctx->fimc_dev;
792 struct samsung_fimc_variant *variant = fimc->variant; 874 struct samsung_fimc_variant *variant = fimc->variant;
793 struct v4l2_pix_format *pix = &f->fmt.pix; 875 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
794 struct fimc_fmt *fmt; 876 struct fimc_fmt *fmt;
795 u32 max_width, mod_x, mod_y, mask; 877 u32 max_width, mod_x, mod_y, mask;
796 int ret = -EINVAL, is_output = 0; 878 int i, is_output = 0;
879
797 880
798 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 881 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
799 if (ctx->state & FIMC_CTX_CAP) 882 if (fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx))
800 return -EINVAL; 883 return -EINVAL;
801 is_output = 1; 884 is_output = 1;
802 } else if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 885 } else if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
803 return -EINVAL; 886 return -EINVAL;
804 } 887 }
805 888
806 dbg("w: %d, h: %d, bpl: %d", 889 dbg("w: %d, h: %d", pix->width, pix->height);
807 pix->width, pix->height, pix->bytesperline);
808
809 if (mutex_lock_interruptible(&fimc->lock))
810 return -ERESTARTSYS;
811 890
812 mask = is_output ? FMT_FLAGS_M2M : FMT_FLAGS_M2M | FMT_FLAGS_CAM; 891 mask = is_output ? FMT_FLAGS_M2M : FMT_FLAGS_M2M | FMT_FLAGS_CAM;
813 fmt = find_format(f, mask); 892 fmt = find_format(f, mask);
814 if (!fmt) { 893 if (!fmt) {
815 v4l2_err(&fimc->m2m.v4l2_dev, "Fourcc format (0x%X) invalid.\n", 894 v4l2_err(&fimc->m2m.v4l2_dev, "Fourcc format (0x%X) invalid.\n",
816 pix->pixelformat); 895 pix->pixelformat);
817 goto tf_out; 896 return -EINVAL;
818 } 897 }
819 898
820 if (pix->field == V4L2_FIELD_ANY) 899 if (pix->field == V4L2_FIELD_ANY)
821 pix->field = V4L2_FIELD_NONE; 900 pix->field = V4L2_FIELD_NONE;
822 else if (V4L2_FIELD_NONE != pix->field) 901 else if (V4L2_FIELD_NONE != pix->field)
823 goto tf_out; 902 return -EINVAL;
824 903
825 if (is_output) { 904 if (is_output) {
826 max_width = variant->pix_limit->scaler_dis_w; 905 max_width = variant->pix_limit->scaler_dis_w;
@@ -834,7 +913,7 @@ int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
834 mod_x = 6; /* 64 x 32 pixels tile */ 913 mod_x = 6; /* 64 x 32 pixels tile */
835 mod_y = 5; 914 mod_y = 5;
836 } else { 915 } else {
837 if (fimc->id == 1 && fimc->variant->pix_hoff) 916 if (fimc->id == 1 && variant->pix_hoff)
838 mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1; 917 mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
839 else 918 else
840 mod_y = mod_x; 919 mod_y = mod_x;
@@ -845,74 +924,72 @@ int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
845 v4l_bound_align_image(&pix->width, 16, max_width, mod_x, 924 v4l_bound_align_image(&pix->width, 16, max_width, mod_x,
846 &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0); 925 &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
847 926
848 if (pix->bytesperline == 0 || 927 pix->num_planes = fmt->memplanes;
849 (pix->bytesperline * 8 / fmt->depth) > pix->width) 928 pix->colorspace = V4L2_COLORSPACE_JPEG;
850 pix->bytesperline = (pix->width * fmt->depth) >> 3;
851 929
852 if (pix->sizeimage == 0) 930 for (i = 0; i < pix->num_planes; ++i) {
853 pix->sizeimage = pix->height * pix->bytesperline; 931 int bpl = pix->plane_fmt[i].bytesperline;
854 932
855 dbg("w: %d, h: %d, bpl: %d, depth: %d", 933 dbg("[%d] bpl: %d, depth: %d, w: %d, h: %d",
856 pix->width, pix->height, pix->bytesperline, fmt->depth); 934 i, bpl, fmt->depth[i], pix->width, pix->height);
857 935
858 ret = 0; 936 if (!bpl || (bpl * 8 / fmt->depth[i]) > pix->width)
937 bpl = (pix->width * fmt->depth[0]) >> 3;
859 938
860tf_out: 939 if (!pix->plane_fmt[i].sizeimage)
861 mutex_unlock(&fimc->lock); 940 pix->plane_fmt[i].sizeimage = pix->height * bpl;
862 return ret; 941
942 pix->plane_fmt[i].bytesperline = bpl;
943
944 dbg("[%d]: bpl: %d, sizeimage: %d",
945 i, pix->plane_fmt[i].bytesperline,
946 pix->plane_fmt[i].sizeimage);
947 }
948
949 return 0;
863} 950}
864 951
865static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) 952static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
953 struct v4l2_format *f)
866{ 954{
867 struct fimc_ctx *ctx = priv; 955 struct fimc_ctx *ctx = priv;
868 struct fimc_dev *fimc = ctx->fimc_dev; 956 struct fimc_dev *fimc = ctx->fimc_dev;
869 struct v4l2_device *v4l2_dev = &fimc->m2m.v4l2_dev; 957 struct vb2_queue *vq;
870 struct videobuf_queue *vq;
871 struct fimc_frame *frame; 958 struct fimc_frame *frame;
872 struct v4l2_pix_format *pix; 959 struct v4l2_pix_format_mplane *pix;
873 unsigned long flags; 960 int i, ret = 0;
874 int ret = 0;
875 961
876 ret = fimc_vidioc_try_fmt(file, priv, f); 962 ret = fimc_vidioc_try_fmt_mplane(file, priv, f);
877 if (ret) 963 if (ret)
878 return ret; 964 return ret;
879 965
880 if (mutex_lock_interruptible(&fimc->lock))
881 return -ERESTARTSYS;
882
883 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 966 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
884 mutex_lock(&vq->vb_lock);
885 967
886 if (videobuf_queue_is_busy(vq)) { 968 if (vb2_is_streaming(vq)) {
887 v4l2_err(v4l2_dev, "%s: queue (%d) busy\n", __func__, f->type); 969 v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type);
888 ret = -EBUSY; 970 return -EBUSY;
889 goto sf_out;
890 } 971 }
891 972
892 spin_lock_irqsave(&ctx->slock, flags); 973 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
893 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
894 frame = &ctx->s_frame; 974 frame = &ctx->s_frame;
895 ctx->state |= FIMC_SRC_FMT; 975 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
896 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
897 frame = &ctx->d_frame; 976 frame = &ctx->d_frame;
898 ctx->state |= FIMC_DST_FMT;
899 } else { 977 } else {
900 spin_unlock_irqrestore(&ctx->slock, flags); 978 v4l2_err(&fimc->m2m.v4l2_dev,
901 v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
902 "Wrong buffer/video queue type (%d)\n", f->type); 979 "Wrong buffer/video queue type (%d)\n", f->type);
903 ret = -EINVAL; 980 return -EINVAL;
904 goto sf_out;
905 } 981 }
906 spin_unlock_irqrestore(&ctx->slock, flags);
907 982
908 pix = &f->fmt.pix; 983 pix = &f->fmt.pix_mp;
909 frame->fmt = find_format(f, FMT_FLAGS_M2M); 984 frame->fmt = find_format(f, FMT_FLAGS_M2M);
910 if (!frame->fmt) { 985 if (!frame->fmt)
911 ret = -EINVAL; 986 return -EINVAL;
912 goto sf_out;
913 }
914 987
915 frame->f_width = pix->bytesperline * 8 / frame->fmt->depth; 988 for (i = 0; i < frame->fmt->colplanes; i++)
989 frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height;
990
991 frame->f_width = pix->plane_fmt[0].bytesperline * 8 /
992 frame->fmt->depth[0];
916 frame->f_height = pix->height; 993 frame->f_height = pix->height;
917 frame->width = pix->width; 994 frame->width = pix->width;
918 frame->height = pix->height; 995 frame->height = pix->height;
@@ -920,19 +997,15 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
920 frame->o_height = pix->height; 997 frame->o_height = pix->height;
921 frame->offs_h = 0; 998 frame->offs_h = 0;
922 frame->offs_v = 0; 999 frame->offs_v = 0;
923 frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3;
924 vq->field = pix->field;
925 1000
926 spin_lock_irqsave(&ctx->slock, flags); 1001 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
927 ctx->state |= FIMC_PARAMS; 1002 fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
928 spin_unlock_irqrestore(&ctx->slock, flags); 1003 else
1004 fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
929 1005
930 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height); 1006 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
931 1007
932sf_out: 1008 return 0;
933 mutex_unlock(&vq->vb_lock);
934 mutex_unlock(&fimc->lock);
935 return ret;
936} 1009}
937 1010
938static int fimc_m2m_reqbufs(struct file *file, void *priv, 1011static int fimc_m2m_reqbufs(struct file *file, void *priv,
@@ -968,6 +1041,15 @@ static int fimc_m2m_streamon(struct file *file, void *priv,
968 enum v4l2_buf_type type) 1041 enum v4l2_buf_type type)
969{ 1042{
970 struct fimc_ctx *ctx = priv; 1043 struct fimc_ctx *ctx = priv;
1044
1045 /* The source and target color format need to be set */
1046 if (V4L2_TYPE_IS_OUTPUT(type)) {
1047 if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
1048 return -EINVAL;
1049 } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
1050 return -EINVAL;
1051 }
1052
971 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); 1053 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
972} 1054}
973 1055
@@ -991,12 +1073,9 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
991 return 0; 1073 return 0;
992 } 1074 }
993 1075
994 if (ctx->state & FIMC_CTX_CAP) { 1076 if (fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx)) {
995 if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) 1077 return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
996 return -ERESTARTSYS;
997 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
998 core, queryctrl, qc); 1078 core, queryctrl, qc);
999 mutex_unlock(&ctx->fimc_dev->lock);
1000 } 1079 }
1001 return ret; 1080 return ret;
1002} 1081}
@@ -1006,10 +1085,6 @@ int fimc_vidioc_g_ctrl(struct file *file, void *priv,
1006{ 1085{
1007 struct fimc_ctx *ctx = priv; 1086 struct fimc_ctx *ctx = priv;
1008 struct fimc_dev *fimc = ctx->fimc_dev; 1087 struct fimc_dev *fimc = ctx->fimc_dev;
1009 int ret = 0;
1010
1011 if (mutex_lock_interruptible(&fimc->lock))
1012 return -ERESTARTSYS;
1013 1088
1014 switch (ctrl->id) { 1089 switch (ctrl->id) {
1015 case V4L2_CID_HFLIP: 1090 case V4L2_CID_HFLIP:
@@ -1022,19 +1097,17 @@ int fimc_vidioc_g_ctrl(struct file *file, void *priv,
1022 ctrl->value = ctx->rotation; 1097 ctrl->value = ctx->rotation;
1023 break; 1098 break;
1024 default: 1099 default:
1025 if (ctx->state & FIMC_CTX_CAP) { 1100 if (fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx)) {
1026 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, 1101 return v4l2_subdev_call(fimc->vid_cap.sd, core,
1027 g_ctrl, ctrl); 1102 g_ctrl, ctrl);
1028 } else { 1103 } else {
1029 v4l2_err(&fimc->m2m.v4l2_dev, 1104 v4l2_err(&fimc->m2m.v4l2_dev, "Invalid control\n");
1030 "Invalid control\n"); 1105 return -EINVAL;
1031 ret = -EINVAL;
1032 } 1106 }
1033 } 1107 }
1034 dbg("ctrl->value= %d", ctrl->value); 1108 dbg("ctrl->value= %d", ctrl->value);
1035 1109
1036 mutex_unlock(&fimc->lock); 1110 return 0;
1037 return ret;
1038} 1111}
1039 1112
1040int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl) 1113int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
@@ -1058,16 +1131,7 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
1058{ 1131{
1059 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; 1132 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
1060 struct fimc_dev *fimc = ctx->fimc_dev; 1133 struct fimc_dev *fimc = ctx->fimc_dev;
1061 unsigned long flags; 1134 int ret = 0;
1062
1063 if (ctx->rotation != 0 &&
1064 (ctrl->id == V4L2_CID_HFLIP || ctrl->id == V4L2_CID_VFLIP)) {
1065 v4l2_err(&fimc->m2m.v4l2_dev,
1066 "Simultaneous flip and rotation is not supported\n");
1067 return -EINVAL;
1068 }
1069
1070 spin_lock_irqsave(&ctx->slock, flags);
1071 1135
1072 switch (ctrl->id) { 1136 switch (ctrl->id) {
1073 case V4L2_CID_HFLIP: 1137 case V4L2_CID_HFLIP:
@@ -1085,29 +1149,36 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
1085 break; 1149 break;
1086 1150
1087 case V4L2_CID_ROTATE: 1151 case V4L2_CID_ROTATE:
1152 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
1153 ret = fimc_check_scaler_ratio(ctx->s_frame.width,
1154 ctx->s_frame.height, ctx->d_frame.width,
1155 ctx->d_frame.height, ctrl->value);
1156 }
1157
1158 if (ret) {
1159 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range\n");
1160 return -EINVAL;
1161 }
1162
1088 /* Check for the output rotator availability */ 1163 /* Check for the output rotator availability */
1089 if ((ctrl->value == 90 || ctrl->value == 270) && 1164 if ((ctrl->value == 90 || ctrl->value == 270) &&
1090 (ctx->in_path == FIMC_DMA && !variant->has_out_rot)) { 1165 (ctx->in_path == FIMC_DMA && !variant->has_out_rot))
1091 spin_unlock_irqrestore(&ctx->slock, flags);
1092 return -EINVAL; 1166 return -EINVAL;
1093 } else { 1167 ctx->rotation = ctrl->value;
1094 ctx->rotation = ctrl->value;
1095 }
1096 break; 1168 break;
1097 1169
1098 default: 1170 default:
1099 spin_unlock_irqrestore(&ctx->slock, flags);
1100 v4l2_err(&fimc->m2m.v4l2_dev, "Invalid control\n"); 1171 v4l2_err(&fimc->m2m.v4l2_dev, "Invalid control\n");
1101 return -EINVAL; 1172 return -EINVAL;
1102 } 1173 }
1103 ctx->state |= FIMC_PARAMS; 1174
1104 spin_unlock_irqrestore(&ctx->slock, flags); 1175 fimc_ctx_state_lock_set(FIMC_PARAMS, ctx);
1105 1176
1106 return 0; 1177 return 0;
1107} 1178}
1108 1179
1109static int fimc_m2m_s_ctrl(struct file *file, void *priv, 1180static int fimc_m2m_s_ctrl(struct file *file, void *priv,
1110 struct v4l2_control *ctrl) 1181 struct v4l2_control *ctrl)
1111{ 1182{
1112 struct fimc_ctx *ctx = priv; 1183 struct fimc_ctx *ctx = priv;
1113 int ret = 0; 1184 int ret = 0;
@@ -1125,22 +1196,17 @@ static int fimc_m2m_cropcap(struct file *file, void *fh,
1125{ 1196{
1126 struct fimc_frame *frame; 1197 struct fimc_frame *frame;
1127 struct fimc_ctx *ctx = fh; 1198 struct fimc_ctx *ctx = fh;
1128 struct fimc_dev *fimc = ctx->fimc_dev;
1129 1199
1130 frame = ctx_get_frame(ctx, cr->type); 1200 frame = ctx_get_frame(ctx, cr->type);
1131 if (IS_ERR(frame)) 1201 if (IS_ERR(frame))
1132 return PTR_ERR(frame); 1202 return PTR_ERR(frame);
1133 1203
1134 if (mutex_lock_interruptible(&fimc->lock))
1135 return -ERESTARTSYS;
1136
1137 cr->bounds.left = 0; 1204 cr->bounds.left = 0;
1138 cr->bounds.top = 0; 1205 cr->bounds.top = 0;
1139 cr->bounds.width = frame->f_width; 1206 cr->bounds.width = frame->f_width;
1140 cr->bounds.height = frame->f_height; 1207 cr->bounds.height = frame->f_height;
1141 cr->defrect = cr->bounds; 1208 cr->defrect = cr->bounds;
1142 1209
1143 mutex_unlock(&fimc->lock);
1144 return 0; 1210 return 0;
1145} 1211}
1146 1212
@@ -1148,21 +1214,16 @@ static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1148{ 1214{
1149 struct fimc_frame *frame; 1215 struct fimc_frame *frame;
1150 struct fimc_ctx *ctx = file->private_data; 1216 struct fimc_ctx *ctx = file->private_data;
1151 struct fimc_dev *fimc = ctx->fimc_dev;
1152 1217
1153 frame = ctx_get_frame(ctx, cr->type); 1218 frame = ctx_get_frame(ctx, cr->type);
1154 if (IS_ERR(frame)) 1219 if (IS_ERR(frame))
1155 return PTR_ERR(frame); 1220 return PTR_ERR(frame);
1156 1221
1157 if (mutex_lock_interruptible(&fimc->lock))
1158 return -ERESTARTSYS;
1159
1160 cr->c.left = frame->offs_h; 1222 cr->c.left = frame->offs_h;
1161 cr->c.top = frame->offs_v; 1223 cr->c.top = frame->offs_v;
1162 cr->c.width = frame->width; 1224 cr->c.width = frame->width;
1163 cr->c.height = frame->height; 1225 cr->c.height = frame->height;
1164 1226
1165 mutex_unlock(&fimc->lock);
1166 return 0; 1227 return 0;
1167} 1228}
1168 1229
@@ -1170,7 +1231,9 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1170{ 1231{
1171 struct fimc_dev *fimc = ctx->fimc_dev; 1232 struct fimc_dev *fimc = ctx->fimc_dev;
1172 struct fimc_frame *f; 1233 struct fimc_frame *f;
1173 u32 min_size, halign; 1234 u32 min_size, halign, depth = 0;
1235 bool is_capture_ctx;
1236 int i;
1174 1237
1175 if (cr->c.top < 0 || cr->c.left < 0) { 1238 if (cr->c.top < 0 || cr->c.left < 0) {
1176 v4l2_err(&fimc->m2m.v4l2_dev, 1239 v4l2_err(&fimc->m2m.v4l2_dev,
@@ -1178,10 +1241,12 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1178 return -EINVAL; 1241 return -EINVAL;
1179 } 1242 }
1180 1243
1181 if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1244 is_capture_ctx = fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx);
1182 f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame; 1245
1183 else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 1246 if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1184 ctx->state & FIMC_CTX_M2M) 1247 f = is_capture_ctx ? &ctx->s_frame : &ctx->d_frame;
1248 else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
1249 !is_capture_ctx)
1185 f = &ctx->s_frame; 1250 f = &ctx->s_frame;
1186 else 1251 else
1187 return -EINVAL; 1252 return -EINVAL;
@@ -1189,21 +1254,24 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1189 min_size = (f == &ctx->s_frame) ? 1254 min_size = (f == &ctx->s_frame) ?
1190 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; 1255 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
1191 1256
1192 if (ctx->state & FIMC_CTX_M2M) { 1257 /* Get pixel alignment constraints. */
1258 if (is_capture_ctx) {
1259 min_size = 16;
1260 halign = 4;
1261 } else {
1193 if (fimc->id == 1 && fimc->variant->pix_hoff) 1262 if (fimc->id == 1 && fimc->variant->pix_hoff)
1194 halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1; 1263 halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
1195 else 1264 else
1196 halign = ffs(min_size) - 1; 1265 halign = ffs(min_size) - 1;
1197 /* there are more strict aligment requirements at camera interface */
1198 } else {
1199 min_size = 16;
1200 halign = 4;
1201 } 1266 }
1202 1267
1268 for (i = 0; i < f->fmt->colplanes; i++)
1269 depth += f->fmt->depth[i];
1270
1203 v4l_bound_align_image(&cr->c.width, min_size, f->o_width, 1271 v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
1204 ffs(min_size) - 1, 1272 ffs(min_size) - 1,
1205 &cr->c.height, min_size, f->o_height, 1273 &cr->c.height, min_size, f->o_height,
1206 halign, 64/(ALIGN(f->fmt->depth, 8))); 1274 halign, 64/(ALIGN(depth, 8)));
1207 1275
1208 /* adjust left/top if cropping rectangle is out of bounds */ 1276 /* adjust left/top if cropping rectangle is out of bounds */
1209 if (cr->c.left + cr->c.width > f->o_width) 1277 if (cr->c.left + cr->c.width > f->o_width)
@@ -1212,8 +1280,7 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1212 cr->c.top = f->o_height - cr->c.height; 1280 cr->c.top = f->o_height - cr->c.height;
1213 1281
1214 cr->c.left = round_down(cr->c.left, min_size); 1282 cr->c.left = round_down(cr->c.left, min_size);
1215 cr->c.top = round_down(cr->c.top, 1283 cr->c.top = round_down(cr->c.top, is_capture_ctx ? 16 : 8);
1216 ctx->state & FIMC_CTX_M2M ? 8 : 16);
1217 1284
1218 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d", 1285 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
1219 cr->c.left, cr->c.top, cr->c.width, cr->c.height, 1286 cr->c.left, cr->c.top, cr->c.width, cr->c.height,
@@ -1222,12 +1289,10 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1222 return 0; 1289 return 0;
1223} 1290}
1224 1291
1225
1226static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1292static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1227{ 1293{
1228 struct fimc_ctx *ctx = file->private_data; 1294 struct fimc_ctx *ctx = file->private_data;
1229 struct fimc_dev *fimc = ctx->fimc_dev; 1295 struct fimc_dev *fimc = ctx->fimc_dev;
1230 unsigned long flags;
1231 struct fimc_frame *f; 1296 struct fimc_frame *f;
1232 int ret; 1297 int ret;
1233 1298
@@ -1235,52 +1300,52 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1235 if (ret) 1300 if (ret)
1236 return ret; 1301 return ret;
1237 1302
1238 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? 1303 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
1239 &ctx->s_frame : &ctx->d_frame; 1304 &ctx->s_frame : &ctx->d_frame;
1240 1305
1241 if (mutex_lock_interruptible(&fimc->lock)) 1306 /* Check to see if scaling ratio is within supported range */
1242 return -ERESTARTSYS; 1307 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
1243 1308 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1244 spin_lock_irqsave(&ctx->slock, flags); 1309 ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height,
1245 if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { 1310 ctx->d_frame.width,
1246 /* Check to see if scaling ratio is within supported range */ 1311 ctx->d_frame.height,
1247 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 1312 ctx->rotation);
1248 ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); 1313 } else {
1249 else 1314 ret = fimc_check_scaler_ratio(ctx->s_frame.width,
1250 ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); 1315 ctx->s_frame.height,
1316 cr->c.width, cr->c.height,
1317 ctx->rotation);
1318 }
1251 if (ret) { 1319 if (ret) {
1252 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); 1320 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range\n");
1253 ret = -EINVAL; 1321 return -EINVAL;
1254 goto scr_unlock;
1255 } 1322 }
1256 } 1323 }
1257 ctx->state |= FIMC_PARAMS;
1258 1324
1259 f->offs_h = cr->c.left; 1325 f->offs_h = cr->c.left;
1260 f->offs_v = cr->c.top; 1326 f->offs_v = cr->c.top;
1261 f->width = cr->c.width; 1327 f->width = cr->c.width;
1262 f->height = cr->c.height; 1328 f->height = cr->c.height;
1263 1329
1264scr_unlock: 1330 fimc_ctx_state_lock_set(FIMC_PARAMS, ctx);
1265 spin_unlock_irqrestore(&ctx->slock, flags); 1331
1266 mutex_unlock(&fimc->lock);
1267 return 0; 1332 return 0;
1268} 1333}
1269 1334
1270static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { 1335static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
1271 .vidioc_querycap = fimc_m2m_querycap, 1336 .vidioc_querycap = fimc_m2m_querycap,
1272 1337
1273 .vidioc_enum_fmt_vid_cap = fimc_vidioc_enum_fmt, 1338 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane,
1274 .vidioc_enum_fmt_vid_out = fimc_vidioc_enum_fmt, 1339 .vidioc_enum_fmt_vid_out_mplane = fimc_vidioc_enum_fmt_mplane,
1275 1340
1276 .vidioc_g_fmt_vid_cap = fimc_vidioc_g_fmt, 1341 .vidioc_g_fmt_vid_cap_mplane = fimc_vidioc_g_fmt_mplane,
1277 .vidioc_g_fmt_vid_out = fimc_vidioc_g_fmt, 1342 .vidioc_g_fmt_vid_out_mplane = fimc_vidioc_g_fmt_mplane,
1278 1343
1279 .vidioc_try_fmt_vid_cap = fimc_vidioc_try_fmt, 1344 .vidioc_try_fmt_vid_cap_mplane = fimc_vidioc_try_fmt_mplane,
1280 .vidioc_try_fmt_vid_out = fimc_vidioc_try_fmt, 1345 .vidioc_try_fmt_vid_out_mplane = fimc_vidioc_try_fmt_mplane,
1281 1346
1282 .vidioc_s_fmt_vid_cap = fimc_m2m_s_fmt, 1347 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
1283 .vidioc_s_fmt_vid_out = fimc_m2m_s_fmt, 1348 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
1284 1349
1285 .vidioc_reqbufs = fimc_m2m_reqbufs, 1350 .vidioc_reqbufs = fimc_m2m_reqbufs,
1286 .vidioc_querybuf = fimc_m2m_querybuf, 1351 .vidioc_querybuf = fimc_m2m_querybuf,
@@ -1301,26 +1366,39 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
1301 1366
1302}; 1367};
1303 1368
1304static void queue_init(void *priv, struct videobuf_queue *vq, 1369static int queue_init(void *priv, struct vb2_queue *src_vq,
1305 enum v4l2_buf_type type) 1370 struct vb2_queue *dst_vq)
1306{ 1371{
1307 struct fimc_ctx *ctx = priv; 1372 struct fimc_ctx *ctx = priv;
1308 struct fimc_dev *fimc = ctx->fimc_dev; 1373 int ret;
1374
1375 memset(src_vq, 0, sizeof(*src_vq));
1376 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1377 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1378 src_vq->drv_priv = ctx;
1379 src_vq->ops = &fimc_qops;
1380 src_vq->mem_ops = &vb2_dma_contig_memops;
1381 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1382
1383 ret = vb2_queue_init(src_vq);
1384 if (ret)
1385 return ret;
1309 1386
1310 videobuf_queue_dma_contig_init(vq, &fimc_qops, 1387 memset(dst_vq, 0, sizeof(*dst_vq));
1311 &fimc->pdev->dev, 1388 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1312 &fimc->irqlock, type, V4L2_FIELD_NONE, 1389 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1313 sizeof(struct fimc_vid_buffer), priv, NULL); 1390 dst_vq->drv_priv = ctx;
1391 dst_vq->ops = &fimc_qops;
1392 dst_vq->mem_ops = &vb2_dma_contig_memops;
1393 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1394
1395 return vb2_queue_init(dst_vq);
1314} 1396}
1315 1397
1316static int fimc_m2m_open(struct file *file) 1398static int fimc_m2m_open(struct file *file)
1317{ 1399{
1318 struct fimc_dev *fimc = video_drvdata(file); 1400 struct fimc_dev *fimc = video_drvdata(file);
1319 struct fimc_ctx *ctx = NULL; 1401 struct fimc_ctx *ctx = NULL;
1320 int err = 0;
1321
1322 if (mutex_lock_interruptible(&fimc->lock))
1323 return -ERESTARTSYS;
1324 1402
1325 dbg("pid: %d, state: 0x%lx, refcnt: %d", 1403 dbg("pid: %d, state: 0x%lx, refcnt: %d",
1326 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); 1404 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
@@ -1329,19 +1407,15 @@ static int fimc_m2m_open(struct file *file)
1329 * Return if the corresponding video capture node 1407 * Return if the corresponding video capture node
1330 * is already opened. 1408 * is already opened.
1331 */ 1409 */
1332 if (fimc->vid_cap.refcnt > 0) { 1410 if (fimc->vid_cap.refcnt > 0)
1333 err = -EBUSY; 1411 return -EBUSY;
1334 goto err_unlock;
1335 }
1336 1412
1337 fimc->m2m.refcnt++; 1413 fimc->m2m.refcnt++;
1338 set_bit(ST_OUTDMA_RUN, &fimc->state); 1414 set_bit(ST_OUTDMA_RUN, &fimc->state);
1339 1415
1340 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 1416 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
1341 if (!ctx) { 1417 if (!ctx)
1342 err = -ENOMEM; 1418 return -ENOMEM;
1343 goto err_unlock;
1344 }
1345 1419
1346 file->private_data = ctx; 1420 file->private_data = ctx;
1347 ctx->fimc_dev = fimc; 1421 ctx->fimc_dev = fimc;
@@ -1355,15 +1429,14 @@ static int fimc_m2m_open(struct file *file)
1355 ctx->out_path = FIMC_DMA; 1429 ctx->out_path = FIMC_DMA;
1356 spin_lock_init(&ctx->slock); 1430 spin_lock_init(&ctx->slock);
1357 1431
1358 ctx->m2m_ctx = v4l2_m2m_ctx_init(ctx, fimc->m2m.m2m_dev, queue_init); 1432 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
1359 if (IS_ERR(ctx->m2m_ctx)) { 1433 if (IS_ERR(ctx->m2m_ctx)) {
1360 err = PTR_ERR(ctx->m2m_ctx); 1434 int err = PTR_ERR(ctx->m2m_ctx);
1361 kfree(ctx); 1435 kfree(ctx);
1436 return err;
1362 } 1437 }
1363 1438
1364err_unlock: 1439 return 0;
1365 mutex_unlock(&fimc->lock);
1366 return err;
1367} 1440}
1368 1441
1369static int fimc_m2m_release(struct file *file) 1442static int fimc_m2m_release(struct file *file)
@@ -1371,8 +1444,6 @@ static int fimc_m2m_release(struct file *file)
1371 struct fimc_ctx *ctx = file->private_data; 1444 struct fimc_ctx *ctx = file->private_data;
1372 struct fimc_dev *fimc = ctx->fimc_dev; 1445 struct fimc_dev *fimc = ctx->fimc_dev;
1373 1446
1374 mutex_lock(&fimc->lock);
1375
1376 dbg("pid: %d, state: 0x%lx, refcnt= %d", 1447 dbg("pid: %d, state: 0x%lx, refcnt= %d",
1377 task_pid_nr(current), fimc->state, fimc->m2m.refcnt); 1448 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
1378 1449
@@ -1381,7 +1452,6 @@ static int fimc_m2m_release(struct file *file)
1381 if (--fimc->m2m.refcnt <= 0) 1452 if (--fimc->m2m.refcnt <= 0)
1382 clear_bit(ST_OUTDMA_RUN, &fimc->state); 1453 clear_bit(ST_OUTDMA_RUN, &fimc->state);
1383 1454
1384 mutex_unlock(&fimc->lock);
1385 return 0; 1455 return 0;
1386} 1456}
1387 1457
@@ -1415,7 +1485,6 @@ static struct v4l2_m2m_ops m2m_ops = {
1415 .job_abort = fimc_job_abort, 1485 .job_abort = fimc_job_abort,
1416}; 1486};
1417 1487
1418
1419static int fimc_register_m2m_device(struct fimc_dev *fimc) 1488static int fimc_register_m2m_device(struct fimc_dev *fimc)
1420{ 1489{
1421 struct video_device *vfd; 1490 struct video_device *vfd;
@@ -1448,6 +1517,7 @@ static int fimc_register_m2m_device(struct fimc_dev *fimc)
1448 vfd->ioctl_ops = &fimc_m2m_ioctl_ops; 1517 vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
1449 vfd->minor = -1; 1518 vfd->minor = -1;
1450 vfd->release = video_device_release; 1519 vfd->release = video_device_release;
1520 vfd->lock = &fimc->lock;
1451 1521
1452 snprintf(vfd->name, sizeof(vfd->name), "%s:m2m", dev_name(&pdev->dev)); 1522 snprintf(vfd->name, sizeof(vfd->name), "%s:m2m", dev_name(&pdev->dev));
1453 1523
@@ -1496,7 +1566,7 @@ static void fimc_unregister_m2m_device(struct fimc_dev *fimc)
1496static void fimc_clk_release(struct fimc_dev *fimc) 1566static void fimc_clk_release(struct fimc_dev *fimc)
1497{ 1567{
1498 int i; 1568 int i;
1499 for (i = 0; i < NUM_FIMC_CLOCKS; i++) { 1569 for (i = 0; i < fimc->num_clocks; i++) {
1500 if (fimc->clock[i]) { 1570 if (fimc->clock[i]) {
1501 clk_disable(fimc->clock[i]); 1571 clk_disable(fimc->clock[i]);
1502 clk_put(fimc->clock[i]); 1572 clk_put(fimc->clock[i]);
@@ -1507,15 +1577,16 @@ static void fimc_clk_release(struct fimc_dev *fimc)
1507static int fimc_clk_get(struct fimc_dev *fimc) 1577static int fimc_clk_get(struct fimc_dev *fimc)
1508{ 1578{
1509 int i; 1579 int i;
1510 for (i = 0; i < NUM_FIMC_CLOCKS; i++) { 1580 for (i = 0; i < fimc->num_clocks; i++) {
1511 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clock_name[i]); 1581 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
1512 if (IS_ERR(fimc->clock[i])) { 1582
1513 dev_err(&fimc->pdev->dev, 1583 if (!IS_ERR_OR_NULL(fimc->clock[i])) {
1514 "failed to get fimc clock: %s\n", 1584 clk_enable(fimc->clock[i]);
1515 fimc_clock_name[i]); 1585 continue;
1516 return -ENXIO;
1517 } 1586 }
1518 clk_enable(fimc->clock[i]); 1587 dev_err(&fimc->pdev->dev, "failed to get fimc clock: %s\n",
1588 fimc_clocks[i]);
1589 return -ENXIO;
1519 } 1590 }
1520 return 0; 1591 return 0;
1521} 1592}
@@ -1525,7 +1596,9 @@ static int fimc_probe(struct platform_device *pdev)
1525 struct fimc_dev *fimc; 1596 struct fimc_dev *fimc;
1526 struct resource *res; 1597 struct resource *res;
1527 struct samsung_fimc_driverdata *drv_data; 1598 struct samsung_fimc_driverdata *drv_data;
1599 struct s5p_platform_fimc *pdata;
1528 int ret = 0; 1600 int ret = 0;
1601 int cap_input_index = -1;
1529 1602
1530 dev_dbg(&pdev->dev, "%s():\n", __func__); 1603 dev_dbg(&pdev->dev, "%s():\n", __func__);
1531 1604
@@ -1545,10 +1618,10 @@ static int fimc_probe(struct platform_device *pdev)
1545 fimc->id = pdev->id; 1618 fimc->id = pdev->id;
1546 fimc->variant = drv_data->variant[fimc->id]; 1619 fimc->variant = drv_data->variant[fimc->id];
1547 fimc->pdev = pdev; 1620 fimc->pdev = pdev;
1548 fimc->pdata = pdev->dev.platform_data; 1621 pdata = pdev->dev.platform_data;
1622 fimc->pdata = pdata;
1549 fimc->state = ST_IDLE; 1623 fimc->state = ST_IDLE;
1550 1624
1551 spin_lock_init(&fimc->irqlock);
1552 init_waitqueue_head(&fimc->irq_queue); 1625 init_waitqueue_head(&fimc->irq_queue);
1553 spin_lock_init(&fimc->slock); 1626 spin_lock_init(&fimc->slock);
1554 1627
@@ -1576,10 +1649,18 @@ static int fimc_probe(struct platform_device *pdev)
1576 goto err_req_region; 1649 goto err_req_region;
1577 } 1650 }
1578 1651
1652 fimc->num_clocks = MAX_FIMC_CLOCKS - 1;
1653
1654 /* Check if a video capture node needs to be registered. */
1655 if (pdata && pdata->num_clients > 0) {
1656 cap_input_index = 0;
1657 fimc->num_clocks++;
1658 }
1659
1579 ret = fimc_clk_get(fimc); 1660 ret = fimc_clk_get(fimc);
1580 if (ret) 1661 if (ret)
1581 goto err_regs_unmap; 1662 goto err_regs_unmap;
1582 clk_set_rate(fimc->clock[0], drv_data->lclk_frequency); 1663 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
1583 1664
1584 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1665 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1585 if (!res) { 1666 if (!res) {
@@ -1597,24 +1678,24 @@ static int fimc_probe(struct platform_device *pdev)
1597 goto err_clk; 1678 goto err_clk;
1598 } 1679 }
1599 1680
1681 /* Initialize contiguous memory allocator */
1682 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&fimc->pdev->dev);
1683 if (IS_ERR(fimc->alloc_ctx)) {
1684 ret = PTR_ERR(fimc->alloc_ctx);
1685 goto err_irq;
1686 }
1687
1600 ret = fimc_register_m2m_device(fimc); 1688 ret = fimc_register_m2m_device(fimc);
1601 if (ret) 1689 if (ret)
1602 goto err_irq; 1690 goto err_irq;
1603 1691
1604 /* At least one camera sensor is required to register capture node */ 1692 /* At least one camera sensor is required to register capture node */
1605 if (fimc->pdata) { 1693 if (cap_input_index >= 0) {
1606 int i; 1694 ret = fimc_register_capture_device(fimc);
1607 for (i = 0; i < FIMC_MAX_CAMIF_CLIENTS; ++i) 1695 if (ret)
1608 if (fimc->pdata->isp_info[i]) 1696 goto err_m2m;
1609 break; 1697 clk_disable(fimc->clock[CLK_CAM]);
1610
1611 if (i < FIMC_MAX_CAMIF_CLIENTS) {
1612 ret = fimc_register_capture_device(fimc);
1613 if (ret)
1614 goto err_m2m;
1615 }
1616 } 1698 }
1617
1618 /* 1699 /*
1619 * Exclude the additional output DMA address registers by masking 1700 * Exclude the additional output DMA address registers by masking
1620 * them out on HW revisions that provide extended capabilites. 1701 * them out on HW revisions that provide extended capabilites.
@@ -1656,6 +1737,9 @@ static int __devexit fimc_remove(struct platform_device *pdev)
1656 fimc_unregister_capture_device(fimc); 1737 fimc_unregister_capture_device(fimc);
1657 1738
1658 fimc_clk_release(fimc); 1739 fimc_clk_release(fimc);
1740
1741 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1742
1659 iounmap(fimc->regs); 1743 iounmap(fimc->regs);
1660 release_resource(fimc->regs_res); 1744 release_resource(fimc->regs_res);
1661 kfree(fimc->regs_res); 1745 kfree(fimc->regs_res);
@@ -1726,6 +1810,7 @@ static struct samsung_fimc_variant fimc1_variant_s5pv210 = {
1726 .pix_hoff = 1, 1810 .pix_hoff = 1,
1727 .has_inp_rot = 1, 1811 .has_inp_rot = 1,
1728 .has_out_rot = 1, 1812 .has_out_rot = 1,
1813 .has_mainscaler_ext = 1,
1729 .min_inp_pixsize = 16, 1814 .min_inp_pixsize = 16,
1730 .min_out_pixsize = 16, 1815 .min_out_pixsize = 16,
1731 .hor_offs_align = 1, 1816 .hor_offs_align = 1,
@@ -1747,6 +1832,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
1747 .has_inp_rot = 1, 1832 .has_inp_rot = 1,
1748 .has_out_rot = 1, 1833 .has_out_rot = 1,
1749 .has_cistatus2 = 1, 1834 .has_cistatus2 = 1,
1835 .has_mainscaler_ext = 1,
1750 .min_inp_pixsize = 16, 1836 .min_inp_pixsize = 16,
1751 .min_out_pixsize = 16, 1837 .min_out_pixsize = 16,
1752 .hor_offs_align = 1, 1838 .hor_offs_align = 1,
@@ -1757,6 +1843,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
1757static struct samsung_fimc_variant fimc2_variant_s5pv310 = { 1843static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
1758 .pix_hoff = 1, 1844 .pix_hoff = 1,
1759 .has_cistatus2 = 1, 1845 .has_cistatus2 = 1,
1846 .has_mainscaler_ext = 1,
1760 .min_inp_pixsize = 16, 1847 .min_inp_pixsize = 16,
1761 .min_out_pixsize = 16, 1848 .min_out_pixsize = 16,
1762 .hor_offs_align = 1, 1849 .hor_offs_align = 1,
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 4f047d35f8ad..3beb1e5320ce 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -14,29 +14,27 @@
14/*#define DEBUG*/ 14/*#define DEBUG*/
15 15
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/spinlock.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/videodev2.h> 19#include <linux/videodev2.h>
19#include <media/videobuf-core.h> 20#include <linux/io.h>
21#include <media/videobuf2-core.h>
20#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
21#include <media/v4l2-mem2mem.h> 23#include <media/v4l2-mem2mem.h>
22#include <media/v4l2-mediabus.h> 24#include <media/v4l2-mediabus.h>
23#include <media/s3c_fimc.h> 25#include <media/s5p_fimc.h>
24 26
25#include "regs-fimc.h" 27#include "regs-fimc.h"
26 28
27#define err(fmt, args...) \ 29#define err(fmt, args...) \
28 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args) 30 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
29 31
30#ifdef DEBUG
31#define dbg(fmt, args...) \ 32#define dbg(fmt, args...) \
32 printk(KERN_DEBUG "%s:%d: " fmt "\n", __func__, __LINE__, ##args) 33 pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
33#else
34#define dbg(fmt, args...)
35#endif
36 34
37/* Time to wait for next frame VSYNC interrupt while stopping operation. */ 35/* Time to wait for next frame VSYNC interrupt while stopping operation. */
38#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000) 36#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
39#define NUM_FIMC_CLOCKS 2 37#define MAX_FIMC_CLOCKS 3
40#define MODULE_NAME "s5p-fimc" 38#define MODULE_NAME "s5p-fimc"
41#define FIMC_MAX_DEVS 4 39#define FIMC_MAX_DEVS 4
42#define FIMC_MAX_OUT_BUFS 4 40#define FIMC_MAX_OUT_BUFS 4
@@ -44,7 +42,13 @@
44#define SCALER_MAX_VRATIO 64 42#define SCALER_MAX_VRATIO 64
45#define DMA_MIN_SIZE 8 43#define DMA_MIN_SIZE 8
46 44
47/* FIMC device state flags */ 45/* indices to the clocks array */
46enum {
47 CLK_BUS,
48 CLK_GATE,
49 CLK_CAM,
50};
51
48enum fimc_dev_flags { 52enum fimc_dev_flags {
49 /* for m2m node */ 53 /* for m2m node */
50 ST_IDLE, 54 ST_IDLE,
@@ -63,20 +67,6 @@ enum fimc_dev_flags {
63#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state) 67#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
64#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state) 68#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
65 69
66#define fimc_capture_active(dev) \
67 (test_bit(ST_CAPT_RUN, &(dev)->state) || \
68 test_bit(ST_CAPT_PEND, &(dev)->state))
69
70#define fimc_capture_streaming(dev) \
71 test_bit(ST_CAPT_STREAM, &(dev)->state)
72
73#define fimc_buf_finish(dev, vid_buf) do { \
74 spin_lock(&(dev)->irqlock); \
75 (vid_buf)->vb.state = VIDEOBUF_DONE; \
76 spin_unlock(&(dev)->irqlock); \
77 wake_up(&(vid_buf)->vb.done); \
78} while (0)
79
80enum fimc_datapath { 70enum fimc_datapath {
81 FIMC_CAMERA, 71 FIMC_CAMERA,
82 FIMC_DMA, 72 FIMC_DMA,
@@ -90,7 +80,6 @@ enum fimc_color_fmt {
90 S5P_FIMC_RGB888, 80 S5P_FIMC_RGB888,
91 S5P_FIMC_RGB30_LOCAL, 81 S5P_FIMC_RGB30_LOCAL,
92 S5P_FIMC_YCBCR420 = 0x20, 82 S5P_FIMC_YCBCR420 = 0x20,
93 S5P_FIMC_YCBCR422,
94 S5P_FIMC_YCBYCR422, 83 S5P_FIMC_YCBYCR422,
95 S5P_FIMC_YCRYCB422, 84 S5P_FIMC_YCRYCB422,
96 S5P_FIMC_CBYCRY422, 85 S5P_FIMC_CBYCRY422,
@@ -100,18 +89,6 @@ enum fimc_color_fmt {
100 89
101#define fimc_fmt_is_rgb(x) ((x) & 0x10) 90#define fimc_fmt_is_rgb(x) ((x) & 0x10)
102 91
103/* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */
104#define S5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY
105#define S5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB
106#define S5P_FIMC_OUT_YCRYCB S5P_CIOCTRL_ORDER422_CBYCRY
107#define S5P_FIMC_OUT_YCBYCR S5P_CIOCTRL_ORDER422_YCBYCR
108
109/* Input Y/Cb/Cr components order for 1 plane YCbCr 4:2:2 color formats. */
110#define S5P_FIMC_IN_CRYCBY S5P_MSCTRL_ORDER422_CRYCBY
111#define S5P_FIMC_IN_CBYCRY S5P_MSCTRL_ORDER422_YCRYCB
112#define S5P_FIMC_IN_YCRYCB S5P_MSCTRL_ORDER422_CBYCRY
113#define S5P_FIMC_IN_YCBYCR S5P_MSCTRL_ORDER422_YCBYCR
114
115/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */ 92/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */
116#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB 93#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB
117 94
@@ -131,6 +108,7 @@ enum fimc_color_fmt {
131#define FIMC_DST_FMT (1 << 4) 108#define FIMC_DST_FMT (1 << 4)
132#define FIMC_CTX_M2M (1 << 5) 109#define FIMC_CTX_M2M (1 << 5)
133#define FIMC_CTX_CAP (1 << 6) 110#define FIMC_CTX_CAP (1 << 6)
111#define FIMC_CTX_SHUT (1 << 7)
134 112
135/* Image conversion flags */ 113/* Image conversion flags */
136#define FIMC_IN_DMA_ACCESS_TILED (1 << 0) 114#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
@@ -157,18 +135,18 @@ enum fimc_color_fmt {
157 * @name: format description 135 * @name: format description
158 * @fourcc: the fourcc code for this format, 0 if not applicable 136 * @fourcc: the fourcc code for this format, 0 if not applicable
159 * @color: the corresponding fimc_color_fmt 137 * @color: the corresponding fimc_color_fmt
160 * @depth: driver's private 'number of bits per pixel' 138 * @depth: per plane driver's private 'number of bits per pixel'
161 * @buff_cnt: number of physically non-contiguous data planes 139 * @memplanes: number of physically non-contiguous data planes
162 * @planes_cnt: number of physically contiguous data planes 140 * @colplanes: number of physically contiguous data planes
163 */ 141 */
164struct fimc_fmt { 142struct fimc_fmt {
165 enum v4l2_mbus_pixelcode mbus_code; 143 enum v4l2_mbus_pixelcode mbus_code;
166 char *name; 144 char *name;
167 u32 fourcc; 145 u32 fourcc;
168 u32 color; 146 u32 color;
169 u16 buff_cnt; 147 u16 memplanes;
170 u16 planes_cnt; 148 u16 colplanes;
171 u16 depth; 149 u8 depth[VIDEO_MAX_PLANES];
172 u16 flags; 150 u16 flags;
173#define FMT_FLAGS_CAM (1 << 0) 151#define FMT_FLAGS_CAM (1 << 0)
174#define FMT_FLAGS_M2M (1 << 1) 152#define FMT_FLAGS_M2M (1 << 1)
@@ -260,7 +238,8 @@ struct fimc_addr {
260 * @index: buffer index for the output DMA engine 238 * @index: buffer index for the output DMA engine
261 */ 239 */
262struct fimc_vid_buffer { 240struct fimc_vid_buffer {
263 struct videobuf_buffer vb; 241 struct vb2_buffer vb;
242 struct list_head list;
264 struct fimc_addr paddr; 243 struct fimc_addr paddr;
265 int index; 244 int index;
266}; 245};
@@ -277,7 +256,7 @@ struct fimc_vid_buffer {
277 * @height: image pixel weight 256 * @height: image pixel weight
278 * @paddr: image frame buffer physical addresses 257 * @paddr: image frame buffer physical addresses
279 * @buf_cnt: number of buffers depending on a color format 258 * @buf_cnt: number of buffers depending on a color format
280 * @size: image size in bytes 259 * @payload: image size in bytes (w x h x bpp)
281 * @color: color format 260 * @color: color format
282 * @dma_offset: DMA offset in bytes 261 * @dma_offset: DMA offset in bytes
283 */ 262 */
@@ -290,7 +269,7 @@ struct fimc_frame {
290 u32 offs_v; 269 u32 offs_v;
291 u32 width; 270 u32 width;
292 u32 height; 271 u32 height;
293 u32 size; 272 unsigned long payload[VIDEO_MAX_PLANES];
294 struct fimc_addr paddr; 273 struct fimc_addr paddr;
295 struct fimc_dma_offset dma_offset; 274 struct fimc_dma_offset dma_offset;
296 struct fimc_fmt *fmt; 275 struct fimc_fmt *fmt;
@@ -331,13 +310,14 @@ struct fimc_m2m_device {
331 */ 310 */
332struct fimc_vid_cap { 311struct fimc_vid_cap {
333 struct fimc_ctx *ctx; 312 struct fimc_ctx *ctx;
313 struct vb2_alloc_ctx *alloc_ctx;
334 struct video_device *vfd; 314 struct video_device *vfd;
335 struct v4l2_device v4l2_dev; 315 struct v4l2_device v4l2_dev;
336 struct v4l2_subdev *sd; 316 struct v4l2_subdev *sd;;
337 struct v4l2_mbus_framefmt fmt; 317 struct v4l2_mbus_framefmt fmt;
338 struct list_head pending_buf_q; 318 struct list_head pending_buf_q;
339 struct list_head active_buf_q; 319 struct list_head active_buf_q;
340 struct videobuf_queue vbq; 320 struct vb2_queue vbq;
341 int active_buf_cnt; 321 int active_buf_cnt;
342 int buf_index; 322 int buf_index;
343 unsigned int frame_count; 323 unsigned int frame_count;
@@ -372,6 +352,8 @@ struct fimc_pix_limit {
372 * @has_inp_rot: set if has input rotator 352 * @has_inp_rot: set if has input rotator
373 * @has_out_rot: set if has output rotator 353 * @has_out_rot: set if has output rotator
374 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision 354 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
355 * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register
356 * are present in this IP revision
375 * @pix_limit: pixel size constraints for the scaler 357 * @pix_limit: pixel size constraints for the scaler
376 * @min_inp_pixsize: minimum input pixel size 358 * @min_inp_pixsize: minimum input pixel size
377 * @min_out_pixsize: minimum output pixel size 359 * @min_out_pixsize: minimum output pixel size
@@ -383,6 +365,7 @@ struct samsung_fimc_variant {
383 unsigned int has_inp_rot:1; 365 unsigned int has_inp_rot:1;
384 unsigned int has_out_rot:1; 366 unsigned int has_out_rot:1;
385 unsigned int has_cistatus2:1; 367 unsigned int has_cistatus2:1;
368 unsigned int has_mainscaler_ext:1;
386 struct fimc_pix_limit *pix_limit; 369 struct fimc_pix_limit *pix_limit;
387 u16 min_inp_pixsize; 370 u16 min_inp_pixsize;
388 u16 min_out_pixsize; 371 u16 min_out_pixsize;
@@ -412,12 +395,12 @@ struct fimc_ctx;
412 * @lock: the mutex protecting this data structure 395 * @lock: the mutex protecting this data structure
413 * @pdev: pointer to the FIMC platform device 396 * @pdev: pointer to the FIMC platform device
414 * @pdata: pointer to the device platform data 397 * @pdata: pointer to the device platform data
415 * @id: FIMC device index (0..2) 398 * @id: FIMC device index (0..FIMC_MAX_DEVS)
399 * @num_clocks: the number of clocks managed by this device instance
416 * @clock[]: the clocks required for FIMC operation 400 * @clock[]: the clocks required for FIMC operation
417 * @regs: the mapped hardware registers 401 * @regs: the mapped hardware registers
418 * @regs_res: the resource claimed for IO registers 402 * @regs_res: the resource claimed for IO registers
419 * @irq: interrupt number of the FIMC subdevice 403 * @irq: interrupt number of the FIMC subdevice
420 * @irqlock: spinlock protecting videobuffer queue
421 * @irq_queue: 404 * @irq_queue:
422 * @m2m: memory-to-memory V4L2 device information 405 * @m2m: memory-to-memory V4L2 device information
423 * @vid_cap: camera capture device information 406 * @vid_cap: camera capture device information
@@ -427,18 +410,19 @@ struct fimc_dev {
427 spinlock_t slock; 410 spinlock_t slock;
428 struct mutex lock; 411 struct mutex lock;
429 struct platform_device *pdev; 412 struct platform_device *pdev;
430 struct s3c_platform_fimc *pdata; 413 struct s5p_platform_fimc *pdata;
431 struct samsung_fimc_variant *variant; 414 struct samsung_fimc_variant *variant;
432 int id; 415 u16 id;
433 struct clk *clock[NUM_FIMC_CLOCKS]; 416 u16 num_clocks;
417 struct clk *clock[MAX_FIMC_CLOCKS];
434 void __iomem *regs; 418 void __iomem *regs;
435 struct resource *regs_res; 419 struct resource *regs_res;
436 int irq; 420 int irq;
437 spinlock_t irqlock;
438 wait_queue_head_t irq_queue; 421 wait_queue_head_t irq_queue;
439 struct fimc_m2m_device m2m; 422 struct fimc_m2m_device m2m;
440 struct fimc_vid_cap vid_cap; 423 struct fimc_vid_cap vid_cap;
441 unsigned long state; 424 unsigned long state;
425 struct vb2_alloc_ctx *alloc_ctx;
442}; 426};
443 427
444/** 428/**
@@ -482,11 +466,41 @@ struct fimc_ctx {
482 struct v4l2_m2m_ctx *m2m_ctx; 466 struct v4l2_m2m_ctx *m2m_ctx;
483}; 467};
484 468
485extern struct videobuf_queue_ops fimc_qops; 469static inline bool fimc_capture_active(struct fimc_dev *fimc)
470{
471 unsigned long flags;
472 bool ret;
473
474 spin_lock_irqsave(&fimc->slock, flags);
475 ret = !!(fimc->state & (1 << ST_CAPT_RUN) ||
476 fimc->state & (1 << ST_CAPT_PEND));
477 spin_unlock_irqrestore(&fimc->slock, flags);
478 return ret;
479}
480
481static inline void fimc_ctx_state_lock_set(u32 state, struct fimc_ctx *ctx)
482{
483 unsigned long flags;
484
485 spin_lock_irqsave(&ctx->slock, flags);
486 ctx->state |= state;
487 spin_unlock_irqrestore(&ctx->slock, flags);
488}
489
490static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
491{
492 unsigned long flags;
493 bool ret;
494
495 spin_lock_irqsave(&ctx->slock, flags);
496 ret = (ctx->state & mask) == mask;
497 spin_unlock_irqrestore(&ctx->slock, flags);
498 return ret;
499}
486 500
487static inline int tiled_fmt(struct fimc_fmt *fmt) 501static inline int tiled_fmt(struct fimc_fmt *fmt)
488{ 502{
489 return 0; 503 return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
490} 504}
491 505
492static inline void fimc_hw_clear_irq(struct fimc_dev *dev) 506static inline void fimc_hw_clear_irq(struct fimc_dev *dev)
@@ -542,12 +556,12 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
542{ 556{
543 struct fimc_frame *frame; 557 struct fimc_frame *frame;
544 558
545 if (V4L2_BUF_TYPE_VIDEO_OUTPUT == type) { 559 if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) {
546 if (ctx->state & FIMC_CTX_M2M) 560 if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
547 frame = &ctx->s_frame; 561 frame = &ctx->s_frame;
548 else 562 else
549 return ERR_PTR(-EINVAL); 563 return ERR_PTR(-EINVAL);
550 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE == type) { 564 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) {
551 frame = &ctx->d_frame; 565 frame = &ctx->d_frame;
552 } else { 566 } else {
553 v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, 567 v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
@@ -581,7 +595,8 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx);
581void fimc_hw_set_out_dma(struct fimc_ctx *ctx); 595void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
582void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable); 596void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
583void fimc_hw_en_irq(struct fimc_dev *fimc, int enable); 597void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
584void fimc_hw_set_scaler(struct fimc_ctx *ctx); 598void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
599void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
585void fimc_hw_en_capture(struct fimc_ctx *ctx); 600void fimc_hw_en_capture(struct fimc_ctx *ctx);
586void fimc_hw_set_effect(struct fimc_ctx *ctx); 601void fimc_hw_set_effect(struct fimc_ctx *ctx);
587void fimc_hw_set_in_dma(struct fimc_ctx *ctx); 602void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
@@ -589,23 +604,23 @@ void fimc_hw_set_input_path(struct fimc_ctx *ctx);
589void fimc_hw_set_output_path(struct fimc_ctx *ctx); 604void fimc_hw_set_output_path(struct fimc_ctx *ctx);
590void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr); 605void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
591void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr, 606void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
592 int index); 607 int index);
593int fimc_hw_set_camera_source(struct fimc_dev *fimc, 608int fimc_hw_set_camera_source(struct fimc_dev *fimc,
594 struct s3c_fimc_isp_info *cam); 609 struct s5p_fimc_isp_info *cam);
595int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f); 610int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
596int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, 611int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
597 struct s3c_fimc_isp_info *cam); 612 struct s5p_fimc_isp_info *cam);
598int fimc_hw_set_camera_type(struct fimc_dev *fimc, 613int fimc_hw_set_camera_type(struct fimc_dev *fimc,
599 struct s3c_fimc_isp_info *cam); 614 struct s5p_fimc_isp_info *cam);
600 615
601/* -----------------------------------------------------*/ 616/* -----------------------------------------------------*/
602/* fimc-core.c */ 617/* fimc-core.c */
603int fimc_vidioc_enum_fmt(struct file *file, void *priv, 618int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
604 struct v4l2_fmtdesc *f); 619 struct v4l2_fmtdesc *f);
605int fimc_vidioc_g_fmt(struct file *file, void *priv, 620int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv,
606 struct v4l2_format *f); 621 struct v4l2_format *f);
607int fimc_vidioc_try_fmt(struct file *file, void *priv, 622int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
608 struct v4l2_format *f); 623 struct v4l2_format *f);
609int fimc_vidioc_queryctrl(struct file *file, void *priv, 624int fimc_vidioc_queryctrl(struct file *file, void *priv,
610 struct v4l2_queryctrl *qc); 625 struct v4l2_queryctrl *qc);
611int fimc_vidioc_g_ctrl(struct file *file, void *priv, 626int fimc_vidioc_g_ctrl(struct file *file, void *priv,
@@ -619,10 +634,10 @@ struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask);
619struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, 634struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,
620 unsigned int mask); 635 unsigned int mask);
621 636
622int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); 637int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot);
623int fimc_set_scaler_info(struct fimc_ctx *ctx); 638int fimc_set_scaler_info(struct fimc_ctx *ctx);
624int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); 639int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
625int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, 640int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
626 struct fimc_frame *frame, struct fimc_addr *paddr); 641 struct fimc_frame *frame, struct fimc_addr *paddr);
627 642
628/* -----------------------------------------------------*/ 643/* -----------------------------------------------------*/
@@ -649,28 +664,27 @@ static inline void fimc_deactivate_capture(struct fimc_dev *fimc)
649} 664}
650 665
651/* 666/*
652 * Add video buffer to the active buffers queue. 667 * Add buf to the capture active buffers queue.
653 * The caller holds irqlock spinlock. 668 * Locking: Need to be called with fimc_dev::slock held.
654 */ 669 */
655static inline void active_queue_add(struct fimc_vid_cap *vid_cap, 670static inline void active_queue_add(struct fimc_vid_cap *vid_cap,
656 struct fimc_vid_buffer *buf) 671 struct fimc_vid_buffer *buf)
657{ 672{
658 buf->vb.state = VIDEOBUF_ACTIVE; 673 list_add_tail(&buf->list, &vid_cap->active_buf_q);
659 list_add_tail(&buf->vb.queue, &vid_cap->active_buf_q);
660 vid_cap->active_buf_cnt++; 674 vid_cap->active_buf_cnt++;
661} 675}
662 676
663/* 677/*
664 * Pop a video buffer from the capture active buffers queue 678 * Pop a video buffer from the capture active buffers queue
665 * Locking: Need to be called with dev->slock held. 679 * Locking: Need to be called with fimc_dev::slock held.
666 */ 680 */
667static inline struct fimc_vid_buffer * 681static inline struct fimc_vid_buffer *
668active_queue_pop(struct fimc_vid_cap *vid_cap) 682active_queue_pop(struct fimc_vid_cap *vid_cap)
669{ 683{
670 struct fimc_vid_buffer *buf; 684 struct fimc_vid_buffer *buf;
671 buf = list_entry(vid_cap->active_buf_q.next, 685 buf = list_entry(vid_cap->active_buf_q.next,
672 struct fimc_vid_buffer, vb.queue); 686 struct fimc_vid_buffer, list);
673 list_del(&buf->vb.queue); 687 list_del(&buf->list);
674 vid_cap->active_buf_cnt--; 688 vid_cap->active_buf_cnt--;
675 return buf; 689 return buf;
676} 690}
@@ -679,8 +693,7 @@ active_queue_pop(struct fimc_vid_cap *vid_cap)
679static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap, 693static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
680 struct fimc_vid_buffer *buf) 694 struct fimc_vid_buffer *buf)
681{ 695{
682 buf->vb.state = VIDEOBUF_QUEUED; 696 list_add_tail(&buf->list, &vid_cap->pending_buf_q);
683 list_add_tail(&buf->vb.queue, &vid_cap->pending_buf_q);
684} 697}
685 698
686/* Add video buffer to the capture pending buffers queue */ 699/* Add video buffer to the capture pending buffers queue */
@@ -689,10 +702,9 @@ pending_queue_pop(struct fimc_vid_cap *vid_cap)
689{ 702{
690 struct fimc_vid_buffer *buf; 703 struct fimc_vid_buffer *buf;
691 buf = list_entry(vid_cap->pending_buf_q.next, 704 buf = list_entry(vid_cap->pending_buf_q.next,
692 struct fimc_vid_buffer, vb.queue); 705 struct fimc_vid_buffer, list);
693 list_del(&buf->vb.queue); 706 list_del(&buf->list);
694 return buf; 707 return buf;
695} 708}
696 709
697
698#endif /* FIMC_CORE_H_ */ 710#endif /* FIMC_CORE_H_ */
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
index 511631a2e5c3..4d929a394521 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ b/drivers/media/video/s5p-fimc/fimc-reg.c
@@ -13,7 +13,7 @@
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <mach/map.h> 15#include <mach/map.h>
16#include <media/s3c_fimc.h> 16#include <media/s5p_fimc.h>
17 17
18#include "fimc-core.h" 18#include "fimc-core.h"
19 19
@@ -37,11 +37,11 @@ void fimc_hw_reset(struct fimc_dev *dev)
37 writel(cfg, dev->regs + S5P_CIGCTRL); 37 writel(cfg, dev->regs + S5P_CIGCTRL);
38} 38}
39 39
40static u32 fimc_hw_get_in_flip(u32 ctx_flip) 40static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
41{ 41{
42 u32 flip = S5P_MSCTRL_FLIP_NORMAL; 42 u32 flip = S5P_MSCTRL_FLIP_NORMAL;
43 43
44 switch (ctx_flip) { 44 switch (ctx->flip) {
45 case FLIP_X_AXIS: 45 case FLIP_X_AXIS:
46 flip = S5P_MSCTRL_FLIP_X_MIRROR; 46 flip = S5P_MSCTRL_FLIP_X_MIRROR;
47 break; 47 break;
@@ -51,16 +51,20 @@ static u32 fimc_hw_get_in_flip(u32 ctx_flip)
51 case FLIP_XY_AXIS: 51 case FLIP_XY_AXIS:
52 flip = S5P_MSCTRL_FLIP_180; 52 flip = S5P_MSCTRL_FLIP_180;
53 break; 53 break;
54 default:
55 break;
54 } 56 }
57 if (ctx->rotation <= 90)
58 return flip;
55 59
56 return flip; 60 return (flip ^ S5P_MSCTRL_FLIP_180) & S5P_MSCTRL_FLIP_180;
57} 61}
58 62
59static u32 fimc_hw_get_target_flip(u32 ctx_flip) 63static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
60{ 64{
61 u32 flip = S5P_CITRGFMT_FLIP_NORMAL; 65 u32 flip = S5P_CITRGFMT_FLIP_NORMAL;
62 66
63 switch (ctx_flip) { 67 switch (ctx->flip) {
64 case FLIP_X_AXIS: 68 case FLIP_X_AXIS:
65 flip = S5P_CITRGFMT_FLIP_X_MIRROR; 69 flip = S5P_CITRGFMT_FLIP_X_MIRROR;
66 break; 70 break;
@@ -70,11 +74,13 @@ static u32 fimc_hw_get_target_flip(u32 ctx_flip)
70 case FLIP_XY_AXIS: 74 case FLIP_XY_AXIS:
71 flip = S5P_CITRGFMT_FLIP_180; 75 flip = S5P_CITRGFMT_FLIP_180;
72 break; 76 break;
73 case FLIP_NONE: 77 default:
74 break; 78 break;
75
76 } 79 }
77 return flip; 80 if (ctx->rotation <= 90)
81 return flip;
82
83 return (flip ^ S5P_CITRGFMT_FLIP_180) & S5P_CITRGFMT_FLIP_180;
78} 84}
79 85
80void fimc_hw_set_rotation(struct fimc_ctx *ctx) 86void fimc_hw_set_rotation(struct fimc_ctx *ctx)
@@ -84,10 +90,7 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
84 90
85 cfg = readl(dev->regs + S5P_CITRGFMT); 91 cfg = readl(dev->regs + S5P_CITRGFMT);
86 cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 | 92 cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 |
87 S5P_CITRGFMT_FLIP_180); 93 S5P_CITRGFMT_FLIP_180);
88
89 flip = readl(dev->regs + S5P_MSCTRL);
90 flip &= ~S5P_MSCTRL_FLIP_MASK;
91 94
92 /* 95 /*
93 * The input and output rotator cannot work simultaneously. 96 * The input and output rotator cannot work simultaneously.
@@ -95,26 +98,22 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
95 * in direct fifo output mode. 98 * in direct fifo output mode.
96 */ 99 */
97 if (ctx->rotation == 90 || ctx->rotation == 270) { 100 if (ctx->rotation == 90 || ctx->rotation == 270) {
98 if (ctx->out_path == FIMC_LCDFIFO) {
99 cfg |= S5P_CITRGFMT_INROT90;
100 if (ctx->rotation == 270)
101 flip |= S5P_MSCTRL_FLIP_180;
102 } else {
103 cfg |= S5P_CITRGFMT_OUTROT90;
104 if (ctx->rotation == 270)
105 cfg |= S5P_CITRGFMT_FLIP_180;
106 }
107 } else if (ctx->rotation == 180) {
108 if (ctx->out_path == FIMC_LCDFIFO) 101 if (ctx->out_path == FIMC_LCDFIFO)
109 flip |= S5P_MSCTRL_FLIP_180; 102 cfg |= S5P_CITRGFMT_INROT90;
110 else 103 else
111 cfg |= S5P_CITRGFMT_FLIP_180; 104 cfg |= S5P_CITRGFMT_OUTROT90;
112 } 105 }
113 if (ctx->rotation == 180 || ctx->rotation == 270)
114 writel(flip, dev->regs + S5P_MSCTRL);
115 106
116 cfg |= fimc_hw_get_target_flip(ctx->flip); 107 if (ctx->out_path == FIMC_DMA) {
117 writel(cfg, dev->regs + S5P_CITRGFMT); 108 cfg |= fimc_hw_get_target_flip(ctx);
109 writel(cfg, dev->regs + S5P_CITRGFMT);
110 } else {
111 /* LCD FIFO path */
112 flip = readl(dev->regs + S5P_MSCTRL);
113 flip &= ~S5P_MSCTRL_FLIP_MASK;
114 flip |= fimc_hw_get_in_flip(ctx);
115 writel(flip, dev->regs + S5P_MSCTRL);
116 }
118} 117}
119 118
120void fimc_hw_set_target_format(struct fimc_ctx *ctx) 119void fimc_hw_set_target_format(struct fimc_ctx *ctx)
@@ -131,19 +130,14 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx)
131 S5P_CITRGFMT_VSIZE_MASK); 130 S5P_CITRGFMT_VSIZE_MASK);
132 131
133 switch (frame->fmt->color) { 132 switch (frame->fmt->color) {
134 case S5P_FIMC_RGB565: 133 case S5P_FIMC_RGB565...S5P_FIMC_RGB888:
135 case S5P_FIMC_RGB666:
136 case S5P_FIMC_RGB888:
137 cfg |= S5P_CITRGFMT_RGB; 134 cfg |= S5P_CITRGFMT_RGB;
138 break; 135 break;
139 case S5P_FIMC_YCBCR420: 136 case S5P_FIMC_YCBCR420:
140 cfg |= S5P_CITRGFMT_YCBCR420; 137 cfg |= S5P_CITRGFMT_YCBCR420;
141 break; 138 break;
142 case S5P_FIMC_YCBYCR422: 139 case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422:
143 case S5P_FIMC_YCRYCB422: 140 if (frame->fmt->colplanes == 1)
144 case S5P_FIMC_CBYCRY422:
145 case S5P_FIMC_CRYCBY422:
146 if (frame->fmt->planes_cnt == 1)
147 cfg |= S5P_CITRGFMT_YCBCR422_1P; 141 cfg |= S5P_CITRGFMT_YCBCR422_1P;
148 else 142 else
149 cfg |= S5P_CITRGFMT_YCBCR422; 143 cfg |= S5P_CITRGFMT_YCBCR422;
@@ -219,11 +213,11 @@ void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
219 cfg &= ~(S5P_CIOCTRL_ORDER2P_MASK | S5P_CIOCTRL_ORDER422_MASK | 213 cfg &= ~(S5P_CIOCTRL_ORDER2P_MASK | S5P_CIOCTRL_ORDER422_MASK |
220 S5P_CIOCTRL_YCBCR_PLANE_MASK); 214 S5P_CIOCTRL_YCBCR_PLANE_MASK);
221 215
222 if (frame->fmt->planes_cnt == 1) 216 if (frame->fmt->colplanes == 1)
223 cfg |= ctx->out_order_1p; 217 cfg |= ctx->out_order_1p;
224 else if (frame->fmt->planes_cnt == 2) 218 else if (frame->fmt->colplanes == 2)
225 cfg |= ctx->out_order_2p | S5P_CIOCTRL_YCBCR_2PLANE; 219 cfg |= ctx->out_order_2p | S5P_CIOCTRL_YCBCR_2PLANE;
226 else if (frame->fmt->planes_cnt == 3) 220 else if (frame->fmt->colplanes == 3)
227 cfg |= S5P_CIOCTRL_YCBCR_3PLANE; 221 cfg |= S5P_CIOCTRL_YCBCR_3PLANE;
228 222
229 writel(cfg, dev->regs + S5P_CIOCTRL); 223 writel(cfg, dev->regs + S5P_CIOCTRL);
@@ -249,7 +243,7 @@ void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
249 writel(cfg, dev->regs + S5P_CIOCTRL); 243 writel(cfg, dev->regs + S5P_CIOCTRL);
250} 244}
251 245
252static void fimc_hw_set_prescaler(struct fimc_ctx *ctx) 246void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
253{ 247{
254 struct fimc_dev *dev = ctx->fimc_dev; 248 struct fimc_dev *dev = ctx->fimc_dev;
255 struct fimc_scaler *sc = &ctx->scaler; 249 struct fimc_scaler *sc = &ctx->scaler;
@@ -267,7 +261,7 @@ static void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
267 writel(cfg, dev->regs + S5P_CISCPREDST); 261 writel(cfg, dev->regs + S5P_CISCPREDST);
268} 262}
269 263
270void fimc_hw_set_scaler(struct fimc_ctx *ctx) 264static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
271{ 265{
272 struct fimc_dev *dev = ctx->fimc_dev; 266 struct fimc_dev *dev = ctx->fimc_dev;
273 struct fimc_scaler *sc = &ctx->scaler; 267 struct fimc_scaler *sc = &ctx->scaler;
@@ -275,8 +269,6 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx)
275 struct fimc_frame *dst_frame = &ctx->d_frame; 269 struct fimc_frame *dst_frame = &ctx->d_frame;
276 u32 cfg = 0; 270 u32 cfg = 0;
277 271
278 fimc_hw_set_prescaler(ctx);
279
280 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) 272 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
281 cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); 273 cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE);
282 274
@@ -316,13 +308,42 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx)
316 cfg |= S5P_CISCCTRL_INTERLACE; 308 cfg |= S5P_CISCCTRL_INTERLACE;
317 } 309 }
318 310
311 writel(cfg, dev->regs + S5P_CISCCTRL);
312}
313
314void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
315{
316 struct fimc_dev *dev = ctx->fimc_dev;
317 struct samsung_fimc_variant *variant = dev->variant;
318 struct fimc_scaler *sc = &ctx->scaler;
319 u32 cfg;
320
319 dbg("main_hratio= 0x%X main_vratio= 0x%X", 321 dbg("main_hratio= 0x%X main_vratio= 0x%X",
320 sc->main_hratio, sc->main_vratio); 322 sc->main_hratio, sc->main_vratio);
321 323
322 cfg |= S5P_CISCCTRL_SC_HORRATIO(sc->main_hratio); 324 fimc_hw_set_scaler(ctx);
323 cfg |= S5P_CISCCTRL_SC_VERRATIO(sc->main_vratio);
324 325
325 writel(cfg, dev->regs + S5P_CISCCTRL); 326 cfg = readl(dev->regs + S5P_CISCCTRL);
327
328 if (variant->has_mainscaler_ext) {
329 cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK);
330 cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
331 cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
332 writel(cfg, dev->regs + S5P_CISCCTRL);
333
334 cfg = readl(dev->regs + S5P_CIEXTEN);
335
336 cfg &= ~(S5P_CIEXTEN_MVRATIO_EXT_MASK |
337 S5P_CIEXTEN_MHRATIO_EXT_MASK);
338 cfg |= S5P_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
339 cfg |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
340 writel(cfg, dev->regs + S5P_CIEXTEN);
341 } else {
342 cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK);
343 cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio);
344 cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio);
345 writel(cfg, dev->regs + S5P_CISCCTRL);
346 }
326} 347}
327 348
328void fimc_hw_en_capture(struct fimc_ctx *ctx) 349void fimc_hw_en_capture(struct fimc_ctx *ctx)
@@ -410,41 +431,37 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
410 431
411 /* Set the input DMA to process single frame only. */ 432 /* Set the input DMA to process single frame only. */
412 cfg = readl(dev->regs + S5P_MSCTRL); 433 cfg = readl(dev->regs + S5P_MSCTRL);
413 cfg &= ~(S5P_MSCTRL_FLIP_MASK 434 cfg &= ~(S5P_MSCTRL_INFORMAT_MASK
414 | S5P_MSCTRL_INFORMAT_MASK
415 | S5P_MSCTRL_IN_BURST_COUNT_MASK 435 | S5P_MSCTRL_IN_BURST_COUNT_MASK
416 | S5P_MSCTRL_INPUT_MASK 436 | S5P_MSCTRL_INPUT_MASK
417 | S5P_MSCTRL_C_INT_IN_MASK 437 | S5P_MSCTRL_C_INT_IN_MASK
418 | S5P_MSCTRL_2P_IN_ORDER_MASK); 438 | S5P_MSCTRL_2P_IN_ORDER_MASK);
419 439
420 cfg |= (S5P_MSCTRL_FRAME_COUNT(1) | S5P_MSCTRL_INPUT_MEMORY); 440 cfg |= (S5P_MSCTRL_IN_BURST_COUNT(4)
441 | S5P_MSCTRL_INPUT_MEMORY
442 | S5P_MSCTRL_FIFO_CTRL_FULL);
421 443
422 switch (frame->fmt->color) { 444 switch (frame->fmt->color) {
423 case S5P_FIMC_RGB565: 445 case S5P_FIMC_RGB565...S5P_FIMC_RGB888:
424 case S5P_FIMC_RGB666:
425 case S5P_FIMC_RGB888:
426 cfg |= S5P_MSCTRL_INFORMAT_RGB; 446 cfg |= S5P_MSCTRL_INFORMAT_RGB;
427 break; 447 break;
428 case S5P_FIMC_YCBCR420: 448 case S5P_FIMC_YCBCR420:
429 cfg |= S5P_MSCTRL_INFORMAT_YCBCR420; 449 cfg |= S5P_MSCTRL_INFORMAT_YCBCR420;
430 450
431 if (frame->fmt->planes_cnt == 2) 451 if (frame->fmt->colplanes == 2)
432 cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE; 452 cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE;
433 else 453 else
434 cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; 454 cfg |= S5P_MSCTRL_C_INT_IN_3PLANE;
435 455
436 break; 456 break;
437 case S5P_FIMC_YCBYCR422: 457 case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422:
438 case S5P_FIMC_YCRYCB422: 458 if (frame->fmt->colplanes == 1) {
439 case S5P_FIMC_CBYCRY422:
440 case S5P_FIMC_CRYCBY422:
441 if (frame->fmt->planes_cnt == 1) {
442 cfg |= ctx->in_order_1p 459 cfg |= ctx->in_order_1p
443 | S5P_MSCTRL_INFORMAT_YCBCR422_1P; 460 | S5P_MSCTRL_INFORMAT_YCBCR422_1P;
444 } else { 461 } else {
445 cfg |= S5P_MSCTRL_INFORMAT_YCBCR422; 462 cfg |= S5P_MSCTRL_INFORMAT_YCBCR422;
446 463
447 if (frame->fmt->planes_cnt == 2) 464 if (frame->fmt->colplanes == 2)
448 cfg |= ctx->in_order_2p 465 cfg |= ctx->in_order_2p
449 | S5P_MSCTRL_C_INT_IN_2PLANE; 466 | S5P_MSCTRL_C_INT_IN_2PLANE;
450 else 467 else
@@ -455,13 +472,6 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
455 break; 472 break;
456 } 473 }
457 474
458 /*
459 * Input DMA flip mode (and rotation).
460 * Do not allow simultaneous rotation and flipping.
461 */
462 if (!ctx->rotation && ctx->out_path == FIMC_LCDFIFO)
463 cfg |= fimc_hw_get_in_flip(ctx->flip);
464
465 writel(cfg, dev->regs + S5P_MSCTRL); 475 writel(cfg, dev->regs + S5P_MSCTRL);
466 476
467 /* Input/output DMA linear/tiled mode. */ 477 /* Input/output DMA linear/tiled mode. */
@@ -532,7 +542,7 @@ void fimc_hw_set_output_addr(struct fimc_dev *dev,
532} 542}
533 543
534int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, 544int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
535 struct s3c_fimc_isp_info *cam) 545 struct s5p_fimc_isp_info *cam)
536{ 546{
537 u32 cfg = readl(fimc->regs + S5P_CIGCTRL); 547 u32 cfg = readl(fimc->regs + S5P_CIGCTRL);
538 548
@@ -557,41 +567,46 @@ int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
557} 567}
558 568
559int fimc_hw_set_camera_source(struct fimc_dev *fimc, 569int fimc_hw_set_camera_source(struct fimc_dev *fimc,
560 struct s3c_fimc_isp_info *cam) 570 struct s5p_fimc_isp_info *cam)
561{ 571{
562 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; 572 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
563 u32 cfg = 0; 573 u32 cfg = 0;
574 u32 bus_width;
575 int i;
576
577 static const struct {
578 u32 pixelcode;
579 u32 cisrcfmt;
580 u16 bus_width;
581 } pix_desc[] = {
582 { V4L2_MBUS_FMT_YUYV8_2X8, S5P_CISRCFMT_ORDER422_YCBYCR, 8 },
583 { V4L2_MBUS_FMT_YVYU8_2X8, S5P_CISRCFMT_ORDER422_YCRYCB, 8 },
584 { V4L2_MBUS_FMT_VYUY8_2X8, S5P_CISRCFMT_ORDER422_CRYCBY, 8 },
585 { V4L2_MBUS_FMT_UYVY8_2X8, S5P_CISRCFMT_ORDER422_CBYCRY, 8 },
586 /* TODO: Add pixel codes for 16-bit bus width */
587 };
564 588
565 if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) { 589 if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) {
590 for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
591 if (fimc->vid_cap.fmt.code == pix_desc[i].pixelcode) {
592 cfg = pix_desc[i].cisrcfmt;
593 bus_width = pix_desc[i].bus_width;
594 break;
595 }
596 }
566 597
567 switch (fimc->vid_cap.fmt.code) { 598 if (i == ARRAY_SIZE(pix_desc)) {
568 case V4L2_MBUS_FMT_YUYV8_2X8: 599 v4l2_err(&fimc->vid_cap.v4l2_dev,
569 cfg = S5P_CISRCFMT_ORDER422_YCBYCR; 600 "Camera color format not supported: %d\n",
570 break; 601 fimc->vid_cap.fmt.code);
571 case V4L2_MBUS_FMT_YVYU8_2X8:
572 cfg = S5P_CISRCFMT_ORDER422_YCRYCB;
573 break;
574 case V4L2_MBUS_FMT_VYUY8_2X8:
575 cfg = S5P_CISRCFMT_ORDER422_CRYCBY;
576 break;
577 case V4L2_MBUS_FMT_UYVY8_2X8:
578 cfg = S5P_CISRCFMT_ORDER422_CBYCRY;
579 break;
580 default:
581 err("camera image format not supported: %d",
582 fimc->vid_cap.fmt.code);
583 return -EINVAL; 602 return -EINVAL;
584 } 603 }
585 604
586 if (cam->bus_type == FIMC_ITU_601) { 605 if (cam->bus_type == FIMC_ITU_601) {
587 if (cam->bus_width == 8) { 606 if (bus_width == 8)
588 cfg |= S5P_CISRCFMT_ITU601_8BIT; 607 cfg |= S5P_CISRCFMT_ITU601_8BIT;
589 } else if (cam->bus_width == 16) { 608 else if (bus_width == 16)
590 cfg |= S5P_CISRCFMT_ITU601_16BIT; 609 cfg |= S5P_CISRCFMT_ITU601_16BIT;
591 } else {
592 err("invalid bus width: %d", cam->bus_width);
593 return -EINVAL;
594 }
595 } /* else defaults to ITU-R BT.656 8-bit */ 610 } /* else defaults to ITU-R BT.656 8-bit */
596 } 611 }
597 612
@@ -624,7 +639,7 @@ int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
624} 639}
625 640
626int fimc_hw_set_camera_type(struct fimc_dev *fimc, 641int fimc_hw_set_camera_type(struct fimc_dev *fimc,
627 struct s3c_fimc_isp_info *cam) 642 struct s5p_fimc_isp_info *cam)
628{ 643{
629 u32 cfg, tmp; 644 u32 cfg, tmp;
630 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; 645 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
@@ -650,10 +665,12 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
650 vid_cap->fmt.code); 665 vid_cap->fmt.code);
651 return -EINVAL; 666 return -EINVAL;
652 } 667 }
653 writel(tmp | (0x1 << 8), fimc->regs + S5P_CSIIMGFMT); 668 tmp |= (cam->csi_data_align == 32) << 8;
669
670 writel(tmp, fimc->regs + S5P_CSIIMGFMT);
654 671
655 } else if (cam->bus_type == FIMC_ITU_601 || 672 } else if (cam->bus_type == FIMC_ITU_601 ||
656 cam->bus_type == FIMC_ITU_656) { 673 cam->bus_type == FIMC_ITU_656) {
657 if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */ 674 if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
658 cfg |= S5P_CIGCTRL_SELCAM_ITU_A; 675 cfg |= S5P_CIGCTRL_SELCAM_ITU_A;
659 } else if (cam->bus_type == FIMC_LCD_WB) { 676 } else if (cam->bus_type == FIMC_LCD_WB) {
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h
index 57e33f84fcfa..0fea3e635d76 100644
--- a/drivers/media/video/s5p-fimc/regs-fimc.h
+++ b/drivers/media/video/s5p-fimc/regs-fimc.h
@@ -98,8 +98,8 @@
98#define S5P_CIOCTRL 0x4c 98#define S5P_CIOCTRL 0x4c
99#define S5P_CIOCTRL_ORDER422_MASK (3 << 0) 99#define S5P_CIOCTRL_ORDER422_MASK (3 << 0)
100#define S5P_CIOCTRL_ORDER422_CRYCBY (0 << 0) 100#define S5P_CIOCTRL_ORDER422_CRYCBY (0 << 0)
101#define S5P_CIOCTRL_ORDER422_YCRYCB (1 << 0) 101#define S5P_CIOCTRL_ORDER422_CBYCRY (1 << 0)
102#define S5P_CIOCTRL_ORDER422_CBYCRY (2 << 0) 102#define S5P_CIOCTRL_ORDER422_YCRYCB (2 << 0)
103#define S5P_CIOCTRL_ORDER422_YCBYCR (3 << 0) 103#define S5P_CIOCTRL_ORDER422_YCBYCR (3 << 0)
104#define S5P_CIOCTRL_LASTIRQ_ENABLE (1 << 2) 104#define S5P_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
105#define S5P_CIOCTRL_YCBCR_3PLANE (0 << 3) 105#define S5P_CIOCTRL_YCBCR_3PLANE (0 << 3)
@@ -139,8 +139,12 @@
139#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11) 139#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
140#define S5P_CISCCTRL_RGB_EXT (1 << 10) 140#define S5P_CISCCTRL_RGB_EXT (1 << 10)
141#define S5P_CISCCTRL_ONE2ONE (1 << 9) 141#define S5P_CISCCTRL_ONE2ONE (1 << 9)
142#define S5P_CISCCTRL_SC_HORRATIO(x) ((x) << 16) 142#define S5P_CISCCTRL_MHRATIO(x) ((x) << 16)
143#define S5P_CISCCTRL_SC_VERRATIO(x) ((x) << 0) 143#define S5P_CISCCTRL_MVRATIO(x) ((x) << 0)
144#define S5P_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
145#define S5P_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
146#define S5P_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
147#define S5P_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
144 148
145/* Target area */ 149/* Target area */
146#define S5P_CITAREA 0x5c 150#define S5P_CITAREA 0x5c
@@ -210,7 +214,7 @@
210 214
211/* Input DMA control */ 215/* Input DMA control */
212#define S5P_MSCTRL 0xfc 216#define S5P_MSCTRL 0xfc
213#define S5P_MSCTRL_IN_BURST_COUNT_MASK (3 << 24) 217#define S5P_MSCTRL_IN_BURST_COUNT_MASK (0xF << 24)
214#define S5P_MSCTRL_2P_IN_ORDER_MASK (3 << 16) 218#define S5P_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
215#define S5P_MSCTRL_2P_IN_ORDER_SHIFT 16 219#define S5P_MSCTRL_2P_IN_ORDER_SHIFT 16
216#define S5P_MSCTRL_C_INT_IN_3PLANE (0 << 15) 220#define S5P_MSCTRL_C_INT_IN_3PLANE (0 << 15)
@@ -222,11 +226,12 @@
222#define S5P_MSCTRL_FLIP_X_MIRROR (1 << 13) 226#define S5P_MSCTRL_FLIP_X_MIRROR (1 << 13)
223#define S5P_MSCTRL_FLIP_Y_MIRROR (2 << 13) 227#define S5P_MSCTRL_FLIP_Y_MIRROR (2 << 13)
224#define S5P_MSCTRL_FLIP_180 (3 << 13) 228#define S5P_MSCTRL_FLIP_180 (3 << 13)
229#define S5P_MSCTRL_FIFO_CTRL_FULL (1 << 12)
225#define S5P_MSCTRL_ORDER422_SHIFT 4 230#define S5P_MSCTRL_ORDER422_SHIFT 4
226#define S5P_MSCTRL_ORDER422_CRYCBY (0 << 4) 231#define S5P_MSCTRL_ORDER422_YCBYCR (0 << 4)
227#define S5P_MSCTRL_ORDER422_YCRYCB (1 << 4) 232#define S5P_MSCTRL_ORDER422_CBYCRY (1 << 4)
228#define S5P_MSCTRL_ORDER422_CBYCRY (2 << 4) 233#define S5P_MSCTRL_ORDER422_YCRYCB (2 << 4)
229#define S5P_MSCTRL_ORDER422_YCBYCR (3 << 4) 234#define S5P_MSCTRL_ORDER422_CRYCBY (3 << 4)
230#define S5P_MSCTRL_ORDER422_MASK (3 << 4) 235#define S5P_MSCTRL_ORDER422_MASK (3 << 4)
231#define S5P_MSCTRL_INPUT_EXTCAM (0 << 3) 236#define S5P_MSCTRL_INPUT_EXTCAM (0 << 3)
232#define S5P_MSCTRL_INPUT_MEMORY (1 << 3) 237#define S5P_MSCTRL_INPUT_MEMORY (1 << 3)
@@ -237,7 +242,7 @@
237#define S5P_MSCTRL_INFORMAT_RGB (3 << 1) 242#define S5P_MSCTRL_INFORMAT_RGB (3 << 1)
238#define S5P_MSCTRL_INFORMAT_MASK (3 << 1) 243#define S5P_MSCTRL_INFORMAT_MASK (3 << 1)
239#define S5P_MSCTRL_ENVID (1 << 0) 244#define S5P_MSCTRL_ENVID (1 << 0)
240#define S5P_MSCTRL_FRAME_COUNT(x) ((x) << 24) 245#define S5P_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
241 246
242/* Output DMA Y/Cb/Cr offset */ 247/* Output DMA Y/Cb/Cr offset */
243#define S5P_CIOYOFF 0x168 248#define S5P_CIOYOFF 0x168
@@ -263,6 +268,10 @@
263 268
264/* Real output DMA image size (extension register) */ 269/* Real output DMA image size (extension register) */
265#define S5P_CIEXTEN 0x188 270#define S5P_CIEXTEN 0x188
271#define S5P_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
272#define S5P_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
273#define S5P_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
274#define S5P_CIEXTEN_MVRATIO_EXT_MASK 0x3f
266 275
267#define S5P_CIDMAPARAM 0x18c 276#define S5P_CIDMAPARAM 0x18c
268#define S5P_CIDMAPARAM_R_LINEAR (0 << 29) 277#define S5P_CIDMAPARAM_R_LINEAR (0 << 29)
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 7913f93979b8..99664205ef4e 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -36,6 +36,7 @@
36#include <linux/videodev2.h> 36#include <linux/videodev2.h>
37#include <media/v4l2-device.h> 37#include <media/v4l2-device.h>
38#include <media/v4l2-chip-ident.h> 38#include <media/v4l2-chip-ident.h>
39#include <media/v4l2-ctrls.h>
39 40
40MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); 41MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
41MODULE_AUTHOR("Pauline Middelink"); 42MODULE_AUTHOR("Pauline Middelink");
@@ -53,15 +54,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 54
54struct saa7110 { 55struct saa7110 {
55 struct v4l2_subdev sd; 56 struct v4l2_subdev sd;
57 struct v4l2_ctrl_handler hdl;
56 u8 reg[SAA7110_NR_REG]; 58 u8 reg[SAA7110_NR_REG];
57 59
58 v4l2_std_id norm; 60 v4l2_std_id norm;
59 int input; 61 int input;
60 int enable; 62 int enable;
61 int bright;
62 int contrast;
63 int hue;
64 int sat;
65 63
66 wait_queue_head_t wq; 64 wait_queue_head_t wq;
67}; 65};
@@ -71,6 +69,11 @@ static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
71 return container_of(sd, struct saa7110, sd); 69 return container_of(sd, struct saa7110, sd);
72} 70}
73 71
72static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
73{
74 return &container_of(ctrl->handler, struct saa7110, hdl)->sd;
75}
76
74/* ----------------------------------------------------------------------- */ 77/* ----------------------------------------------------------------------- */
75/* I2C support functions */ 78/* I2C support functions */
76/* ----------------------------------------------------------------------- */ 79/* ----------------------------------------------------------------------- */
@@ -326,73 +329,22 @@ static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
326 return 0; 329 return 0;
327} 330}
328 331
329static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 332static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl)
330{
331 switch (qc->id) {
332 case V4L2_CID_BRIGHTNESS:
333 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
334 case V4L2_CID_CONTRAST:
335 case V4L2_CID_SATURATION:
336 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
337 case V4L2_CID_HUE:
338 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
339 default:
340 return -EINVAL;
341 }
342 return 0;
343}
344
345static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
346{
347 struct saa7110 *decoder = to_saa7110(sd);
348
349 switch (ctrl->id) {
350 case V4L2_CID_BRIGHTNESS:
351 ctrl->value = decoder->bright;
352 break;
353 case V4L2_CID_CONTRAST:
354 ctrl->value = decoder->contrast;
355 break;
356 case V4L2_CID_SATURATION:
357 ctrl->value = decoder->sat;
358 break;
359 case V4L2_CID_HUE:
360 ctrl->value = decoder->hue;
361 break;
362 default:
363 return -EINVAL;
364 }
365 return 0;
366}
367
368static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
369{ 333{
370 struct saa7110 *decoder = to_saa7110(sd); 334 struct v4l2_subdev *sd = to_sd(ctrl);
371 335
372 switch (ctrl->id) { 336 switch (ctrl->id) {
373 case V4L2_CID_BRIGHTNESS: 337 case V4L2_CID_BRIGHTNESS:
374 if (decoder->bright != ctrl->value) { 338 saa7110_write(sd, 0x19, ctrl->val);
375 decoder->bright = ctrl->value;
376 saa7110_write(sd, 0x19, decoder->bright);
377 }
378 break; 339 break;
379 case V4L2_CID_CONTRAST: 340 case V4L2_CID_CONTRAST:
380 if (decoder->contrast != ctrl->value) { 341 saa7110_write(sd, 0x13, ctrl->val);
381 decoder->contrast = ctrl->value;
382 saa7110_write(sd, 0x13, decoder->contrast);
383 }
384 break; 342 break;
385 case V4L2_CID_SATURATION: 343 case V4L2_CID_SATURATION:
386 if (decoder->sat != ctrl->value) { 344 saa7110_write(sd, 0x12, ctrl->val);
387 decoder->sat = ctrl->value;
388 saa7110_write(sd, 0x12, decoder->sat);
389 }
390 break; 345 break;
391 case V4L2_CID_HUE: 346 case V4L2_CID_HUE:
392 if (decoder->hue != ctrl->value) { 347 saa7110_write(sd, 0x07, ctrl->val);
393 decoder->hue = ctrl->value;
394 saa7110_write(sd, 0x07, decoder->hue);
395 }
396 break; 348 break;
397 default: 349 default:
398 return -EINVAL; 350 return -EINVAL;
@@ -409,11 +361,19 @@ static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
409 361
410/* ----------------------------------------------------------------------- */ 362/* ----------------------------------------------------------------------- */
411 363
364static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
365 .s_ctrl = saa7110_s_ctrl,
366};
367
412static const struct v4l2_subdev_core_ops saa7110_core_ops = { 368static const struct v4l2_subdev_core_ops saa7110_core_ops = {
413 .g_chip_ident = saa7110_g_chip_ident, 369 .g_chip_ident = saa7110_g_chip_ident,
414 .g_ctrl = saa7110_g_ctrl, 370 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
415 .s_ctrl = saa7110_s_ctrl, 371 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
416 .queryctrl = saa7110_queryctrl, 372 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
373 .g_ctrl = v4l2_subdev_g_ctrl,
374 .s_ctrl = v4l2_subdev_s_ctrl,
375 .queryctrl = v4l2_subdev_queryctrl,
376 .querymenu = v4l2_subdev_querymenu,
417 .s_std = saa7110_s_std, 377 .s_std = saa7110_s_std,
418}; 378};
419 379
@@ -454,10 +414,25 @@ static int saa7110_probe(struct i2c_client *client,
454 decoder->norm = V4L2_STD_PAL; 414 decoder->norm = V4L2_STD_PAL;
455 decoder->input = 0; 415 decoder->input = 0;
456 decoder->enable = 1; 416 decoder->enable = 1;
457 decoder->bright = 32768; 417 v4l2_ctrl_handler_init(&decoder->hdl, 2);
458 decoder->contrast = 32768; 418 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
459 decoder->hue = 32768; 419 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
460 decoder->sat = 32768; 420 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
421 V4L2_CID_CONTRAST, 0, 127, 1, 64);
422 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
423 V4L2_CID_SATURATION, 0, 127, 1, 64);
424 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
425 V4L2_CID_HUE, -128, 127, 1, 0);
426 sd->ctrl_handler = &decoder->hdl;
427 if (decoder->hdl.error) {
428 int err = decoder->hdl.error;
429
430 v4l2_ctrl_handler_free(&decoder->hdl);
431 kfree(decoder);
432 return err;
433 }
434 v4l2_ctrl_handler_setup(&decoder->hdl);
435
461 init_waitqueue_head(&decoder->wq); 436 init_waitqueue_head(&decoder->wq);
462 437
463 rv = saa7110_write_block(sd, initseq, sizeof(initseq)); 438 rv = saa7110_write_block(sd, initseq, sizeof(initseq));
@@ -490,9 +465,11 @@ static int saa7110_probe(struct i2c_client *client,
490static int saa7110_remove(struct i2c_client *client) 465static int saa7110_remove(struct i2c_client *client)
491{ 466{
492 struct v4l2_subdev *sd = i2c_get_clientdata(client); 467 struct v4l2_subdev *sd = i2c_get_clientdata(client);
468 struct saa7110 *decoder = to_saa7110(sd);
493 469
494 v4l2_device_unregister_subdev(sd); 470 v4l2_device_unregister_subdev(sd);
495 kfree(to_saa7110(sd)); 471 v4l2_ctrl_handler_free(&decoder->hdl);
472 kfree(decoder);
496 return 0; 473 return 0;
497} 474}
498 475
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 380f1b28cfcc..39fc0187a747 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -28,6 +28,7 @@ config VIDEO_SAA7134_RC
28 bool "Philips SAA7134 Remote Controller support" 28 bool "Philips SAA7134 Remote Controller support"
29 depends on RC_CORE 29 depends on RC_CORE
30 depends on VIDEO_SAA7134 30 depends on VIDEO_SAA7134
31 depends on !(RC_CORE=m && VIDEO_SAA7134=y)
31 default y 32 default y
32 ---help--- 33 ---help---
33 Enables Remote Controller support on saa7134 driver. 34 Enables Remote Controller support on saa7134 driver.
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index deb8fcf4aa49..61c6007c8ea6 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -3620,6 +3620,38 @@ struct saa7134_board saa7134_boards[] = {
3620 .amux = 0, 3620 .amux = 0,
3621 }, 3621 },
3622 }, 3622 },
3623 [SAA7134_BOARD_ENCORE_ENLTV_FM3] = {
3624 .name = "Encore ENLTV-FM 3",
3625 .audio_clock = 0x02187de7,
3626 .tuner_type = TUNER_TENA_TNF_5337,
3627 .radio_type = TUNER_TEA5767,
3628 .tuner_addr = 0x61,
3629 .radio_addr = 0x60,
3630 .inputs = { {
3631 .name = name_tv,
3632 .vmux = 1,
3633 .amux = LINE2,
3634 .tv = 1,
3635 }, {
3636 .name = name_comp1,
3637 .vmux = 3,
3638 .amux = LINE1,
3639 }, {
3640 .name = name_svideo,
3641 .vmux = 8,
3642 .amux = LINE1,
3643 } },
3644 .radio = {
3645 .name = name_radio,
3646 .vmux = 1,
3647 .amux = LINE1,
3648 },
3649 .mute = {
3650 .name = name_mute,
3651 .amux = LINE1,
3652 .gpio = 0x43000,
3653 },
3654 },
3623 [SAA7134_BOARD_CINERGY_HT_PCI] = { 3655 [SAA7134_BOARD_CINERGY_HT_PCI] = {
3624 .name = "Terratec Cinergy HT PCI", 3656 .name = "Terratec Cinergy HT PCI",
3625 .audio_clock = 0x00187de7, 3657 .audio_clock = 0x00187de7,
@@ -6387,6 +6419,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
6387 .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53, 6419 .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53,
6388 }, { 6420 }, {
6389 .vendor = PCI_VENDOR_ID_PHILIPS, 6421 .vendor = PCI_VENDOR_ID_PHILIPS,
6422 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6423 .subvendor = 0x1a7f,
6424 .subdevice = 0x2108,
6425 .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM3,
6426 }, {
6427 .vendor = PCI_VENDOR_ID_PHILIPS,
6390 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6428 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6391 .subvendor = 0x153b, 6429 .subvendor = 0x153b,
6392 .subdevice = 0x1175, 6430 .subdevice = 0x1175,
@@ -7102,6 +7140,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7102 case SAA7134_BOARD_ENCORE_ENLTV: 7140 case SAA7134_BOARD_ENCORE_ENLTV:
7103 case SAA7134_BOARD_ENCORE_ENLTV_FM: 7141 case SAA7134_BOARD_ENCORE_ENLTV_FM:
7104 case SAA7134_BOARD_ENCORE_ENLTV_FM53: 7142 case SAA7134_BOARD_ENCORE_ENLTV_FM53:
7143 case SAA7134_BOARD_ENCORE_ENLTV_FM3:
7105 case SAA7134_BOARD_10MOONSTVMASTER3: 7144 case SAA7134_BOARD_10MOONSTVMASTER3:
7106 case SAA7134_BOARD_BEHOLD_401: 7145 case SAA7134_BOARD_BEHOLD_401:
7107 case SAA7134_BOARD_BEHOLD_403: 7146 case SAA7134_BOARD_BEHOLD_403:
@@ -7294,9 +7333,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7294static void saa7134_tuner_setup(struct saa7134_dev *dev) 7333static void saa7134_tuner_setup(struct saa7134_dev *dev)
7295{ 7334{
7296 struct tuner_setup tun_setup; 7335 struct tuner_setup tun_setup;
7297 unsigned int mode_mask = T_RADIO | 7336 unsigned int mode_mask = T_RADIO | T_ANALOG_TV;
7298 T_ANALOG_TV |
7299 T_DIGITAL_TV;
7300 7337
7301 memset(&tun_setup, 0, sizeof(tun_setup)); 7338 memset(&tun_setup, 0, sizeof(tun_setup));
7302 tun_setup.tuner_callback = saa7134_tuner_callback; 7339 tun_setup.tuner_callback = saa7134_tuner_callback;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 6abeecff6da7..41f836fc93ec 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -752,19 +752,28 @@ static int saa7134_hwfini(struct saa7134_dev *dev)
752 return 0; 752 return 0;
753} 753}
754 754
755static void __devinit must_configure_manually(void) 755static void __devinit must_configure_manually(int has_eeprom)
756{ 756{
757 unsigned int i,p; 757 unsigned int i,p;
758 758
759 printk(KERN_WARNING 759 if (!has_eeprom)
760 "saa7134: <rant>\n" 760 printk(KERN_WARNING
761 "saa7134: Congratulations! Your TV card vendor saved a few\n" 761 "saa7134: <rant>\n"
762 "saa7134: cents for a eeprom, thus your pci board has no\n" 762 "saa7134: Congratulations! Your TV card vendor saved a few\n"
763 "saa7134: subsystem ID and I can't identify it automatically\n" 763 "saa7134: cents for a eeprom, thus your pci board has no\n"
764 "saa7134: </rant>\n" 764 "saa7134: subsystem ID and I can't identify it automatically\n"
765 "saa7134: I feel better now. Ok, here are the good news:\n" 765 "saa7134: </rant>\n"
766 "saa7134: You can use the card=<nr> insmod option to specify\n" 766 "saa7134: I feel better now. Ok, here are the good news:\n"
767 "saa7134: which board do you have. The list:\n"); 767 "saa7134: You can use the card=<nr> insmod option to specify\n"
768 "saa7134: which board do you have. The list:\n");
769 else
770 printk(KERN_WARNING
771 "saa7134: Board is currently unknown. You might try to use the card=<nr>\n"
772 "saa7134: insmod option to specify which board do you have, but this is\n"
773 "saa7134: somewhat risky, as might damage your card. It is better to ask\n"
774 "saa7134: for support at linux-media@vger.kernel.org.\n"
775 "saa7134: The supported cards are:\n");
776
768 for (i = 0; i < saa7134_bcount; i++) { 777 for (i = 0; i < saa7134_bcount; i++) {
769 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s", 778 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s",
770 i,saa7134_boards[i].name); 779 i,saa7134_boards[i].name);
@@ -936,8 +945,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
936 if (card[dev->nr] >= 0 && 945 if (card[dev->nr] >= 0 &&
937 card[dev->nr] < saa7134_bcount) 946 card[dev->nr] < saa7134_bcount)
938 dev->board = card[dev->nr]; 947 dev->board = card[dev->nr];
939 if (SAA7134_BOARD_NOAUTO == dev->board) { 948 if (SAA7134_BOARD_UNKNOWN == dev->board)
940 must_configure_manually(); 949 must_configure_manually(0);
950 else if (SAA7134_BOARD_NOAUTO == dev->board) {
951 must_configure_manually(1);
941 dev->board = SAA7134_BOARD_UNKNOWN; 952 dev->board = SAA7134_BOARD_UNKNOWN;
942 } 953 }
943 dev->autodetected = card[dev->nr] != dev->board; 954 dev->autodetected = card[dev->nr] != dev->board;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 6b8459c7728e..18294db38a01 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -373,6 +373,10 @@ static int empress_queryctrl(struct file *file, void *priv,
373 static const u32 mpeg_ctrls[] = { 373 static const u32 mpeg_ctrls[] = {
374 V4L2_CID_MPEG_CLASS, 374 V4L2_CID_MPEG_CLASS,
375 V4L2_CID_MPEG_STREAM_TYPE, 375 V4L2_CID_MPEG_STREAM_TYPE,
376 V4L2_CID_MPEG_STREAM_PID_PMT,
377 V4L2_CID_MPEG_STREAM_PID_AUDIO,
378 V4L2_CID_MPEG_STREAM_PID_VIDEO,
379 V4L2_CID_MPEG_STREAM_PID_PCR,
376 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, 380 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
377 V4L2_CID_MPEG_AUDIO_ENCODING, 381 V4L2_CID_MPEG_AUDIO_ENCODING,
378 V4L2_CID_MPEG_AUDIO_L2_BITRATE, 382 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index dc646e65edb7..be1c2a2de27c 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -414,6 +414,41 @@ static int __saa7134_ir_start(void *priv)
414 if (ir->running) 414 if (ir->running)
415 return 0; 415 return 0;
416 416
417 /* Moved here from saa7134_input_init1() because the latter
418 * is not called on device resume */
419 switch (dev->board) {
420 case SAA7134_BOARD_MD2819:
421 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
422 case SAA7134_BOARD_AVERMEDIA_305:
423 case SAA7134_BOARD_AVERMEDIA_307:
424 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
425 case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
426 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
427 case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
428 case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
429 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
430 case SAA7134_BOARD_AVERMEDIA_M102:
431 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
432 /* Without this we won't receive key up events */
433 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
434 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
435 break;
436 case SAA7134_BOARD_AVERMEDIA_777:
437 case SAA7134_BOARD_AVERMEDIA_A16AR:
438 /* Without this we won't receive key up events */
439 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
440 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
441 break;
442 case SAA7134_BOARD_AVERMEDIA_A16D:
443 /* Without this we won't receive key up events */
444 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
445 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
446 break;
447 case SAA7134_BOARD_GOTVIEW_7135:
448 saa_setb(SAA7134_GPIO_GPMODE1, 0x80);
449 break;
450 }
451
417 ir->running = true; 452 ir->running = true;
418 ir->active = false; 453 ir->active = false;
419 454
@@ -548,9 +583,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
548 mask_keycode = 0x0007C8; 583 mask_keycode = 0x0007C8;
549 mask_keydown = 0x000010; 584 mask_keydown = 0x000010;
550 polling = 50; // ms 585 polling = 50; // ms
551 /* Set GPIO pin2 to high to enable the IR controller */ 586 /* GPIO stuff moved to __saa7134_ir_start() */
552 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
553 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
554 break; 587 break;
555 case SAA7134_BOARD_AVERMEDIA_M135A: 588 case SAA7134_BOARD_AVERMEDIA_M135A:
556 ir_codes = RC_MAP_AVERMEDIA_M135A; 589 ir_codes = RC_MAP_AVERMEDIA_M135A;
@@ -572,18 +605,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
572 mask_keycode = 0x02F200; 605 mask_keycode = 0x02F200;
573 mask_keydown = 0x000400; 606 mask_keydown = 0x000400;
574 polling = 50; // ms 607 polling = 50; // ms
575 /* Without this we won't receive key up events */ 608 /* GPIO stuff moved to __saa7134_ir_start() */
576 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
577 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
578 break; 609 break;
579 case SAA7134_BOARD_AVERMEDIA_A16D: 610 case SAA7134_BOARD_AVERMEDIA_A16D:
580 ir_codes = RC_MAP_AVERMEDIA_A16D; 611 ir_codes = RC_MAP_AVERMEDIA_A16D;
581 mask_keycode = 0x02F200; 612 mask_keycode = 0x02F200;
582 mask_keydown = 0x000400; 613 mask_keydown = 0x000400;
583 polling = 50; /* ms */ 614 polling = 50; /* ms */
584 /* Without this we won't receive key up events */ 615 /* GPIO stuff moved to __saa7134_ir_start() */
585 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
586 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
587 break; 616 break;
588 case SAA7134_BOARD_KWORLD_TERMINATOR: 617 case SAA7134_BOARD_KWORLD_TERMINATOR:
589 ir_codes = RC_MAP_PIXELVIEW; 618 ir_codes = RC_MAP_PIXELVIEW;
@@ -635,7 +664,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
635 mask_keycode = 0x0003CC; 664 mask_keycode = 0x0003CC;
636 mask_keydown = 0x000010; 665 mask_keydown = 0x000010;
637 polling = 5; /* ms */ 666 polling = 5; /* ms */
638 saa_setb(SAA7134_GPIO_GPMODE1, 0x80); 667 /* GPIO stuff moved to __saa7134_ir_start() */
639 break; 668 break;
640 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 669 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
641 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: 670 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
@@ -681,6 +710,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
681 polling = 50; // ms 710 polling = 50; // ms
682 break; 711 break;
683 case SAA7134_BOARD_ENCORE_ENLTV_FM53: 712 case SAA7134_BOARD_ENCORE_ENLTV_FM53:
713 case SAA7134_BOARD_ENCORE_ENLTV_FM3:
684 ir_codes = RC_MAP_ENCORE_ENLTV_FM53; 714 ir_codes = RC_MAP_ENCORE_ENLTV_FM53;
685 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ 715 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
686 mask_keyup = 0x0040000; 716 mask_keyup = 0x0040000;
@@ -863,7 +893,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
863 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 893 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
864 dev->init_data.name = "HVR 1110"; 894 dev->init_data.name = "HVR 1110";
865 dev->init_data.get_key = get_key_hvr1110; 895 dev->init_data.get_key = get_key_hvr1110;
866 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; 896 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
867 info.addr = 0x71; 897 info.addr = 0x71;
868 break; 898 break;
869 case SAA7134_BOARD_BEHOLD_607FM_MK3: 899 case SAA7134_BOARD_BEHOLD_607FM_MK3:
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 5b0a347b0b8f..f96cd5d761f9 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -327,6 +327,7 @@ struct saa7134_card_ir {
327#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181 327#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181
328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182 328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
329#define SAA7134_BOARD_VIDEOMATE_M1F 183 329#define SAA7134_BOARD_VIDEOMATE_M1F 183
330#define SAA7134_BOARD_ENCORE_ENLTV_FM3 184
330 331
331#define SAA7134_MAXBOARDS 32 332#define SAA7134_MAXBOARDS 32
332#define SAA7134_INPUT_MAX 8 333#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
index bd86d970f4c2..8a98ab68239e 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -743,7 +743,7 @@ int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
743int saa7164_api_initialize_dif(struct saa7164_port *port) 743int saa7164_api_initialize_dif(struct saa7164_port *port)
744{ 744{
745 struct saa7164_dev *dev = port->dev; 745 struct saa7164_dev *dev = port->dev;
746 struct saa7164_port *p = 0; 746 struct saa7164_port *p = NULL;
747 int ret = -EINVAL; 747 int ret = -EINVAL;
748 u32 std = 0; 748 u32 std = 0;
749 749
@@ -926,9 +926,9 @@ int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
926 926
927int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) 927int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
928{ 928{
929 struct saa7164_port *tsport = 0; 929 struct saa7164_port *tsport = NULL;
930 struct saa7164_port *encport = 0; 930 struct saa7164_port *encport = NULL;
931 struct saa7164_port *vbiport = 0; 931 struct saa7164_port *vbiport = NULL;
932 u32 idx, next_offset; 932 u32 idx, next_offset;
933 int i; 933 int i;
934 struct tmComResDescrHeader *hdr, *t; 934 struct tmComResDescrHeader *hdr, *t;
@@ -1340,7 +1340,7 @@ int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
1340 1340
1341 /* Allocate enough storage for all of the descs */ 1341 /* Allocate enough storage for all of the descs */
1342 buf = kzalloc(buflen, GFP_KERNEL); 1342 buf = kzalloc(buflen, GFP_KERNEL);
1343 if (buf == NULL) 1343 if (!buf)
1344 return SAA_ERR_NO_RESOURCES; 1344 return SAA_ERR_NO_RESOURCES;
1345 1345
1346 /* Retrieve them */ 1346 /* Retrieve them */
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
index ddd25211c9e8..66696fa8341d 100644
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -93,7 +93,7 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
93 u32 len) 93 u32 len)
94{ 94{
95 struct tmHWStreamParameters *params = &port->hw_streamingparams; 95 struct tmHWStreamParameters *params = &port->hw_streamingparams;
96 struct saa7164_buffer *buf = 0; 96 struct saa7164_buffer *buf = NULL;
97 struct saa7164_dev *dev = port->dev; 97 struct saa7164_dev *dev = port->dev;
98 int i; 98 int i;
99 99
@@ -103,7 +103,7 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
103 } 103 }
104 104
105 buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL); 105 buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
106 if (buf == NULL) { 106 if (!buf) {
107 log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__); 107 log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
108 goto ret; 108 goto ret;
109 } 109 }
@@ -157,7 +157,7 @@ fail2:
157fail1: 157fail1:
158 kfree(buf); 158 kfree(buf);
159 159
160 buf = 0; 160 buf = NULL;
161ret: 161ret:
162 return buf; 162 return buf;
163} 163}
@@ -289,14 +289,14 @@ struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
289 struct saa7164_user_buffer *buf; 289 struct saa7164_user_buffer *buf;
290 290
291 buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL); 291 buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL);
292 if (buf == 0) 292 if (!buf)
293 return 0; 293 return NULL;
294 294
295 buf->data = kzalloc(len, GFP_KERNEL); 295 buf->data = kzalloc(len, GFP_KERNEL);
296 296
297 if (buf->data == 0) { 297 if (!buf->data) {
298 kfree(buf); 298 kfree(buf);
299 return 0; 299 return NULL;
300 } 300 }
301 301
302 buf->actual_size = len; 302 buf->actual_size = len;
@@ -315,7 +315,7 @@ void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
315 return; 315 return;
316 316
317 kfree(buf->data); 317 kfree(buf->data);
318 buf->data = 0; 318 buf->data = NULL;
319 319
320 kfree(buf); 320 kfree(buf);
321} 321}
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
index b2b0d97101d0..466e1b02f91f 100644
--- a/drivers/media/video/saa7164/saa7164-bus.c
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -158,7 +158,7 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
158 return SAA_ERR_BAD_PARAMETER; 158 return SAA_ERR_BAD_PARAMETER;
159 } 159 }
160 160
161 if ((msg->size > 0) && (buf == 0)) { 161 if ((msg->size > 0) && (buf == NULL)) {
162 printk(KERN_ERR "%s() Missing message buffer\n", __func__); 162 printk(KERN_ERR "%s() Missing message buffer\n", __func__);
163 return SAA_ERR_BAD_PARAMETER; 163 return SAA_ERR_BAD_PARAMETER;
164 } 164 }
@@ -315,7 +315,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
315 315
316 saa7164_bus_verify(dev); 316 saa7164_bus_verify(dev);
317 317
318 if (msg == 0) 318 if (msg == NULL)
319 return ret; 319 return ret;
320 320
321 if (msg->size > dev->bus.m_wMaxReqSize) { 321 if (msg->size > dev->bus.m_wMaxReqSize) {
@@ -324,7 +324,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
324 return ret; 324 return ret;
325 } 325 }
326 326
327 if ((peekonly == 0) && (msg->size > 0) && (buf == 0)) { 327 if ((peekonly == 0) && (msg->size > 0) && (buf == NULL)) {
328 printk(KERN_ERR 328 printk(KERN_ERR
329 "%s() Missing msg buf, size should be %d bytes\n", 329 "%s() Missing msg buf, size should be %d bytes\n",
330 __func__, msg->size); 330 __func__, msg->size);
@@ -392,7 +392,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
392 392
393 printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__); 393 printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
394 saa7164_bus_dumpmsg(dev, msg, buf); 394 saa7164_bus_dumpmsg(dev, msg, buf);
395 saa7164_bus_dumpmsg(dev, &msg_tmp, 0); 395 saa7164_bus_dumpmsg(dev, &msg_tmp, NULL);
396 ret = SAA_ERR_INVALID_COMMAND; 396 ret = SAA_ERR_INVALID_COMMAND;
397 goto out; 397 goto out;
398 } 398 }
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
index a97ae17b36c2..6a4c217ed3a7 100644
--- a/drivers/media/video/saa7164/saa7164-cmd.c
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -84,7 +84,7 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev)
84{ 84{
85 int ret = SAA_OK, i = 0; 85 int ret = SAA_OK, i = 0;
86 u32 timeout; 86 u32 timeout;
87 wait_queue_head_t *q = 0; 87 wait_queue_head_t *q = NULL;
88 u8 tmp[512]; 88 u8 tmp[512];
89 dprintk(DBGLVL_CMD, "%s()\n", __func__); 89 dprintk(DBGLVL_CMD, "%s()\n", __func__);
90 90
@@ -137,7 +137,7 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev)
137 int loop = 1; 137 int loop = 1;
138 int ret; 138 int ret;
139 u32 timeout; 139 u32 timeout;
140 wait_queue_head_t *q = 0; 140 wait_queue_head_t *q = NULL;
141 u8 tmp[512]; 141 u8 tmp[512];
142 dprintk(DBGLVL_CMD, "%s()\n", __func__); 142 dprintk(DBGLVL_CMD, "%s()\n", __func__);
143 143
@@ -261,7 +261,7 @@ out:
261 */ 261 */
262int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno) 262int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
263{ 263{
264 wait_queue_head_t *q = 0; 264 wait_queue_head_t *q = NULL;
265 int ret = SAA_BUS_TIMEOUT; 265 int ret = SAA_BUS_TIMEOUT;
266 unsigned long stamp; 266 unsigned long stamp;
267 int r; 267 int r;
@@ -357,7 +357,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
357 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id, 357 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
358 command, controlselector); 358 command, controlselector);
359 359
360 if ((size == 0) || (buf == 0)) { 360 if ((size == 0) || (buf == NULL)) {
361 printk(KERN_ERR "%s() Invalid param\n", __func__); 361 printk(KERN_ERR "%s() Invalid param\n", __func__);
362 return SAA_ERR_BAD_PARAMETER; 362 return SAA_ERR_BAD_PARAMETER;
363 } 363 }
@@ -538,7 +538,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
538 538
539 /* Invalid */ 539 /* Invalid */
540 dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__); 540 dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
541 ret = saa7164_bus_get(dev, presponse_t, 0, 0); 541 ret = saa7164_bus_get(dev, presponse_t, NULL, 0);
542 if (ret != SAA_OK) { 542 if (ret != SAA_OK) {
543 printk(KERN_ERR "get failed\n"); 543 printk(KERN_ERR "get failed\n");
544 return ret; 544 return ret;
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index 58af67f2278b..b813aec1e456 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -277,8 +277,8 @@ static void saa7164_histogram_print(struct saa7164_port *port,
277static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) 277static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
278{ 278{
279 struct saa7164_dev *dev = port->dev; 279 struct saa7164_dev *dev = port->dev;
280 struct saa7164_buffer *buf = 0; 280 struct saa7164_buffer *buf = NULL;
281 struct saa7164_user_buffer *ubuf = 0; 281 struct saa7164_user_buffer *ubuf = NULL;
282 struct list_head *c, *n; 282 struct list_head *c, *n;
283 int i = 0; 283 int i = 0;
284 u8 __iomem *p; 284 u8 __iomem *p;
@@ -649,7 +649,7 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id)
649 u32 intid, intstat[INT_SIZE/4]; 649 u32 intid, intstat[INT_SIZE/4];
650 int i, handled = 0, bit; 650 int i, handled = 0, bit;
651 651
652 if (dev == 0) { 652 if (dev == NULL) {
653 printk(KERN_ERR "%s() No device specified\n", __func__); 653 printk(KERN_ERR "%s() No device specified\n", __func__);
654 handled = 0; 654 handled = 0;
655 goto out; 655 goto out;
@@ -945,7 +945,7 @@ static int get_resources(struct saa7164_dev *dev)
945 945
946static int saa7164_port_init(struct saa7164_dev *dev, int portnr) 946static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
947{ 947{
948 struct saa7164_port *port = 0; 948 struct saa7164_port *port = NULL;
949 949
950 if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS)) 950 if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
951 BUG(); 951 BUG();
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
index b305a01b3bde..f65eab63ca87 100644
--- a/drivers/media/video/saa7164/saa7164-dvb.c
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -309,8 +309,8 @@ static int dvb_register(struct saa7164_port *port)
309 309
310 port->hw_streamingparams.pitch = 188; 310 port->hw_streamingparams.pitch = 188;
311 port->hw_streamingparams.linethreshold = 0; 311 port->hw_streamingparams.linethreshold = 0;
312 port->hw_streamingparams.pagetablelistvirt = 0; 312 port->hw_streamingparams.pagetablelistvirt = NULL;
313 port->hw_streamingparams.pagetablelistphys = 0; 313 port->hw_streamingparams.pagetablelistphys = NULL;
314 port->hw_streamingparams.numpagetables = 2 + 314 port->hw_streamingparams.numpagetables = 2 +
315 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE); 315 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
316 316
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
index 1838408cd5cb..f9d594698832 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -152,8 +152,8 @@ static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
152 /* Init and establish defaults */ 152 /* Init and establish defaults */
153 params->bitspersample = 8; 153 params->bitspersample = 8;
154 params->linethreshold = 0; 154 params->linethreshold = 0;
155 params->pagetablelistvirt = 0; 155 params->pagetablelistvirt = NULL;
156 params->pagetablelistphys = 0; 156 params->pagetablelistphys = NULL;
157 params->numpagetableentries = port->hwcfg.buffercount; 157 params->numpagetableentries = port->hwcfg.buffercount;
158 158
159 /* Allocate the PCI resources, buffers (hard) */ 159 /* Allocate the PCI resources, buffers (hard) */
@@ -1108,7 +1108,7 @@ static int fops_release(struct file *file)
1108 1108
1109struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port) 1109struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
1110{ 1110{
1111 struct saa7164_user_buffer *ubuf = 0; 1111 struct saa7164_user_buffer *ubuf = NULL;
1112 struct saa7164_dev *dev = port->dev; 1112 struct saa7164_dev *dev = port->dev;
1113 u32 crc; 1113 u32 crc;
1114 1114
@@ -1443,7 +1443,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
1443 port->v4l_device = saa7164_encoder_alloc(port, 1443 port->v4l_device = saa7164_encoder_alloc(port,
1444 dev->pci, &saa7164_mpeg_template, "mpeg"); 1444 dev->pci, &saa7164_mpeg_template, "mpeg");
1445 1445
1446 if (port->v4l_device == NULL) { 1446 if (!port->v4l_device) {
1447 printk(KERN_INFO "%s: can't allocate mpeg device\n", 1447 printk(KERN_INFO "%s: can't allocate mpeg device\n",
1448 dev->name); 1448 dev->name);
1449 result = -ENOMEM; 1449 result = -ENOMEM;
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
index ebed6f786a23..b369300cce06 100644
--- a/drivers/media/video/saa7164/saa7164-fw.c
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -88,7 +88,7 @@ int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
88 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n", 88 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
89 __func__, src, srcsize, dlflags, dst, dstsize); 89 __func__, src, srcsize, dlflags, dst, dstsize);
90 90
91 if ((src == 0) || (dst == 0)) { 91 if ((src == NULL) || (dst == NULL)) {
92 ret = -EIO; 92 ret = -EIO;
93 goto out; 93 goto out;
94 } 94 }
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
index 8abbe6d661e4..9e5b01c29cf5 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -123,8 +123,8 @@ static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
123 ((params->numberoflines * params->pitch) / PAGE_SIZE); 123 ((params->numberoflines * params->pitch) / PAGE_SIZE);
124 params->bitspersample = 8; 124 params->bitspersample = 8;
125 params->linethreshold = 0; 125 params->linethreshold = 0;
126 params->pagetablelistvirt = 0; 126 params->pagetablelistvirt = NULL;
127 params->pagetablelistphys = 0; 127 params->pagetablelistphys = NULL;
128 params->numpagetableentries = port->hwcfg.buffercount; 128 params->numpagetableentries = port->hwcfg.buffercount;
129 129
130 /* Allocate the PCI resources, buffers (hard) */ 130 /* Allocate the PCI resources, buffers (hard) */
@@ -1054,7 +1054,7 @@ static int fops_release(struct file *file)
1054 1054
1055struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port) 1055struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
1056{ 1056{
1057 struct saa7164_user_buffer *ubuf = 0; 1057 struct saa7164_user_buffer *ubuf = NULL;
1058 struct saa7164_dev *dev = port->dev; 1058 struct saa7164_dev *dev = port->dev;
1059 u32 crc; 1059 u32 crc;
1060 1060
@@ -1334,7 +1334,7 @@ int saa7164_vbi_register(struct saa7164_port *port)
1334 port->v4l_device = saa7164_vbi_alloc(port, 1334 port->v4l_device = saa7164_vbi_alloc(port,
1335 dev->pci, &saa7164_vbi_template, "vbi"); 1335 dev->pci, &saa7164_vbi_template, "vbi");
1336 1336
1337 if (port->v4l_device == NULL) { 1337 if (!port->v4l_device) {
1338 printk(KERN_INFO "%s: can't allocate vbi device\n", 1338 printk(KERN_INFO "%s: can't allocate vbi device\n",
1339 dev->name); 1339 dev->name);
1340 result = -ENOMEM; 1340 result = -ENOMEM;
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 954222bc3458..3fe54bf41142 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -38,7 +38,7 @@
38#include <media/v4l2-dev.h> 38#include <media/v4l2-dev.h>
39#include <media/soc_camera.h> 39#include <media/soc_camera.h>
40#include <media/sh_mobile_ceu.h> 40#include <media/sh_mobile_ceu.h>
41#include <media/videobuf-dma-contig.h> 41#include <media/videobuf2-dma-contig.h>
42#include <media/v4l2-mediabus.h> 42#include <media/v4l2-mediabus.h>
43#include <media/soc_mediabus.h> 43#include <media/soc_mediabus.h>
44 44
@@ -87,7 +87,8 @@
87 87
88/* per video frame buffer */ 88/* per video frame buffer */
89struct sh_mobile_ceu_buffer { 89struct sh_mobile_ceu_buffer {
90 struct videobuf_buffer vb; /* v4l buffer must be first */ 90 struct vb2_buffer vb; /* v4l buffer must be first */
91 struct list_head queue;
91 enum v4l2_mbus_pixelcode code; 92 enum v4l2_mbus_pixelcode code;
92}; 93};
93 94
@@ -99,16 +100,17 @@ struct sh_mobile_ceu_dev {
99 void __iomem *base; 100 void __iomem *base;
100 unsigned long video_limit; 101 unsigned long video_limit;
101 102
102 /* lock used to protect videobuf */ 103 spinlock_t lock; /* Protects video buffer lists */
103 spinlock_t lock;
104 struct list_head capture; 104 struct list_head capture;
105 struct videobuf_buffer *active; 105 struct vb2_buffer *active;
106 struct vb2_alloc_ctx *alloc_ctx;
106 107
107 struct sh_mobile_ceu_info *pdata; 108 struct sh_mobile_ceu_info *pdata;
108 109
109 u32 cflcr; 110 u32 cflcr;
110 111
111 enum v4l2_field field; 112 enum v4l2_field field;
113 int sequence;
112 114
113 unsigned int image_mode:1; 115 unsigned int image_mode:1;
114 unsigned int is_16bit:1; 116 unsigned int is_16bit:1;
@@ -133,6 +135,11 @@ struct sh_mobile_ceu_cam {
133 enum v4l2_mbus_pixelcode code; 135 enum v4l2_mbus_pixelcode code;
134}; 136};
135 137
138static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
139{
140 return container_of(vb, struct sh_mobile_ceu_buffer, vb);
141}
142
136static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev) 143static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
137{ 144{
138 unsigned long flags; 145 unsigned long flags;
@@ -205,11 +212,11 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
205/* 212/*
206 * Videobuf operations 213 * Videobuf operations
207 */ 214 */
208static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq, 215static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
209 unsigned int *count, 216 unsigned int *count, unsigned int *num_planes,
210 unsigned int *size) 217 unsigned long sizes[], void *alloc_ctxs[])
211{ 218{
212 struct soc_camera_device *icd = vq->priv_data; 219 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
213 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 220 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
214 struct sh_mobile_ceu_dev *pcdev = ici->priv; 221 struct sh_mobile_ceu_dev *pcdev = ici->priv;
215 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 222 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
@@ -218,39 +225,25 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
218 if (bytes_per_line < 0) 225 if (bytes_per_line < 0)
219 return bytes_per_line; 226 return bytes_per_line;
220 227
221 *size = bytes_per_line * icd->user_height; 228 *num_planes = 1;
229
230 pcdev->sequence = 0;
231 sizes[0] = bytes_per_line * icd->user_height;
232 alloc_ctxs[0] = pcdev->alloc_ctx;
222 233
223 if (0 == *count) 234 if (!*count)
224 *count = 2; 235 *count = 2;
225 236
226 if (pcdev->video_limit) { 237 if (pcdev->video_limit) {
227 if (PAGE_ALIGN(*size) * *count > pcdev->video_limit) 238 if (PAGE_ALIGN(sizes[0]) * *count > pcdev->video_limit)
228 *count = pcdev->video_limit / PAGE_ALIGN(*size); 239 *count = pcdev->video_limit / PAGE_ALIGN(sizes[0]);
229 } 240 }
230 241
231 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); 242 dev_dbg(icd->dev.parent, "count=%d, size=%lu\n", *count, sizes[0]);
232 243
233 return 0; 244 return 0;
234} 245}
235 246
236static void free_buffer(struct videobuf_queue *vq,
237 struct sh_mobile_ceu_buffer *buf)
238{
239 struct soc_camera_device *icd = vq->priv_data;
240 struct device *dev = icd->dev.parent;
241
242 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
243 &buf->vb, buf->vb.baddr, buf->vb.bsize);
244
245 if (in_interrupt())
246 BUG();
247
248 videobuf_waiton(vq, &buf->vb, 0, 0);
249 videobuf_dma_contig_free(vq, &buf->vb);
250 dev_dbg(dev, "%s freed\n", __func__);
251 buf->vb.state = VIDEOBUF_NEEDS_INIT;
252}
253
254#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */ 247#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
255#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */ 248#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
256#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */ 249#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
@@ -309,7 +302,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
309 bottom2 = CDBCR; 302 bottom2 = CDBCR;
310 } 303 }
311 304
312 phys_addr_top = videobuf_to_dma_contig(pcdev->active); 305 phys_addr_top = vb2_dma_contig_plane_paddr(pcdev->active, 0);
306
313 ceu_write(pcdev, top1, phys_addr_top); 307 ceu_write(pcdev, top1, phys_addr_top);
314 if (V4L2_FIELD_NONE != pcdev->field) { 308 if (V4L2_FIELD_NONE != pcdev->field) {
315 phys_addr_bottom = phys_addr_top + icd->user_width; 309 phys_addr_bottom = phys_addr_top + icd->user_width;
@@ -330,87 +324,67 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
330 } 324 }
331 } 325 }
332 326
333 pcdev->active->state = VIDEOBUF_ACTIVE;
334 ceu_write(pcdev, CAPSR, 0x1); /* start capture */ 327 ceu_write(pcdev, CAPSR, 0x1); /* start capture */
335 328
336 return ret; 329 return ret;
337} 330}
338 331
339static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, 332static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
340 struct videobuf_buffer *vb,
341 enum v4l2_field field)
342{ 333{
343 struct soc_camera_device *icd = vq->priv_data; 334 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
344 struct sh_mobile_ceu_buffer *buf; 335 struct sh_mobile_ceu_buffer *buf;
345 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 336 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
346 icd->current_fmt->host_fmt); 337 icd->current_fmt->host_fmt);
347 int ret; 338 unsigned long size;
348 339
349 if (bytes_per_line < 0) 340 if (bytes_per_line < 0)
350 return bytes_per_line; 341 return bytes_per_line;
351 342
352 buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); 343 buf = to_ceu_vb(vb);
353 344
354 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 345 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
355 vb, vb->baddr, vb->bsize); 346 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
356 347
357 /* Added list head initialization on alloc */ 348 /* Added list head initialization on alloc */
358 WARN_ON(!list_empty(&vb->queue)); 349 WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
359 350
360#ifdef DEBUG 351#ifdef DEBUG
361 /* 352 /*
362 * This can be useful if you want to see if we actually fill 353 * This can be useful if you want to see if we actually fill
363 * the buffer with something 354 * the buffer with something
364 */ 355 */
365 memset((void *)vb->baddr, 0xaa, vb->bsize); 356 if (vb2_plane_vaddr(vb, 0))
357 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
366#endif 358#endif
367 359
368 BUG_ON(NULL == icd->current_fmt); 360 BUG_ON(NULL == icd->current_fmt);
369 361
370 if (buf->code != icd->current_fmt->code || 362 size = icd->user_height * bytes_per_line;
371 vb->width != icd->user_width ||
372 vb->height != icd->user_height ||
373 vb->field != field) {
374 buf->code = icd->current_fmt->code;
375 vb->width = icd->user_width;
376 vb->height = icd->user_height;
377 vb->field = field;
378 vb->state = VIDEOBUF_NEEDS_INIT;
379 }
380 363
381 vb->size = vb->height * bytes_per_line; 364 if (vb2_plane_size(vb, 0) < size) {
382 if (0 != vb->baddr && vb->bsize < vb->size) { 365 dev_err(icd->dev.parent, "Buffer too small (%lu < %lu)\n",
383 ret = -EINVAL; 366 vb2_plane_size(vb, 0), size);
384 goto out; 367 return -ENOBUFS;
385 } 368 }
386 369
387 if (vb->state == VIDEOBUF_NEEDS_INIT) { 370 vb2_set_plane_payload(vb, 0, size);
388 ret = videobuf_iolock(vq, vb, NULL);
389 if (ret)
390 goto fail;
391 vb->state = VIDEOBUF_PREPARED;
392 }
393 371
394 return 0; 372 return 0;
395fail:
396 free_buffer(vq, buf);
397out:
398 return ret;
399} 373}
400 374
401/* Called under spinlock_irqsave(&pcdev->lock, ...) */ 375static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
402static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
403 struct videobuf_buffer *vb)
404{ 376{
405 struct soc_camera_device *icd = vq->priv_data; 377 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
406 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 378 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
407 struct sh_mobile_ceu_dev *pcdev = ici->priv; 379 struct sh_mobile_ceu_dev *pcdev = ici->priv;
380 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
381 unsigned long flags;
408 382
409 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 383 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
410 vb, vb->baddr, vb->bsize); 384 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
411 385
412 vb->state = VIDEOBUF_QUEUED; 386 spin_lock_irqsave(&pcdev->lock, flags);
413 list_add_tail(&vb->queue, &pcdev->capture); 387 list_add_tail(&buf->queue, &pcdev->capture);
414 388
415 if (!pcdev->active) { 389 if (!pcdev->active) {
416 /* 390 /*
@@ -421,13 +395,14 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
421 pcdev->active = vb; 395 pcdev->active = vb;
422 sh_mobile_ceu_capture(pcdev); 396 sh_mobile_ceu_capture(pcdev);
423 } 397 }
398 spin_unlock_irqrestore(&pcdev->lock, flags);
424} 399}
425 400
426static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, 401static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
427 struct videobuf_buffer *vb)
428{ 402{
429 struct soc_camera_device *icd = vq->priv_data; 403 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
430 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 404 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
405 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
431 struct sh_mobile_ceu_dev *pcdev = ici->priv; 406 struct sh_mobile_ceu_dev *pcdev = ici->priv;
432 unsigned long flags; 407 unsigned long flags;
433 408
@@ -439,53 +414,60 @@ static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
439 pcdev->active = NULL; 414 pcdev->active = NULL;
440 } 415 }
441 416
442 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) && 417 /* Doesn't hurt also if the list is empty */
443 !list_empty(&vb->queue)) { 418 list_del_init(&buf->queue);
444 vb->state = VIDEOBUF_ERROR;
445 list_del_init(&vb->queue);
446 }
447 419
448 spin_unlock_irqrestore(&pcdev->lock, flags); 420 spin_unlock_irqrestore(&pcdev->lock, flags);
421}
449 422
450 free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); 423static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
424{
425 /* This is for locking debugging only */
426 INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
427 return 0;
451} 428}
452 429
453static struct videobuf_queue_ops sh_mobile_ceu_videobuf_ops = { 430static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
454 .buf_setup = sh_mobile_ceu_videobuf_setup, 431 .queue_setup = sh_mobile_ceu_videobuf_setup,
455 .buf_prepare = sh_mobile_ceu_videobuf_prepare, 432 .buf_prepare = sh_mobile_ceu_videobuf_prepare,
456 .buf_queue = sh_mobile_ceu_videobuf_queue, 433 .buf_queue = sh_mobile_ceu_videobuf_queue,
457 .buf_release = sh_mobile_ceu_videobuf_release, 434 .buf_cleanup = sh_mobile_ceu_videobuf_release,
435 .buf_init = sh_mobile_ceu_videobuf_init,
436 .wait_prepare = soc_camera_unlock,
437 .wait_finish = soc_camera_lock,
458}; 438};
459 439
460static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) 440static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
461{ 441{
462 struct sh_mobile_ceu_dev *pcdev = data; 442 struct sh_mobile_ceu_dev *pcdev = data;
463 struct videobuf_buffer *vb; 443 struct vb2_buffer *vb;
464 unsigned long flags; 444 int ret;
465 445
466 spin_lock_irqsave(&pcdev->lock, flags); 446 spin_lock(&pcdev->lock);
467 447
468 vb = pcdev->active; 448 vb = pcdev->active;
469 if (!vb) 449 if (!vb)
470 /* Stale interrupt from a released buffer */ 450 /* Stale interrupt from a released buffer */
471 goto out; 451 goto out;
472 452
473 list_del_init(&vb->queue); 453 list_del_init(&to_ceu_vb(vb)->queue);
474 454
475 if (!list_empty(&pcdev->capture)) 455 if (!list_empty(&pcdev->capture))
476 pcdev->active = list_entry(pcdev->capture.next, 456 pcdev->active = &list_entry(pcdev->capture.next,
477 struct videobuf_buffer, queue); 457 struct sh_mobile_ceu_buffer, queue)->vb;
478 else 458 else
479 pcdev->active = NULL; 459 pcdev->active = NULL;
480 460
481 vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ? 461 ret = sh_mobile_ceu_capture(pcdev);
482 VIDEOBUF_ERROR : VIDEOBUF_DONE; 462 do_gettimeofday(&vb->v4l2_buf.timestamp);
483 do_gettimeofday(&vb->ts); 463 if (!ret) {
484 vb->field_count++; 464 vb->v4l2_buf.field = pcdev->field;
485 wake_up(&vb->done); 465 vb->v4l2_buf.sequence = pcdev->sequence++;
466 }
467 vb2_buffer_done(vb, ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
486 468
487out: 469out:
488 spin_unlock_irqrestore(&pcdev->lock, flags); 470 spin_unlock(&pcdev->lock);
489 471
490 return IRQ_HANDLED; 472 return IRQ_HANDLED;
491} 473}
@@ -529,9 +511,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
529 /* make sure active buffer is canceled */ 511 /* make sure active buffer is canceled */
530 spin_lock_irqsave(&pcdev->lock, flags); 512 spin_lock_irqsave(&pcdev->lock, flags);
531 if (pcdev->active) { 513 if (pcdev->active) {
532 list_del(&pcdev->active->queue); 514 list_del_init(&to_ceu_vb(pcdev->active)->queue);
533 pcdev->active->state = VIDEOBUF_ERROR; 515 vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
534 wake_up_all(&pcdev->active->done);
535 pcdev->active = NULL; 516 pcdev->active = NULL;
536 } 517 }
537 spin_unlock_irqrestore(&pcdev->lock, flags); 518 spin_unlock_irqrestore(&pcdev->lock, flags);
@@ -686,6 +667,7 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
686 ceu_write(pcdev, CAPSR, capsr); 667 ceu_write(pcdev, CAPSR, capsr);
687} 668}
688 669
670/* Capture is not running, no interrupts, no locking needed */
689static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, 671static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
690 __u32 pixfmt) 672 __u32 pixfmt)
691{ 673{
@@ -1364,7 +1346,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1364 struct device *dev = icd->dev.parent; 1346 struct device *dev = icd->dev.parent;
1365 struct v4l2_mbus_framefmt mf; 1347 struct v4l2_mbus_framefmt mf;
1366 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v, 1348 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v,
1367 out_width, out_height, scale_h, scale_v; 1349 out_width, out_height;
1368 int interm_width, interm_height; 1350 int interm_width, interm_height;
1369 u32 capsr, cflcr; 1351 u32 capsr, cflcr;
1370 int ret; 1352 int ret;
@@ -1422,10 +1404,6 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1422 scale_ceu_h = calc_scale(interm_width, &out_width); 1404 scale_ceu_h = calc_scale(interm_width, &out_width);
1423 scale_ceu_v = calc_scale(interm_height, &out_height); 1405 scale_ceu_v = calc_scale(interm_height, &out_height);
1424 1406
1425 /* Calculate camera scales */
1426 scale_h = calc_generic_scale(cam_rect->width, out_width);
1427 scale_v = calc_generic_scale(cam_rect->height, out_height);
1428
1429 dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v); 1407 dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
1430 1408
1431 /* Apply CEU scales. */ 1409 /* Apply CEU scales. */
@@ -1437,8 +1415,8 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1437 1415
1438 icd->user_width = out_width; 1416 icd->user_width = out_width;
1439 icd->user_height = out_height; 1417 icd->user_height = out_height;
1440 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_h) & ~1; 1418 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
1441 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_v) & ~1; 1419 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
1442 1420
1443 /* 6. Use CEU cropping to crop to the new window. */ 1421 /* 6. Use CEU cropping to crop to the new window. */
1444 sh_mobile_ceu_set_rect(icd); 1422 sh_mobile_ceu_set_rect(icd);
@@ -1449,7 +1427,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1449 icd->user_width, icd->user_height, 1427 icd->user_width, icd->user_height,
1450 cam->ceu_left, cam->ceu_top); 1428 cam->ceu_left, cam->ceu_top);
1451 1429
1452 /* Restore capture */ 1430 /* Restore capture. The CE bit can be cleared by the hardware */
1453 if (pcdev->active) 1431 if (pcdev->active)
1454 capsr |= 1; 1432 capsr |= 1;
1455 capture_restore(pcdev, capsr); 1433 capture_restore(pcdev, capsr);
@@ -1726,43 +1704,11 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1726 return ret; 1704 return ret;
1727} 1705}
1728 1706
1729static int sh_mobile_ceu_reqbufs(struct soc_camera_device *icd,
1730 struct v4l2_requestbuffers *p)
1731{
1732 int i;
1733
1734 /*
1735 * This is for locking debugging only. I removed spinlocks and now I
1736 * check whether .prepare is ever called on a linked buffer, or whether
1737 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1738 * it hadn't triggered
1739 */
1740 for (i = 0; i < p->count; i++) {
1741 struct sh_mobile_ceu_buffer *buf;
1742
1743 buf = container_of(icd->vb_vidq.bufs[i],
1744 struct sh_mobile_ceu_buffer, vb);
1745 INIT_LIST_HEAD(&buf->vb.queue);
1746 }
1747
1748 return 0;
1749}
1750
1751static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) 1707static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
1752{ 1708{
1753 struct soc_camera_device *icd = file->private_data; 1709 struct soc_camera_device *icd = file->private_data;
1754 struct sh_mobile_ceu_buffer *buf;
1755
1756 buf = list_entry(icd->vb_vidq.stream.next,
1757 struct sh_mobile_ceu_buffer, vb.stream);
1758
1759 poll_wait(file, &buf->vb.done, pt);
1760 1710
1761 if (buf->vb.state == VIDEOBUF_DONE || 1711 return vb2_poll(&icd->vb2_vidq, file, pt);
1762 buf->vb.state == VIDEOBUF_ERROR)
1763 return POLLIN|POLLRDNORM;
1764
1765 return 0;
1766} 1712}
1767 1713
1768static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, 1714static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
@@ -1774,19 +1720,17 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
1774 return 0; 1720 return 0;
1775} 1721}
1776 1722
1777static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, 1723static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
1778 struct soc_camera_device *icd) 1724 struct soc_camera_device *icd)
1779{ 1725{
1780 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1726 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1781 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1727 q->io_modes = VB2_MMAP | VB2_USERPTR;
1782 1728 q->drv_priv = icd;
1783 videobuf_queue_dma_contig_init(q, 1729 q->ops = &sh_mobile_ceu_videobuf_ops;
1784 &sh_mobile_ceu_videobuf_ops, 1730 q->mem_ops = &vb2_dma_contig_memops;
1785 icd->dev.parent, &pcdev->lock, 1731 q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer);
1786 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1732
1787 pcdev->field, 1733 return vb2_queue_init(q);
1788 sizeof(struct sh_mobile_ceu_buffer),
1789 icd, &icd->video_lock);
1790} 1734}
1791 1735
1792static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, 1736static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
@@ -1850,11 +1794,10 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1850 .try_fmt = sh_mobile_ceu_try_fmt, 1794 .try_fmt = sh_mobile_ceu_try_fmt,
1851 .set_ctrl = sh_mobile_ceu_set_ctrl, 1795 .set_ctrl = sh_mobile_ceu_set_ctrl,
1852 .get_ctrl = sh_mobile_ceu_get_ctrl, 1796 .get_ctrl = sh_mobile_ceu_get_ctrl,
1853 .reqbufs = sh_mobile_ceu_reqbufs,
1854 .poll = sh_mobile_ceu_poll, 1797 .poll = sh_mobile_ceu_poll,
1855 .querycap = sh_mobile_ceu_querycap, 1798 .querycap = sh_mobile_ceu_querycap,
1856 .set_bus_param = sh_mobile_ceu_set_bus_param, 1799 .set_bus_param = sh_mobile_ceu_set_bus_param,
1857 .init_videobuf = sh_mobile_ceu_init_videobuf, 1800 .init_videobuf2 = sh_mobile_ceu_init_videobuf,
1858 .controls = sh_mobile_ceu_controls, 1801 .controls = sh_mobile_ceu_controls,
1859 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls), 1802 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls),
1860}; 1803};
@@ -2005,12 +1948,20 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2005 } 1948 }
2006 } 1949 }
2007 1950
1951 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1952 if (IS_ERR(pcdev->alloc_ctx)) {
1953 err = PTR_ERR(pcdev->alloc_ctx);
1954 goto exit_module_put;
1955 }
1956
2008 err = soc_camera_host_register(&pcdev->ici); 1957 err = soc_camera_host_register(&pcdev->ici);
2009 if (err) 1958 if (err)
2010 goto exit_module_put; 1959 goto exit_free_ctx;
2011 1960
2012 return 0; 1961 return 0;
2013 1962
1963exit_free_ctx:
1964 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2014exit_module_put: 1965exit_module_put:
2015 if (csi2 && csi2->driver) 1966 if (csi2 && csi2->driver)
2016 module_put(csi2->driver->owner); 1967 module_put(csi2->driver->owner);
@@ -2041,6 +1992,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2041 if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) 1992 if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
2042 dma_release_declared_memory(&pdev->dev); 1993 dma_release_declared_memory(&pdev->dev);
2043 iounmap(pcdev->base); 1994 iounmap(pcdev->base);
1995 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2044 if (csi2 && csi2->driver) 1996 if (csi2 && csi2->driver)
2045 module_put(csi2->driver->owner); 1997 module_put(csi2->driver->owner);
2046 kfree(pcdev); 1998 kfree(pcdev);
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c
index 84a646819318..dd1b81b1442b 100644
--- a/drivers/media/video/sh_mobile_csi2.c
+++ b/drivers/media/video/sh_mobile_csi2.c
@@ -56,7 +56,7 @@ static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
56 switch (mf->code) { 56 switch (mf->code) {
57 case V4L2_MBUS_FMT_UYVY8_2X8: /* YUV422 */ 57 case V4L2_MBUS_FMT_UYVY8_2X8: /* YUV422 */
58 case V4L2_MBUS_FMT_YUYV8_1_5X8: /* YUV420 */ 58 case V4L2_MBUS_FMT_YUYV8_1_5X8: /* YUV420 */
59 case V4L2_MBUS_FMT_GREY8_1X8: /* RAW8 */ 59 case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */
60 case V4L2_MBUS_FMT_SBGGR8_1X8: 60 case V4L2_MBUS_FMT_SBGGR8_1X8:
61 case V4L2_MBUS_FMT_SGRBG8_1X8: 61 case V4L2_MBUS_FMT_SGRBG8_1X8:
62 break; 62 break;
@@ -67,7 +67,7 @@ static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
67 break; 67 break;
68 case SH_CSI2I: 68 case SH_CSI2I:
69 switch (mf->code) { 69 switch (mf->code) {
70 case V4L2_MBUS_FMT_GREY8_1X8: /* RAW8 */ 70 case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */
71 case V4L2_MBUS_FMT_SBGGR8_1X8: 71 case V4L2_MBUS_FMT_SBGGR8_1X8:
72 case V4L2_MBUS_FMT_SGRBG8_1X8: 72 case V4L2_MBUS_FMT_SGRBG8_1X8:
73 case V4L2_MBUS_FMT_SBGGR10_1X10: /* RAW10 */ 73 case V4L2_MBUS_FMT_SBGGR10_1X10: /* RAW10 */
@@ -111,7 +111,7 @@ static int sh_csi2_s_fmt(struct v4l2_subdev *sd,
111 case V4L2_MBUS_FMT_RGB565_2X8_BE: 111 case V4L2_MBUS_FMT_RGB565_2X8_BE:
112 tmp |= 0x22; /* RGB565 */ 112 tmp |= 0x22; /* RGB565 */
113 break; 113 break;
114 case V4L2_MBUS_FMT_GREY8_1X8: 114 case V4L2_MBUS_FMT_Y8_1X8:
115 case V4L2_MBUS_FMT_SBGGR8_1X8: 115 case V4L2_MBUS_FMT_SBGGR8_1X8:
116 case V4L2_MBUS_FMT_SGRBG8_1X8: 116 case V4L2_MBUS_FMT_SGRBG8_1X8:
117 tmp |= 0x2a; /* RAW8 */ 117 tmp |= 0x2a; /* RAW8 */
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 84984f64b234..ce56a1cdbf0a 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1430,9 +1430,9 @@ static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
1430 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg); 1430 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
1431static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, 1431static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
1432 sn9c102_show_i2c_val, sn9c102_store_i2c_val); 1432 sn9c102_show_i2c_val, sn9c102_store_i2c_val);
1433static DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green); 1433static DEVICE_ATTR(green, S_IWUSR, NULL, sn9c102_store_green);
1434static DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue); 1434static DEVICE_ATTR(blue, S_IWUSR, NULL, sn9c102_store_blue);
1435static DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red); 1435static DEVICE_ATTR(red, S_IWUSR, NULL, sn9c102_store_red);
1436static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL); 1436static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
1437 1437
1438 1438
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a66811b43710..46284489e4eb 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -34,6 +34,7 @@
34#include <media/v4l2-ioctl.h> 34#include <media/v4l2-ioctl.h>
35#include <media/v4l2-dev.h> 35#include <media/v4l2-dev.h>
36#include <media/videobuf-core.h> 36#include <media/videobuf-core.h>
37#include <media/videobuf2-core.h>
37#include <media/soc_mediabus.h> 38#include <media/soc_mediabus.h>
38 39
39/* Default to VGA resolution */ 40/* Default to VGA resolution */
@@ -143,6 +144,10 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
143 144
144 WARN_ON(priv != file->private_data); 145 WARN_ON(priv != file->private_data);
145 146
147 /* Only single-plane capture is supported so far */
148 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
149 return -EINVAL;
150
146 /* limit format to hardware capabilities */ 151 /* limit format to hardware capabilities */
147 return ici->ops->try_fmt(icd, f); 152 return ici->ops->try_fmt(icd, f);
148} 153}
@@ -191,6 +196,15 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
191 return v4l2_subdev_call(sd, core, s_std, *a); 196 return v4l2_subdev_call(sd, core, s_std, *a);
192} 197}
193 198
199static int soc_camera_enum_fsizes(struct file *file, void *fh,
200 struct v4l2_frmsizeenum *fsize)
201{
202 struct soc_camera_device *icd = file->private_data;
203 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
204
205 return ici->ops->enum_fsizes(icd, fsize);
206}
207
194static int soc_camera_reqbufs(struct file *file, void *priv, 208static int soc_camera_reqbufs(struct file *file, void *priv,
195 struct v4l2_requestbuffers *p) 209 struct v4l2_requestbuffers *p)
196{ 210{
@@ -203,11 +217,16 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
203 if (icd->streamer && icd->streamer != file) 217 if (icd->streamer && icd->streamer != file)
204 return -EBUSY; 218 return -EBUSY;
205 219
206 ret = videobuf_reqbufs(&icd->vb_vidq, p); 220 if (ici->ops->init_videobuf) {
207 if (ret < 0) 221 ret = videobuf_reqbufs(&icd->vb_vidq, p);
208 return ret; 222 if (ret < 0)
223 return ret;
224
225 ret = ici->ops->reqbufs(icd, p);
226 } else {
227 ret = vb2_reqbufs(&icd->vb2_vidq, p);
228 }
209 229
210 ret = ici->ops->reqbufs(icd, p);
211 if (!ret && !icd->streamer) 230 if (!ret && !icd->streamer)
212 icd->streamer = file; 231 icd->streamer = file;
213 232
@@ -218,36 +237,48 @@ static int soc_camera_querybuf(struct file *file, void *priv,
218 struct v4l2_buffer *p) 237 struct v4l2_buffer *p)
219{ 238{
220 struct soc_camera_device *icd = file->private_data; 239 struct soc_camera_device *icd = file->private_data;
240 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
221 241
222 WARN_ON(priv != file->private_data); 242 WARN_ON(priv != file->private_data);
223 243
224 return videobuf_querybuf(&icd->vb_vidq, p); 244 if (ici->ops->init_videobuf)
245 return videobuf_querybuf(&icd->vb_vidq, p);
246 else
247 return vb2_querybuf(&icd->vb2_vidq, p);
225} 248}
226 249
227static int soc_camera_qbuf(struct file *file, void *priv, 250static int soc_camera_qbuf(struct file *file, void *priv,
228 struct v4l2_buffer *p) 251 struct v4l2_buffer *p)
229{ 252{
230 struct soc_camera_device *icd = file->private_data; 253 struct soc_camera_device *icd = file->private_data;
254 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
231 255
232 WARN_ON(priv != file->private_data); 256 WARN_ON(priv != file->private_data);
233 257
234 if (icd->streamer != file) 258 if (icd->streamer != file)
235 return -EBUSY; 259 return -EBUSY;
236 260
237 return videobuf_qbuf(&icd->vb_vidq, p); 261 if (ici->ops->init_videobuf)
262 return videobuf_qbuf(&icd->vb_vidq, p);
263 else
264 return vb2_qbuf(&icd->vb2_vidq, p);
238} 265}
239 266
240static int soc_camera_dqbuf(struct file *file, void *priv, 267static int soc_camera_dqbuf(struct file *file, void *priv,
241 struct v4l2_buffer *p) 268 struct v4l2_buffer *p)
242{ 269{
243 struct soc_camera_device *icd = file->private_data; 270 struct soc_camera_device *icd = file->private_data;
271 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
244 272
245 WARN_ON(priv != file->private_data); 273 WARN_ON(priv != file->private_data);
246 274
247 if (icd->streamer != file) 275 if (icd->streamer != file)
248 return -EBUSY; 276 return -EBUSY;
249 277
250 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK); 278 if (ici->ops->init_videobuf)
279 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);
280 else
281 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
251} 282}
252 283
253/* Always entered with .video_lock held */ 284/* Always entered with .video_lock held */
@@ -362,13 +393,12 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
362 393
363 icd->user_width = pix->width; 394 icd->user_width = pix->width;
364 icd->user_height = pix->height; 395 icd->user_height = pix->height;
396 icd->bytesperline = pix->bytesperline;
397 icd->sizeimage = pix->sizeimage;
365 icd->colorspace = pix->colorspace; 398 icd->colorspace = pix->colorspace;
366 icd->vb_vidq.field = 399 icd->field = pix->field;
367 icd->field = pix->field; 400 if (ici->ops->init_videobuf)
368 401 icd->vb_vidq.field = pix->field;
369 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
370 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
371 f->type);
372 402
373 dev_dbg(&icd->dev, "set width: %d height: %d\n", 403 dev_dbg(&icd->dev, "set width: %d height: %d\n",
374 icd->user_width, icd->user_height); 404 icd->user_width, icd->user_height);
@@ -444,7 +474,13 @@ static int soc_camera_open(struct file *file)
444 if (ret < 0) 474 if (ret < 0)
445 goto esfmt; 475 goto esfmt;
446 476
447 ici->ops->init_videobuf(&icd->vb_vidq, icd); 477 if (ici->ops->init_videobuf) {
478 ici->ops->init_videobuf(&icd->vb_vidq, icd);
479 } else {
480 ret = ici->ops->init_videobuf2(&icd->vb2_vidq, icd);
481 if (ret < 0)
482 goto einitvb;
483 }
448 } 484 }
449 485
450 file->private_data = icd; 486 file->private_data = icd;
@@ -456,6 +492,7 @@ static int soc_camera_open(struct file *file)
456 * First four errors are entered with the .video_lock held 492 * First four errors are entered with the .video_lock held
457 * and use_count == 1 493 * and use_count == 1
458 */ 494 */
495einitvb:
459esfmt: 496esfmt:
460 pm_runtime_disable(&icd->vdev->dev); 497 pm_runtime_disable(&icd->vdev->dev);
461eresume: 498eresume:
@@ -482,6 +519,8 @@ static int soc_camera_close(struct file *file)
482 pm_runtime_disable(&icd->vdev->dev); 519 pm_runtime_disable(&icd->vdev->dev);
483 520
484 ici->ops->remove(icd); 521 ici->ops->remove(icd);
522 if (ici->ops->init_videobuf2)
523 vb2_queue_release(&icd->vb2_vidq);
485 524
486 soc_camera_power_set(icd, icl, 0); 525 soc_camera_power_set(icd, icl, 0);
487 } 526 }
@@ -510,6 +549,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
510static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) 549static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
511{ 550{
512 struct soc_camera_device *icd = file->private_data; 551 struct soc_camera_device *icd = file->private_data;
552 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
513 int err; 553 int err;
514 554
515 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 555 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
@@ -517,7 +557,10 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
517 if (icd->streamer != file) 557 if (icd->streamer != file)
518 return -EBUSY; 558 return -EBUSY;
519 559
520 err = videobuf_mmap_mapper(&icd->vb_vidq, vma); 560 if (ici->ops->init_videobuf)
561 err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
562 else
563 err = vb2_mmap(&icd->vb2_vidq, vma);
521 564
522 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", 565 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n",
523 (unsigned long)vma->vm_start, 566 (unsigned long)vma->vm_start,
@@ -535,7 +578,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
535 if (icd->streamer != file) 578 if (icd->streamer != file)
536 return -EBUSY; 579 return -EBUSY;
537 580
538 if (list_empty(&icd->vb_vidq.stream)) { 581 if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) {
539 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); 582 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n");
540 return POLLERR; 583 return POLLERR;
541 } 584 }
@@ -543,6 +586,20 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
543 return ici->ops->poll(file, pt); 586 return ici->ops->poll(file, pt);
544} 587}
545 588
589void soc_camera_lock(struct vb2_queue *vq)
590{
591 struct soc_camera_device *icd = vb2_get_drv_priv(vq);
592 mutex_lock(&icd->video_lock);
593}
594EXPORT_SYMBOL(soc_camera_lock);
595
596void soc_camera_unlock(struct vb2_queue *vq)
597{
598 struct soc_camera_device *icd = vb2_get_drv_priv(vq);
599 mutex_unlock(&icd->video_lock);
600}
601EXPORT_SYMBOL(soc_camera_unlock);
602
546static struct v4l2_file_operations soc_camera_fops = { 603static struct v4l2_file_operations soc_camera_fops = {
547 .owner = THIS_MODULE, 604 .owner = THIS_MODULE,
548 .open = soc_camera_open, 605 .open = soc_camera_open,
@@ -561,6 +618,11 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
561 618
562 WARN_ON(priv != file->private_data); 619 WARN_ON(priv != file->private_data);
563 620
621 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
622 dev_warn(&icd->dev, "Wrong buf-type %d\n", f->type);
623 return -EINVAL;
624 }
625
564 if (icd->streamer && icd->streamer != file) 626 if (icd->streamer && icd->streamer != file)
565 return -EBUSY; 627 return -EBUSY;
566 628
@@ -604,16 +666,16 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
604 666
605 WARN_ON(priv != file->private_data); 667 WARN_ON(priv != file->private_data);
606 668
669 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
670 return -EINVAL;
671
607 pix->width = icd->user_width; 672 pix->width = icd->user_width;
608 pix->height = icd->user_height; 673 pix->height = icd->user_height;
609 pix->field = icd->vb_vidq.field; 674 pix->bytesperline = icd->bytesperline;
675 pix->sizeimage = icd->sizeimage;
676 pix->field = icd->field;
610 pix->pixelformat = icd->current_fmt->host_fmt->fourcc; 677 pix->pixelformat = icd->current_fmt->host_fmt->fourcc;
611 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
612 icd->current_fmt->host_fmt);
613 pix->colorspace = icd->colorspace; 678 pix->colorspace = icd->colorspace;
614 if (pix->bytesperline < 0)
615 return pix->bytesperline;
616 pix->sizeimage = pix->height * pix->bytesperline;
617 dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", 679 dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n",
618 icd->current_fmt->host_fmt->fourcc); 680 icd->current_fmt->host_fmt->fourcc);
619 return 0; 681 return 0;
@@ -635,6 +697,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
635 enum v4l2_buf_type i) 697 enum v4l2_buf_type i)
636{ 698{
637 struct soc_camera_device *icd = file->private_data; 699 struct soc_camera_device *icd = file->private_data;
700 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
638 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 701 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
639 int ret; 702 int ret;
640 703
@@ -646,10 +709,14 @@ static int soc_camera_streamon(struct file *file, void *priv,
646 if (icd->streamer != file) 709 if (icd->streamer != file)
647 return -EBUSY; 710 return -EBUSY;
648 711
649 v4l2_subdev_call(sd, video, s_stream, 1);
650
651 /* This calls buf_queue from host driver's videobuf_queue_ops */ 712 /* This calls buf_queue from host driver's videobuf_queue_ops */
652 ret = videobuf_streamon(&icd->vb_vidq); 713 if (ici->ops->init_videobuf)
714 ret = videobuf_streamon(&icd->vb_vidq);
715 else
716 ret = vb2_streamon(&icd->vb2_vidq, i);
717
718 if (!ret)
719 v4l2_subdev_call(sd, video, s_stream, 1);
653 720
654 return ret; 721 return ret;
655} 722}
@@ -659,6 +726,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
659{ 726{
660 struct soc_camera_device *icd = file->private_data; 727 struct soc_camera_device *icd = file->private_data;
661 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 728 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
729 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
662 730
663 WARN_ON(priv != file->private_data); 731 WARN_ON(priv != file->private_data);
664 732
@@ -672,7 +740,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
672 * This calls buf_release from host driver's videobuf_queue_ops for all 740 * This calls buf_release from host driver's videobuf_queue_ops for all
673 * remaining buffers. When the last buffer is freed, stop capture 741 * remaining buffers. When the last buffer is freed, stop capture
674 */ 742 */
675 videobuf_streamoff(&icd->vb_vidq); 743 if (ici->ops->init_videobuf)
744 videobuf_streamoff(&icd->vb_vidq);
745 else
746 vb2_streamoff(&icd->vb2_vidq, i);
676 747
677 v4l2_subdev_call(sd, video, s_stream, 0); 748 v4l2_subdev_call(sd, video, s_stream, 0);
678 749
@@ -1175,6 +1246,31 @@ static int default_s_parm(struct soc_camera_device *icd,
1175 return v4l2_subdev_call(sd, video, s_parm, parm); 1246 return v4l2_subdev_call(sd, video, s_parm, parm);
1176} 1247}
1177 1248
1249static int default_enum_fsizes(struct soc_camera_device *icd,
1250 struct v4l2_frmsizeenum *fsize)
1251{
1252 int ret;
1253 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1254 const struct soc_camera_format_xlate *xlate;
1255 __u32 pixfmt = fsize->pixel_format;
1256 struct v4l2_frmsizeenum fsize_mbus = *fsize;
1257
1258 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1259 if (!xlate)
1260 return -EINVAL;
1261 /* map xlate-code to pixel_format, sensor only handle xlate-code*/
1262 fsize_mbus.pixel_format = xlate->code;
1263
1264 ret = v4l2_subdev_call(sd, video, enum_mbus_fsizes, &fsize_mbus);
1265 if (ret < 0)
1266 return ret;
1267
1268 *fsize = fsize_mbus;
1269 fsize->pixel_format = pixfmt;
1270
1271 return 0;
1272}
1273
1178static void soc_camera_device_init(struct device *dev, void *pdata) 1274static void soc_camera_device_init(struct device *dev, void *pdata)
1179{ 1275{
1180 dev->platform_data = pdata; 1276 dev->platform_data = pdata;
@@ -1192,8 +1288,9 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1192 !ici->ops->set_fmt || 1288 !ici->ops->set_fmt ||
1193 !ici->ops->set_bus_param || 1289 !ici->ops->set_bus_param ||
1194 !ici->ops->querycap || 1290 !ici->ops->querycap ||
1195 !ici->ops->init_videobuf || 1291 ((!ici->ops->init_videobuf ||
1196 !ici->ops->reqbufs || 1292 !ici->ops->reqbufs) &&
1293 !ici->ops->init_videobuf2) ||
1197 !ici->ops->add || 1294 !ici->ops->add ||
1198 !ici->ops->remove || 1295 !ici->ops->remove ||
1199 !ici->ops->poll || 1296 !ici->ops->poll ||
@@ -1210,6 +1307,8 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1210 ici->ops->set_parm = default_s_parm; 1307 ici->ops->set_parm = default_s_parm;
1211 if (!ici->ops->get_parm) 1308 if (!ici->ops->get_parm)
1212 ici->ops->get_parm = default_g_parm; 1309 ici->ops->get_parm = default_g_parm;
1310 if (!ici->ops->enum_fsizes)
1311 ici->ops->enum_fsizes = default_enum_fsizes;
1213 1312
1214 mutex_lock(&list_lock); 1313 mutex_lock(&list_lock);
1215 list_for_each_entry(ix, &hosts, list) { 1314 list_for_each_entry(ix, &hosts, list) {
@@ -1317,6 +1416,7 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1317 .vidioc_g_input = soc_camera_g_input, 1416 .vidioc_g_input = soc_camera_g_input,
1318 .vidioc_s_input = soc_camera_s_input, 1417 .vidioc_s_input = soc_camera_s_input,
1319 .vidioc_s_std = soc_camera_s_std, 1418 .vidioc_s_std = soc_camera_s_std,
1419 .vidioc_enum_framesizes = soc_camera_enum_fsizes,
1320 .vidioc_reqbufs = soc_camera_reqbufs, 1420 .vidioc_reqbufs = soc_camera_reqbufs,
1321 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap, 1421 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
1322 .vidioc_querybuf = soc_camera_querybuf, 1422 .vidioc_querybuf = soc_camera_querybuf,
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index 91391214c682..ed77aa055b63 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -88,7 +88,7 @@ static const struct soc_mbus_pixelfmt mbus_fmt[] = {
88 .packing = SOC_MBUS_PACKING_EXTEND16, 88 .packing = SOC_MBUS_PACKING_EXTEND16,
89 .order = SOC_MBUS_ORDER_LE, 89 .order = SOC_MBUS_ORDER_LE,
90 }, 90 },
91 [MBUS_IDX(GREY8_1X8)] = { 91 [MBUS_IDX(Y8_1X8)] = {
92 .fourcc = V4L2_PIX_FMT_GREY, 92 .fourcc = V4L2_PIX_FMT_GREY,
93 .name = "Grey", 93 .name = "Grey",
94 .bits_per_sample = 8, 94 .bits_per_sample = 8,
@@ -132,6 +132,20 @@ static const struct soc_mbus_pixelfmt mbus_fmt[] = {
132 }, 132 },
133}; 133};
134 134
135int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf)
136{
137 switch (mf->packing) {
138 case SOC_MBUS_PACKING_NONE:
139 case SOC_MBUS_PACKING_EXTEND16:
140 return 1;
141 case SOC_MBUS_PACKING_2X8_PADHI:
142 case SOC_MBUS_PACKING_2X8_PADLO:
143 return 2;
144 }
145 return -EINVAL;
146}
147EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
148
135s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) 149s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
136{ 150{
137 switch (mf->packing) { 151 switch (mf->packing) {
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/video/timblogiw.c
index fc611ebeb82c..84d4c7c83435 100644
--- a/drivers/media/video/timblogiw.c
+++ b/drivers/media/video/timblogiw.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/dmaengine.h> 26#include <linux/dmaengine.h>
27#include <linux/mfd/core.h>
27#include <linux/scatterlist.h> 28#include <linux/scatterlist.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
29#include <linux/list.h> 30#include <linux/list.h>
@@ -790,7 +791,7 @@ static int __devinit timblogiw_probe(struct platform_device *pdev)
790{ 791{
791 int err; 792 int err;
792 struct timblogiw *lw = NULL; 793 struct timblogiw *lw = NULL;
793 struct timb_video_platform_data *pdata = pdev->dev.platform_data; 794 struct timb_video_platform_data *pdata = mfd_get_data(pdev);
794 795
795 if (!pdata) { 796 if (!pdata) {
796 dev_err(&pdev->dev, "No platform data\n"); 797 dev_err(&pdev->dev, "No platform data\n");
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
index df33a1d188bb..a794ae62aebf 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -764,10 +764,8 @@ static int pd_vidioc_s_fmt(struct poseidon *pd, struct v4l2_pix_format *pix)
764 } 764 }
765 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL, 765 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
766 vid_resol, &cmd_status); 766 vid_resol, &cmd_status);
767 if (ret || cmd_status) { 767 if (ret || cmd_status)
768 mutex_unlock(&pd->lock);
769 return -EBUSY; 768 return -EBUSY;
770 }
771 769
772 pix_def->pixelformat = pix->pixelformat; /* save it */ 770 pix_def->pixelformat = pix->pixelformat; /* save it */
773 pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576; 771 pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576;
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index dfc4dd7c5097..286ec7e7062a 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -31,6 +31,7 @@
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/videodev2.h> 32#include <linux/videodev2.h>
33#include <media/v4l2-device.h> 33#include <media/v4l2-device.h>
34#include <media/v4l2-ctrls.h>
34 35
35MODULE_DESCRIPTION("tlv320aic23b driver"); 36MODULE_DESCRIPTION("tlv320aic23b driver");
36MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil"); 37MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL");
41 42
42struct tlv320aic23b_state { 43struct tlv320aic23b_state {
43 struct v4l2_subdev sd; 44 struct v4l2_subdev sd;
44 u8 muted; 45 struct v4l2_ctrl_handler hdl;
45}; 46};
46 47
47static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd) 48static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd)
@@ -49,6 +50,11 @@ static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd)
49 return container_of(sd, struct tlv320aic23b_state, sd); 50 return container_of(sd, struct tlv320aic23b_state, sd);
50} 51}
51 52
53static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
54{
55 return &container_of(ctrl->handler, struct tlv320aic23b_state, hdl)->sd;
56}
57
52static int tlv320aic23b_write(struct v4l2_subdev *sd, int reg, u16 val) 58static int tlv320aic23b_write(struct v4l2_subdev *sd, int reg, u16 val)
53{ 59{
54 struct i2c_client *client = v4l2_get_subdevdata(sd); 60 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -85,44 +91,44 @@ static int tlv320aic23b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
85 return 0; 91 return 0;
86} 92}
87 93
88static int tlv320aic23b_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 94static int tlv320aic23b_s_ctrl(struct v4l2_ctrl *ctrl)
89{
90 struct tlv320aic23b_state *state = to_state(sd);
91
92 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
93 return -EINVAL;
94 ctrl->value = state->muted;
95 return 0;
96}
97
98static int tlv320aic23b_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
99{ 95{
100 struct tlv320aic23b_state *state = to_state(sd); 96 struct v4l2_subdev *sd = to_sd(ctrl);
101 97
102 if (ctrl->id != V4L2_CID_AUDIO_MUTE) 98 switch (ctrl->id) {
103 return -EINVAL; 99 case V4L2_CID_AUDIO_MUTE:
104 state->muted = ctrl->value; 100 tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */
105 tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */ 101 /* set gain on both channels to +3.0 dB */
106 /* set gain on both channels to +3.0 dB */ 102 if (!ctrl->val)
107 if (!state->muted) 103 tlv320aic23b_write(sd, 0, 0x119);
108 tlv320aic23b_write(sd, 0, 0x119); 104 return 0;
109 return 0; 105 }
106 return -EINVAL;
110} 107}
111 108
112static int tlv320aic23b_log_status(struct v4l2_subdev *sd) 109static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
113{ 110{
114 struct tlv320aic23b_state *state = to_state(sd); 111 struct tlv320aic23b_state *state = to_state(sd);
115 112
116 v4l2_info(sd, "Input: %s\n", state->muted ? "muted" : "active"); 113 v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
117 return 0; 114 return 0;
118} 115}
119 116
120/* ----------------------------------------------------------------------- */ 117/* ----------------------------------------------------------------------- */
121 118
119static const struct v4l2_ctrl_ops tlv320aic23b_ctrl_ops = {
120 .s_ctrl = tlv320aic23b_s_ctrl,
121};
122
122static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = { 123static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
123 .log_status = tlv320aic23b_log_status, 124 .log_status = tlv320aic23b_log_status,
124 .g_ctrl = tlv320aic23b_g_ctrl, 125 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
125 .s_ctrl = tlv320aic23b_s_ctrl, 126 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
127 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
128 .g_ctrl = v4l2_subdev_g_ctrl,
129 .s_ctrl = v4l2_subdev_s_ctrl,
130 .queryctrl = v4l2_subdev_queryctrl,
131 .querymenu = v4l2_subdev_querymenu,
126}; 132};
127 133
128static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = { 134static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = {
@@ -161,7 +167,6 @@ static int tlv320aic23b_probe(struct i2c_client *client,
161 return -ENOMEM; 167 return -ENOMEM;
162 sd = &state->sd; 168 sd = &state->sd;
163 v4l2_i2c_subdev_init(sd, client, &tlv320aic23b_ops); 169 v4l2_i2c_subdev_init(sd, client, &tlv320aic23b_ops);
164 state->muted = 0;
165 170
166 /* Initialize tlv320aic23b */ 171 /* Initialize tlv320aic23b */
167 172
@@ -177,15 +182,30 @@ static int tlv320aic23b_probe(struct i2c_client *client,
177 tlv320aic23b_write(sd, 8, 0x000); 182 tlv320aic23b_write(sd, 8, 0x000);
178 /* activate digital interface */ 183 /* activate digital interface */
179 tlv320aic23b_write(sd, 9, 0x001); 184 tlv320aic23b_write(sd, 9, 0x001);
185
186 v4l2_ctrl_handler_init(&state->hdl, 1);
187 v4l2_ctrl_new_std(&state->hdl, &tlv320aic23b_ctrl_ops,
188 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
189 sd->ctrl_handler = &state->hdl;
190 if (state->hdl.error) {
191 int err = state->hdl.error;
192
193 v4l2_ctrl_handler_free(&state->hdl);
194 kfree(state);
195 return err;
196 }
197 v4l2_ctrl_handler_setup(&state->hdl);
180 return 0; 198 return 0;
181} 199}
182 200
183static int tlv320aic23b_remove(struct i2c_client *client) 201static int tlv320aic23b_remove(struct i2c_client *client)
184{ 202{
185 struct v4l2_subdev *sd = i2c_get_clientdata(client); 203 struct v4l2_subdev *sd = i2c_get_clientdata(client);
204 struct tlv320aic23b_state *state = to_state(sd);
186 205
187 v4l2_device_unregister_subdev(sd); 206 v4l2_device_unregister_subdev(sd);
188 kfree(to_state(sd)); 207 v4l2_ctrl_handler_free(&state->hdl);
208 kfree(state);
189 return 0; 209 return 0;
190} 210}
191 211
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 1cec1224913f..9363ed91a4cb 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,7 +1,17 @@
1/* 1/*
2 *
3 * i2c tv tuner chip device driver 2 * i2c tv tuner chip device driver
4 * core core, i.e. kernel interfaces, registering and so on 3 * core core, i.e. kernel interfaces, registering and so on
4 *
5 * Copyright(c) by Ralph Metzler, Gerd Knorr, Gunther Mayer
6 *
7 * Copyright(c) 2005-2011 by Mauro Carvalho Chehab
8 * - Added support for a separate Radio tuner
9 * - Major rework and cleanups at the code
10 *
11 * This driver supports many devices and the idea is to let the driver
12 * detect which device is present. So rather than listing all supported
13 * devices here, we pretend to support a single, fake device type that will
14 * handle both radio and analog TV tuning.
5 */ 15 */
6 16
7#include <linux/module.h> 17#include <linux/module.h>
@@ -32,9 +42,111 @@
32 42
33#define UNSET (-1U) 43#define UNSET (-1U)
34 44
35#define PREFIX t->i2c->driver->driver.name 45#define PREFIX (t->i2c->driver->driver.name)
46
47/*
48 * Driver modprobe parameters
49 */
50
51/* insmod options used at init time => read/only */
52static unsigned int addr;
53static unsigned int no_autodetect;
54static unsigned int show_i2c;
55
56module_param(addr, int, 0444);
57module_param(no_autodetect, int, 0444);
58module_param(show_i2c, int, 0444);
59
60/* insmod options used at runtime => read/write */
61static int tuner_debug;
62static unsigned int tv_range[2] = { 44, 958 };
63static unsigned int radio_range[2] = { 65, 108 };
64static char pal[] = "--";
65static char secam[] = "--";
66static char ntsc[] = "-";
67
68module_param_named(debug, tuner_debug, int, 0644);
69module_param_array(tv_range, int, NULL, 0644);
70module_param_array(radio_range, int, NULL, 0644);
71module_param_string(pal, pal, sizeof(pal), 0644);
72module_param_string(secam, secam, sizeof(secam), 0644);
73module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
74
75/*
76 * Static vars
77 */
78
79static LIST_HEAD(tuner_list);
80static const struct v4l2_subdev_ops tuner_ops;
81
82/*
83 * Debug macros
84 */
85
86#define tuner_warn(fmt, arg...) do { \
87 printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
88 i2c_adapter_id(t->i2c->adapter), \
89 t->i2c->addr, ##arg); \
90 } while (0)
91
92#define tuner_info(fmt, arg...) do { \
93 printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \
94 i2c_adapter_id(t->i2c->adapter), \
95 t->i2c->addr, ##arg); \
96 } while (0)
97
98#define tuner_err(fmt, arg...) do { \
99 printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \
100 i2c_adapter_id(t->i2c->adapter), \
101 t->i2c->addr, ##arg); \
102 } while (0)
36 103
37/** This macro allows us to probe dynamically, avoiding static links */ 104#define tuner_dbg(fmt, arg...) do { \
105 if (tuner_debug) \
106 printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \
107 i2c_adapter_id(t->i2c->adapter), \
108 t->i2c->addr, ##arg); \
109 } while (0)
110
111/*
112 * Internal struct used inside the driver
113 */
114
115struct tuner {
116 /* device */
117 struct dvb_frontend fe;
118 struct i2c_client *i2c;
119 struct v4l2_subdev sd;
120 struct list_head list;
121
122 /* keep track of the current settings */
123 v4l2_std_id std;
124 unsigned int tv_freq;
125 unsigned int radio_freq;
126 unsigned int audmode;
127
128 enum v4l2_tuner_type mode;
129 unsigned int mode_mask; /* Combination of allowable modes */
130
131 bool standby; /* Standby mode */
132
133 unsigned int type; /* chip type id */
134 unsigned int config;
135 const char *name;
136};
137
138/*
139 * Function prototypes
140 */
141
142static void set_tv_freq(struct i2c_client *c, unsigned int freq);
143static void set_radio_freq(struct i2c_client *c, unsigned int freq);
144
145/*
146 * tuner attach/detach logic
147 */
148
149/* This macro allows us to probe dynamically, avoiding static links */
38#ifdef CONFIG_MEDIA_ATTACH 150#ifdef CONFIG_MEDIA_ATTACH
39#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \ 151#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
40 int __r = -EINVAL; \ 152 int __r = -EINVAL; \
@@ -74,92 +186,15 @@ static void tuner_detach(struct dvb_frontend *fe)
74} 186}
75#endif 187#endif
76 188
77struct tuner {
78 /* device */
79 struct dvb_frontend fe;
80 struct i2c_client *i2c;
81 struct v4l2_subdev sd;
82 struct list_head list;
83 unsigned int using_v4l2:1;
84
85 /* keep track of the current settings */
86 v4l2_std_id std;
87 unsigned int tv_freq;
88 unsigned int radio_freq;
89 unsigned int audmode;
90
91 unsigned int mode;
92 unsigned int mode_mask; /* Combination of allowable modes */
93
94 unsigned int type; /* chip type id */
95 unsigned int config;
96 const char *name;
97};
98 189
99static inline struct tuner *to_tuner(struct v4l2_subdev *sd) 190static inline struct tuner *to_tuner(struct v4l2_subdev *sd)
100{ 191{
101 return container_of(sd, struct tuner, sd); 192 return container_of(sd, struct tuner, sd);
102} 193}
103 194
104 195/*
105/* insmod options used at init time => read/only */ 196 * struct analog_demod_ops callbacks
106static unsigned int addr; 197 */
107static unsigned int no_autodetect;
108static unsigned int show_i2c;
109
110/* insmod options used at runtime => read/write */
111static int tuner_debug;
112
113#define tuner_warn(fmt, arg...) do { \
114 printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
115 i2c_adapter_id(t->i2c->adapter), \
116 t->i2c->addr, ##arg); \
117 } while (0)
118
119#define tuner_info(fmt, arg...) do { \
120 printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \
121 i2c_adapter_id(t->i2c->adapter), \
122 t->i2c->addr, ##arg); \
123 } while (0)
124
125#define tuner_err(fmt, arg...) do { \
126 printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \
127 i2c_adapter_id(t->i2c->adapter), \
128 t->i2c->addr, ##arg); \
129 } while (0)
130
131#define tuner_dbg(fmt, arg...) do { \
132 if (tuner_debug) \
133 printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \
134 i2c_adapter_id(t->i2c->adapter), \
135 t->i2c->addr, ##arg); \
136 } while (0)
137
138/* ------------------------------------------------------------------------ */
139
140static unsigned int tv_range[2] = { 44, 958 };
141static unsigned int radio_range[2] = { 65, 108 };
142
143static char pal[] = "--";
144static char secam[] = "--";
145static char ntsc[] = "-";
146
147
148module_param(addr, int, 0444);
149module_param(no_autodetect, int, 0444);
150module_param(show_i2c, int, 0444);
151module_param_named(debug,tuner_debug, int, 0644);
152module_param_string(pal, pal, sizeof(pal), 0644);
153module_param_string(secam, secam, sizeof(secam), 0644);
154module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
155module_param_array(tv_range, int, NULL, 0644);
156module_param_array(radio_range, int, NULL, 0644);
157
158MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
159MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
160MODULE_LICENSE("GPL");
161
162/* ---------------------------------------------------------------------- */
163 198
164static void fe_set_params(struct dvb_frontend *fe, 199static void fe_set_params(struct dvb_frontend *fe,
165 struct analog_parameters *params) 200 struct analog_parameters *params)
@@ -215,102 +250,25 @@ static struct analog_demod_ops tuner_analog_ops = {
215 .tuner_status = tuner_status 250 .tuner_status = tuner_status
216}; 251};
217 252
218/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */ 253/*
219static void set_tv_freq(struct i2c_client *c, unsigned int freq) 254 * Functions to select between radio and TV and tuner probe/remove functions
220{ 255 */
221 struct tuner *t = to_tuner(i2c_get_clientdata(c));
222 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
223
224 struct analog_parameters params = {
225 .mode = t->mode,
226 .audmode = t->audmode,
227 .std = t->std
228 };
229
230 if (t->type == UNSET) {
231 tuner_warn ("tuner type not set\n");
232 return;
233 }
234 if (NULL == analog_ops->set_params) {
235 tuner_warn ("Tuner has no way to set tv freq\n");
236 return;
237 }
238 if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
239 tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
240 freq / 16, freq % 16 * 100 / 16, tv_range[0],
241 tv_range[1]);
242 /* V4L2 spec: if the freq is not possible then the closest
243 possible value should be selected */
244 if (freq < tv_range[0] * 16)
245 freq = tv_range[0] * 16;
246 else
247 freq = tv_range[1] * 16;
248 }
249 params.frequency = freq;
250
251 analog_ops->set_params(&t->fe, &params);
252}
253
254static void set_radio_freq(struct i2c_client *c, unsigned int freq)
255{
256 struct tuner *t = to_tuner(i2c_get_clientdata(c));
257 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
258
259 struct analog_parameters params = {
260 .mode = t->mode,
261 .audmode = t->audmode,
262 .std = t->std
263 };
264
265 if (t->type == UNSET) {
266 tuner_warn ("tuner type not set\n");
267 return;
268 }
269 if (NULL == analog_ops->set_params) {
270 tuner_warn ("tuner has no way to set radio frequency\n");
271 return;
272 }
273 if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
274 tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
275 freq / 16000, freq % 16000 * 100 / 16000,
276 radio_range[0], radio_range[1]);
277 /* V4L2 spec: if the freq is not possible then the closest
278 possible value should be selected */
279 if (freq < radio_range[0] * 16000)
280 freq = radio_range[0] * 16000;
281 else
282 freq = radio_range[1] * 16000;
283 }
284 params.frequency = freq;
285
286 analog_ops->set_params(&t->fe, &params);
287}
288
289static void set_freq(struct i2c_client *c, unsigned long freq)
290{
291 struct tuner *t = to_tuner(i2c_get_clientdata(c));
292
293 switch (t->mode) {
294 case V4L2_TUNER_RADIO:
295 tuner_dbg("radio freq set to %lu.%02lu\n",
296 freq / 16000, freq % 16000 * 100 / 16000);
297 set_radio_freq(c, freq);
298 t->radio_freq = freq;
299 break;
300 case V4L2_TUNER_ANALOG_TV:
301 case V4L2_TUNER_DIGITAL_TV:
302 tuner_dbg("tv freq set to %lu.%02lu\n",
303 freq / 16, freq % 16 * 100 / 16);
304 set_tv_freq(c, freq);
305 t->tv_freq = freq;
306 break;
307 default:
308 tuner_dbg("freq set: unknown mode: 0x%04x!\n",t->mode);
309 }
310}
311
312static struct xc5000_config xc5000_cfg;
313 256
257/**
258 * set_type - Sets the tuner type for a given device
259 *
260 * @c: i2c_client descriptoy
261 * @type: type of the tuner (e. g. tuner number)
262 * @new_mode_mask: Indicates if tuner supports TV and/or Radio
263 * @new_config: an optional parameter ranging from 0-255 used by
264 a few tuners to adjust an internal parameter,
265 like LNA mode
266 * @tuner_callback: an optional function to be called when switching
267 * to analog mode
268 *
269 * This function applys the tuner config to tuner specified
270 * by tun_setup structure. It contains several per-tuner initialization "magic"
271 */
314static void set_type(struct i2c_client *c, unsigned int type, 272static void set_type(struct i2c_client *c, unsigned int type,
315 unsigned int new_mode_mask, unsigned int new_config, 273 unsigned int new_mode_mask, unsigned int new_config,
316 int (*tuner_callback) (void *dev, int component, int cmd, int arg)) 274 int (*tuner_callback) (void *dev, int component, int cmd, int arg))
@@ -322,7 +280,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
322 int tune_now = 1; 280 int tune_now = 1;
323 281
324 if (type == UNSET || type == TUNER_ABSENT) { 282 if (type == UNSET || type == TUNER_ABSENT) {
325 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr); 283 tuner_dbg("tuner 0x%02x: Tuner type absent\n", c->addr);
326 return; 284 return;
327 } 285 }
328 286
@@ -334,12 +292,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
334 t->fe.callback = tuner_callback; 292 t->fe.callback = tuner_callback;
335 } 293 }
336 294
337 if (t->mode == T_UNINITIALIZED) {
338 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
339
340 return;
341 }
342
343 /* discard private data, in case set_type() was previously called */ 295 /* discard private data, in case set_type() was previously called */
344 tuner_detach(&t->fe); 296 tuner_detach(&t->fe);
345 t->fe.analog_demod_priv = NULL; 297 t->fe.analog_demod_priv = NULL;
@@ -414,9 +366,12 @@ static void set_type(struct i2c_client *c, unsigned int type,
414 break; 366 break;
415 case TUNER_XC5000: 367 case TUNER_XC5000:
416 { 368 {
417 xc5000_cfg.i2c_address = t->i2c->addr; 369 struct xc5000_config xc5000_cfg = {
418 /* if_khz will be set when the digital dvb_attach() occurs */ 370 .i2c_address = t->i2c->addr,
419 xc5000_cfg.if_khz = 0; 371 /* if_khz will be set at dvb_attach() */
372 .if_khz = 0,
373 };
374
420 if (!dvb_attach(xc5000_attach, 375 if (!dvb_attach(xc5000_attach,
421 &t->fe, t->i2c->adapter, &xc5000_cfg)) 376 &t->fe, t->i2c->adapter, &xc5000_cfg))
422 goto attach_failed; 377 goto attach_failed;
@@ -459,8 +414,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
459 414
460 tuner_dbg("type set to %s\n", t->name); 415 tuner_dbg("type set to %s\n", t->name);
461 416
462 if (t->mode_mask == T_UNINITIALIZED) 417 t->mode_mask = new_mode_mask;
463 t->mode_mask = new_mode_mask;
464 418
465 /* Some tuners require more initialization setup before use, 419 /* Some tuners require more initialization setup before use,
466 such as firmware download or device calibration. 420 such as firmware download or device calibration.
@@ -468,9 +422,12 @@ static void set_type(struct i2c_client *c, unsigned int type,
468 FIXME: better to move set_freq to the tuner code. This is needed 422 FIXME: better to move set_freq to the tuner code. This is needed
469 on analog tuners for PLL to properly work 423 on analog tuners for PLL to properly work
470 */ 424 */
471 if (tune_now) 425 if (tune_now) {
472 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? 426 if (V4L2_TUNER_RADIO == t->mode)
473 t->radio_freq : t->tv_freq); 427 set_radio_freq(c, t->radio_freq);
428 else
429 set_tv_freq(c, t->tv_freq);
430 }
474 431
475 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", 432 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
476 c->adapter->name, c->driver->driver.name, c->addr << 1, type, 433 c->adapter->name, c->driver->driver.name, c->addr << 1, type,
@@ -480,86 +437,426 @@ static void set_type(struct i2c_client *c, unsigned int type,
480attach_failed: 437attach_failed:
481 tuner_dbg("Tuner attach for type = %d failed.\n", t->type); 438 tuner_dbg("Tuner attach for type = %d failed.\n", t->type);
482 t->type = TUNER_ABSENT; 439 t->type = TUNER_ABSENT;
483 t->mode_mask = T_UNINITIALIZED;
484 440
485 return; 441 return;
486} 442}
487 443
488/* 444/**
489 * This function apply tuner config to tuner specified 445 * tuner_s_type_addr - Sets the tuner type for a device
490 * by tun_setup structure. I addr is unset, then admin status 446 *
491 * and tun addr status is more precise then current status, 447 * @sd: subdev descriptor
492 * it's applied. Otherwise status and type are applied only to 448 * @tun_setup: type to be associated to a given tuner i2c address
493 * tuner with exactly the same addr. 449 *
494*/ 450 * This function applys the tuner config to tuner specified
495 451 * by tun_setup structure.
496static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) 452 * If tuner I2C address is UNSET, then it will only set the device
453 * if the tuner supports the mode specified in the call.
454 * If the address is specified, the change will be applied only if
455 * tuner I2C address matches.
456 * The call can change the tuner number and the tuner mode.
457 */
458static int tuner_s_type_addr(struct v4l2_subdev *sd,
459 struct tuner_setup *tun_setup)
497{ 460{
498 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 461 struct tuner *t = to_tuner(sd);
462 struct i2c_client *c = v4l2_get_subdevdata(sd);
499 463
500 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) && 464 tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
501 (t->mode_mask & tun_setup->mode_mask))) || 465 tun_setup->type,
502 (tun_setup->addr == c->addr)) { 466 tun_setup->addr,
503 set_type(c, tun_setup->type, tun_setup->mode_mask, 467 tun_setup->mode_mask,
504 tun_setup->config, tun_setup->tuner_callback); 468 tun_setup->config);
469
470 if ((t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
471 (t->mode_mask & tun_setup->mode_mask))) ||
472 (tun_setup->addr == c->addr)) {
473 set_type(c, tun_setup->type, tun_setup->mode_mask,
474 tun_setup->config, tun_setup->tuner_callback);
505 } else 475 } else
506 tuner_dbg("set addr discarded for type %i, mask %x. " 476 tuner_dbg("set addr discarded for type %i, mask %x. "
507 "Asked to change tuner at addr 0x%02x, with mask %x\n", 477 "Asked to change tuner at addr 0x%02x, with mask %x\n",
508 t->type, t->mode_mask, 478 t->type, t->mode_mask,
509 tun_setup->addr, tun_setup->mode_mask); 479 tun_setup->addr, tun_setup->mode_mask);
480
481 return 0;
510} 482}
511 483
512static inline int check_mode(struct tuner *t, char *cmd) 484/**
485 * tuner_s_config - Sets tuner configuration
486 *
487 * @sd: subdev descriptor
488 * @cfg: tuner configuration
489 *
490 * Calls tuner set_config() private function to set some tuner-internal
491 * parameters
492 */
493static int tuner_s_config(struct v4l2_subdev *sd,
494 const struct v4l2_priv_tun_config *cfg)
513{ 495{
514 if ((1 << t->mode & t->mode_mask) == 0) { 496 struct tuner *t = to_tuner(sd);
515 return -EINVAL; 497 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
498
499 if (t->type != cfg->tuner)
500 return 0;
501
502 if (analog_ops->set_config) {
503 analog_ops->set_config(&t->fe, cfg->priv);
504 return 0;
516 } 505 }
517 506
518 switch (t->mode) { 507 tuner_dbg("Tuner frontend module has no way to set config\n");
519 case V4L2_TUNER_RADIO: 508 return 0;
520 tuner_dbg("Cmd %s accepted for radio\n", cmd); 509}
521 break; 510
522 case V4L2_TUNER_ANALOG_TV: 511/**
523 tuner_dbg("Cmd %s accepted for analog TV\n", cmd); 512 * tuner_lookup - Seek for tuner adapters
524 break; 513 *
525 case V4L2_TUNER_DIGITAL_TV: 514 * @adap: i2c_adapter struct
526 tuner_dbg("Cmd %s accepted for digital TV\n", cmd); 515 * @radio: pointer to be filled if the adapter is radio
527 break; 516 * @tv: pointer to be filled if the adapter is TV
517 *
518 * Search for existing radio and/or TV tuners on the given I2C adapter,
519 * discarding demod-only adapters (tda9887).
520 *
521 * Note that when this function is called from tuner_probe you can be
522 * certain no other devices will be added/deleted at the same time, I2C
523 * core protects against that.
524 */
525static void tuner_lookup(struct i2c_adapter *adap,
526 struct tuner **radio, struct tuner **tv)
527{
528 struct tuner *pos;
529
530 *radio = NULL;
531 *tv = NULL;
532
533 list_for_each_entry(pos, &tuner_list, list) {
534 int mode_mask;
535
536 if (pos->i2c->adapter != adap ||
537 strcmp(pos->i2c->driver->driver.name, "tuner"))
538 continue;
539
540 mode_mask = pos->mode_mask;
541 if (*radio == NULL && mode_mask == T_RADIO)
542 *radio = pos;
543 /* Note: currently TDA9887 is the only demod-only
544 device. If other devices appear then we need to
545 make this test more general. */
546 else if (*tv == NULL && pos->type != TUNER_TDA9887 &&
547 (pos->mode_mask & T_ANALOG_TV))
548 *tv = pos;
549 }
550}
551
552/**
553 *tuner_probe - Probes the existing tuners on an I2C bus
554 *
555 * @client: i2c_client descriptor
556 * @id: not used
557 *
558 * This routine probes for tuners at the expected I2C addresses. On most
559 * cases, if a device answers to a given I2C address, it assumes that the
560 * device is a tuner. On a few cases, however, an additional logic is needed
561 * to double check if the device is really a tuner, or to identify the tuner
562 * type, like on tea5767/5761 devices.
563 *
564 * During client attach, set_type is called by adapter's attach_inform callback.
565 * set_type must then be completed by tuner_probe.
566 */
567static int tuner_probe(struct i2c_client *client,
568 const struct i2c_device_id *id)
569{
570 struct tuner *t;
571 struct tuner *radio;
572 struct tuner *tv;
573
574 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
575 if (NULL == t)
576 return -ENOMEM;
577 v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
578 t->i2c = client;
579 t->name = "(tuner unset)";
580 t->type = UNSET;
581 t->audmode = V4L2_TUNER_MODE_STEREO;
582 t->standby = 1;
583 t->radio_freq = 87.5 * 16000; /* Initial freq range */
584 t->tv_freq = 400 * 16; /* Sets freq to VHF High - needed for some PLL's to properly start */
585
586 if (show_i2c) {
587 unsigned char buffer[16];
588 int i, rc;
589
590 memset(buffer, 0, sizeof(buffer));
591 rc = i2c_master_recv(client, buffer, sizeof(buffer));
592 tuner_info("I2C RECV = ");
593 for (i = 0; i < rc; i++)
594 printk(KERN_CONT "%02x ", buffer[i]);
595 printk("\n");
596 }
597
598 /* autodetection code based on the i2c addr */
599 if (!no_autodetect) {
600 switch (client->addr) {
601 case 0x10:
602 if (tuner_symbol_probe(tea5761_autodetection,
603 t->i2c->adapter,
604 t->i2c->addr) >= 0) {
605 t->type = TUNER_TEA5761;
606 t->mode_mask = T_RADIO;
607 tuner_lookup(t->i2c->adapter, &radio, &tv);
608 if (tv)
609 tv->mode_mask &= ~T_RADIO;
610
611 goto register_client;
612 }
613 kfree(t);
614 return -ENODEV;
615 case 0x42:
616 case 0x43:
617 case 0x4a:
618 case 0x4b:
619 /* If chip is not tda8290, don't register.
620 since it can be tda9887*/
621 if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
622 t->i2c->addr) >= 0) {
623 tuner_dbg("tda829x detected\n");
624 } else {
625 /* Default is being tda9887 */
626 t->type = TUNER_TDA9887;
627 t->mode_mask = T_RADIO | T_ANALOG_TV;
628 goto register_client;
629 }
630 break;
631 case 0x60:
632 if (tuner_symbol_probe(tea5767_autodetection,
633 t->i2c->adapter, t->i2c->addr)
634 >= 0) {
635 t->type = TUNER_TEA5767;
636 t->mode_mask = T_RADIO;
637 /* Sets freq to FM range */
638 tuner_lookup(t->i2c->adapter, &radio, &tv);
639 if (tv)
640 tv->mode_mask &= ~T_RADIO;
641
642 goto register_client;
643 }
644 break;
645 }
646 }
647
648 /* Initializes only the first TV tuner on this adapter. Why only the
649 first? Because there are some devices (notably the ones with TI
650 tuners) that have more than one i2c address for the *same* device.
651 Experience shows that, except for just one case, the first
652 address is the right one. The exception is a Russian tuner
653 (ACORP_Y878F). So, the desired behavior is just to enable the
654 first found TV tuner. */
655 tuner_lookup(t->i2c->adapter, &radio, &tv);
656 if (tv == NULL) {
657 t->mode_mask = T_ANALOG_TV;
658 if (radio == NULL)
659 t->mode_mask |= T_RADIO;
660 tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
661 }
662
663 /* Should be just before return */
664register_client:
665 /* Sets a default mode */
666 if (t->mode_mask & T_ANALOG_TV)
667 t->mode = V4L2_TUNER_ANALOG_TV;
668 else
669 t->mode = V4L2_TUNER_RADIO;
670 set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
671 list_add_tail(&t->list, &tuner_list);
672
673 tuner_info("Tuner %d found with type(s)%s%s.\n",
674 t->type,
675 t->mode_mask & T_RADIO ? " Radio" : "",
676 t->mode_mask & T_ANALOG_TV ? " TV" : "");
677 return 0;
678}
679
680/**
681 * tuner_remove - detaches a tuner
682 *
683 * @client: i2c_client descriptor
684 */
685
686static int tuner_remove(struct i2c_client *client)
687{
688 struct tuner *t = to_tuner(i2c_get_clientdata(client));
689
690 v4l2_device_unregister_subdev(&t->sd);
691 tuner_detach(&t->fe);
692 t->fe.analog_demod_priv = NULL;
693
694 list_del(&t->list);
695 kfree(t);
696 return 0;
697}
698
699/*
700 * Functions to switch between Radio and TV
701 *
702 * A few cards have a separate I2C tuner for radio. Those routines
703 * take care of switching between TV/Radio mode, filtering only the
704 * commands that apply to the Radio or TV tuner.
705 */
706
707/**
708 * check_mode - Verify if tuner supports the requested mode
709 * @t: a pointer to the module's internal struct_tuner
710 *
711 * This function checks if the tuner is capable of tuning analog TV,
712 * digital TV or radio, depending on what the caller wants. If the
713 * tuner can't support that mode, it returns -EINVAL. Otherwise, it
714 * returns 0.
715 * This function is needed for boards that have a separate tuner for
716 * radio (like devices with tea5767).
717 */
718static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
719{
720 if ((1 << mode & t->mode_mask) == 0)
721 return -EINVAL;
722
723 return 0;
724}
725
726/**
727 * set_mode_freq - Switch tuner to other mode.
728 * @client: struct i2c_client pointer
729 * @t: a pointer to the module's internal struct_tuner
730 * @mode: enum v4l2_type (radio or TV)
731 * @freq: frequency to set (0 means to use the previous one)
732 *
733 * If tuner doesn't support the needed mode (radio or TV), prints a
734 * debug message and returns -EINVAL, changing its state to standby.
735 * Otherwise, changes the state and sets frequency to the last value, if
736 * the tuner can sleep or if it supports both Radio and TV.
737 */
738static int set_mode_freq(struct i2c_client *client, struct tuner *t,
739 enum v4l2_tuner_type mode, unsigned int freq)
740{
741 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
742
743 if (mode != t->mode) {
744 if (check_mode(t, mode) == -EINVAL) {
745 tuner_dbg("Tuner doesn't support mode %d. "
746 "Putting tuner to sleep\n", mode);
747 t->standby = true;
748 if (analog_ops->standby)
749 analog_ops->standby(&t->fe);
750 return -EINVAL;
751 }
752 t->mode = mode;
753 tuner_dbg("Changing to mode %d\n", mode);
528 } 754 }
755 if (t->mode == V4L2_TUNER_RADIO) {
756 if (freq)
757 t->radio_freq = freq;
758 set_radio_freq(client, t->radio_freq);
759 } else {
760 if (freq)
761 t->tv_freq = freq;
762 set_tv_freq(client, t->tv_freq);
763 }
764
529 return 0; 765 return 0;
530} 766}
531 767
532/* get more precise norm info from insmod option */ 768/*
769 * Functions that are specific for TV mode
770 */
771
772/**
773 * set_tv_freq - Set tuner frequency, freq in Units of 62.5 kHz = 1/16MHz
774 *
775 * @c: i2c_client descriptor
776 * @freq: frequency
777 */
778static void set_tv_freq(struct i2c_client *c, unsigned int freq)
779{
780 struct tuner *t = to_tuner(i2c_get_clientdata(c));
781 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
782
783 struct analog_parameters params = {
784 .mode = t->mode,
785 .audmode = t->audmode,
786 .std = t->std
787 };
788
789 if (t->type == UNSET) {
790 tuner_warn("tuner type not set\n");
791 return;
792 }
793 if (NULL == analog_ops->set_params) {
794 tuner_warn("Tuner has no way to set tv freq\n");
795 return;
796 }
797 if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
798 tuner_dbg("TV freq (%d.%02d) out of range (%d-%d)\n",
799 freq / 16, freq % 16 * 100 / 16, tv_range[0],
800 tv_range[1]);
801 /* V4L2 spec: if the freq is not possible then the closest
802 possible value should be selected */
803 if (freq < tv_range[0] * 16)
804 freq = tv_range[0] * 16;
805 else
806 freq = tv_range[1] * 16;
807 }
808 params.frequency = freq;
809 tuner_dbg("tv freq set to %d.%02d\n",
810 freq / 16, freq % 16 * 100 / 16);
811 t->tv_freq = freq;
812 t->standby = false;
813
814 analog_ops->set_params(&t->fe, &params);
815}
816
817/**
818 * tuner_fixup_std - force a given video standard variant
819 *
820 * @t: tuner internal struct
821 *
822 * A few devices or drivers have problem to detect some standard variations.
823 * On other operational systems, the drivers generally have a per-country
824 * code, and some logic to apply per-country hacks. V4L2 API doesn't provide
825 * such hacks. Instead, it relies on a proper video standard selection from
826 * the userspace application. However, as some apps are buggy, not allowing
827 * to distinguish all video standard variations, a modprobe parameter can
828 * be used to force a video standard match.
829 */
533static int tuner_fixup_std(struct tuner *t) 830static int tuner_fixup_std(struct tuner *t)
534{ 831{
535 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { 832 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
536 switch (pal[0]) { 833 switch (pal[0]) {
537 case '6': 834 case '6':
538 tuner_dbg ("insmod fixup: PAL => PAL-60\n"); 835 tuner_dbg("insmod fixup: PAL => PAL-60\n");
539 t->std = V4L2_STD_PAL_60; 836 t->std = V4L2_STD_PAL_60;
540 break; 837 break;
541 case 'b': 838 case 'b':
542 case 'B': 839 case 'B':
543 case 'g': 840 case 'g':
544 case 'G': 841 case 'G':
545 tuner_dbg ("insmod fixup: PAL => PAL-BG\n"); 842 tuner_dbg("insmod fixup: PAL => PAL-BG\n");
546 t->std = V4L2_STD_PAL_BG; 843 t->std = V4L2_STD_PAL_BG;
547 break; 844 break;
548 case 'i': 845 case 'i':
549 case 'I': 846 case 'I':
550 tuner_dbg ("insmod fixup: PAL => PAL-I\n"); 847 tuner_dbg("insmod fixup: PAL => PAL-I\n");
551 t->std = V4L2_STD_PAL_I; 848 t->std = V4L2_STD_PAL_I;
552 break; 849 break;
553 case 'd': 850 case 'd':
554 case 'D': 851 case 'D':
555 case 'k': 852 case 'k':
556 case 'K': 853 case 'K':
557 tuner_dbg ("insmod fixup: PAL => PAL-DK\n"); 854 tuner_dbg("insmod fixup: PAL => PAL-DK\n");
558 t->std = V4L2_STD_PAL_DK; 855 t->std = V4L2_STD_PAL_DK;
559 break; 856 break;
560 case 'M': 857 case 'M':
561 case 'm': 858 case 'm':
562 tuner_dbg ("insmod fixup: PAL => PAL-M\n"); 859 tuner_dbg("insmod fixup: PAL => PAL-M\n");
563 t->std = V4L2_STD_PAL_M; 860 t->std = V4L2_STD_PAL_M;
564 break; 861 break;
565 case 'N': 862 case 'N':
@@ -568,7 +865,7 @@ static int tuner_fixup_std(struct tuner *t)
568 tuner_dbg("insmod fixup: PAL => PAL-Nc\n"); 865 tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
569 t->std = V4L2_STD_PAL_Nc; 866 t->std = V4L2_STD_PAL_Nc;
570 } else { 867 } else {
571 tuner_dbg ("insmod fixup: PAL => PAL-N\n"); 868 tuner_dbg("insmod fixup: PAL => PAL-N\n");
572 t->std = V4L2_STD_PAL_N; 869 t->std = V4L2_STD_PAL_N;
573 } 870 }
574 break; 871 break;
@@ -576,7 +873,7 @@ static int tuner_fixup_std(struct tuner *t)
576 /* default parameter, do nothing */ 873 /* default parameter, do nothing */
577 break; 874 break;
578 default: 875 default:
579 tuner_warn ("pal= argument not recognised\n"); 876 tuner_warn("pal= argument not recognised\n");
580 break; 877 break;
581 } 878 }
582 } 879 }
@@ -589,22 +886,24 @@ static int tuner_fixup_std(struct tuner *t)
589 case 'h': 886 case 'h':
590 case 'H': 887 case 'H':
591 tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n"); 888 tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
592 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; 889 t->std = V4L2_STD_SECAM_B |
890 V4L2_STD_SECAM_G |
891 V4L2_STD_SECAM_H;
593 break; 892 break;
594 case 'd': 893 case 'd':
595 case 'D': 894 case 'D':
596 case 'k': 895 case 'k':
597 case 'K': 896 case 'K':
598 tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n"); 897 tuner_dbg("insmod fixup: SECAM => SECAM-DK\n");
599 t->std = V4L2_STD_SECAM_DK; 898 t->std = V4L2_STD_SECAM_DK;
600 break; 899 break;
601 case 'l': 900 case 'l':
602 case 'L': 901 case 'L':
603 if ((secam[1]=='C')||(secam[1]=='c')) { 902 if ((secam[1] == 'C') || (secam[1] == 'c')) {
604 tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n"); 903 tuner_dbg("insmod fixup: SECAM => SECAM-L'\n");
605 t->std = V4L2_STD_SECAM_LC; 904 t->std = V4L2_STD_SECAM_LC;
606 } else { 905 } else {
607 tuner_dbg ("insmod fixup: SECAM => SECAM-L\n"); 906 tuner_dbg("insmod fixup: SECAM => SECAM-L\n");
608 t->std = V4L2_STD_SECAM_L; 907 t->std = V4L2_STD_SECAM_L;
609 } 908 }
610 break; 909 break;
@@ -612,7 +911,7 @@ static int tuner_fixup_std(struct tuner *t)
612 /* default parameter, do nothing */ 911 /* default parameter, do nothing */
613 break; 912 break;
614 default: 913 default:
615 tuner_warn ("secam= argument not recognised\n"); 914 tuner_warn("secam= argument not recognised\n");
616 break; 915 break;
617 } 916 }
618 } 917 }
@@ -645,6 +944,66 @@ static int tuner_fixup_std(struct tuner *t)
645 return 0; 944 return 0;
646} 945}
647 946
947/*
948 * Functions that are specific for Radio mode
949 */
950
951/**
952 * set_radio_freq - Set tuner frequency, freq in Units of 62.5 Hz = 1/16kHz
953 *
954 * @c: i2c_client descriptor
955 * @freq: frequency
956 */
957static void set_radio_freq(struct i2c_client *c, unsigned int freq)
958{
959 struct tuner *t = to_tuner(i2c_get_clientdata(c));
960 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
961
962 struct analog_parameters params = {
963 .mode = t->mode,
964 .audmode = t->audmode,
965 .std = t->std
966 };
967
968 if (t->type == UNSET) {
969 tuner_warn("tuner type not set\n");
970 return;
971 }
972 if (NULL == analog_ops->set_params) {
973 tuner_warn("tuner has no way to set radio frequency\n");
974 return;
975 }
976 if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
977 tuner_dbg("radio freq (%d.%02d) out of range (%d-%d)\n",
978 freq / 16000, freq % 16000 * 100 / 16000,
979 radio_range[0], radio_range[1]);
980 /* V4L2 spec: if the freq is not possible then the closest
981 possible value should be selected */
982 if (freq < radio_range[0] * 16000)
983 freq = radio_range[0] * 16000;
984 else
985 freq = radio_range[1] * 16000;
986 }
987 params.frequency = freq;
988 tuner_dbg("radio freq set to %d.%02d\n",
989 freq / 16000, freq % 16000 * 100 / 16000);
990 t->radio_freq = freq;
991 t->standby = false;
992
993 analog_ops->set_params(&t->fe, &params);
994}
995
996/*
997 * Debug function for reporting tuner status to userspace
998 */
999
1000/**
1001 * tuner_status - Dumps the current tuner status at dmesg
1002 * @fe: pointer to struct dvb_frontend
1003 *
1004 * This callback is used only for driver debug purposes, answering to
1005 * VIDIOC_LOG_STATUS. No changes should happen on this call.
1006 */
648static void tuner_status(struct dvb_frontend *fe) 1007static void tuner_status(struct dvb_frontend *fe)
649{ 1008{
650 struct tuner *t = fe->analog_demod_priv; 1009 struct tuner *t = fe->analog_demod_priv;
@@ -654,10 +1013,16 @@ static void tuner_status(struct dvb_frontend *fe)
654 const char *p; 1013 const char *p;
655 1014
656 switch (t->mode) { 1015 switch (t->mode) {
657 case V4L2_TUNER_RADIO: p = "radio"; break; 1016 case V4L2_TUNER_RADIO:
658 case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break; 1017 p = "radio";
659 case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break; 1018 break;
660 default: p = "undefined"; break; 1019 case V4L2_TUNER_DIGITAL_TV:
1020 p = "digital TV";
1021 break;
1022 case V4L2_TUNER_ANALOG_TV:
1023 default:
1024 p = "analog TV";
1025 break;
661 } 1026 }
662 if (t->mode == V4L2_TUNER_RADIO) { 1027 if (t->mode == V4L2_TUNER_RADIO) {
663 freq = t->radio_freq / 16000; 1028 freq = t->radio_freq / 16000;
@@ -666,11 +1031,12 @@ static void tuner_status(struct dvb_frontend *fe)
666 freq = t->tv_freq / 16; 1031 freq = t->tv_freq / 16;
667 freq_fraction = (t->tv_freq % 16) * 100 / 16; 1032 freq_fraction = (t->tv_freq % 16) * 100 / 16;
668 } 1033 }
669 tuner_info("Tuner mode: %s\n", p); 1034 tuner_info("Tuner mode: %s%s\n", p,
1035 t->standby ? " on standby mode" : "");
670 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); 1036 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
671 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); 1037 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std);
672 if (t->mode != V4L2_TUNER_RADIO) 1038 if (t->mode != V4L2_TUNER_RADIO)
673 return; 1039 return;
674 if (fe_tuner_ops->get_status) { 1040 if (fe_tuner_ops->get_status) {
675 u32 tuner_status; 1041 u32 tuner_status;
676 1042
@@ -683,132 +1049,58 @@ static void tuner_status(struct dvb_frontend *fe)
683 if (analog_ops->has_signal) 1049 if (analog_ops->has_signal)
684 tuner_info("Signal strength: %d\n", 1050 tuner_info("Signal strength: %d\n",
685 analog_ops->has_signal(fe)); 1051 analog_ops->has_signal(fe));
686 if (analog_ops->is_stereo)
687 tuner_info("Stereo: %s\n",
688 analog_ops->is_stereo(fe) ? "yes" : "no");
689} 1052}
690 1053
691/* ---------------------------------------------------------------------- */
692
693/* 1054/*
694 * Switch tuner to other mode. If tuner support both tv and radio, 1055 * Function to splicitly change mode to radio. Probably not needed anymore
695 * set another frequency to some value (This is needed for some pal
696 * tuners to avoid locking). Otherwise, just put second tuner in
697 * standby mode.
698 */ 1056 */
699 1057
700static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
701{
702 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
703
704 if (mode == t->mode)
705 return 0;
706
707 t->mode = mode;
708
709 if (check_mode(t, cmd) == -EINVAL) {
710 tuner_dbg("Tuner doesn't support this mode. "
711 "Putting tuner to sleep\n");
712 t->mode = T_STANDBY;
713 if (analog_ops->standby)
714 analog_ops->standby(&t->fe);
715 return -EINVAL;
716 }
717 return 0;
718}
719
720#define switch_v4l2() if (!t->using_v4l2) \
721 tuner_dbg("switching to v4l2\n"); \
722 t->using_v4l2 = 1;
723
724static inline int check_v4l2(struct tuner *t)
725{
726 /* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for
727 TV, v4l1 for radio), until that is fixed this code is disabled.
728 Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2)
729 first. */
730 return 0;
731}
732
733static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
734{
735 struct tuner *t = to_tuner(sd);
736 struct i2c_client *client = v4l2_get_subdevdata(sd);
737
738 tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
739 type->type,
740 type->addr,
741 type->mode_mask,
742 type->config);
743
744 set_addr(client, type);
745 return 0;
746}
747
748static int tuner_s_radio(struct v4l2_subdev *sd) 1058static int tuner_s_radio(struct v4l2_subdev *sd)
749{ 1059{
750 struct tuner *t = to_tuner(sd); 1060 struct tuner *t = to_tuner(sd);
751 struct i2c_client *client = v4l2_get_subdevdata(sd); 1061 struct i2c_client *client = v4l2_get_subdevdata(sd);
752 1062
753 if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL) 1063 if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
754 return 0; 1064 return 0;
755 if (t->radio_freq)
756 set_freq(client, t->radio_freq);
757 return 0; 1065 return 0;
758} 1066}
759 1067
1068/*
1069 * Tuner callbacks to handle userspace ioctl's
1070 */
1071
1072/**
1073 * tuner_s_power - controls the power state of the tuner
1074 * @sd: pointer to struct v4l2_subdev
1075 * @on: a zero value puts the tuner to sleep
1076 */
760static int tuner_s_power(struct v4l2_subdev *sd, int on) 1077static int tuner_s_power(struct v4l2_subdev *sd, int on)
761{ 1078{
762 struct tuner *t = to_tuner(sd); 1079 struct tuner *t = to_tuner(sd);
763 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 1080 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
764 1081
1082 /* FIXME: Why this function don't wake the tuner if on != 0 ? */
765 if (on) 1083 if (on)
766 return 0; 1084 return 0;
767 1085
768 tuner_dbg("Putting tuner to sleep\n"); 1086 tuner_dbg("Putting tuner to sleep\n");
769 1087 t->standby = true;
770 if (check_mode(t, "s_power") == -EINVAL)
771 return 0;
772 t->mode = T_STANDBY;
773 if (analog_ops->standby) 1088 if (analog_ops->standby)
774 analog_ops->standby(&t->fe); 1089 analog_ops->standby(&t->fe);
775 return 0; 1090 return 0;
776} 1091}
777 1092
778static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
779{
780 struct tuner *t = to_tuner(sd);
781 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
782
783 if (t->type != cfg->tuner)
784 return 0;
785
786 if (analog_ops->set_config) {
787 analog_ops->set_config(&t->fe, cfg->priv);
788 return 0;
789 }
790
791 tuner_dbg("Tuner frontend module has no way to set config\n");
792 return 0;
793}
794
795/* --- v4l ioctls --- */
796/* take care: bttv does userspace copying, we'll get a
797 kernel pointer here... */
798static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 1093static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
799{ 1094{
800 struct tuner *t = to_tuner(sd); 1095 struct tuner *t = to_tuner(sd);
801 struct i2c_client *client = v4l2_get_subdevdata(sd); 1096 struct i2c_client *client = v4l2_get_subdevdata(sd);
802 1097
803 if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL) 1098 if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
804 return 0; 1099 return 0;
805 1100
806 switch_v4l2();
807
808 t->std = std; 1101 t->std = std;
809 tuner_fixup_std(t); 1102 tuner_fixup_std(t);
810 if (t->tv_freq) 1103
811 set_freq(client, t->tv_freq);
812 return 0; 1104 return 0;
813} 1105}
814 1106
@@ -817,10 +1109,8 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
817 struct tuner *t = to_tuner(sd); 1109 struct tuner *t = to_tuner(sd);
818 struct i2c_client *client = v4l2_get_subdevdata(sd); 1110 struct i2c_client *client = v4l2_get_subdevdata(sd);
819 1111
820 if (set_mode(client, t, f->type, "s_frequency") == -EINVAL) 1112 if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
821 return 0; 1113 return 0;
822 switch_v4l2();
823 set_freq(client, f->frequency);
824 1114
825 return 0; 1115 return 0;
826} 1116}
@@ -830,21 +1120,20 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
830 struct tuner *t = to_tuner(sd); 1120 struct tuner *t = to_tuner(sd);
831 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 1121 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
832 1122
833 if (check_mode(t, "g_frequency") == -EINVAL) 1123 if (check_mode(t, f->type) == -EINVAL)
834 return 0; 1124 return 0;
835 switch_v4l2();
836 f->type = t->mode; 1125 f->type = t->mode;
837 if (fe_tuner_ops->get_frequency) { 1126 if (fe_tuner_ops->get_frequency && !t->standby) {
838 u32 abs_freq; 1127 u32 abs_freq;
839 1128
840 fe_tuner_ops->get_frequency(&t->fe, &abs_freq); 1129 fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
841 f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 1130 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
842 DIV_ROUND_CLOSEST(abs_freq * 2, 125) : 1131 DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
843 DIV_ROUND_CLOSEST(abs_freq, 62500); 1132 DIV_ROUND_CLOSEST(abs_freq, 62500);
844 return 0; 1133 } else {
1134 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
1135 t->radio_freq : t->tv_freq;
845 } 1136 }
846 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
847 t->radio_freq : t->tv_freq;
848 return 0; 1137 return 0;
849} 1138}
850 1139
@@ -854,10 +1143,8 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
854 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 1143 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
855 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 1144 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
856 1145
857 if (check_mode(t, "g_tuner") == -EINVAL) 1146 if (check_mode(t, vt->type) == -EINVAL)
858 return 0; 1147 return 0;
859 switch_v4l2();
860
861 vt->type = t->mode; 1148 vt->type = t->mode;
862 if (analog_ops->get_afc) 1149 if (analog_ops->get_afc)
863 vt->afc = analog_ops->get_afc(&t->fe); 1150 vt->afc = analog_ops->get_afc(&t->fe);
@@ -870,8 +1157,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
870 } 1157 }
871 1158
872 /* radio mode */ 1159 /* radio mode */
873 vt->rxsubchans = 1160 vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
874 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
875 if (fe_tuner_ops->get_status) { 1161 if (fe_tuner_ops->get_status) {
876 u32 tuner_status; 1162 u32 tuner_status;
877 1163
@@ -880,21 +1166,14 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
880 (tuner_status & TUNER_STATUS_STEREO) ? 1166 (tuner_status & TUNER_STATUS_STEREO) ?
881 V4L2_TUNER_SUB_STEREO : 1167 V4L2_TUNER_SUB_STEREO :
882 V4L2_TUNER_SUB_MONO; 1168 V4L2_TUNER_SUB_MONO;
883 } else {
884 if (analog_ops->is_stereo) {
885 vt->rxsubchans =
886 analog_ops->is_stereo(&t->fe) ?
887 V4L2_TUNER_SUB_STEREO :
888 V4L2_TUNER_SUB_MONO;
889 }
890 } 1169 }
891 if (analog_ops->has_signal) 1170 if (analog_ops->has_signal)
892 vt->signal = analog_ops->has_signal(&t->fe); 1171 vt->signal = analog_ops->has_signal(&t->fe);
893 vt->capability |= 1172 vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
894 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
895 vt->audmode = t->audmode; 1173 vt->audmode = t->audmode;
896 vt->rangelow = radio_range[0] * 16000; 1174 vt->rangelow = radio_range[0] * 16000;
897 vt->rangehigh = radio_range[1] * 16000; 1175 vt->rangehigh = radio_range[1] * 16000;
1176
898 return 0; 1177 return 0;
899} 1178}
900 1179
@@ -903,16 +1182,12 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
903 struct tuner *t = to_tuner(sd); 1182 struct tuner *t = to_tuner(sd);
904 struct i2c_client *client = v4l2_get_subdevdata(sd); 1183 struct i2c_client *client = v4l2_get_subdevdata(sd);
905 1184
906 if (check_mode(t, "s_tuner") == -EINVAL) 1185 if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
907 return 0; 1186 return 0;
908 1187
909 switch_v4l2(); 1188 if (t->mode == V4L2_TUNER_RADIO)
1189 t->audmode = vt->audmode;
910 1190
911 /* do nothing unless we're a radio tuner */
912 if (t->mode != V4L2_TUNER_RADIO)
913 return 0;
914 t->audmode = vt->audmode;
915 set_radio_freq(client, t->radio_freq);
916 return 0; 1191 return 0;
917} 1192}
918 1193
@@ -929,9 +1204,13 @@ static int tuner_log_status(struct v4l2_subdev *sd)
929static int tuner_suspend(struct i2c_client *c, pm_message_t state) 1204static int tuner_suspend(struct i2c_client *c, pm_message_t state)
930{ 1205{
931 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 1206 struct tuner *t = to_tuner(i2c_get_clientdata(c));
1207 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
932 1208
933 tuner_dbg("suspend\n"); 1209 tuner_dbg("suspend\n");
934 /* FIXME: power down ??? */ 1210
1211 if (!t->standby && analog_ops->standby)
1212 analog_ops->standby(&t->fe);
1213
935 return 0; 1214 return 0;
936} 1215}
937 1216
@@ -940,13 +1219,10 @@ static int tuner_resume(struct i2c_client *c)
940 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 1219 struct tuner *t = to_tuner(i2c_get_clientdata(c));
941 1220
942 tuner_dbg("resume\n"); 1221 tuner_dbg("resume\n");
943 if (V4L2_TUNER_RADIO == t->mode) { 1222
944 if (t->radio_freq) 1223 if (!t->standby)
945 set_freq(c, t->radio_freq); 1224 set_mode_freq(c, t, t->type, 0);
946 } else { 1225
947 if (t->tv_freq)
948 set_freq(c, t->tv_freq);
949 }
950 return 0; 1226 return 0;
951} 1227}
952 1228
@@ -964,7 +1240,9 @@ static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
964 return -ENOIOCTLCMD; 1240 return -ENOIOCTLCMD;
965} 1241}
966 1242
967/* ----------------------------------------------------------------------- */ 1243/*
1244 * Callback structs
1245 */
968 1246
969static const struct v4l2_subdev_core_ops tuner_core_ops = { 1247static const struct v4l2_subdev_core_ops tuner_core_ops = {
970 .log_status = tuner_log_status, 1248 .log_status = tuner_log_status,
@@ -987,183 +1265,10 @@ static const struct v4l2_subdev_ops tuner_ops = {
987 .tuner = &tuner_tuner_ops, 1265 .tuner = &tuner_tuner_ops,
988}; 1266};
989 1267
990/* ---------------------------------------------------------------------- */ 1268/*
991 1269 * I2C structs and module init functions
992static LIST_HEAD(tuner_list);
993
994/* Search for existing radio and/or TV tuners on the given I2C adapter.
995 Note that when this function is called from tuner_probe you can be
996 certain no other devices will be added/deleted at the same time, I2C
997 core protects against that. */
998static void tuner_lookup(struct i2c_adapter *adap,
999 struct tuner **radio, struct tuner **tv)
1000{
1001 struct tuner *pos;
1002
1003 *radio = NULL;
1004 *tv = NULL;
1005
1006 list_for_each_entry(pos, &tuner_list, list) {
1007 int mode_mask;
1008
1009 if (pos->i2c->adapter != adap ||
1010 strcmp(pos->i2c->driver->driver.name, "tuner"))
1011 continue;
1012
1013 mode_mask = pos->mode_mask & ~T_STANDBY;
1014 if (*radio == NULL && mode_mask == T_RADIO)
1015 *radio = pos;
1016 /* Note: currently TDA9887 is the only demod-only
1017 device. If other devices appear then we need to
1018 make this test more general. */
1019 else if (*tv == NULL && pos->type != TUNER_TDA9887 &&
1020 (pos->mode_mask & (T_ANALOG_TV | T_DIGITAL_TV)))
1021 *tv = pos;
1022 }
1023}
1024
1025/* During client attach, set_type is called by adapter's attach_inform callback.
1026 set_type must then be completed by tuner_probe.
1027 */ 1270 */
1028static int tuner_probe(struct i2c_client *client,
1029 const struct i2c_device_id *id)
1030{
1031 struct tuner *t;
1032 struct tuner *radio;
1033 struct tuner *tv;
1034
1035 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
1036 if (NULL == t)
1037 return -ENOMEM;
1038 v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
1039 t->i2c = client;
1040 t->name = "(tuner unset)";
1041 t->type = UNSET;
1042 t->audmode = V4L2_TUNER_MODE_STEREO;
1043 t->mode_mask = T_UNINITIALIZED;
1044
1045 if (show_i2c) {
1046 unsigned char buffer[16];
1047 int i, rc;
1048
1049 memset(buffer, 0, sizeof(buffer));
1050 rc = i2c_master_recv(client, buffer, sizeof(buffer));
1051 tuner_info("I2C RECV = ");
1052 for (i = 0; i < rc; i++)
1053 printk(KERN_CONT "%02x ", buffer[i]);
1054 printk("\n");
1055 }
1056 1271
1057 /* autodetection code based on the i2c addr */
1058 if (!no_autodetect) {
1059 switch (client->addr) {
1060 case 0x10:
1061 if (tuner_symbol_probe(tea5761_autodetection,
1062 t->i2c->adapter,
1063 t->i2c->addr) >= 0) {
1064 t->type = TUNER_TEA5761;
1065 t->mode_mask = T_RADIO;
1066 t->mode = T_STANDBY;
1067 /* Sets freq to FM range */
1068 t->radio_freq = 87.5 * 16000;
1069 tuner_lookup(t->i2c->adapter, &radio, &tv);
1070 if (tv)
1071 tv->mode_mask &= ~T_RADIO;
1072
1073 goto register_client;
1074 }
1075 kfree(t);
1076 return -ENODEV;
1077 case 0x42:
1078 case 0x43:
1079 case 0x4a:
1080 case 0x4b:
1081 /* If chip is not tda8290, don't register.
1082 since it can be tda9887*/
1083 if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
1084 t->i2c->addr) >= 0) {
1085 tuner_dbg("tda829x detected\n");
1086 } else {
1087 /* Default is being tda9887 */
1088 t->type = TUNER_TDA9887;
1089 t->mode_mask = T_RADIO | T_ANALOG_TV |
1090 T_DIGITAL_TV;
1091 t->mode = T_STANDBY;
1092 goto register_client;
1093 }
1094 break;
1095 case 0x60:
1096 if (tuner_symbol_probe(tea5767_autodetection,
1097 t->i2c->adapter, t->i2c->addr)
1098 >= 0) {
1099 t->type = TUNER_TEA5767;
1100 t->mode_mask = T_RADIO;
1101 t->mode = T_STANDBY;
1102 /* Sets freq to FM range */
1103 t->radio_freq = 87.5 * 16000;
1104 tuner_lookup(t->i2c->adapter, &radio, &tv);
1105 if (tv)
1106 tv->mode_mask &= ~T_RADIO;
1107
1108 goto register_client;
1109 }
1110 break;
1111 }
1112 }
1113
1114 /* Initializes only the first TV tuner on this adapter. Why only the
1115 first? Because there are some devices (notably the ones with TI
1116 tuners) that have more than one i2c address for the *same* device.
1117 Experience shows that, except for just one case, the first
1118 address is the right one. The exception is a Russian tuner
1119 (ACORP_Y878F). So, the desired behavior is just to enable the
1120 first found TV tuner. */
1121 tuner_lookup(t->i2c->adapter, &radio, &tv);
1122 if (tv == NULL) {
1123 t->mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
1124 if (radio == NULL)
1125 t->mode_mask |= T_RADIO;
1126 tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
1127 t->tv_freq = 400 * 16; /* Sets freq to VHF High */
1128 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
1129 }
1130
1131 /* Should be just before return */
1132register_client:
1133 tuner_info("chip found @ 0x%x (%s)\n", client->addr << 1,
1134 client->adapter->name);
1135
1136 /* Sets a default mode */
1137 if (t->mode_mask & T_ANALOG_TV) {
1138 t->mode = V4L2_TUNER_ANALOG_TV;
1139 } else if (t->mode_mask & T_RADIO) {
1140 t->mode = V4L2_TUNER_RADIO;
1141 } else {
1142 t->mode = V4L2_TUNER_DIGITAL_TV;
1143 }
1144 set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
1145 list_add_tail(&t->list, &tuner_list);
1146 return 0;
1147}
1148
1149static int tuner_remove(struct i2c_client *client)
1150{
1151 struct tuner *t = to_tuner(i2c_get_clientdata(client));
1152
1153 v4l2_device_unregister_subdev(&t->sd);
1154 tuner_detach(&t->fe);
1155 t->fe.analog_demod_priv = NULL;
1156
1157 list_del(&t->list);
1158 kfree(t);
1159 return 0;
1160}
1161
1162/* ----------------------------------------------------------------------- */
1163
1164/* This driver supports many devices and the idea is to let the driver
1165 detect which device is present. So rather than listing all supported
1166 devices here, we pretend to support a single, fake device type. */
1167static const struct i2c_device_id tuner_id[] = { 1272static const struct i2c_device_id tuner_id[] = {
1168 { "tuner", }, /* autodetect */ 1273 { "tuner", }, /* autodetect */
1169 { } 1274 { }
@@ -1196,10 +1301,6 @@ static __exit void exit_tuner(void)
1196module_init(init_tuner); 1301module_init(init_tuner);
1197module_exit(exit_tuner); 1302module_exit(exit_tuner);
1198 1303
1199/* 1304MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
1200 * Overrides for Emacs so that we follow Linus's tabbing style. 1305MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
1201 * --------------------------------------------------------------------------- 1306MODULE_LICENSE("GPL");
1202 * Local variables:
1203 * c-basic-offset: 8
1204 * End:
1205 */
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 45bcf0358a1d..9b3e828b0775 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -37,6 +37,7 @@
37#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
38#include <media/v4l2-mediabus.h> 38#include <media/v4l2-mediabus.h>
39#include <media/v4l2-chip-ident.h> 39#include <media/v4l2-chip-ident.h>
40#include <media/v4l2-ctrls.h>
40#include <media/tvp514x.h> 41#include <media/tvp514x.h>
41 42
42#include "tvp514x_regs.h" 43#include "tvp514x_regs.h"
@@ -97,6 +98,7 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
97 */ 98 */
98struct tvp514x_decoder { 99struct tvp514x_decoder {
99 struct v4l2_subdev sd; 100 struct v4l2_subdev sd;
101 struct v4l2_ctrl_handler hdl;
100 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; 102 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
101 const struct tvp514x_platform_data *pdata; 103 const struct tvp514x_platform_data *pdata;
102 104
@@ -238,6 +240,11 @@ static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
238 return container_of(sd, struct tvp514x_decoder, sd); 240 return container_of(sd, struct tvp514x_decoder, sd);
239} 241}
240 242
243static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
244{
245 return &container_of(ctrl->handler, struct tvp514x_decoder, hdl)->sd;
246}
247
241 248
242/** 249/**
243 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47. 250 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
@@ -719,213 +726,54 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
719} 726}
720 727
721/** 728/**
722 * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl
723 * @sd: pointer to standard V4L2 sub-device structure
724 * @qctrl: standard V4L2 v4l2_queryctrl structure
725 *
726 * If the requested control is supported, returns the control information.
727 * Otherwise, returns -EINVAL if the control is not supported.
728 */
729static int
730tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
731{
732 int err = -EINVAL;
733
734 if (qctrl == NULL)
735 return err;
736
737 switch (qctrl->id) {
738 case V4L2_CID_BRIGHTNESS:
739 /* Brightness supported is (0-255), */
740 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
741 break;
742 case V4L2_CID_CONTRAST:
743 case V4L2_CID_SATURATION:
744 /**
745 * Saturation and Contrast supported is -
746 * Contrast: 0 - 255 (Default - 128)
747 * Saturation: 0 - 255 (Default - 128)
748 */
749 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
750 break;
751 case V4L2_CID_HUE:
752 /* Hue Supported is -
753 * Hue - -180 - +180 (Default - 0, Step - +180)
754 */
755 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
756 break;
757 case V4L2_CID_AUTOGAIN:
758 /**
759 * Auto Gain supported is -
760 * 0 - 1 (Default - 1)
761 */
762 err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
763 break;
764 default:
765 v4l2_err(sd, "invalid control id %d\n", qctrl->id);
766 return err;
767 }
768
769 v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d\n",
770 qctrl->name, qctrl->minimum, qctrl->maximum,
771 qctrl->default_value);
772
773 return err;
774}
775
776/**
777 * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl
778 * @sd: pointer to standard V4L2 sub-device structure
779 * @ctrl: pointer to v4l2_control structure
780 *
781 * If the requested control is supported, returns the control's current
782 * value from the decoder. Otherwise, returns -EINVAL if the control is not
783 * supported.
784 */
785static int
786tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
787{
788 struct tvp514x_decoder *decoder = to_decoder(sd);
789
790 if (ctrl == NULL)
791 return -EINVAL;
792
793 switch (ctrl->id) {
794 case V4L2_CID_BRIGHTNESS:
795 ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val;
796 break;
797 case V4L2_CID_CONTRAST:
798 ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val;
799 break;
800 case V4L2_CID_SATURATION:
801 ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val;
802 break;
803 case V4L2_CID_HUE:
804 ctrl->value = decoder->tvp514x_regs[REG_HUE].val;
805 if (ctrl->value == 0x7F)
806 ctrl->value = 180;
807 else if (ctrl->value == 0x80)
808 ctrl->value = -180;
809 else
810 ctrl->value = 0;
811
812 break;
813 case V4L2_CID_AUTOGAIN:
814 ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val;
815 if ((ctrl->value & 0x3) == 3)
816 ctrl->value = 1;
817 else
818 ctrl->value = 0;
819
820 break;
821 default:
822 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
823 return -EINVAL;
824 }
825
826 v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d\n",
827 ctrl->id, ctrl->value);
828 return 0;
829}
830
831/**
832 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl 729 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
833 * @sd: pointer to standard V4L2 sub-device structure 730 * @ctrl: pointer to v4l2_ctrl structure
834 * @ctrl: pointer to v4l2_control structure
835 * 731 *
836 * If the requested control is supported, sets the control's current 732 * If the requested control is supported, sets the control's current
837 * value in HW. Otherwise, returns -EINVAL if the control is not supported. 733 * value in HW. Otherwise, returns -EINVAL if the control is not supported.
838 */ 734 */
839static int 735static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl)
840tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
841{ 736{
737 struct v4l2_subdev *sd = to_sd(ctrl);
842 struct tvp514x_decoder *decoder = to_decoder(sd); 738 struct tvp514x_decoder *decoder = to_decoder(sd);
843 int err = -EINVAL, value; 739 int err = -EINVAL, value;
844 740
845 if (ctrl == NULL) 741 value = ctrl->val;
846 return err;
847
848 value = ctrl->value;
849 742
850 switch (ctrl->id) { 743 switch (ctrl->id) {
851 case V4L2_CID_BRIGHTNESS: 744 case V4L2_CID_BRIGHTNESS:
852 if (ctrl->value < 0 || ctrl->value > 255) { 745 err = tvp514x_write_reg(sd, REG_BRIGHTNESS, value);
853 v4l2_err(sd, "invalid brightness setting %d\n", 746 if (!err)
854 ctrl->value); 747 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
855 return -ERANGE;
856 }
857 err = tvp514x_write_reg(sd, REG_BRIGHTNESS,
858 value);
859 if (err)
860 return err;
861
862 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
863 break; 748 break;
864 case V4L2_CID_CONTRAST: 749 case V4L2_CID_CONTRAST:
865 if (ctrl->value < 0 || ctrl->value > 255) {
866 v4l2_err(sd, "invalid contrast setting %d\n",
867 ctrl->value);
868 return -ERANGE;
869 }
870 err = tvp514x_write_reg(sd, REG_CONTRAST, value); 750 err = tvp514x_write_reg(sd, REG_CONTRAST, value);
871 if (err) 751 if (!err)
872 return err; 752 decoder->tvp514x_regs[REG_CONTRAST].val = value;
873
874 decoder->tvp514x_regs[REG_CONTRAST].val = value;
875 break; 753 break;
876 case V4L2_CID_SATURATION: 754 case V4L2_CID_SATURATION:
877 if (ctrl->value < 0 || ctrl->value > 255) {
878 v4l2_err(sd, "invalid saturation setting %d\n",
879 ctrl->value);
880 return -ERANGE;
881 }
882 err = tvp514x_write_reg(sd, REG_SATURATION, value); 755 err = tvp514x_write_reg(sd, REG_SATURATION, value);
883 if (err) 756 if (!err)
884 return err; 757 decoder->tvp514x_regs[REG_SATURATION].val = value;
885
886 decoder->tvp514x_regs[REG_SATURATION].val = value;
887 break; 758 break;
888 case V4L2_CID_HUE: 759 case V4L2_CID_HUE:
889 if (value == 180) 760 if (value == 180)
890 value = 0x7F; 761 value = 0x7F;
891 else if (value == -180) 762 else if (value == -180)
892 value = 0x80; 763 value = 0x80;
893 else if (value == 0)
894 value = 0;
895 else {
896 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
897 return -ERANGE;
898 }
899 err = tvp514x_write_reg(sd, REG_HUE, value); 764 err = tvp514x_write_reg(sd, REG_HUE, value);
900 if (err) 765 if (!err)
901 return err; 766 decoder->tvp514x_regs[REG_HUE].val = value;
902
903 decoder->tvp514x_regs[REG_HUE].val = value;
904 break; 767 break;
905 case V4L2_CID_AUTOGAIN: 768 case V4L2_CID_AUTOGAIN:
906 if (value == 1) 769 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value ? 0x0f : 0x0c);
907 value = 0x0F; 770 if (!err)
908 else if (value == 0) 771 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
909 value = 0x0C;
910 else {
911 v4l2_err(sd, "invalid auto gain setting %d\n",
912 ctrl->value);
913 return -ERANGE;
914 }
915 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value);
916 if (err)
917 return err;
918
919 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
920 break; 772 break;
921 default:
922 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
923 return err;
924 } 773 }
925 774
926 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n", 775 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n",
927 ctrl->id, ctrl->value); 776 ctrl->id, ctrl->val);
928
929 return err; 777 return err;
930} 778}
931 779
@@ -1104,10 +952,18 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
1104 return err; 952 return err;
1105} 953}
1106 954
1107static const struct v4l2_subdev_core_ops tvp514x_core_ops = { 955static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = {
1108 .queryctrl = tvp514x_queryctrl,
1109 .g_ctrl = tvp514x_g_ctrl,
1110 .s_ctrl = tvp514x_s_ctrl, 956 .s_ctrl = tvp514x_s_ctrl,
957};
958
959static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
960 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
961 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
962 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
963 .g_ctrl = v4l2_subdev_g_ctrl,
964 .s_ctrl = v4l2_subdev_s_ctrl,
965 .queryctrl = v4l2_subdev_queryctrl,
966 .querymenu = v4l2_subdev_querymenu,
1111 .s_std = tvp514x_s_std, 967 .s_std = tvp514x_s_std,
1112}; 968};
1113 969
@@ -1190,6 +1046,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
1190 sd = &decoder->sd; 1046 sd = &decoder->sd;
1191 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops); 1047 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
1192 1048
1049 v4l2_ctrl_handler_init(&decoder->hdl, 5);
1050 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1051 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1052 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1053 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1054 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1055 V4L2_CID_SATURATION, 0, 255, 1, 128);
1056 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1057 V4L2_CID_HUE, -180, 180, 180, 0);
1058 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1059 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1060 sd->ctrl_handler = &decoder->hdl;
1061 if (decoder->hdl.error) {
1062 int err = decoder->hdl.error;
1063
1064 v4l2_ctrl_handler_free(&decoder->hdl);
1065 kfree(decoder);
1066 return err;
1067 }
1068 v4l2_ctrl_handler_setup(&decoder->hdl);
1069
1193 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name); 1070 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
1194 1071
1195 return 0; 1072 return 0;
@@ -1209,6 +1086,7 @@ static int tvp514x_remove(struct i2c_client *client)
1209 struct tvp514x_decoder *decoder = to_decoder(sd); 1086 struct tvp514x_decoder *decoder = to_decoder(sd);
1210 1087
1211 v4l2_device_unregister_subdev(sd); 1088 v4l2_device_unregister_subdev(sd);
1089 v4l2_ctrl_handler_free(&decoder->hdl);
1212 kfree(decoder); 1090 kfree(decoder);
1213 return 0; 1091 return 0;
1214} 1092}
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 58927664d3ea..e927d25e0d35 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -12,6 +12,7 @@
12#include <media/v4l2-device.h> 12#include <media/v4l2-device.h>
13#include <media/tvp5150.h> 13#include <media/tvp5150.h>
14#include <media/v4l2-chip-ident.h> 14#include <media/v4l2-chip-ident.h>
15#include <media/v4l2-ctrls.h>
15 16
16#include "tvp5150_reg.h" 17#include "tvp5150_reg.h"
17 18
@@ -24,58 +25,14 @@ static int debug;
24module_param(debug, int, 0); 25module_param(debug, int, 0);
25MODULE_PARM_DESC(debug, "Debug level (0-2)"); 26MODULE_PARM_DESC(debug, "Debug level (0-2)");
26 27
27/* supported controls */
28static struct v4l2_queryctrl tvp5150_qctrl[] = {
29 {
30 .id = V4L2_CID_BRIGHTNESS,
31 .type = V4L2_CTRL_TYPE_INTEGER,
32 .name = "Brightness",
33 .minimum = 0,
34 .maximum = 255,
35 .step = 1,
36 .default_value = 128,
37 .flags = 0,
38 }, {
39 .id = V4L2_CID_CONTRAST,
40 .type = V4L2_CTRL_TYPE_INTEGER,
41 .name = "Contrast",
42 .minimum = 0,
43 .maximum = 255,
44 .step = 0x1,
45 .default_value = 128,
46 .flags = 0,
47 }, {
48 .id = V4L2_CID_SATURATION,
49 .type = V4L2_CTRL_TYPE_INTEGER,
50 .name = "Saturation",
51 .minimum = 0,
52 .maximum = 255,
53 .step = 0x1,
54 .default_value = 128,
55 .flags = 0,
56 }, {
57 .id = V4L2_CID_HUE,
58 .type = V4L2_CTRL_TYPE_INTEGER,
59 .name = "Hue",
60 .minimum = -128,
61 .maximum = 127,
62 .step = 0x1,
63 .default_value = 0,
64 .flags = 0,
65 }
66};
67
68struct tvp5150 { 28struct tvp5150 {
69 struct v4l2_subdev sd; 29 struct v4l2_subdev sd;
30 struct v4l2_ctrl_handler hdl;
70 31
71 v4l2_std_id norm; /* Current set standard */ 32 v4l2_std_id norm; /* Current set standard */
72 u32 input; 33 u32 input;
73 u32 output; 34 u32 output;
74 int enable; 35 int enable;
75 int bright;
76 int contrast;
77 int hue;
78 int sat;
79}; 36};
80 37
81static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd) 38static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
@@ -83,6 +40,11 @@ static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
83 return container_of(sd, struct tvp5150, sd); 40 return container_of(sd, struct tvp5150, sd);
84} 41}
85 42
43static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
44{
45 return &container_of(ctrl->handler, struct tvp5150, hdl)->sd;
46}
47
86static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) 48static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
87{ 49{
88 struct i2c_client *c = v4l2_get_subdevdata(sd); 50 struct i2c_client *c = v4l2_get_subdevdata(sd);
@@ -775,27 +737,6 @@ static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
775static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) 737static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
776{ 738{
777 struct tvp5150 *decoder = to_tvp5150(sd); 739 struct tvp5150 *decoder = to_tvp5150(sd);
778 u8 msb_id, lsb_id, msb_rom, lsb_rom;
779
780 msb_id = tvp5150_read(sd, TVP5150_MSB_DEV_ID);
781 lsb_id = tvp5150_read(sd, TVP5150_LSB_DEV_ID);
782 msb_rom = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER);
783 lsb_rom = tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
784
785 if (msb_rom == 4 && lsb_rom == 0) { /* Is TVP5150AM1 */
786 v4l2_info(sd, "tvp%02x%02xam1 detected.\n", msb_id, lsb_id);
787
788 /* ITU-T BT.656.4 timing */
789 tvp5150_write(sd, TVP5150_REV_SELECT, 0);
790 } else {
791 if (msb_rom == 3 || lsb_rom == 0x21) { /* Is TVP5150A */
792 v4l2_info(sd, "tvp%02x%02xa detected.\n", msb_id, lsb_id);
793 } else {
794 v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
795 msb_id, lsb_id);
796 v4l2_info(sd, "*** Rom ver is %d.%d\n", msb_rom, lsb_rom);
797 }
798 }
799 740
800 /* Initializes TVP5150 to its default values */ 741 /* Initializes TVP5150 to its default values */
801 tvp5150_write_inittab(sd, tvp5150_init_default); 742 tvp5150_write_inittab(sd, tvp5150_init_default);
@@ -810,64 +751,28 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
810 tvp5150_write_inittab(sd, tvp5150_init_enable); 751 tvp5150_write_inittab(sd, tvp5150_init_enable);
811 752
812 /* Initialize image preferences */ 753 /* Initialize image preferences */
813 tvp5150_write(sd, TVP5150_BRIGHT_CTL, decoder->bright); 754 v4l2_ctrl_handler_setup(&decoder->hdl);
814 tvp5150_write(sd, TVP5150_CONTRAST_CTL, decoder->contrast);
815 tvp5150_write(sd, TVP5150_SATURATION_CTL, decoder->contrast);
816 tvp5150_write(sd, TVP5150_HUE_CTL, decoder->hue);
817 755
818 tvp5150_set_std(sd, decoder->norm); 756 tvp5150_set_std(sd, decoder->norm);
819 return 0; 757 return 0;
820}; 758};
821 759
822static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 760static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
823{
824 v4l2_dbg(1, debug, sd, "g_ctrl called\n");
825
826 switch (ctrl->id) {
827 case V4L2_CID_BRIGHTNESS:
828 ctrl->value = tvp5150_read(sd, TVP5150_BRIGHT_CTL);
829 return 0;
830 case V4L2_CID_CONTRAST:
831 ctrl->value = tvp5150_read(sd, TVP5150_CONTRAST_CTL);
832 return 0;
833 case V4L2_CID_SATURATION:
834 ctrl->value = tvp5150_read(sd, TVP5150_SATURATION_CTL);
835 return 0;
836 case V4L2_CID_HUE:
837 ctrl->value = tvp5150_read(sd, TVP5150_HUE_CTL);
838 return 0;
839 }
840 return -EINVAL;
841}
842
843static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
844{ 761{
845 u8 i, n; 762 struct v4l2_subdev *sd = to_sd(ctrl);
846 n = ARRAY_SIZE(tvp5150_qctrl);
847
848 for (i = 0; i < n; i++) {
849 if (ctrl->id != tvp5150_qctrl[i].id)
850 continue;
851 if (ctrl->value < tvp5150_qctrl[i].minimum ||
852 ctrl->value > tvp5150_qctrl[i].maximum)
853 return -ERANGE;
854 v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
855 ctrl->id, ctrl->value);
856 break;
857 }
858 763
859 switch (ctrl->id) { 764 switch (ctrl->id) {
860 case V4L2_CID_BRIGHTNESS: 765 case V4L2_CID_BRIGHTNESS:
861 tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->value); 766 tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val);
862 return 0; 767 return 0;
863 case V4L2_CID_CONTRAST: 768 case V4L2_CID_CONTRAST:
864 tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->value); 769 tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val);
865 return 0; 770 return 0;
866 case V4L2_CID_SATURATION: 771 case V4L2_CID_SATURATION:
867 tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->value); 772 tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->val);
868 return 0; 773 return 0;
869 case V4L2_CID_HUE: 774 case V4L2_CID_HUE:
870 tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->value); 775 tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val);
871 return 0; 776 return 0;
872 } 777 }
873 return -EINVAL; 778 return -EINVAL;
@@ -995,29 +900,21 @@ static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
995 return 0; 900 return 0;
996} 901}
997 902
998static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
999{
1000 int i;
1001
1002 v4l2_dbg(1, debug, sd, "queryctrl called\n");
1003
1004 for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
1005 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
1006 memcpy(qc, &(tvp5150_qctrl[i]),
1007 sizeof(*qc));
1008 return 0;
1009 }
1010
1011 return -EINVAL;
1012}
1013
1014/* ----------------------------------------------------------------------- */ 903/* ----------------------------------------------------------------------- */
1015 904
905static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
906 .s_ctrl = tvp5150_s_ctrl,
907};
908
1016static const struct v4l2_subdev_core_ops tvp5150_core_ops = { 909static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
1017 .log_status = tvp5150_log_status, 910 .log_status = tvp5150_log_status,
1018 .g_ctrl = tvp5150_g_ctrl, 911 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1019 .s_ctrl = tvp5150_s_ctrl, 912 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1020 .queryctrl = tvp5150_queryctrl, 913 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
914 .g_ctrl = v4l2_subdev_g_ctrl,
915 .s_ctrl = v4l2_subdev_s_ctrl,
916 .queryctrl = v4l2_subdev_queryctrl,
917 .querymenu = v4l2_subdev_querymenu,
1021 .s_std = tvp5150_s_std, 918 .s_std = tvp5150_s_std,
1022 .reset = tvp5150_reset, 919 .reset = tvp5150_reset,
1023 .g_chip_ident = tvp5150_g_chip_ident, 920 .g_chip_ident = tvp5150_g_chip_ident,
@@ -1059,6 +956,7 @@ static int tvp5150_probe(struct i2c_client *c,
1059{ 956{
1060 struct tvp5150 *core; 957 struct tvp5150 *core;
1061 struct v4l2_subdev *sd; 958 struct v4l2_subdev *sd;
959 u8 msb_id, lsb_id, msb_rom, lsb_rom;
1062 960
1063 /* Check if the adapter supports the needed features */ 961 /* Check if the adapter supports the needed features */
1064 if (!i2c_check_functionality(c->adapter, 962 if (!i2c_check_functionality(c->adapter,
@@ -1074,13 +972,48 @@ static int tvp5150_probe(struct i2c_client *c,
1074 v4l_info(c, "chip found @ 0x%02x (%s)\n", 972 v4l_info(c, "chip found @ 0x%02x (%s)\n",
1075 c->addr << 1, c->adapter->name); 973 c->addr << 1, c->adapter->name);
1076 974
975 msb_id = tvp5150_read(sd, TVP5150_MSB_DEV_ID);
976 lsb_id = tvp5150_read(sd, TVP5150_LSB_DEV_ID);
977 msb_rom = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER);
978 lsb_rom = tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
979
980 if (msb_rom == 4 && lsb_rom == 0) { /* Is TVP5150AM1 */
981 v4l2_info(sd, "tvp%02x%02xam1 detected.\n", msb_id, lsb_id);
982
983 /* ITU-T BT.656.4 timing */
984 tvp5150_write(sd, TVP5150_REV_SELECT, 0);
985 } else {
986 if (msb_rom == 3 || lsb_rom == 0x21) { /* Is TVP5150A */
987 v4l2_info(sd, "tvp%02x%02xa detected.\n", msb_id, lsb_id);
988 } else {
989 v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
990 msb_id, lsb_id);
991 v4l2_info(sd, "*** Rom ver is %d.%d\n", msb_rom, lsb_rom);
992 }
993 }
994
1077 core->norm = V4L2_STD_ALL; /* Default is autodetect */ 995 core->norm = V4L2_STD_ALL; /* Default is autodetect */
1078 core->input = TVP5150_COMPOSITE1; 996 core->input = TVP5150_COMPOSITE1;
1079 core->enable = 1; 997 core->enable = 1;
1080 core->bright = 128; 998
1081 core->contrast = 128; 999 v4l2_ctrl_handler_init(&core->hdl, 4);
1082 core->hue = 0; 1000 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1083 core->sat = 128; 1001 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1002 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1003 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1004 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1005 V4L2_CID_SATURATION, 0, 255, 1, 128);
1006 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1007 V4L2_CID_HUE, -128, 127, 1, 0);
1008 sd->ctrl_handler = &core->hdl;
1009 if (core->hdl.error) {
1010 int err = core->hdl.error;
1011
1012 v4l2_ctrl_handler_free(&core->hdl);
1013 kfree(core);
1014 return err;
1015 }
1016 v4l2_ctrl_handler_setup(&core->hdl);
1084 1017
1085 if (debug > 1) 1018 if (debug > 1)
1086 tvp5150_log_status(sd); 1019 tvp5150_log_status(sd);
@@ -1090,12 +1023,14 @@ static int tvp5150_probe(struct i2c_client *c,
1090static int tvp5150_remove(struct i2c_client *c) 1023static int tvp5150_remove(struct i2c_client *c)
1091{ 1024{
1092 struct v4l2_subdev *sd = i2c_get_clientdata(c); 1025 struct v4l2_subdev *sd = i2c_get_clientdata(c);
1026 struct tvp5150 *decoder = to_tvp5150(sd);
1093 1027
1094 v4l2_dbg(1, debug, sd, 1028 v4l2_dbg(1, debug, sd,
1095 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", 1029 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
1096 c->addr << 1); 1030 c->addr << 1);
1097 1031
1098 v4l2_device_unregister_subdev(sd); 1032 v4l2_device_unregister_subdev(sd);
1033 v4l2_ctrl_handler_free(&decoder->hdl);
1099 kfree(to_tvp5150(sd)); 1034 kfree(to_tvp5150(sd));
1100 return 0; 1035 return 0;
1101} 1036}
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index c799e4eb6fcd..b799851bf3d0 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -32,6 +32,7 @@
32#include <media/v4l2-device.h> 32#include <media/v4l2-device.h>
33#include <media/v4l2-chip-ident.h> 33#include <media/v4l2-chip-ident.h>
34#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
35#include <media/v4l2-ctrls.h>
35#include "tvp7002_reg.h" 36#include "tvp7002_reg.h"
36 37
37MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver"); 38MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
@@ -421,13 +422,13 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
421/* Device definition */ 422/* Device definition */
422struct tvp7002 { 423struct tvp7002 {
423 struct v4l2_subdev sd; 424 struct v4l2_subdev sd;
425 struct v4l2_ctrl_handler hdl;
424 const struct tvp7002_config *pdata; 426 const struct tvp7002_config *pdata;
425 427
426 int ver; 428 int ver;
427 int streaming; 429 int streaming;
428 430
429 const struct tvp7002_preset_definition *current_preset; 431 const struct tvp7002_preset_definition *current_preset;
430 u8 gain;
431}; 432};
432 433
433/* 434/*
@@ -441,6 +442,11 @@ static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
441 return container_of(sd, struct tvp7002, sd); 442 return container_of(sd, struct tvp7002, sd);
442} 443}
443 444
445static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
446{
447 return &container_of(ctrl->handler, struct tvp7002, hdl)->sd;
448}
449
444/* 450/*
445 * tvp7002_read - Read a value from a register in an TVP7002 451 * tvp7002_read - Read a value from a register in an TVP7002
446 * @sd: ptr to v4l2_subdev struct 452 * @sd: ptr to v4l2_subdev struct
@@ -606,78 +612,25 @@ static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
606} 612}
607 613
608/* 614/*
609 * tvp7002_g_ctrl() - Get a control
610 * @sd: ptr to v4l2_subdev struct
611 * @ctrl: ptr to v4l2_control struct
612 *
613 * Get a control for a TVP7002 decoder device.
614 * Returns zero when successful or -EINVAL if register access fails.
615 */
616static int tvp7002_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
617{
618 struct tvp7002 *device = to_tvp7002(sd);
619
620 switch (ctrl->id) {
621 case V4L2_CID_GAIN:
622 ctrl->value = device->gain;
623 return 0;
624 default:
625 return -EINVAL;
626 }
627}
628
629/*
630 * tvp7002_s_ctrl() - Set a control 615 * tvp7002_s_ctrl() - Set a control
631 * @sd: ptr to v4l2_subdev struct 616 * @ctrl: ptr to v4l2_ctrl struct
632 * @ctrl: ptr to v4l2_control struct
633 * 617 *
634 * Set a control in TVP7002 decoder device. 618 * Set a control in TVP7002 decoder device.
635 * Returns zero when successful or -EINVAL if register access fails. 619 * Returns zero when successful or -EINVAL if register access fails.
636 */ 620 */
637static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 621static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
638{ 622{
639 struct tvp7002 *device = to_tvp7002(sd); 623 struct v4l2_subdev *sd = to_sd(ctrl);
640 int error = 0; 624 int error = 0;
641 625
642 switch (ctrl->id) { 626 switch (ctrl->id) {
643 case V4L2_CID_GAIN: 627 case V4L2_CID_GAIN:
644 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, 628 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, ctrl->val, &error);
645 ctrl->value & 0xff, &error); 629 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, ctrl->val, &error);
646 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, 630 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN, ctrl->val, &error);
647 ctrl->value & 0xff, &error); 631 return error;
648 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN,
649 ctrl->value & 0xff, &error);
650
651 if (error < 0)
652 return error;
653
654 /* Set only after knowing there is no error */
655 device->gain = ctrl->value & 0xff;
656 return 0;
657 default:
658 return -EINVAL;
659 }
660}
661
662/*
663 * tvp7002_queryctrl() - Query a control
664 * @sd: ptr to v4l2_subdev struct
665 * @qc: ptr to v4l2_queryctrl struct
666 *
667 * Query a control of a TVP7002 decoder device.
668 * Returns zero when successful or -EINVAL if register read fails.
669 */
670static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
671{
672 switch (qc->id) {
673 case V4L2_CID_GAIN:
674 /*
675 * Gain is supported [0-255, default=0, step=1]
676 */
677 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
678 default:
679 return -EINVAL;
680 } 632 }
633 return -EINVAL;
681} 634}
682 635
683/* 636/*
@@ -924,7 +877,7 @@ static int tvp7002_log_status(struct v4l2_subdev *sd)
924 device->streaming ? "yes" : "no"); 877 device->streaming ? "yes" : "no");
925 878
926 /* Print the current value of the gain control */ 879 /* Print the current value of the gain control */
927 v4l2_info(sd, "Gain: %u\n", device->gain); 880 v4l2_ctrl_handler_log_status(&device->hdl, sd->name);
928 881
929 return 0; 882 return 0;
930} 883}
@@ -946,13 +899,21 @@ static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
946 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset); 899 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset);
947} 900}
948 901
902static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
903 .s_ctrl = tvp7002_s_ctrl,
904};
905
949/* V4L2 core operation handlers */ 906/* V4L2 core operation handlers */
950static const struct v4l2_subdev_core_ops tvp7002_core_ops = { 907static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
951 .g_chip_ident = tvp7002_g_chip_ident, 908 .g_chip_ident = tvp7002_g_chip_ident,
952 .log_status = tvp7002_log_status, 909 .log_status = tvp7002_log_status,
953 .g_ctrl = tvp7002_g_ctrl, 910 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
954 .s_ctrl = tvp7002_s_ctrl, 911 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
955 .queryctrl = tvp7002_queryctrl, 912 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
913 .g_ctrl = v4l2_subdev_g_ctrl,
914 .s_ctrl = v4l2_subdev_s_ctrl,
915 .queryctrl = v4l2_subdev_queryctrl,
916 .querymenu = v4l2_subdev_querymenu,
956#ifdef CONFIG_VIDEO_ADV_DEBUG 917#ifdef CONFIG_VIDEO_ADV_DEBUG
957 .g_register = tvp7002_g_register, 918 .g_register = tvp7002_g_register,
958 .s_register = tvp7002_s_register, 919 .s_register = tvp7002_s_register,
@@ -977,12 +938,6 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
977 .video = &tvp7002_video_ops, 938 .video = &tvp7002_video_ops,
978}; 939};
979 940
980static struct tvp7002 tvp7002_dev = {
981 .streaming = 0,
982 .current_preset = tvp7002_presets,
983 .gain = 0,
984};
985
986/* 941/*
987 * tvp7002_probe - Probe a TVP7002 device 942 * tvp7002_probe - Probe a TVP7002 device
988 * @c: ptr to i2c_client struct 943 * @c: ptr to i2c_client struct
@@ -1013,14 +968,14 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1013 return -ENODEV; 968 return -ENODEV;
1014 } 969 }
1015 970
1016 device = kmalloc(sizeof(struct tvp7002), GFP_KERNEL); 971 device = kzalloc(sizeof(struct tvp7002), GFP_KERNEL);
1017 972
1018 if (!device) 973 if (!device)
1019 return -ENOMEM; 974 return -ENOMEM;
1020 975
1021 *device = tvp7002_dev;
1022 sd = &device->sd; 976 sd = &device->sd;
1023 device->pdata = c->dev.platform_data; 977 device->pdata = c->dev.platform_data;
978 device->current_preset = tvp7002_presets;
1024 979
1025 /* Tell v4l2 the device is ready */ 980 /* Tell v4l2 the device is ready */
1026 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops); 981 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
@@ -1060,6 +1015,19 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1060 preset.preset = device->current_preset->preset; 1015 preset.preset = device->current_preset->preset;
1061 error = tvp7002_s_dv_preset(sd, &preset); 1016 error = tvp7002_s_dv_preset(sd, &preset);
1062 1017
1018 v4l2_ctrl_handler_init(&device->hdl, 1);
1019 v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
1020 V4L2_CID_GAIN, 0, 255, 1, 0);
1021 sd->ctrl_handler = &device->hdl;
1022 if (device->hdl.error) {
1023 int err = device->hdl.error;
1024
1025 v4l2_ctrl_handler_free(&device->hdl);
1026 kfree(device);
1027 return err;
1028 }
1029 v4l2_ctrl_handler_setup(&device->hdl);
1030
1063found_error: 1031found_error:
1064 if (error < 0) 1032 if (error < 0)
1065 kfree(device); 1033 kfree(device);
@@ -1083,6 +1051,7 @@ static int tvp7002_remove(struct i2c_client *c)
1083 "on address 0x%x\n", c->addr); 1051 "on address 0x%x\n", c->addr);
1084 1052
1085 v4l2_device_unregister_subdev(sd); 1053 v4l2_device_unregister_subdev(sd);
1054 v4l2_ctrl_handler_free(&device->hdl);
1086 kfree(device); 1055 kfree(device);
1087 return 0; 1056 return 0;
1088} 1057}
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index a1e9dfb52f69..6459b8cba223 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1264,6 +1264,14 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1264 1264
1265 break; 1265 break;
1266 1266
1267 case UVC_OTT_VENDOR_SPECIFIC:
1268 case UVC_OTT_DISPLAY:
1269 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1270 if (uvc_trace_param & UVC_TRACE_PROBE)
1271 printk(" OT %d", entity->id);
1272
1273 break;
1274
1267 case UVC_TT_STREAMING: 1275 case UVC_TT_STREAMING:
1268 if (UVC_ENTITY_IS_ITERM(entity)) { 1276 if (UVC_ENTITY_IS_ITERM(entity)) {
1269 if (uvc_trace_param & UVC_TRACE_PROBE) 1277 if (uvc_trace_param & UVC_TRACE_PROBE)
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 5673d673504b..545c0294813d 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -89,15 +89,19 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
89static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, 89static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
90 struct uvc_streaming_control *ctrl) 90 struct uvc_streaming_control *ctrl)
91{ 91{
92 struct uvc_format *format; 92 struct uvc_format *format = NULL;
93 struct uvc_frame *frame = NULL; 93 struct uvc_frame *frame = NULL;
94 unsigned int i; 94 unsigned int i;
95 95
96 if (ctrl->bFormatIndex <= 0 || 96 for (i = 0; i < stream->nformats; ++i) {
97 ctrl->bFormatIndex > stream->nformats) 97 if (stream->format[i].index == ctrl->bFormatIndex) {
98 return; 98 format = &stream->format[i];
99 break;
100 }
101 }
99 102
100 format = &stream->format[ctrl->bFormatIndex - 1]; 103 if (format == NULL)
104 return;
101 105
102 for (i = 0; i < format->nframes; ++i) { 106 for (i = 0; i < format->nframes; ++i) {
103 if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { 107 if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 810eef43c216..06b9f9f82013 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -59,7 +59,6 @@
59#include <asm/pgtable.h> 59#include <asm/pgtable.h>
60#include <asm/io.h> 60#include <asm/io.h>
61#include <asm/div64.h> 61#include <asm/div64.h>
62#define __OLD_VIDIOC_ /* To allow fixing old calls*/
63#include <media/v4l2-common.h> 62#include <media/v4l2-common.h>
64#include <media/v4l2-device.h> 63#include <media/v4l2-device.h>
65#include <media/v4l2-ctrls.h> 64#include <media/v4l2-ctrls.h>
@@ -81,69 +80,6 @@ MODULE_LICENSE("GPL");
81 * Video Standard Operations (contributed by Michael Schimek) 80 * Video Standard Operations (contributed by Michael Schimek)
82 */ 81 */
83 82
84
85/* ----------------------------------------------------------------- */
86/* priority handling */
87
88#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND || \
89 val == V4L2_PRIORITY_INTERACTIVE || \
90 val == V4L2_PRIORITY_RECORD)
91
92void v4l2_prio_init(struct v4l2_prio_state *global)
93{
94 memset(global, 0, sizeof(*global));
95}
96EXPORT_SYMBOL(v4l2_prio_init);
97
98int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
99 enum v4l2_priority new)
100{
101 if (!V4L2_PRIO_VALID(new))
102 return -EINVAL;
103 if (*local == new)
104 return 0;
105
106 atomic_inc(&global->prios[new]);
107 if (V4L2_PRIO_VALID(*local))
108 atomic_dec(&global->prios[*local]);
109 *local = new;
110 return 0;
111}
112EXPORT_SYMBOL(v4l2_prio_change);
113
114void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
115{
116 v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
117}
118EXPORT_SYMBOL(v4l2_prio_open);
119
120void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
121{
122 if (V4L2_PRIO_VALID(local))
123 atomic_dec(&global->prios[local]);
124}
125EXPORT_SYMBOL(v4l2_prio_close);
126
127enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
128{
129 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
130 return V4L2_PRIORITY_RECORD;
131 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
132 return V4L2_PRIORITY_INTERACTIVE;
133 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
134 return V4L2_PRIORITY_BACKGROUND;
135 return V4L2_PRIORITY_UNSET;
136}
137EXPORT_SYMBOL(v4l2_prio_max);
138
139int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
140{
141 return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
142}
143EXPORT_SYMBOL(v4l2_prio_check);
144
145/* ----------------------------------------------------------------- */
146
147/* Helper functions for control handling */ 83/* Helper functions for control handling */
148 84
149/* Check for correctness of the ctrl's value based on the data from 85/* Check for correctness of the ctrl's value based on the data from
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index dc82eb83c1d4..7c2694738b31 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/compat.h> 16#include <linux/compat.h>
17#define __OLD_VIDIOC_ /* To allow fixing old calls*/
18#include <linux/videodev2.h> 17#include <linux/videodev2.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <media/v4l2-ioctl.h> 19#include <media/v4l2-ioctl.h>
@@ -97,6 +96,14 @@ static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pi
97 return 0; 96 return 0;
98} 97}
99 98
99static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
100 struct v4l2_pix_format_mplane __user *up)
101{
102 if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
103 return -EFAULT;
104 return 0;
105}
106
100static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) 107static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
101{ 108{
102 if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) 109 if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
@@ -104,6 +111,14 @@ static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pi
104 return 0; 111 return 0;
105} 112}
106 113
114static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
115 struct v4l2_pix_format_mplane __user *up)
116{
117 if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
118 return -EFAULT;
119 return 0;
120}
121
107static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) 122static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
108{ 123{
109 if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) 124 if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
@@ -136,6 +151,7 @@ struct v4l2_format32 {
136 enum v4l2_buf_type type; 151 enum v4l2_buf_type type;
137 union { 152 union {
138 struct v4l2_pix_format pix; 153 struct v4l2_pix_format pix;
154 struct v4l2_pix_format_mplane pix_mp;
139 struct v4l2_window32 win; 155 struct v4l2_window32 win;
140 struct v4l2_vbi_format vbi; 156 struct v4l2_vbi_format vbi;
141 struct v4l2_sliced_vbi_format sliced; 157 struct v4l2_sliced_vbi_format sliced;
@@ -152,6 +168,10 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
152 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 168 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
153 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 169 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
154 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); 170 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
171 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
172 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
173 return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
174 &up->fmt.pix_mp);
155 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 175 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
156 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 176 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
157 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); 177 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
@@ -181,6 +201,10 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
181 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 201 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
182 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 202 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
183 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); 203 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
204 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
205 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
206 return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
207 &up->fmt.pix_mp);
184 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 208 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
185 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 209 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
186 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); 210 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
@@ -232,6 +256,17 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
232 return 0; 256 return 0;
233} 257}
234 258
259struct v4l2_plane32 {
260 __u32 bytesused;
261 __u32 length;
262 union {
263 __u32 mem_offset;
264 compat_long_t userptr;
265 } m;
266 __u32 data_offset;
267 __u32 reserved[11];
268};
269
235struct v4l2_buffer32 { 270struct v4l2_buffer32 {
236 __u32 index; 271 __u32 index;
237 enum v4l2_buf_type type; 272 enum v4l2_buf_type type;
@@ -247,14 +282,64 @@ struct v4l2_buffer32 {
247 union { 282 union {
248 __u32 offset; 283 __u32 offset;
249 compat_long_t userptr; 284 compat_long_t userptr;
285 compat_caddr_t planes;
250 } m; 286 } m;
251 __u32 length; 287 __u32 length;
252 __u32 input; 288 __u32 input;
253 __u32 reserved; 289 __u32 reserved;
254}; 290};
255 291
292static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
293 enum v4l2_memory memory)
294{
295 void __user *up_pln;
296 compat_long_t p;
297
298 if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
299 copy_in_user(&up->data_offset, &up32->data_offset,
300 sizeof(__u32)))
301 return -EFAULT;
302
303 if (memory == V4L2_MEMORY_USERPTR) {
304 if (get_user(p, &up32->m.userptr))
305 return -EFAULT;
306 up_pln = compat_ptr(p);
307 if (put_user((unsigned long)up_pln, &up->m.userptr))
308 return -EFAULT;
309 } else {
310 if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
311 sizeof(__u32)))
312 return -EFAULT;
313 }
314
315 return 0;
316}
317
318static int put_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
319 enum v4l2_memory memory)
320{
321 if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
322 copy_in_user(&up32->data_offset, &up->data_offset,
323 sizeof(__u32)))
324 return -EFAULT;
325
326 /* For MMAP, driver might've set up the offset, so copy it back.
327 * USERPTR stays the same (was userspace-provided), so no copying. */
328 if (memory == V4L2_MEMORY_MMAP)
329 if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
330 sizeof(__u32)))
331 return -EFAULT;
332
333 return 0;
334}
335
256static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) 336static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
257{ 337{
338 struct v4l2_plane32 __user *uplane32;
339 struct v4l2_plane __user *uplane;
340 compat_caddr_t p;
341 int num_planes;
342 int ret;
258 343
259 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) || 344 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
260 get_user(kp->index, &up->index) || 345 get_user(kp->index, &up->index) ||
@@ -263,33 +348,84 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
263 get_user(kp->memory, &up->memory) || 348 get_user(kp->memory, &up->memory) ||
264 get_user(kp->input, &up->input)) 349 get_user(kp->input, &up->input))
265 return -EFAULT; 350 return -EFAULT;
266 switch (kp->memory) { 351
267 case V4L2_MEMORY_MMAP: 352 if (V4L2_TYPE_IS_OUTPUT(kp->type))
268 if (get_user(kp->length, &up->length) || 353 if (get_user(kp->bytesused, &up->bytesused) ||
269 get_user(kp->m.offset, &up->m.offset)) 354 get_user(kp->field, &up->field) ||
355 get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
356 get_user(kp->timestamp.tv_usec,
357 &up->timestamp.tv_usec))
270 return -EFAULT; 358 return -EFAULT;
271 break;
272 case V4L2_MEMORY_USERPTR:
273 {
274 compat_long_t tmp;
275 359
276 if (get_user(kp->length, &up->length) || 360 if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
277 get_user(tmp, &up->m.userptr)) 361 if (get_user(kp->length, &up->length))
278 return -EFAULT; 362 return -EFAULT;
279 363
280 kp->m.userptr = (unsigned long)compat_ptr(tmp); 364 num_planes = kp->length;
365 if (num_planes == 0) {
366 kp->m.planes = NULL;
367 /* num_planes == 0 is legal, e.g. when userspace doesn't
368 * need planes array on DQBUF*/
369 return 0;
281 } 370 }
282 break; 371
283 case V4L2_MEMORY_OVERLAY: 372 if (get_user(p, &up->m.planes))
284 if (get_user(kp->m.offset, &up->m.offset))
285 return -EFAULT; 373 return -EFAULT;
286 break; 374
375 uplane32 = compat_ptr(p);
376 if (!access_ok(VERIFY_READ, uplane32,
377 num_planes * sizeof(struct v4l2_plane32)))
378 return -EFAULT;
379
380 /* We don't really care if userspace decides to kill itself
381 * by passing a very big num_planes value */
382 uplane = compat_alloc_user_space(num_planes *
383 sizeof(struct v4l2_plane));
384 kp->m.planes = uplane;
385
386 while (--num_planes >= 0) {
387 ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
388 if (ret)
389 return ret;
390 ++uplane;
391 ++uplane32;
392 }
393 } else {
394 switch (kp->memory) {
395 case V4L2_MEMORY_MMAP:
396 if (get_user(kp->length, &up->length) ||
397 get_user(kp->m.offset, &up->m.offset))
398 return -EFAULT;
399 break;
400 case V4L2_MEMORY_USERPTR:
401 {
402 compat_long_t tmp;
403
404 if (get_user(kp->length, &up->length) ||
405 get_user(tmp, &up->m.userptr))
406 return -EFAULT;
407
408 kp->m.userptr = (unsigned long)compat_ptr(tmp);
409 }
410 break;
411 case V4L2_MEMORY_OVERLAY:
412 if (get_user(kp->m.offset, &up->m.offset))
413 return -EFAULT;
414 break;
415 }
287 } 416 }
417
288 return 0; 418 return 0;
289} 419}
290 420
291static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) 421static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
292{ 422{
423 struct v4l2_plane32 __user *uplane32;
424 struct v4l2_plane __user *uplane;
425 compat_caddr_t p;
426 int num_planes;
427 int ret;
428
293 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) || 429 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
294 put_user(kp->index, &up->index) || 430 put_user(kp->index, &up->index) ||
295 put_user(kp->type, &up->type) || 431 put_user(kp->type, &up->type) ||
@@ -297,22 +433,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
297 put_user(kp->memory, &up->memory) || 433 put_user(kp->memory, &up->memory) ||
298 put_user(kp->input, &up->input)) 434 put_user(kp->input, &up->input))
299 return -EFAULT; 435 return -EFAULT;
300 switch (kp->memory) { 436
301 case V4L2_MEMORY_MMAP:
302 if (put_user(kp->length, &up->length) ||
303 put_user(kp->m.offset, &up->m.offset))
304 return -EFAULT;
305 break;
306 case V4L2_MEMORY_USERPTR:
307 if (put_user(kp->length, &up->length) ||
308 put_user(kp->m.userptr, &up->m.userptr))
309 return -EFAULT;
310 break;
311 case V4L2_MEMORY_OVERLAY:
312 if (put_user(kp->m.offset, &up->m.offset))
313 return -EFAULT;
314 break;
315 }
316 if (put_user(kp->bytesused, &up->bytesused) || 437 if (put_user(kp->bytesused, &up->bytesused) ||
317 put_user(kp->field, &up->field) || 438 put_user(kp->field, &up->field) ||
318 put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || 439 put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
@@ -321,6 +442,43 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
321 put_user(kp->sequence, &up->sequence) || 442 put_user(kp->sequence, &up->sequence) ||
322 put_user(kp->reserved, &up->reserved)) 443 put_user(kp->reserved, &up->reserved))
323 return -EFAULT; 444 return -EFAULT;
445
446 if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
447 num_planes = kp->length;
448 if (num_planes == 0)
449 return 0;
450
451 uplane = kp->m.planes;
452 if (get_user(p, &up->m.planes))
453 return -EFAULT;
454 uplane32 = compat_ptr(p);
455
456 while (--num_planes >= 0) {
457 ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
458 if (ret)
459 return ret;
460 ++uplane;
461 ++uplane32;
462 }
463 } else {
464 switch (kp->memory) {
465 case V4L2_MEMORY_MMAP:
466 if (put_user(kp->length, &up->length) ||
467 put_user(kp->m.offset, &up->m.offset))
468 return -EFAULT;
469 break;
470 case V4L2_MEMORY_USERPTR:
471 if (put_user(kp->length, &up->length) ||
472 put_user(kp->m.userptr, &up->m.userptr))
473 return -EFAULT;
474 break;
475 case V4L2_MEMORY_OVERLAY:
476 if (put_user(kp->m.offset, &up->m.offset))
477 return -EFAULT;
478 break;
479 }
480 }
481
324 return 0; 482 return 0;
325} 483}
326 484
@@ -442,12 +600,13 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
442 if (get_user(p, &up->controls)) 600 if (get_user(p, &up->controls))
443 return -EFAULT; 601 return -EFAULT;
444 ucontrols = compat_ptr(p); 602 ucontrols = compat_ptr(p);
445 if (!access_ok(VERIFY_READ, ucontrols, n * sizeof(struct v4l2_ext_control))) 603 if (!access_ok(VERIFY_READ, ucontrols,
604 n * sizeof(struct v4l2_ext_control32)))
446 return -EFAULT; 605 return -EFAULT;
447 kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control)); 606 kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
448 kp->controls = kcontrols; 607 kp->controls = kcontrols;
449 while (--n >= 0) { 608 while (--n >= 0) {
450 if (copy_in_user(kcontrols, ucontrols, sizeof(*kcontrols))) 609 if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
451 return -EFAULT; 610 return -EFAULT;
452 if (ctrl_is_pointer(kcontrols->id)) { 611 if (ctrl_is_pointer(kcontrols->id)) {
453 void __user *s; 612 void __user *s;
@@ -483,7 +642,8 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
483 if (get_user(p, &up->controls)) 642 if (get_user(p, &up->controls))
484 return -EFAULT; 643 return -EFAULT;
485 ucontrols = compat_ptr(p); 644 ucontrols = compat_ptr(p);
486 if (!access_ok(VERIFY_WRITE, ucontrols, n * sizeof(struct v4l2_ext_control))) 645 if (!access_ok(VERIFY_WRITE, ucontrols,
646 n * sizeof(struct v4l2_ext_control32)))
487 return -EFAULT; 647 return -EFAULT;
488 648
489 while (--n >= 0) { 649 while (--n >= 0) {
@@ -517,9 +677,6 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
517#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) 677#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
518 678
519#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32) 679#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
520#ifdef __OLD_VIDIOC_
521#define VIDIOC_OVERLAY32_OLD _IOWR('V', 14, s32)
522#endif
523#define VIDIOC_STREAMON32 _IOW ('V', 18, s32) 680#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
524#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32) 681#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32)
525#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32) 682#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32)
@@ -559,9 +716,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
559 case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break; 716 case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break;
560 case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break; 717 case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break;
561 case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; 718 case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
562#ifdef __OLD_VIDIOC_
563 case VIDIOC_OVERLAY32_OLD: cmd = VIDIOC_OVERLAY; break;
564#endif
565 case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; 719 case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
566 case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; 720 case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
567 case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; 721 case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
@@ -695,14 +849,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
695 return ret; 849 return ret;
696 850
697 switch (cmd) { 851 switch (cmd) {
698#ifdef __OLD_VIDIOC_
699 case VIDIOC_OVERLAY32_OLD:
700 case VIDIOC_S_PARM_OLD:
701 case VIDIOC_S_CTRL_OLD:
702 case VIDIOC_G_AUDIO_OLD:
703 case VIDIOC_G_AUDOUT_OLD:
704 case VIDIOC_CROPCAP_OLD:
705#endif
706 case VIDIOC_QUERYCAP: 852 case VIDIOC_QUERYCAP:
707 case VIDIOC_RESERVED: 853 case VIDIOC_RESERVED:
708 case VIDIOC_ENUM_FMT: 854 case VIDIOC_ENUM_FMT:
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index ef66d2af0c57..2412f08527aa 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -1364,6 +1364,8 @@ EXPORT_SYMBOL(v4l2_queryctrl);
1364 1364
1365int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 1365int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1366{ 1366{
1367 if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
1368 return -EINVAL;
1367 return v4l2_queryctrl(sd->ctrl_handler, qc); 1369 return v4l2_queryctrl(sd->ctrl_handler, qc);
1368} 1370}
1369EXPORT_SYMBOL(v4l2_subdev_queryctrl); 1371EXPORT_SYMBOL(v4l2_subdev_queryctrl);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 341764a3a990..498e6742579e 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -143,6 +143,7 @@ static inline void video_put(struct video_device *vdev)
143static void v4l2_device_release(struct device *cd) 143static void v4l2_device_release(struct device *cd)
144{ 144{
145 struct video_device *vdev = to_video_device(cd); 145 struct video_device *vdev = to_video_device(cd);
146 struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
146 147
147 mutex_lock(&videodev_lock); 148 mutex_lock(&videodev_lock);
148 if (video_device[vdev->minor] != vdev) { 149 if (video_device[vdev->minor] != vdev) {
@@ -169,6 +170,10 @@ static void v4l2_device_release(struct device *cd)
169 /* Release video_device and perform other 170 /* Release video_device and perform other
170 cleanups as needed. */ 171 cleanups as needed. */
171 vdev->release(vdev); 172 vdev->release(vdev);
173
174 /* Decrease v4l2_device refcount */
175 if (v4l2_dev)
176 v4l2_device_put(v4l2_dev);
172} 177}
173 178
174static struct class video_class = { 179static struct class video_class = {
@@ -182,6 +187,70 @@ struct video_device *video_devdata(struct file *file)
182} 187}
183EXPORT_SYMBOL(video_devdata); 188EXPORT_SYMBOL(video_devdata);
184 189
190
191/* Priority handling */
192
193static inline bool prio_is_valid(enum v4l2_priority prio)
194{
195 return prio == V4L2_PRIORITY_BACKGROUND ||
196 prio == V4L2_PRIORITY_INTERACTIVE ||
197 prio == V4L2_PRIORITY_RECORD;
198}
199
200void v4l2_prio_init(struct v4l2_prio_state *global)
201{
202 memset(global, 0, sizeof(*global));
203}
204EXPORT_SYMBOL(v4l2_prio_init);
205
206int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
207 enum v4l2_priority new)
208{
209 if (!prio_is_valid(new))
210 return -EINVAL;
211 if (*local == new)
212 return 0;
213
214 atomic_inc(&global->prios[new]);
215 if (prio_is_valid(*local))
216 atomic_dec(&global->prios[*local]);
217 *local = new;
218 return 0;
219}
220EXPORT_SYMBOL(v4l2_prio_change);
221
222void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
223{
224 v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
225}
226EXPORT_SYMBOL(v4l2_prio_open);
227
228void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
229{
230 if (prio_is_valid(local))
231 atomic_dec(&global->prios[local]);
232}
233EXPORT_SYMBOL(v4l2_prio_close);
234
235enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
236{
237 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
238 return V4L2_PRIORITY_RECORD;
239 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
240 return V4L2_PRIORITY_INTERACTIVE;
241 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
242 return V4L2_PRIORITY_BACKGROUND;
243 return V4L2_PRIORITY_UNSET;
244}
245EXPORT_SYMBOL(v4l2_prio_max);
246
247int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
248{
249 return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
250}
251EXPORT_SYMBOL(v4l2_prio_check);
252
253
185static ssize_t v4l2_read(struct file *filp, char __user *buf, 254static ssize_t v4l2_read(struct file *filp, char __user *buf,
186 size_t sz, loff_t *off) 255 size_t sz, loff_t *off)
187{ 256{
@@ -303,6 +372,9 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
303static int v4l2_open(struct inode *inode, struct file *filp) 372static int v4l2_open(struct inode *inode, struct file *filp)
304{ 373{
305 struct video_device *vdev; 374 struct video_device *vdev;
375#if defined(CONFIG_MEDIA_CONTROLLER)
376 struct media_entity *entity = NULL;
377#endif
306 int ret = 0; 378 int ret = 0;
307 379
308 /* Check if the video device is available */ 380 /* Check if the video device is available */
@@ -316,6 +388,16 @@ static int v4l2_open(struct inode *inode, struct file *filp)
316 /* and increase the device refcount */ 388 /* and increase the device refcount */
317 video_get(vdev); 389 video_get(vdev);
318 mutex_unlock(&videodev_lock); 390 mutex_unlock(&videodev_lock);
391#if defined(CONFIG_MEDIA_CONTROLLER)
392 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
393 entity = media_entity_get(&vdev->entity);
394 if (!entity) {
395 ret = -EBUSY;
396 video_put(vdev);
397 return ret;
398 }
399 }
400#endif
319 if (vdev->fops->open) { 401 if (vdev->fops->open) {
320 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { 402 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
321 ret = -ERESTARTSYS; 403 ret = -ERESTARTSYS;
@@ -331,8 +413,13 @@ static int v4l2_open(struct inode *inode, struct file *filp)
331 413
332err: 414err:
333 /* decrease the refcount in case of an error */ 415 /* decrease the refcount in case of an error */
334 if (ret) 416 if (ret) {
417#if defined(CONFIG_MEDIA_CONTROLLER)
418 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
419 media_entity_put(entity);
420#endif
335 video_put(vdev); 421 video_put(vdev);
422 }
336 return ret; 423 return ret;
337} 424}
338 425
@@ -349,7 +436,10 @@ static int v4l2_release(struct inode *inode, struct file *filp)
349 if (vdev->lock) 436 if (vdev->lock)
350 mutex_unlock(vdev->lock); 437 mutex_unlock(vdev->lock);
351 } 438 }
352 439#if defined(CONFIG_MEDIA_CONTROLLER)
440 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
441 media_entity_put(&vdev->entity);
442#endif
353 /* decrease the refcount unconditionally since the release() 443 /* decrease the refcount unconditionally since the release()
354 return value is ignored. */ 444 return value is ignored. */
355 video_put(vdev); 445 video_put(vdev);
@@ -408,13 +498,14 @@ static int get_index(struct video_device *vdev)
408} 498}
409 499
410/** 500/**
411 * video_register_device - register video4linux devices 501 * __video_register_device - register video4linux devices
412 * @vdev: video device structure we want to register 502 * @vdev: video device structure we want to register
413 * @type: type of device to register 503 * @type: type of device to register
414 * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ... 504 * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ...
415 * -1 == first free) 505 * -1 == first free)
416 * @warn_if_nr_in_use: warn if the desired device node number 506 * @warn_if_nr_in_use: warn if the desired device node number
417 * was already in use and another number was chosen instead. 507 * was already in use and another number was chosen instead.
508 * @owner: module that owns the video device node
418 * 509 *
419 * The registration code assigns minor numbers and device node numbers 510 * The registration code assigns minor numbers and device node numbers
420 * based on the requested type and registers the new device node with 511 * based on the requested type and registers the new device node with
@@ -435,9 +526,11 @@ static int get_index(struct video_device *vdev)
435 * %VFL_TYPE_VBI - Vertical blank data (undecoded) 526 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
436 * 527 *
437 * %VFL_TYPE_RADIO - A radio card 528 * %VFL_TYPE_RADIO - A radio card
529 *
530 * %VFL_TYPE_SUBDEV - A subdevice
438 */ 531 */
439static int __video_register_device(struct video_device *vdev, int type, int nr, 532int __video_register_device(struct video_device *vdev, int type, int nr,
440 int warn_if_nr_in_use) 533 int warn_if_nr_in_use, struct module *owner)
441{ 534{
442 int i = 0; 535 int i = 0;
443 int ret; 536 int ret;
@@ -469,6 +562,9 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
469 case VFL_TYPE_RADIO: 562 case VFL_TYPE_RADIO:
470 name_base = "radio"; 563 name_base = "radio";
471 break; 564 break;
565 case VFL_TYPE_SUBDEV:
566 name_base = "v4l-subdev";
567 break;
472 default: 568 default:
473 printk(KERN_ERR "%s called with unknown type: %d\n", 569 printk(KERN_ERR "%s called with unknown type: %d\n",
474 __func__, type); 570 __func__, type);
@@ -482,6 +578,10 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
482 vdev->parent = vdev->v4l2_dev->dev; 578 vdev->parent = vdev->v4l2_dev->dev;
483 if (vdev->ctrl_handler == NULL) 579 if (vdev->ctrl_handler == NULL)
484 vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler; 580 vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
581 /* If the prio state pointer is NULL, then use the v4l2_device
582 prio state. */
583 if (vdev->prio == NULL)
584 vdev->prio = &vdev->v4l2_dev->prio;
485 } 585 }
486 586
487 /* Part 2: find a free minor, device node number and device index. */ 587 /* Part 2: find a free minor, device node number and device index. */
@@ -552,7 +652,7 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
552 goto cleanup; 652 goto cleanup;
553 } 653 }
554 vdev->cdev->ops = &v4l2_fops; 654 vdev->cdev->ops = &v4l2_fops;
555 vdev->cdev->owner = vdev->fops->owner; 655 vdev->cdev->owner = owner;
556 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); 656 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
557 if (ret < 0) { 657 if (ret < 0) {
558 printk(KERN_ERR "%s: cdev_add failed\n", __func__); 658 printk(KERN_ERR "%s: cdev_add failed\n", __func__);
@@ -580,11 +680,31 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
580 printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__, 680 printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
581 name_base, nr, video_device_node_name(vdev)); 681 name_base, nr, video_device_node_name(vdev));
582 682
583 /* Part 5: Activate this minor. The char device can now be used. */ 683 /* Increase v4l2_device refcount */
684 if (vdev->v4l2_dev)
685 v4l2_device_get(vdev->v4l2_dev);
686
687#if defined(CONFIG_MEDIA_CONTROLLER)
688 /* Part 5: Register the entity. */
689 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
690 vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
691 vdev->entity.name = vdev->name;
692 vdev->entity.v4l.major = VIDEO_MAJOR;
693 vdev->entity.v4l.minor = vdev->minor;
694 ret = media_device_register_entity(vdev->v4l2_dev->mdev,
695 &vdev->entity);
696 if (ret < 0)
697 printk(KERN_WARNING
698 "%s: media_device_register_entity failed\n",
699 __func__);
700 }
701#endif
702 /* Part 6: Activate this minor. The char device can now be used. */
584 set_bit(V4L2_FL_REGISTERED, &vdev->flags); 703 set_bit(V4L2_FL_REGISTERED, &vdev->flags);
585 mutex_lock(&videodev_lock); 704 mutex_lock(&videodev_lock);
586 video_device[vdev->minor] = vdev; 705 video_device[vdev->minor] = vdev;
587 mutex_unlock(&videodev_lock); 706 mutex_unlock(&videodev_lock);
707
588 return 0; 708 return 0;
589 709
590cleanup: 710cleanup:
@@ -597,18 +717,7 @@ cleanup:
597 vdev->minor = -1; 717 vdev->minor = -1;
598 return ret; 718 return ret;
599} 719}
600 720EXPORT_SYMBOL(__video_register_device);
601int video_register_device(struct video_device *vdev, int type, int nr)
602{
603 return __video_register_device(vdev, type, nr, 1);
604}
605EXPORT_SYMBOL(video_register_device);
606
607int video_register_device_no_warn(struct video_device *vdev, int type, int nr)
608{
609 return __video_register_device(vdev, type, nr, 0);
610}
611EXPORT_SYMBOL(video_register_device_no_warn);
612 721
613/** 722/**
614 * video_unregister_device - unregister a video4linux device 723 * video_unregister_device - unregister a video4linux device
@@ -623,6 +732,11 @@ void video_unregister_device(struct video_device *vdev)
623 if (!vdev || !video_is_registered(vdev)) 732 if (!vdev || !video_is_registered(vdev))
624 return; 733 return;
625 734
735#if defined(CONFIG_MEDIA_CONTROLLER)
736 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
737 media_device_unregister_entity(&vdev->entity);
738#endif
739
626 mutex_lock(&videodev_lock); 740 mutex_lock(&videodev_lock);
627 /* This must be in a critical section to prevent a race with v4l2_open. 741 /* This must be in a critical section to prevent a race with v4l2_open.
628 * Once this bit has been cleared video_get may never be called again. 742 * Once this bit has been cleared video_get may never be called again.
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index ce64fe16bc60..5aeaf876ba9b 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -36,6 +36,8 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
36 INIT_LIST_HEAD(&v4l2_dev->subdevs); 36 INIT_LIST_HEAD(&v4l2_dev->subdevs);
37 spin_lock_init(&v4l2_dev->lock); 37 spin_lock_init(&v4l2_dev->lock);
38 mutex_init(&v4l2_dev->ioctl_lock); 38 mutex_init(&v4l2_dev->ioctl_lock);
39 v4l2_prio_init(&v4l2_dev->prio);
40 kref_init(&v4l2_dev->ref);
39 v4l2_dev->dev = dev; 41 v4l2_dev->dev = dev;
40 if (dev == NULL) { 42 if (dev == NULL) {
41 /* If dev == NULL, then name must be filled in by the caller */ 43 /* If dev == NULL, then name must be filled in by the caller */
@@ -47,13 +49,27 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
47 if (!v4l2_dev->name[0]) 49 if (!v4l2_dev->name[0])
48 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", 50 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
49 dev->driver->name, dev_name(dev)); 51 dev->driver->name, dev_name(dev));
50 if (dev_get_drvdata(dev)) 52 if (!dev_get_drvdata(dev))
51 v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n"); 53 dev_set_drvdata(dev, v4l2_dev);
52 dev_set_drvdata(dev, v4l2_dev);
53 return 0; 54 return 0;
54} 55}
55EXPORT_SYMBOL_GPL(v4l2_device_register); 56EXPORT_SYMBOL_GPL(v4l2_device_register);
56 57
58static void v4l2_device_release(struct kref *ref)
59{
60 struct v4l2_device *v4l2_dev =
61 container_of(ref, struct v4l2_device, ref);
62
63 if (v4l2_dev->release)
64 v4l2_dev->release(v4l2_dev);
65}
66
67int v4l2_device_put(struct v4l2_device *v4l2_dev)
68{
69 return kref_put(&v4l2_dev->ref, v4l2_device_release);
70}
71EXPORT_SYMBOL_GPL(v4l2_device_put);
72
57int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, 73int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
58 atomic_t *instance) 74 atomic_t *instance)
59{ 75{
@@ -72,10 +88,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_set_name);
72 88
73void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) 89void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
74{ 90{
75 if (v4l2_dev->dev) { 91 if (v4l2_dev->dev == NULL)
92 return;
93
94 if (dev_get_drvdata(v4l2_dev->dev) == v4l2_dev)
76 dev_set_drvdata(v4l2_dev->dev, NULL); 95 dev_set_drvdata(v4l2_dev->dev, NULL);
77 v4l2_dev->dev = NULL; 96 v4l2_dev->dev = NULL;
78 }
79} 97}
80EXPORT_SYMBOL_GPL(v4l2_device_disconnect); 98EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
81 99
@@ -117,23 +135,30 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
117EXPORT_SYMBOL_GPL(v4l2_device_unregister); 135EXPORT_SYMBOL_GPL(v4l2_device_unregister);
118 136
119int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, 137int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
120 struct v4l2_subdev *sd) 138 struct v4l2_subdev *sd)
121{ 139{
140#if defined(CONFIG_MEDIA_CONTROLLER)
141 struct media_entity *entity = &sd->entity;
142#endif
122 int err; 143 int err;
123 144
124 /* Check for valid input */ 145 /* Check for valid input */
125 if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) 146 if (v4l2_dev == NULL || sd == NULL || !sd->name[0])
126 return -EINVAL; 147 return -EINVAL;
148
127 /* Warn if we apparently re-register a subdev */ 149 /* Warn if we apparently re-register a subdev */
128 WARN_ON(sd->v4l2_dev != NULL); 150 WARN_ON(sd->v4l2_dev != NULL);
151
129 if (!try_module_get(sd->owner)) 152 if (!try_module_get(sd->owner))
130 return -ENODEV; 153 return -ENODEV;
154
131 sd->v4l2_dev = v4l2_dev; 155 sd->v4l2_dev = v4l2_dev;
132 if (sd->internal_ops && sd->internal_ops->registered) { 156 if (sd->internal_ops && sd->internal_ops->registered) {
133 err = sd->internal_ops->registered(sd); 157 err = sd->internal_ops->registered(sd);
134 if (err) 158 if (err)
135 return err; 159 return err;
136 } 160 }
161
137 /* This just returns 0 if either of the two args is NULL */ 162 /* This just returns 0 if either of the two args is NULL */
138 err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler); 163 err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
139 if (err) { 164 if (err) {
@@ -141,24 +166,82 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
141 sd->internal_ops->unregistered(sd); 166 sd->internal_ops->unregistered(sd);
142 return err; 167 return err;
143 } 168 }
169
170#if defined(CONFIG_MEDIA_CONTROLLER)
171 /* Register the entity. */
172 if (v4l2_dev->mdev) {
173 err = media_device_register_entity(v4l2_dev->mdev, entity);
174 if (err < 0) {
175 if (sd->internal_ops && sd->internal_ops->unregistered)
176 sd->internal_ops->unregistered(sd);
177 module_put(sd->owner);
178 return err;
179 }
180 }
181#endif
182
144 spin_lock(&v4l2_dev->lock); 183 spin_lock(&v4l2_dev->lock);
145 list_add_tail(&sd->list, &v4l2_dev->subdevs); 184 list_add_tail(&sd->list, &v4l2_dev->subdevs);
146 spin_unlock(&v4l2_dev->lock); 185 spin_unlock(&v4l2_dev->lock);
186
147 return 0; 187 return 0;
148} 188}
149EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); 189EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
150 190
191int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
192{
193 struct video_device *vdev;
194 struct v4l2_subdev *sd;
195 int err;
196
197 /* Register a device node for every subdev marked with the
198 * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
199 */
200 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
201 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
202 continue;
203
204 vdev = &sd->devnode;
205 strlcpy(vdev->name, sd->name, sizeof(vdev->name));
206 vdev->v4l2_dev = v4l2_dev;
207 vdev->fops = &v4l2_subdev_fops;
208 vdev->release = video_device_release_empty;
209 err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
210 sd->owner);
211 if (err < 0)
212 return err;
213#if defined(CONFIG_MEDIA_CONTROLLER)
214 sd->entity.v4l.major = VIDEO_MAJOR;
215 sd->entity.v4l.minor = vdev->minor;
216#endif
217 }
218 return 0;
219}
220EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
221
151void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) 222void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
152{ 223{
224 struct v4l2_device *v4l2_dev;
225
153 /* return if it isn't registered */ 226 /* return if it isn't registered */
154 if (sd == NULL || sd->v4l2_dev == NULL) 227 if (sd == NULL || sd->v4l2_dev == NULL)
155 return; 228 return;
156 spin_lock(&sd->v4l2_dev->lock); 229
230 v4l2_dev = sd->v4l2_dev;
231
232 spin_lock(&v4l2_dev->lock);
157 list_del(&sd->list); 233 list_del(&sd->list);
158 spin_unlock(&sd->v4l2_dev->lock); 234 spin_unlock(&v4l2_dev->lock);
235
159 if (sd->internal_ops && sd->internal_ops->unregistered) 236 if (sd->internal_ops && sd->internal_ops->unregistered)
160 sd->internal_ops->unregistered(sd); 237 sd->internal_ops->unregistered(sd);
161 sd->v4l2_dev = NULL; 238 sd->v4l2_dev = NULL;
239
240#if defined(CONFIG_MEDIA_CONTROLLER)
241 if (v4l2_dev->mdev)
242 media_device_unregister_entity(&sd->entity);
243#endif
244 video_unregister_device(&sd->devnode);
162 module_put(sd->owner); 245 module_put(sd->owner);
163} 246}
164EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); 247EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-fh.c b/drivers/media/video/v4l2-fh.c
index d78f184f40c5..717f71e6370e 100644
--- a/drivers/media/video/v4l2-fh.c
+++ b/drivers/media/video/v4l2-fh.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26#include <linux/slab.h>
26#include <media/v4l2-dev.h> 27#include <media/v4l2-dev.h>
27#include <media/v4l2-fh.h> 28#include <media/v4l2-fh.h>
28#include <media/v4l2-event.h> 29#include <media/v4l2-event.h>
@@ -33,6 +34,7 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
33 fh->vdev = vdev; 34 fh->vdev = vdev;
34 INIT_LIST_HEAD(&fh->list); 35 INIT_LIST_HEAD(&fh->list);
35 set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags); 36 set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
37 fh->prio = V4L2_PRIORITY_UNSET;
36 38
37 /* 39 /*
38 * fh->events only needs to be initialized if the driver 40 * fh->events only needs to be initialized if the driver
@@ -51,12 +53,28 @@ void v4l2_fh_add(struct v4l2_fh *fh)
51{ 53{
52 unsigned long flags; 54 unsigned long flags;
53 55
56 if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
57 v4l2_prio_open(fh->vdev->prio, &fh->prio);
54 spin_lock_irqsave(&fh->vdev->fh_lock, flags); 58 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
55 list_add(&fh->list, &fh->vdev->fh_list); 59 list_add(&fh->list, &fh->vdev->fh_list);
56 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); 60 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
57} 61}
58EXPORT_SYMBOL_GPL(v4l2_fh_add); 62EXPORT_SYMBOL_GPL(v4l2_fh_add);
59 63
64int v4l2_fh_open(struct file *filp)
65{
66 struct video_device *vdev = video_devdata(filp);
67 struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
68
69 filp->private_data = fh;
70 if (fh == NULL)
71 return -ENOMEM;
72 v4l2_fh_init(fh, vdev);
73 v4l2_fh_add(fh);
74 return 0;
75}
76EXPORT_SYMBOL_GPL(v4l2_fh_open);
77
60void v4l2_fh_del(struct v4l2_fh *fh) 78void v4l2_fh_del(struct v4l2_fh *fh)
61{ 79{
62 unsigned long flags; 80 unsigned long flags;
@@ -64,6 +82,8 @@ void v4l2_fh_del(struct v4l2_fh *fh)
64 spin_lock_irqsave(&fh->vdev->fh_lock, flags); 82 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
65 list_del_init(&fh->list); 83 list_del_init(&fh->list);
66 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); 84 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
85 if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
86 v4l2_prio_close(fh->vdev->prio, fh->prio);
67} 87}
68EXPORT_SYMBOL_GPL(v4l2_fh_del); 88EXPORT_SYMBOL_GPL(v4l2_fh_del);
69 89
@@ -77,3 +97,30 @@ void v4l2_fh_exit(struct v4l2_fh *fh)
77 v4l2_event_free(fh); 97 v4l2_event_free(fh);
78} 98}
79EXPORT_SYMBOL_GPL(v4l2_fh_exit); 99EXPORT_SYMBOL_GPL(v4l2_fh_exit);
100
101int v4l2_fh_release(struct file *filp)
102{
103 struct v4l2_fh *fh = filp->private_data;
104
105 if (fh) {
106 v4l2_fh_del(fh);
107 v4l2_fh_exit(fh);
108 kfree(fh);
109 }
110 return 0;
111}
112EXPORT_SYMBOL_GPL(v4l2_fh_release);
113
114int v4l2_fh_is_singular(struct v4l2_fh *fh)
115{
116 unsigned long flags;
117 int is_singular;
118
119 if (fh == NULL || fh->vdev == NULL)
120 return 0;
121 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
122 is_singular = list_is_singular(&fh->list);
123 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
124 return is_singular;
125}
126EXPORT_SYMBOL_GPL(v4l2_fh_is_singular);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index f51327ef6757..a01ed39e6c16 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -17,7 +17,6 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19 19
20#define __OLD_VIDIOC_ /* To allow fixing old calls */
21#include <linux/videodev2.h> 20#include <linux/videodev2.h>
22 21
23#include <media/v4l2-common.h> 22#include <media/v4l2-common.h>
@@ -25,6 +24,7 @@
25#include <media/v4l2-ctrls.h> 24#include <media/v4l2-ctrls.h>
26#include <media/v4l2-fh.h> 25#include <media/v4l2-fh.h>
27#include <media/v4l2-event.h> 26#include <media/v4l2-event.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-chip-ident.h> 28#include <media/v4l2-chip-ident.h>
29 29
30#define dbgarg(cmd, fmt, arg...) \ 30#define dbgarg(cmd, fmt, arg...) \
@@ -165,6 +165,8 @@ const char *v4l2_type_names[] = {
165 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", 165 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
166 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", 166 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
167 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", 167 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
168 [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
169 [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
168}; 170};
169EXPORT_SYMBOL(v4l2_type_names); 171EXPORT_SYMBOL(v4l2_type_names);
170 172
@@ -293,153 +295,37 @@ void v4l_printk_ioctl(unsigned int cmd)
293} 295}
294EXPORT_SYMBOL(v4l_printk_ioctl); 296EXPORT_SYMBOL(v4l_printk_ioctl);
295 297
296/*
297 * helper function -- handles userspace copying for ioctl arguments
298 */
299
300#ifdef __OLD_VIDIOC_
301static unsigned int
302video_fix_command(unsigned int cmd)
303{
304 switch (cmd) {
305 case VIDIOC_OVERLAY_OLD:
306 cmd = VIDIOC_OVERLAY;
307 break;
308 case VIDIOC_S_PARM_OLD:
309 cmd = VIDIOC_S_PARM;
310 break;
311 case VIDIOC_S_CTRL_OLD:
312 cmd = VIDIOC_S_CTRL;
313 break;
314 case VIDIOC_G_AUDIO_OLD:
315 cmd = VIDIOC_G_AUDIO;
316 break;
317 case VIDIOC_G_AUDOUT_OLD:
318 cmd = VIDIOC_G_AUDOUT;
319 break;
320 case VIDIOC_CROPCAP_OLD:
321 cmd = VIDIOC_CROPCAP;
322 break;
323 }
324 return cmd;
325}
326#endif
327
328/*
329 * Obsolete usercopy function - Should be removed soon
330 */
331long
332video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
333 v4l2_kioctl func)
334{
335 char sbuf[128];
336 void *mbuf = NULL;
337 void *parg = NULL;
338 long err = -EINVAL;
339 int is_ext_ctrl;
340 size_t ctrls_size = 0;
341 void __user *user_ptr = NULL;
342
343#ifdef __OLD_VIDIOC_
344 cmd = video_fix_command(cmd);
345#endif
346 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
347 cmd == VIDIOC_TRY_EXT_CTRLS);
348
349 /* Copy arguments into temp kernel buffer */
350 switch (_IOC_DIR(cmd)) {
351 case _IOC_NONE:
352 parg = NULL;
353 break;
354 case _IOC_READ:
355 case _IOC_WRITE:
356 case (_IOC_WRITE | _IOC_READ):
357 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
358 parg = sbuf;
359 } else {
360 /* too big to allocate from stack */
361 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
362 if (NULL == mbuf)
363 return -ENOMEM;
364 parg = mbuf;
365 }
366
367 err = -EFAULT;
368 if (_IOC_DIR(cmd) & _IOC_WRITE)
369 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
370 goto out;
371 break;
372 }
373 if (is_ext_ctrl) {
374 struct v4l2_ext_controls *p = parg;
375
376 /* In case of an error, tell the caller that it wasn't
377 a specific control that caused it. */
378 p->error_idx = p->count;
379 user_ptr = (void __user *)p->controls;
380 if (p->count) {
381 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
382 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
383 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
384 err = -ENOMEM;
385 if (NULL == mbuf)
386 goto out_ext_ctrl;
387 err = -EFAULT;
388 if (copy_from_user(mbuf, user_ptr, ctrls_size))
389 goto out_ext_ctrl;
390 p->controls = mbuf;
391 }
392 }
393
394 /* call driver */
395 err = func(file, cmd, parg);
396 if (err == -ENOIOCTLCMD)
397 err = -EINVAL;
398 if (is_ext_ctrl) {
399 struct v4l2_ext_controls *p = parg;
400
401 p->controls = (void *)user_ptr;
402 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
403 err = -EFAULT;
404 goto out_ext_ctrl;
405 }
406 if (err < 0)
407 goto out;
408
409out_ext_ctrl:
410 /* Copy results into user buffer */
411 switch (_IOC_DIR(cmd)) {
412 case _IOC_READ:
413 case (_IOC_WRITE | _IOC_READ):
414 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
415 err = -EFAULT;
416 break;
417 }
418
419out:
420 kfree(mbuf);
421 return err;
422}
423EXPORT_SYMBOL(video_usercopy);
424
425static void dbgbuf(unsigned int cmd, struct video_device *vfd, 298static void dbgbuf(unsigned int cmd, struct video_device *vfd,
426 struct v4l2_buffer *p) 299 struct v4l2_buffer *p)
427{ 300{
428 struct v4l2_timecode *tc = &p->timecode; 301 struct v4l2_timecode *tc = &p->timecode;
302 struct v4l2_plane *plane;
303 int i;
429 304
430 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " 305 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
431 "bytesused=%d, flags=0x%08d, " 306 "flags=0x%08d, field=%0d, sequence=%d, memory=%s\n",
432 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
433 p->timestamp.tv_sec / 3600, 307 p->timestamp.tv_sec / 3600,
434 (int)(p->timestamp.tv_sec / 60) % 60, 308 (int)(p->timestamp.tv_sec / 60) % 60,
435 (int)(p->timestamp.tv_sec % 60), 309 (int)(p->timestamp.tv_sec % 60),
436 (long)p->timestamp.tv_usec, 310 (long)p->timestamp.tv_usec,
437 p->index, 311 p->index,
438 prt_names(p->type, v4l2_type_names), 312 prt_names(p->type, v4l2_type_names),
439 p->bytesused, p->flags, 313 p->flags, p->field, p->sequence,
440 p->field, p->sequence, 314 prt_names(p->memory, v4l2_memory_names));
441 prt_names(p->memory, v4l2_memory_names), 315
442 p->m.userptr, p->length); 316 if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
317 for (i = 0; i < p->length; ++i) {
318 plane = &p->m.planes[i];
319 dbgarg2("plane %d: bytesused=%d, data_offset=0x%08x "
320 "offset/userptr=0x%08lx, length=%d\n",
321 i, plane->bytesused, plane->data_offset,
322 plane->m.userptr, plane->length);
323 }
324 } else {
325 dbgarg2("bytesused=%d, offset/userptr=0x%08lx, length=%d\n",
326 p->bytesused, p->m.userptr, p->length);
327 }
328
443 dbgarg2("timecode=%02d:%02d:%02d type=%d, " 329 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
444 "flags=0x%08d, frames=%d, userbits=0x%08x\n", 330 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
445 tc->hours, tc->minutes, tc->seconds, 331 tc->hours, tc->minutes, tc->seconds,
@@ -467,6 +353,27 @@ static inline void v4l_print_pix_fmt(struct video_device *vfd,
467 fmt->bytesperline, fmt->sizeimage, fmt->colorspace); 353 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
468}; 354};
469 355
356static inline void v4l_print_pix_fmt_mplane(struct video_device *vfd,
357 struct v4l2_pix_format_mplane *fmt)
358{
359 int i;
360
361 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
362 "colorspace=%d, num_planes=%d\n",
363 fmt->width, fmt->height,
364 (fmt->pixelformat & 0xff),
365 (fmt->pixelformat >> 8) & 0xff,
366 (fmt->pixelformat >> 16) & 0xff,
367 (fmt->pixelformat >> 24) & 0xff,
368 prt_names(fmt->field, v4l2_field_names),
369 fmt->colorspace, fmt->num_planes);
370
371 for (i = 0; i < fmt->num_planes; ++i)
372 dbgarg2("plane %d: bytesperline=%d sizeimage=%d\n", i,
373 fmt->plane_fmt[i].bytesperline,
374 fmt->plane_fmt[i].sizeimage);
375}
376
470static inline void v4l_print_ext_ctrls(unsigned int cmd, 377static inline void v4l_print_ext_ctrls(unsigned int cmd,
471 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) 378 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
472{ 379{
@@ -520,7 +427,12 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
520 427
521 switch (type) { 428 switch (type) {
522 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 429 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
523 if (ops->vidioc_g_fmt_vid_cap) 430 if (ops->vidioc_g_fmt_vid_cap ||
431 ops->vidioc_g_fmt_vid_cap_mplane)
432 return 0;
433 break;
434 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
435 if (ops->vidioc_g_fmt_vid_cap_mplane)
524 return 0; 436 return 0;
525 break; 437 break;
526 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 438 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -528,7 +440,12 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
528 return 0; 440 return 0;
529 break; 441 break;
530 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 442 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
531 if (ops->vidioc_g_fmt_vid_out) 443 if (ops->vidioc_g_fmt_vid_out ||
444 ops->vidioc_g_fmt_vid_out_mplane)
445 return 0;
446 break;
447 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
448 if (ops->vidioc_g_fmt_vid_out_mplane)
532 return 0; 449 return 0;
533 break; 450 break;
534 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 451 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
@@ -559,12 +476,72 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
559 return -EINVAL; 476 return -EINVAL;
560} 477}
561 478
479/**
480 * fmt_sp_to_mp() - Convert a single-plane format to its multi-planar 1-plane
481 * equivalent
482 */
483static int fmt_sp_to_mp(const struct v4l2_format *f_sp,
484 struct v4l2_format *f_mp)
485{
486 struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp;
487 const struct v4l2_pix_format *pix = &f_sp->fmt.pix;
488
489 if (f_sp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
490 f_mp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
491 else if (f_sp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
492 f_mp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
493 else
494 return -EINVAL;
495
496 pix_mp->width = pix->width;
497 pix_mp->height = pix->height;
498 pix_mp->pixelformat = pix->pixelformat;
499 pix_mp->field = pix->field;
500 pix_mp->colorspace = pix->colorspace;
501 pix_mp->num_planes = 1;
502 pix_mp->plane_fmt[0].sizeimage = pix->sizeimage;
503 pix_mp->plane_fmt[0].bytesperline = pix->bytesperline;
504
505 return 0;
506}
507
508/**
509 * fmt_mp_to_sp() - Convert a multi-planar 1-plane format to its single-planar
510 * equivalent
511 */
512static int fmt_mp_to_sp(const struct v4l2_format *f_mp,
513 struct v4l2_format *f_sp)
514{
515 const struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp;
516 struct v4l2_pix_format *pix = &f_sp->fmt.pix;
517
518 if (f_mp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
519 f_sp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
520 else if (f_mp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
521 f_sp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
522 else
523 return -EINVAL;
524
525 pix->width = pix_mp->width;
526 pix->height = pix_mp->height;
527 pix->pixelformat = pix_mp->pixelformat;
528 pix->field = pix_mp->field;
529 pix->colorspace = pix_mp->colorspace;
530 pix->sizeimage = pix_mp->plane_fmt[0].sizeimage;
531 pix->bytesperline = pix_mp->plane_fmt[0].bytesperline;
532
533 return 0;
534}
535
562static long __video_do_ioctl(struct file *file, 536static long __video_do_ioctl(struct file *file,
563 unsigned int cmd, void *arg) 537 unsigned int cmd, void *arg)
564{ 538{
565 struct video_device *vfd = video_devdata(file); 539 struct video_device *vfd = video_devdata(file);
566 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 540 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
567 void *fh = file->private_data; 541 void *fh = file->private_data;
542 struct v4l2_fh *vfh = NULL;
543 struct v4l2_format f_copy;
544 int use_fh_prio = 0;
568 long ret = -EINVAL; 545 long ret = -EINVAL;
569 546
570 if (ops == NULL) { 547 if (ops == NULL) {
@@ -579,6 +556,45 @@ static long __video_do_ioctl(struct file *file,
579 printk(KERN_CONT "\n"); 556 printk(KERN_CONT "\n");
580 } 557 }
581 558
559 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
560 vfh = file->private_data;
561 use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
562 }
563
564 if (use_fh_prio) {
565 switch (cmd) {
566 case VIDIOC_S_CTRL:
567 case VIDIOC_S_STD:
568 case VIDIOC_S_INPUT:
569 case VIDIOC_S_OUTPUT:
570 case VIDIOC_S_TUNER:
571 case VIDIOC_S_FREQUENCY:
572 case VIDIOC_S_FMT:
573 case VIDIOC_S_CROP:
574 case VIDIOC_S_AUDIO:
575 case VIDIOC_S_AUDOUT:
576 case VIDIOC_S_EXT_CTRLS:
577 case VIDIOC_S_FBUF:
578 case VIDIOC_S_PRIORITY:
579 case VIDIOC_S_DV_PRESET:
580 case VIDIOC_S_DV_TIMINGS:
581 case VIDIOC_S_JPEGCOMP:
582 case VIDIOC_S_MODULATOR:
583 case VIDIOC_S_PARM:
584 case VIDIOC_S_HW_FREQ_SEEK:
585 case VIDIOC_ENCODER_CMD:
586 case VIDIOC_OVERLAY:
587 case VIDIOC_REQBUFS:
588 case VIDIOC_STREAMON:
589 case VIDIOC_STREAMOFF:
590 ret = v4l2_prio_check(vfd->prio, vfh->prio);
591 if (ret)
592 goto exit_prio;
593 ret = -EINVAL;
594 break;
595 }
596 }
597
582 switch (cmd) { 598 switch (cmd) {
583 599
584 /* --- capabilities ------------------------------------------ */ 600 /* --- capabilities ------------------------------------------ */
@@ -605,9 +621,12 @@ static long __video_do_ioctl(struct file *file,
605 { 621 {
606 enum v4l2_priority *p = arg; 622 enum v4l2_priority *p = arg;
607 623
608 if (!ops->vidioc_g_priority) 624 if (ops->vidioc_g_priority) {
609 break; 625 ret = ops->vidioc_g_priority(file, fh, p);
610 ret = ops->vidioc_g_priority(file, fh, p); 626 } else if (use_fh_prio) {
627 *p = v4l2_prio_max(&vfd->v4l2_dev->prio);
628 ret = 0;
629 }
611 if (!ret) 630 if (!ret)
612 dbgarg(cmd, "priority is %d\n", *p); 631 dbgarg(cmd, "priority is %d\n", *p);
613 break; 632 break;
@@ -616,10 +635,13 @@ static long __video_do_ioctl(struct file *file,
616 { 635 {
617 enum v4l2_priority *p = arg; 636 enum v4l2_priority *p = arg;
618 637
619 if (!ops->vidioc_s_priority) 638 if (!ops->vidioc_s_priority && !use_fh_prio)
620 break; 639 break;
621 dbgarg(cmd, "setting priority to %d\n", *p); 640 dbgarg(cmd, "setting priority to %d\n", *p);
622 ret = ops->vidioc_s_priority(file, fh, *p); 641 if (ops->vidioc_s_priority)
642 ret = ops->vidioc_s_priority(file, fh, *p);
643 else
644 ret = v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p);
623 break; 645 break;
624 } 646 }
625 647
@@ -633,6 +655,11 @@ static long __video_do_ioctl(struct file *file,
633 if (ops->vidioc_enum_fmt_vid_cap) 655 if (ops->vidioc_enum_fmt_vid_cap)
634 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); 656 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
635 break; 657 break;
658 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
659 if (ops->vidioc_enum_fmt_vid_cap_mplane)
660 ret = ops->vidioc_enum_fmt_vid_cap_mplane(file,
661 fh, f);
662 break;
636 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 663 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
637 if (ops->vidioc_enum_fmt_vid_overlay) 664 if (ops->vidioc_enum_fmt_vid_overlay)
638 ret = ops->vidioc_enum_fmt_vid_overlay(file, 665 ret = ops->vidioc_enum_fmt_vid_overlay(file,
@@ -642,6 +669,11 @@ static long __video_do_ioctl(struct file *file,
642 if (ops->vidioc_enum_fmt_vid_out) 669 if (ops->vidioc_enum_fmt_vid_out)
643 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); 670 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
644 break; 671 break;
672 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
673 if (ops->vidioc_enum_fmt_vid_out_mplane)
674 ret = ops->vidioc_enum_fmt_vid_out_mplane(file,
675 fh, f);
676 break;
645 case V4L2_BUF_TYPE_PRIVATE: 677 case V4L2_BUF_TYPE_PRIVATE:
646 if (ops->vidioc_enum_fmt_type_private) 678 if (ops->vidioc_enum_fmt_type_private)
647 ret = ops->vidioc_enum_fmt_type_private(file, 679 ret = ops->vidioc_enum_fmt_type_private(file,
@@ -670,22 +702,90 @@ static long __video_do_ioctl(struct file *file,
670 702
671 switch (f->type) { 703 switch (f->type) {
672 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 704 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
673 if (ops->vidioc_g_fmt_vid_cap) 705 if (ops->vidioc_g_fmt_vid_cap) {
674 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); 706 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
707 } else if (ops->vidioc_g_fmt_vid_cap_mplane) {
708 if (fmt_sp_to_mp(f, &f_copy))
709 break;
710 ret = ops->vidioc_g_fmt_vid_cap_mplane(file, fh,
711 &f_copy);
712 if (ret)
713 break;
714
715 /* Driver is currently in multi-planar format,
716 * we can't return it in single-planar API*/
717 if (f_copy.fmt.pix_mp.num_planes > 1) {
718 ret = -EBUSY;
719 break;
720 }
721
722 ret = fmt_mp_to_sp(&f_copy, f);
723 }
675 if (!ret) 724 if (!ret)
676 v4l_print_pix_fmt(vfd, &f->fmt.pix); 725 v4l_print_pix_fmt(vfd, &f->fmt.pix);
677 break; 726 break;
727 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
728 if (ops->vidioc_g_fmt_vid_cap_mplane) {
729 ret = ops->vidioc_g_fmt_vid_cap_mplane(file,
730 fh, f);
731 } else if (ops->vidioc_g_fmt_vid_cap) {
732 if (fmt_mp_to_sp(f, &f_copy))
733 break;
734 ret = ops->vidioc_g_fmt_vid_cap(file,
735 fh, &f_copy);
736 if (ret)
737 break;
738
739 ret = fmt_sp_to_mp(&f_copy, f);
740 }
741 if (!ret)
742 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
743 break;
678 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 744 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
679 if (ops->vidioc_g_fmt_vid_overlay) 745 if (ops->vidioc_g_fmt_vid_overlay)
680 ret = ops->vidioc_g_fmt_vid_overlay(file, 746 ret = ops->vidioc_g_fmt_vid_overlay(file,
681 fh, f); 747 fh, f);
682 break; 748 break;
683 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 749 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
684 if (ops->vidioc_g_fmt_vid_out) 750 if (ops->vidioc_g_fmt_vid_out) {
685 ret = ops->vidioc_g_fmt_vid_out(file, fh, f); 751 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
752 } else if (ops->vidioc_g_fmt_vid_out_mplane) {
753 if (fmt_sp_to_mp(f, &f_copy))
754 break;
755 ret = ops->vidioc_g_fmt_vid_out_mplane(file, fh,
756 &f_copy);
757 if (ret)
758 break;
759
760 /* Driver is currently in multi-planar format,
761 * we can't return it in single-planar API*/
762 if (f_copy.fmt.pix_mp.num_planes > 1) {
763 ret = -EBUSY;
764 break;
765 }
766
767 ret = fmt_mp_to_sp(&f_copy, f);
768 }
686 if (!ret) 769 if (!ret)
687 v4l_print_pix_fmt(vfd, &f->fmt.pix); 770 v4l_print_pix_fmt(vfd, &f->fmt.pix);
688 break; 771 break;
772 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
773 if (ops->vidioc_g_fmt_vid_out_mplane) {
774 ret = ops->vidioc_g_fmt_vid_out_mplane(file,
775 fh, f);
776 } else if (ops->vidioc_g_fmt_vid_out) {
777 if (fmt_mp_to_sp(f, &f_copy))
778 break;
779 ret = ops->vidioc_g_fmt_vid_out(file,
780 fh, &f_copy);
781 if (ret)
782 break;
783
784 ret = fmt_sp_to_mp(&f_copy, f);
785 }
786 if (!ret)
787 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
788 break;
689 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 789 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
690 if (ops->vidioc_g_fmt_vid_out_overlay) 790 if (ops->vidioc_g_fmt_vid_out_overlay)
691 ret = ops->vidioc_g_fmt_vid_out_overlay(file, 791 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
@@ -729,8 +829,44 @@ static long __video_do_ioctl(struct file *file,
729 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 829 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
730 CLEAR_AFTER_FIELD(f, fmt.pix); 830 CLEAR_AFTER_FIELD(f, fmt.pix);
731 v4l_print_pix_fmt(vfd, &f->fmt.pix); 831 v4l_print_pix_fmt(vfd, &f->fmt.pix);
732 if (ops->vidioc_s_fmt_vid_cap) 832 if (ops->vidioc_s_fmt_vid_cap) {
733 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); 833 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
834 } else if (ops->vidioc_s_fmt_vid_cap_mplane) {
835 if (fmt_sp_to_mp(f, &f_copy))
836 break;
837 ret = ops->vidioc_s_fmt_vid_cap_mplane(file, fh,
838 &f_copy);
839 if (ret)
840 break;
841
842 if (f_copy.fmt.pix_mp.num_planes > 1) {
843 /* Drivers shouldn't adjust from 1-plane
844 * to more than 1-plane formats */
845 ret = -EBUSY;
846 WARN_ON(1);
847 break;
848 }
849
850 ret = fmt_mp_to_sp(&f_copy, f);
851 }
852 break;
853 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
854 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
855 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
856 if (ops->vidioc_s_fmt_vid_cap_mplane) {
857 ret = ops->vidioc_s_fmt_vid_cap_mplane(file,
858 fh, f);
859 } else if (ops->vidioc_s_fmt_vid_cap &&
860 f->fmt.pix_mp.num_planes == 1) {
861 if (fmt_mp_to_sp(f, &f_copy))
862 break;
863 ret = ops->vidioc_s_fmt_vid_cap(file,
864 fh, &f_copy);
865 if (ret)
866 break;
867
868 ret = fmt_sp_to_mp(&f_copy, f);
869 }
734 break; 870 break;
735 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 871 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
736 CLEAR_AFTER_FIELD(f, fmt.win); 872 CLEAR_AFTER_FIELD(f, fmt.win);
@@ -741,8 +877,44 @@ static long __video_do_ioctl(struct file *file,
741 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 877 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
742 CLEAR_AFTER_FIELD(f, fmt.pix); 878 CLEAR_AFTER_FIELD(f, fmt.pix);
743 v4l_print_pix_fmt(vfd, &f->fmt.pix); 879 v4l_print_pix_fmt(vfd, &f->fmt.pix);
744 if (ops->vidioc_s_fmt_vid_out) 880 if (ops->vidioc_s_fmt_vid_out) {
745 ret = ops->vidioc_s_fmt_vid_out(file, fh, f); 881 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
882 } else if (ops->vidioc_s_fmt_vid_out_mplane) {
883 if (fmt_sp_to_mp(f, &f_copy))
884 break;
885 ret = ops->vidioc_s_fmt_vid_out_mplane(file, fh,
886 &f_copy);
887 if (ret)
888 break;
889
890 if (f_copy.fmt.pix_mp.num_planes > 1) {
891 /* Drivers shouldn't adjust from 1-plane
892 * to more than 1-plane formats */
893 ret = -EBUSY;
894 WARN_ON(1);
895 break;
896 }
897
898 ret = fmt_mp_to_sp(&f_copy, f);
899 }
900 break;
901 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
902 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
903 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
904 if (ops->vidioc_s_fmt_vid_out_mplane) {
905 ret = ops->vidioc_s_fmt_vid_out_mplane(file,
906 fh, f);
907 } else if (ops->vidioc_s_fmt_vid_out &&
908 f->fmt.pix_mp.num_planes == 1) {
909 if (fmt_mp_to_sp(f, &f_copy))
910 break;
911 ret = ops->vidioc_s_fmt_vid_out(file,
912 fh, &f_copy);
913 if (ret)
914 break;
915
916 ret = fmt_mp_to_sp(&f_copy, f);
917 }
746 break; 918 break;
747 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 919 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
748 CLEAR_AFTER_FIELD(f, fmt.win); 920 CLEAR_AFTER_FIELD(f, fmt.win);
@@ -791,11 +963,47 @@ static long __video_do_ioctl(struct file *file,
791 switch (f->type) { 963 switch (f->type) {
792 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 964 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
793 CLEAR_AFTER_FIELD(f, fmt.pix); 965 CLEAR_AFTER_FIELD(f, fmt.pix);
794 if (ops->vidioc_try_fmt_vid_cap) 966 if (ops->vidioc_try_fmt_vid_cap) {
795 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); 967 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
968 } else if (ops->vidioc_try_fmt_vid_cap_mplane) {
969 if (fmt_sp_to_mp(f, &f_copy))
970 break;
971 ret = ops->vidioc_try_fmt_vid_cap_mplane(file,
972 fh, &f_copy);
973 if (ret)
974 break;
975
976 if (f_copy.fmt.pix_mp.num_planes > 1) {
977 /* Drivers shouldn't adjust from 1-plane
978 * to more than 1-plane formats */
979 ret = -EBUSY;
980 WARN_ON(1);
981 break;
982 }
983 ret = fmt_mp_to_sp(&f_copy, f);
984 }
796 if (!ret) 985 if (!ret)
797 v4l_print_pix_fmt(vfd, &f->fmt.pix); 986 v4l_print_pix_fmt(vfd, &f->fmt.pix);
798 break; 987 break;
988 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
989 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
990 if (ops->vidioc_try_fmt_vid_cap_mplane) {
991 ret = ops->vidioc_try_fmt_vid_cap_mplane(file,
992 fh, f);
993 } else if (ops->vidioc_try_fmt_vid_cap &&
994 f->fmt.pix_mp.num_planes == 1) {
995 if (fmt_mp_to_sp(f, &f_copy))
996 break;
997 ret = ops->vidioc_try_fmt_vid_cap(file,
998 fh, &f_copy);
999 if (ret)
1000 break;
1001
1002 ret = fmt_sp_to_mp(&f_copy, f);
1003 }
1004 if (!ret)
1005 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
1006 break;
799 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1007 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
800 CLEAR_AFTER_FIELD(f, fmt.win); 1008 CLEAR_AFTER_FIELD(f, fmt.win);
801 if (ops->vidioc_try_fmt_vid_overlay) 1009 if (ops->vidioc_try_fmt_vid_overlay)
@@ -804,11 +1012,47 @@ static long __video_do_ioctl(struct file *file,
804 break; 1012 break;
805 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1013 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
806 CLEAR_AFTER_FIELD(f, fmt.pix); 1014 CLEAR_AFTER_FIELD(f, fmt.pix);
807 if (ops->vidioc_try_fmt_vid_out) 1015 if (ops->vidioc_try_fmt_vid_out) {
808 ret = ops->vidioc_try_fmt_vid_out(file, fh, f); 1016 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
1017 } else if (ops->vidioc_try_fmt_vid_out_mplane) {
1018 if (fmt_sp_to_mp(f, &f_copy))
1019 break;
1020 ret = ops->vidioc_try_fmt_vid_out_mplane(file,
1021 fh, &f_copy);
1022 if (ret)
1023 break;
1024
1025 if (f_copy.fmt.pix_mp.num_planes > 1) {
1026 /* Drivers shouldn't adjust from 1-plane
1027 * to more than 1-plane formats */
1028 ret = -EBUSY;
1029 WARN_ON(1);
1030 break;
1031 }
1032 ret = fmt_mp_to_sp(&f_copy, f);
1033 }
809 if (!ret) 1034 if (!ret)
810 v4l_print_pix_fmt(vfd, &f->fmt.pix); 1035 v4l_print_pix_fmt(vfd, &f->fmt.pix);
811 break; 1036 break;
1037 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1038 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
1039 if (ops->vidioc_try_fmt_vid_out_mplane) {
1040 ret = ops->vidioc_try_fmt_vid_out_mplane(file,
1041 fh, f);
1042 } else if (ops->vidioc_try_fmt_vid_out &&
1043 f->fmt.pix_mp.num_planes == 1) {
1044 if (fmt_mp_to_sp(f, &f_copy))
1045 break;
1046 ret = ops->vidioc_try_fmt_vid_out(file,
1047 fh, &f_copy);
1048 if (ret)
1049 break;
1050
1051 ret = fmt_sp_to_mp(&f_copy, f);
1052 }
1053 if (!ret)
1054 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
1055 break;
812 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 1056 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
813 CLEAR_AFTER_FIELD(f, fmt.win); 1057 CLEAR_AFTER_FIELD(f, fmt.win);
814 if (ops->vidioc_try_fmt_vid_out_overlay) 1058 if (ops->vidioc_try_fmt_vid_out_overlay)
@@ -1942,13 +2186,18 @@ static long __video_do_ioctl(struct file *file,
1942 } 2186 }
1943 default: 2187 default:
1944 { 2188 {
2189 bool valid_prio = true;
2190
1945 if (!ops->vidioc_default) 2191 if (!ops->vidioc_default)
1946 break; 2192 break;
1947 ret = ops->vidioc_default(file, fh, cmd, arg); 2193 if (use_fh_prio)
2194 valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0;
2195 ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg);
1948 break; 2196 break;
1949 } 2197 }
1950 } /* switch */ 2198 } /* switch */
1951 2199
2200exit_prio:
1952 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { 2201 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1953 if (ret < 0) { 2202 if (ret < 0) {
1954 v4l_print_ioctl(vfd->name, cmd); 2203 v4l_print_ioctl(vfd->name, cmd);
@@ -1973,7 +2222,7 @@ static unsigned long cmd_input_size(unsigned int cmd)
1973 switch (cmd) { 2222 switch (cmd) {
1974 CMDINSIZE(ENUM_FMT, fmtdesc, type); 2223 CMDINSIZE(ENUM_FMT, fmtdesc, type);
1975 CMDINSIZE(G_FMT, format, type); 2224 CMDINSIZE(G_FMT, format, type);
1976 CMDINSIZE(QUERYBUF, buffer, type); 2225 CMDINSIZE(QUERYBUF, buffer, length);
1977 CMDINSIZE(G_PARM, streamparm, type); 2226 CMDINSIZE(G_PARM, streamparm, type);
1978 CMDINSIZE(ENUMSTD, standard, index); 2227 CMDINSIZE(ENUMSTD, standard, index);
1979 CMDINSIZE(ENUMINPUT, input, index); 2228 CMDINSIZE(ENUMINPUT, input, index);
@@ -1998,22 +2247,61 @@ static unsigned long cmd_input_size(unsigned int cmd)
1998 } 2247 }
1999} 2248}
2000 2249
2001long video_ioctl2(struct file *file, 2250static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2002 unsigned int cmd, unsigned long arg) 2251 void * __user *user_ptr, void ***kernel_ptr)
2252{
2253 int ret = 0;
2254
2255 switch (cmd) {
2256 case VIDIOC_QUERYBUF:
2257 case VIDIOC_QBUF:
2258 case VIDIOC_DQBUF: {
2259 struct v4l2_buffer *buf = parg;
2260
2261 if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
2262 if (buf->length > VIDEO_MAX_PLANES) {
2263 ret = -EINVAL;
2264 break;
2265 }
2266 *user_ptr = (void __user *)buf->m.planes;
2267 *kernel_ptr = (void **)&buf->m.planes;
2268 *array_size = sizeof(struct v4l2_plane) * buf->length;
2269 ret = 1;
2270 }
2271 break;
2272 }
2273
2274 case VIDIOC_S_EXT_CTRLS:
2275 case VIDIOC_G_EXT_CTRLS:
2276 case VIDIOC_TRY_EXT_CTRLS: {
2277 struct v4l2_ext_controls *ctrls = parg;
2278
2279 if (ctrls->count != 0) {
2280 *user_ptr = (void __user *)ctrls->controls;
2281 *kernel_ptr = (void **)&ctrls->controls;
2282 *array_size = sizeof(struct v4l2_ext_control)
2283 * ctrls->count;
2284 ret = 1;
2285 }
2286 break;
2287 }
2288 }
2289
2290 return ret;
2291}
2292
2293long
2294video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2295 v4l2_kioctl func)
2003{ 2296{
2004 char sbuf[128]; 2297 char sbuf[128];
2005 void *mbuf = NULL; 2298 void *mbuf = NULL;
2006 void *parg = (void *)arg; 2299 void *parg = (void *)arg;
2007 long err = -EINVAL; 2300 long err = -EINVAL;
2008 int is_ext_ctrl; 2301 bool has_array_args;
2009 size_t ctrls_size = 0; 2302 size_t array_size = 0;
2010 void __user *user_ptr = NULL; 2303 void __user *user_ptr = NULL;
2011 2304 void **kernel_ptr = NULL;
2012#ifdef __OLD_VIDIOC_
2013 cmd = video_fix_command(cmd);
2014#endif
2015 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
2016 cmd == VIDIOC_TRY_EXT_CTRLS);
2017 2305
2018 /* Copy arguments into temp kernel buffer */ 2306 /* Copy arguments into temp kernel buffer */
2019 if (_IOC_DIR(cmd) != _IOC_NONE) { 2307 if (_IOC_DIR(cmd) != _IOC_NONE) {
@@ -2043,43 +2331,43 @@ long video_ioctl2(struct file *file,
2043 } 2331 }
2044 } 2332 }
2045 2333
2046 if (is_ext_ctrl) { 2334 err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
2047 struct v4l2_ext_controls *p = parg; 2335 if (err < 0)
2336 goto out;
2337 has_array_args = err;
2048 2338
2049 /* In case of an error, tell the caller that it wasn't 2339 if (has_array_args) {
2050 a specific control that caused it. */ 2340 /*
2051 p->error_idx = p->count; 2341 * When adding new types of array args, make sure that the
2052 user_ptr = (void __user *)p->controls; 2342 * parent argument to ioctl (which contains the pointer to the
2053 if (p->count) { 2343 * array) fits into sbuf (so that mbuf will still remain
2054 ctrls_size = sizeof(struct v4l2_ext_control) * p->count; 2344 * unused up to here).
2055 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ 2345 */
2056 mbuf = kmalloc(ctrls_size, GFP_KERNEL); 2346 mbuf = kmalloc(array_size, GFP_KERNEL);
2057 err = -ENOMEM; 2347 err = -ENOMEM;
2058 if (NULL == mbuf) 2348 if (NULL == mbuf)
2059 goto out_ext_ctrl; 2349 goto out_array_args;
2060 err = -EFAULT; 2350 err = -EFAULT;
2061 if (copy_from_user(mbuf, user_ptr, ctrls_size)) 2351 if (copy_from_user(mbuf, user_ptr, array_size))
2062 goto out_ext_ctrl; 2352 goto out_array_args;
2063 p->controls = mbuf; 2353 *kernel_ptr = mbuf;
2064 }
2065 } 2354 }
2066 2355
2067 /* Handles IOCTL */ 2356 /* Handles IOCTL */
2068 err = __video_do_ioctl(file, cmd, parg); 2357 err = func(file, cmd, parg);
2069 if (err == -ENOIOCTLCMD) 2358 if (err == -ENOIOCTLCMD)
2070 err = -EINVAL; 2359 err = -EINVAL;
2071 if (is_ext_ctrl) {
2072 struct v4l2_ext_controls *p = parg;
2073 2360
2074 p->controls = (void *)user_ptr; 2361 if (has_array_args) {
2075 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) 2362 *kernel_ptr = user_ptr;
2363 if (copy_to_user(user_ptr, mbuf, array_size))
2076 err = -EFAULT; 2364 err = -EFAULT;
2077 goto out_ext_ctrl; 2365 goto out_array_args;
2078 } 2366 }
2079 if (err < 0) 2367 if (err < 0)
2080 goto out; 2368 goto out;
2081 2369
2082out_ext_ctrl: 2370out_array_args:
2083 /* Copy results into user buffer */ 2371 /* Copy results into user buffer */
2084 switch (_IOC_DIR(cmd)) { 2372 switch (_IOC_DIR(cmd)) {
2085 case _IOC_READ: 2373 case _IOC_READ:
@@ -2093,4 +2381,11 @@ out:
2093 kfree(mbuf); 2381 kfree(mbuf);
2094 return err; 2382 return err;
2095} 2383}
2384EXPORT_SYMBOL(video_usercopy);
2385
2386long video_ioctl2(struct file *file,
2387 unsigned int cmd, unsigned long arg)
2388{
2389 return video_usercopy(file, cmd, arg, __video_do_ioctl);
2390}
2096EXPORT_SYMBOL(video_ioctl2); 2391EXPORT_SYMBOL(video_ioctl2);
diff --git a/drivers/media/video/v4l2-mem2mem.c b/drivers/media/video/v4l2-mem2mem.c
index ac832a28e18e..3b15bf5892a8 100644
--- a/drivers/media/video/v4l2-mem2mem.c
+++ b/drivers/media/video/v4l2-mem2mem.c
@@ -5,7 +5,7 @@
5 * source and destination. 5 * source and destination.
6 * 6 *
7 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
8 * Pawel Osciak, <p.osciak@samsung.com> 8 * Pawel Osciak, <pawel@osciak.com>
9 * Marek Szyprowski, <m.szyprowski@samsung.com> 9 * Marek Szyprowski, <m.szyprowski@samsung.com>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
@@ -17,11 +17,11 @@
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19 19
20#include <media/videobuf-core.h> 20#include <media/videobuf2-core.h>
21#include <media/v4l2-mem2mem.h> 21#include <media/v4l2-mem2mem.h>
22 22
23MODULE_DESCRIPTION("Mem to mem device framework for videobuf"); 23MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
24MODULE_AUTHOR("Pawel Osciak, <p.osciak@samsung.com>"); 24MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
25MODULE_LICENSE("GPL"); 25MODULE_LICENSE("GPL");
26 26
27static bool debug; 27static bool debug;
@@ -65,21 +65,16 @@ struct v4l2_m2m_dev {
65static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct v4l2_m2m_ctx *m2m_ctx, 65static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct v4l2_m2m_ctx *m2m_ctx,
66 enum v4l2_buf_type type) 66 enum v4l2_buf_type type)
67{ 67{
68 switch (type) { 68 if (V4L2_TYPE_IS_OUTPUT(type))
69 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
70 return &m2m_ctx->cap_q_ctx;
71 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
72 return &m2m_ctx->out_q_ctx; 69 return &m2m_ctx->out_q_ctx;
73 default: 70 else
74 printk(KERN_ERR "Invalid buffer type\n"); 71 return &m2m_ctx->cap_q_ctx;
75 return NULL;
76 }
77} 72}
78 73
79/** 74/**
80 * v4l2_m2m_get_vq() - return videobuf_queue for the given type 75 * v4l2_m2m_get_vq() - return vb2_queue for the given type
81 */ 76 */
82struct videobuf_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, 77struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
83 enum v4l2_buf_type type) 78 enum v4l2_buf_type type)
84{ 79{
85 struct v4l2_m2m_queue_ctx *q_ctx; 80 struct v4l2_m2m_queue_ctx *q_ctx;
@@ -95,27 +90,20 @@ EXPORT_SYMBOL(v4l2_m2m_get_vq);
95/** 90/**
96 * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers 91 * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers
97 */ 92 */
98void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) 93void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx)
99{ 94{
100 struct v4l2_m2m_queue_ctx *q_ctx; 95 struct v4l2_m2m_buffer *b = NULL;
101 struct videobuf_buffer *vb = NULL;
102 unsigned long flags; 96 unsigned long flags;
103 97
104 q_ctx = get_queue_ctx(m2m_ctx, type); 98 spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
105 if (!q_ctx)
106 return NULL;
107
108 spin_lock_irqsave(q_ctx->q.irqlock, flags);
109 99
110 if (list_empty(&q_ctx->rdy_queue)) 100 if (list_empty(&q_ctx->rdy_queue))
111 goto end; 101 goto end;
112 102
113 vb = list_entry(q_ctx->rdy_queue.next, struct videobuf_buffer, queue); 103 b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer, list);
114 vb->state = VIDEOBUF_ACTIVE;
115
116end: 104end:
117 spin_unlock_irqrestore(q_ctx->q.irqlock, flags); 105 spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
118 return vb; 106 return &b->vb;
119} 107}
120EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf); 108EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf);
121 109
@@ -123,26 +111,21 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf);
123 * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and 111 * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
124 * return it 112 * return it
125 */ 113 */
126void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) 114void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
127{ 115{
128 struct v4l2_m2m_queue_ctx *q_ctx; 116 struct v4l2_m2m_buffer *b = NULL;
129 struct videobuf_buffer *vb = NULL;
130 unsigned long flags; 117 unsigned long flags;
131 118
132 q_ctx = get_queue_ctx(m2m_ctx, type); 119 spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
133 if (!q_ctx)
134 return NULL;
135
136 spin_lock_irqsave(q_ctx->q.irqlock, flags);
137 if (!list_empty(&q_ctx->rdy_queue)) { 120 if (!list_empty(&q_ctx->rdy_queue)) {
138 vb = list_entry(q_ctx->rdy_queue.next, struct videobuf_buffer, 121 b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer,
139 queue); 122 list);
140 list_del(&vb->queue); 123 list_del(&b->list);
141 q_ctx->num_rdy--; 124 q_ctx->num_rdy--;
142 } 125 }
143 spin_unlock_irqrestore(q_ctx->q.irqlock, flags); 126 spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
144 127
145 return vb; 128 return &b->vb;
146} 129}
147EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove); 130EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
148 131
@@ -235,20 +218,20 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
235 return; 218 return;
236 } 219 }
237 220
238 spin_lock_irqsave(m2m_ctx->out_q_ctx.q.irqlock, flags); 221 spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
239 if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) { 222 if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) {
240 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags); 223 spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
241 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); 224 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
242 dprintk("No input buffers available\n"); 225 dprintk("No input buffers available\n");
243 return; 226 return;
244 } 227 }
245 if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) { 228 if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) {
246 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags); 229 spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
247 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); 230 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
248 dprintk("No output buffers available\n"); 231 dprintk("No output buffers available\n");
249 return; 232 return;
250 } 233 }
251 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags); 234 spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
252 235
253 if (m2m_dev->m2m_ops->job_ready 236 if (m2m_dev->m2m_ops->job_ready
254 && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) { 237 && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
@@ -291,6 +274,7 @@ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
291 274
292 list_del(&m2m_dev->curr_ctx->queue); 275 list_del(&m2m_dev->curr_ctx->queue);
293 m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); 276 m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
277 wake_up(&m2m_dev->curr_ctx->finished);
294 m2m_dev->curr_ctx = NULL; 278 m2m_dev->curr_ctx = NULL;
295 279
296 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); 280 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
@@ -309,10 +293,10 @@ EXPORT_SYMBOL(v4l2_m2m_job_finish);
309int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 293int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
310 struct v4l2_requestbuffers *reqbufs) 294 struct v4l2_requestbuffers *reqbufs)
311{ 295{
312 struct videobuf_queue *vq; 296 struct vb2_queue *vq;
313 297
314 vq = v4l2_m2m_get_vq(m2m_ctx, reqbufs->type); 298 vq = v4l2_m2m_get_vq(m2m_ctx, reqbufs->type);
315 return videobuf_reqbufs(vq, reqbufs); 299 return vb2_reqbufs(vq, reqbufs);
316} 300}
317EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs); 301EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs);
318 302
@@ -324,15 +308,22 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs);
324int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 308int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
325 struct v4l2_buffer *buf) 309 struct v4l2_buffer *buf)
326{ 310{
327 struct videobuf_queue *vq; 311 struct vb2_queue *vq;
328 int ret; 312 int ret = 0;
313 unsigned int i;
329 314
330 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); 315 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
331 ret = videobuf_querybuf(vq, buf); 316 ret = vb2_querybuf(vq, buf);
332 317
333 if (buf->memory == V4L2_MEMORY_MMAP 318 /* Adjust MMAP memory offsets for the CAPTURE queue */
334 && vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 319 if (buf->memory == V4L2_MEMORY_MMAP && !V4L2_TYPE_IS_OUTPUT(vq->type)) {
335 buf->m.offset += DST_QUEUE_OFF_BASE; 320 if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) {
321 for (i = 0; i < buf->length; ++i)
322 buf->m.planes[i].m.mem_offset
323 += DST_QUEUE_OFF_BASE;
324 } else {
325 buf->m.offset += DST_QUEUE_OFF_BASE;
326 }
336 } 327 }
337 328
338 return ret; 329 return ret;
@@ -346,11 +337,11 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
346int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 337int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
347 struct v4l2_buffer *buf) 338 struct v4l2_buffer *buf)
348{ 339{
349 struct videobuf_queue *vq; 340 struct vb2_queue *vq;
350 int ret; 341 int ret;
351 342
352 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); 343 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
353 ret = videobuf_qbuf(vq, buf); 344 ret = vb2_qbuf(vq, buf);
354 if (!ret) 345 if (!ret)
355 v4l2_m2m_try_schedule(m2m_ctx); 346 v4l2_m2m_try_schedule(m2m_ctx);
356 347
@@ -365,10 +356,10 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf);
365int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 356int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
366 struct v4l2_buffer *buf) 357 struct v4l2_buffer *buf)
367{ 358{
368 struct videobuf_queue *vq; 359 struct vb2_queue *vq;
369 360
370 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); 361 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
371 return videobuf_dqbuf(vq, buf, file->f_flags & O_NONBLOCK); 362 return vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK);
372} 363}
373EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); 364EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
374 365
@@ -378,11 +369,11 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
378int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 369int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
379 enum v4l2_buf_type type) 370 enum v4l2_buf_type type)
380{ 371{
381 struct videobuf_queue *vq; 372 struct vb2_queue *vq;
382 int ret; 373 int ret;
383 374
384 vq = v4l2_m2m_get_vq(m2m_ctx, type); 375 vq = v4l2_m2m_get_vq(m2m_ctx, type);
385 ret = videobuf_streamon(vq); 376 ret = vb2_streamon(vq, type);
386 if (!ret) 377 if (!ret)
387 v4l2_m2m_try_schedule(m2m_ctx); 378 v4l2_m2m_try_schedule(m2m_ctx);
388 379
@@ -396,10 +387,10 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_streamon);
396int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 387int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
397 enum v4l2_buf_type type) 388 enum v4l2_buf_type type)
398{ 389{
399 struct videobuf_queue *vq; 390 struct vb2_queue *vq;
400 391
401 vq = v4l2_m2m_get_vq(m2m_ctx, type); 392 vq = v4l2_m2m_get_vq(m2m_ctx, type);
402 return videobuf_streamoff(vq); 393 return vb2_streamoff(vq, type);
403} 394}
404EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff); 395EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff);
405 396
@@ -414,44 +405,53 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff);
414unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 405unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
415 struct poll_table_struct *wait) 406 struct poll_table_struct *wait)
416{ 407{
417 struct videobuf_queue *src_q, *dst_q; 408 struct vb2_queue *src_q, *dst_q;
418 struct videobuf_buffer *src_vb = NULL, *dst_vb = NULL; 409 struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
419 unsigned int rc = 0; 410 unsigned int rc = 0;
411 unsigned long flags;
420 412
421 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 413 src_q = v4l2_m2m_get_src_vq(m2m_ctx);
422 dst_q = v4l2_m2m_get_dst_vq(m2m_ctx); 414 dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
423 415
424 videobuf_queue_lock(src_q); 416 /*
425 videobuf_queue_lock(dst_q); 417 * There has to be at least one buffer queued on each queued_list, which
426 418 * means either in driver already or waiting for driver to claim it
427 if (src_q->streaming && !list_empty(&src_q->stream)) 419 * and start processing.
428 src_vb = list_first_entry(&src_q->stream, 420 */
429 struct videobuf_buffer, stream); 421 if ((!src_q->streaming || list_empty(&src_q->queued_list))
430 if (dst_q->streaming && !list_empty(&dst_q->stream)) 422 && (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
431 dst_vb = list_first_entry(&dst_q->stream,
432 struct videobuf_buffer, stream);
433
434 if (!src_vb && !dst_vb) {
435 rc = POLLERR; 423 rc = POLLERR;
436 goto end; 424 goto end;
437 } 425 }
438 426
439 if (src_vb) { 427 if (m2m_ctx->m2m_dev->m2m_ops->unlock)
440 poll_wait(file, &src_vb->done, wait); 428 m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
441 if (src_vb->state == VIDEOBUF_DONE 429
442 || src_vb->state == VIDEOBUF_ERROR) 430 poll_wait(file, &src_q->done_wq, wait);
443 rc |= POLLOUT | POLLWRNORM; 431 poll_wait(file, &dst_q->done_wq, wait);
444 } 432
445 if (dst_vb) { 433 if (m2m_ctx->m2m_dev->m2m_ops->lock)
446 poll_wait(file, &dst_vb->done, wait); 434 m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
447 if (dst_vb->state == VIDEOBUF_DONE 435
448 || dst_vb->state == VIDEOBUF_ERROR) 436 spin_lock_irqsave(&src_q->done_lock, flags);
449 rc |= POLLIN | POLLRDNORM; 437 if (!list_empty(&src_q->done_list))
450 } 438 src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer,
439 done_entry);
440 if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE
441 || src_vb->state == VB2_BUF_STATE_ERROR))
442 rc |= POLLOUT | POLLWRNORM;
443 spin_unlock_irqrestore(&src_q->done_lock, flags);
444
445 spin_lock_irqsave(&dst_q->done_lock, flags);
446 if (!list_empty(&dst_q->done_list))
447 dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer,
448 done_entry);
449 if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE
450 || dst_vb->state == VB2_BUF_STATE_ERROR))
451 rc |= POLLIN | POLLRDNORM;
452 spin_unlock_irqrestore(&dst_q->done_lock, flags);
451 453
452end: 454end:
453 videobuf_queue_unlock(dst_q);
454 videobuf_queue_unlock(src_q);
455 return rc; 455 return rc;
456} 456}
457EXPORT_SYMBOL_GPL(v4l2_m2m_poll); 457EXPORT_SYMBOL_GPL(v4l2_m2m_poll);
@@ -470,7 +470,7 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
470 struct vm_area_struct *vma) 470 struct vm_area_struct *vma)
471{ 471{
472 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 472 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
473 struct videobuf_queue *vq; 473 struct vb2_queue *vq;
474 474
475 if (offset < DST_QUEUE_OFF_BASE) { 475 if (offset < DST_QUEUE_OFF_BASE) {
476 vq = v4l2_m2m_get_src_vq(m2m_ctx); 476 vq = v4l2_m2m_get_src_vq(m2m_ctx);
@@ -479,7 +479,7 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
479 vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT); 479 vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
480 } 480 }
481 481
482 return videobuf_mmap_mapper(vq, vma); 482 return vb2_mmap(vq, vma);
483} 483}
484EXPORT_SYMBOL(v4l2_m2m_mmap); 484EXPORT_SYMBOL(v4l2_m2m_mmap);
485 485
@@ -531,36 +531,41 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_release);
531 * 531 *
532 * Usually called from driver's open() function. 532 * Usually called from driver's open() function.
533 */ 533 */
534struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(void *priv, struct v4l2_m2m_dev *m2m_dev, 534struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
535 void (*vq_init)(void *priv, struct videobuf_queue *, 535 void *drv_priv,
536 enum v4l2_buf_type)) 536 int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq))
537{ 537{
538 struct v4l2_m2m_ctx *m2m_ctx; 538 struct v4l2_m2m_ctx *m2m_ctx;
539 struct v4l2_m2m_queue_ctx *out_q_ctx, *cap_q_ctx; 539 struct v4l2_m2m_queue_ctx *out_q_ctx, *cap_q_ctx;
540 540 int ret;
541 if (!vq_init)
542 return ERR_PTR(-EINVAL);
543 541
544 m2m_ctx = kzalloc(sizeof *m2m_ctx, GFP_KERNEL); 542 m2m_ctx = kzalloc(sizeof *m2m_ctx, GFP_KERNEL);
545 if (!m2m_ctx) 543 if (!m2m_ctx)
546 return ERR_PTR(-ENOMEM); 544 return ERR_PTR(-ENOMEM);
547 545
548 m2m_ctx->priv = priv; 546 m2m_ctx->priv = drv_priv;
549 m2m_ctx->m2m_dev = m2m_dev; 547 m2m_ctx->m2m_dev = m2m_dev;
548 init_waitqueue_head(&m2m_ctx->finished);
550 549
551 out_q_ctx = get_queue_ctx(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 550 out_q_ctx = &m2m_ctx->out_q_ctx;
552 cap_q_ctx = get_queue_ctx(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 551 cap_q_ctx = &m2m_ctx->cap_q_ctx;
553 552
554 INIT_LIST_HEAD(&out_q_ctx->rdy_queue); 553 INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
555 INIT_LIST_HEAD(&cap_q_ctx->rdy_queue); 554 INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
555 spin_lock_init(&out_q_ctx->rdy_spinlock);
556 spin_lock_init(&cap_q_ctx->rdy_spinlock);
556 557
557 INIT_LIST_HEAD(&m2m_ctx->queue); 558 INIT_LIST_HEAD(&m2m_ctx->queue);
558 559
559 vq_init(priv, &out_q_ctx->q, V4L2_BUF_TYPE_VIDEO_OUTPUT); 560 ret = queue_init(drv_priv, &out_q_ctx->q, &cap_q_ctx->q);
560 vq_init(priv, &cap_q_ctx->q, V4L2_BUF_TYPE_VIDEO_CAPTURE); 561
561 out_q_ctx->q.priv_data = cap_q_ctx->q.priv_data = priv; 562 if (ret)
563 goto err;
562 564
563 return m2m_ctx; 565 return m2m_ctx;
566err:
567 kfree(m2m_ctx);
568 return ERR_PTR(ret);
564} 569}
565EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init); 570EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
566 571
@@ -572,7 +577,6 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
572void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx) 577void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
573{ 578{
574 struct v4l2_m2m_dev *m2m_dev; 579 struct v4l2_m2m_dev *m2m_dev;
575 struct videobuf_buffer *vb;
576 unsigned long flags; 580 unsigned long flags;
577 581
578 m2m_dev = m2m_ctx->m2m_dev; 582 m2m_dev = m2m_ctx->m2m_dev;
@@ -582,10 +586,7 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
582 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); 586 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
583 m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); 587 m2m_dev->m2m_ops->job_abort(m2m_ctx->priv);
584 dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx); 588 dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx);
585 vb = v4l2_m2m_next_dst_buf(m2m_ctx); 589 wait_event(m2m_ctx->finished, !(m2m_ctx->job_flags & TRANS_RUNNING));
586 BUG_ON(NULL == vb);
587 wait_event(vb->done, vb->state != VIDEOBUF_ACTIVE
588 && vb->state != VIDEOBUF_QUEUED);
589 } else if (m2m_ctx->job_flags & TRANS_QUEUED) { 590 } else if (m2m_ctx->job_flags & TRANS_QUEUED) {
590 list_del(&m2m_ctx->queue); 591 list_del(&m2m_ctx->queue);
591 m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); 592 m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
@@ -597,11 +598,8 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
597 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); 598 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
598 } 599 }
599 600
600 videobuf_stop(&m2m_ctx->cap_q_ctx.q); 601 vb2_queue_release(&m2m_ctx->cap_q_ctx.q);
601 videobuf_stop(&m2m_ctx->out_q_ctx.q); 602 vb2_queue_release(&m2m_ctx->out_q_ctx.q);
602
603 videobuf_mmap_free(&m2m_ctx->cap_q_ctx.q);
604 videobuf_mmap_free(&m2m_ctx->out_q_ctx.q);
605 603
606 kfree(m2m_ctx); 604 kfree(m2m_ctx);
607} 605}
@@ -611,23 +609,21 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_release);
611 * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list. 609 * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list.
612 * 610 *
613 * Call from buf_queue(), videobuf_queue_ops callback. 611 * Call from buf_queue(), videobuf_queue_ops callback.
614 *
615 * Locking: Caller holds q->irqlock (taken by videobuf before calling buf_queue
616 * callback in the driver).
617 */ 612 */
618void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct videobuf_queue *vq, 613void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb)
619 struct videobuf_buffer *vb)
620{ 614{
615 struct v4l2_m2m_buffer *b = container_of(vb, struct v4l2_m2m_buffer, vb);
621 struct v4l2_m2m_queue_ctx *q_ctx; 616 struct v4l2_m2m_queue_ctx *q_ctx;
617 unsigned long flags;
622 618
623 q_ctx = get_queue_ctx(m2m_ctx, vq->type); 619 q_ctx = get_queue_ctx(m2m_ctx, vb->vb2_queue->type);
624 if (!q_ctx) 620 if (!q_ctx)
625 return; 621 return;
626 622
627 list_add_tail(&vb->queue, &q_ctx->rdy_queue); 623 spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
624 list_add_tail(&b->list, &q_ctx->rdy_queue);
628 q_ctx->num_rdy++; 625 q_ctx->num_rdy++;
629 626 spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
630 vb->state = VIDEOBUF_QUEUED;
631} 627}
632EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue); 628EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
633 629
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
new file mode 100644
index 000000000000..0b8064490676
--- /dev/null
+++ b/drivers/media/video/v4l2-subdev.c
@@ -0,0 +1,332 @@
1/*
2 * V4L2 sub-device
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/ioctl.h>
24#include <linux/slab.h>
25#include <linux/types.h>
26#include <linux/videodev2.h>
27
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-ioctl.h>
31#include <media/v4l2-fh.h>
32#include <media/v4l2-event.h>
33
34static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
35{
36#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
37 /* Allocate try format and crop in the same memory block */
38 fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
39 * sd->entity.num_pads, GFP_KERNEL);
40 if (fh->try_fmt == NULL)
41 return -ENOMEM;
42
43 fh->try_crop = (struct v4l2_rect *)
44 (fh->try_fmt + sd->entity.num_pads);
45#endif
46 return 0;
47}
48
49static void subdev_fh_free(struct v4l2_subdev_fh *fh)
50{
51#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
52 kfree(fh->try_fmt);
53 fh->try_fmt = NULL;
54 fh->try_crop = NULL;
55#endif
56}
57
58static int subdev_open(struct file *file)
59{
60 struct video_device *vdev = video_devdata(file);
61 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
62 struct v4l2_subdev_fh *subdev_fh;
63#if defined(CONFIG_MEDIA_CONTROLLER)
64 struct media_entity *entity = NULL;
65#endif
66 int ret;
67
68 subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);
69 if (subdev_fh == NULL)
70 return -ENOMEM;
71
72 ret = subdev_fh_init(subdev_fh, sd);
73 if (ret) {
74 kfree(subdev_fh);
75 return ret;
76 }
77
78 ret = v4l2_fh_init(&subdev_fh->vfh, vdev);
79 if (ret)
80 goto err;
81
82 if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) {
83 ret = v4l2_event_init(&subdev_fh->vfh);
84 if (ret)
85 goto err;
86
87 ret = v4l2_event_alloc(&subdev_fh->vfh, sd->nevents);
88 if (ret)
89 goto err;
90 }
91
92 v4l2_fh_add(&subdev_fh->vfh);
93 file->private_data = &subdev_fh->vfh;
94#if defined(CONFIG_MEDIA_CONTROLLER)
95 if (sd->v4l2_dev->mdev) {
96 entity = media_entity_get(&sd->entity);
97 if (!entity) {
98 ret = -EBUSY;
99 goto err;
100 }
101 }
102#endif
103
104 if (sd->internal_ops && sd->internal_ops->open) {
105 ret = sd->internal_ops->open(sd, subdev_fh);
106 if (ret < 0)
107 goto err;
108 }
109
110 return 0;
111
112err:
113#if defined(CONFIG_MEDIA_CONTROLLER)
114 if (entity)
115 media_entity_put(entity);
116#endif
117 v4l2_fh_del(&subdev_fh->vfh);
118 v4l2_fh_exit(&subdev_fh->vfh);
119 subdev_fh_free(subdev_fh);
120 kfree(subdev_fh);
121
122 return ret;
123}
124
125static int subdev_close(struct file *file)
126{
127 struct video_device *vdev = video_devdata(file);
128 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
129 struct v4l2_fh *vfh = file->private_data;
130 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
131
132 if (sd->internal_ops && sd->internal_ops->close)
133 sd->internal_ops->close(sd, subdev_fh);
134#if defined(CONFIG_MEDIA_CONTROLLER)
135 if (sd->v4l2_dev->mdev)
136 media_entity_put(&sd->entity);
137#endif
138 v4l2_fh_del(vfh);
139 v4l2_fh_exit(vfh);
140 subdev_fh_free(subdev_fh);
141 kfree(subdev_fh);
142 file->private_data = NULL;
143
144 return 0;
145}
146
147static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
148{
149 struct video_device *vdev = video_devdata(file);
150 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
151 struct v4l2_fh *vfh = file->private_data;
152#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
153 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
154#endif
155
156 switch (cmd) {
157 case VIDIOC_QUERYCTRL:
158 return v4l2_subdev_queryctrl(sd, arg);
159
160 case VIDIOC_QUERYMENU:
161 return v4l2_subdev_querymenu(sd, arg);
162
163 case VIDIOC_G_CTRL:
164 return v4l2_subdev_g_ctrl(sd, arg);
165
166 case VIDIOC_S_CTRL:
167 return v4l2_subdev_s_ctrl(sd, arg);
168
169 case VIDIOC_G_EXT_CTRLS:
170 return v4l2_subdev_g_ext_ctrls(sd, arg);
171
172 case VIDIOC_S_EXT_CTRLS:
173 return v4l2_subdev_s_ext_ctrls(sd, arg);
174
175 case VIDIOC_TRY_EXT_CTRLS:
176 return v4l2_subdev_try_ext_ctrls(sd, arg);
177
178 case VIDIOC_DQEVENT:
179 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
180 return -ENOIOCTLCMD;
181
182 return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
183
184 case VIDIOC_SUBSCRIBE_EVENT:
185 return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
186
187 case VIDIOC_UNSUBSCRIBE_EVENT:
188 return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
189#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
190 case VIDIOC_SUBDEV_G_FMT: {
191 struct v4l2_subdev_format *format = arg;
192
193 if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
194 format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
195 return -EINVAL;
196
197 if (format->pad >= sd->entity.num_pads)
198 return -EINVAL;
199
200 return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);
201 }
202
203 case VIDIOC_SUBDEV_S_FMT: {
204 struct v4l2_subdev_format *format = arg;
205
206 if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
207 format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
208 return -EINVAL;
209
210 if (format->pad >= sd->entity.num_pads)
211 return -EINVAL;
212
213 return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
214 }
215
216 case VIDIOC_SUBDEV_G_CROP: {
217 struct v4l2_subdev_crop *crop = arg;
218
219 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
220 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
221 return -EINVAL;
222
223 if (crop->pad >= sd->entity.num_pads)
224 return -EINVAL;
225
226 return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
227 }
228
229 case VIDIOC_SUBDEV_S_CROP: {
230 struct v4l2_subdev_crop *crop = arg;
231
232 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
233 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
234 return -EINVAL;
235
236 if (crop->pad >= sd->entity.num_pads)
237 return -EINVAL;
238
239 return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
240 }
241
242 case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
243 struct v4l2_subdev_mbus_code_enum *code = arg;
244
245 if (code->pad >= sd->entity.num_pads)
246 return -EINVAL;
247
248 return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh,
249 code);
250 }
251
252 case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {
253 struct v4l2_subdev_frame_size_enum *fse = arg;
254
255 if (fse->pad >= sd->entity.num_pads)
256 return -EINVAL;
257
258 return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh,
259 fse);
260 }
261
262 case VIDIOC_SUBDEV_G_FRAME_INTERVAL:
263 return v4l2_subdev_call(sd, video, g_frame_interval, arg);
264
265 case VIDIOC_SUBDEV_S_FRAME_INTERVAL:
266 return v4l2_subdev_call(sd, video, s_frame_interval, arg);
267
268 case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {
269 struct v4l2_subdev_frame_interval_enum *fie = arg;
270
271 if (fie->pad >= sd->entity.num_pads)
272 return -EINVAL;
273
274 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
275 fie);
276 }
277#endif
278 default:
279 return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
280 }
281
282 return 0;
283}
284
285static long subdev_ioctl(struct file *file, unsigned int cmd,
286 unsigned long arg)
287{
288 return video_usercopy(file, cmd, arg, subdev_do_ioctl);
289}
290
291static unsigned int subdev_poll(struct file *file, poll_table *wait)
292{
293 struct video_device *vdev = video_devdata(file);
294 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
295 struct v4l2_fh *fh = file->private_data;
296
297 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
298 return POLLERR;
299
300 poll_wait(file, &fh->events->wait, wait);
301
302 if (v4l2_event_pending(fh))
303 return POLLPRI;
304
305 return 0;
306}
307
308const struct v4l2_file_operations v4l2_subdev_fops = {
309 .owner = THIS_MODULE,
310 .open = subdev_open,
311 .unlocked_ioctl = subdev_ioctl,
312 .release = subdev_close,
313 .poll = subdev_poll,
314};
315
316void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
317{
318 INIT_LIST_HEAD(&sd->list);
319 BUG_ON(!ops);
320 sd->ops = ops;
321 sd->v4l2_dev = NULL;
322 sd->flags = 0;
323 sd->name[0] = '\0';
324 sd->grp_id = 0;
325 sd->dev_priv = NULL;
326 sd->host_priv = NULL;
327#if defined(CONFIG_MEDIA_CONTROLLER)
328 sd->entity.name = sd->name;
329 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
330#endif
331}
332EXPORT_SYMBOL(v4l2_subdev_init);
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 2f973cd56408..8c780c2d937b 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -25,6 +25,7 @@
25#include <linux/via-core.h> 25#include <linux/via-core.h>
26#include <linux/via-gpio.h> 26#include <linux/via-gpio.h>
27#include <linux/via_i2c.h> 27#include <linux/via_i2c.h>
28#include <asm/olpc.h>
28 29
29#include "via-camera.h" 30#include "via-camera.h"
30 31
@@ -38,14 +39,12 @@ MODULE_PARM_DESC(flip_image,
38 "If set, the sensor will be instructed to flip the image " 39 "If set, the sensor will be instructed to flip the image "
39 "vertically."); 40 "vertically.");
40 41
41#ifdef CONFIG_OLPC_XO_1_5
42static int override_serial; 42static int override_serial;
43module_param(override_serial, bool, 0444); 43module_param(override_serial, bool, 0444);
44MODULE_PARM_DESC(override_serial, 44MODULE_PARM_DESC(override_serial,
45 "The camera driver will normally refuse to load if " 45 "The camera driver will normally refuse to load if "
46 "the XO 1.5 serial port is enabled. Set this option " 46 "the XO 1.5 serial port is enabled. Set this option "
47 "to force the issue."); 47 "to force-enable the camera.");
48#endif
49 48
50/* 49/*
51 * Basic window sizes. 50 * Basic window sizes.
@@ -1246,6 +1245,62 @@ static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
1246/* 1245/*
1247 * Power management. 1246 * Power management.
1248 */ 1247 */
1248#ifdef CONFIG_PM
1249
1250static int viacam_suspend(void *priv)
1251{
1252 struct via_camera *cam = priv;
1253 enum viacam_opstate state = cam->opstate;
1254
1255 if (cam->opstate != S_IDLE) {
1256 viacam_stop_engine(cam);
1257 cam->opstate = state; /* So resume restarts */
1258 }
1259
1260 return 0;
1261}
1262
1263static int viacam_resume(void *priv)
1264{
1265 struct via_camera *cam = priv;
1266 int ret = 0;
1267
1268 /*
1269 * Get back to a reasonable operating state.
1270 */
1271 via_write_reg_mask(VIASR, 0x78, 0, 0x80);
1272 via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
1273 viacam_int_disable(cam);
1274 set_bit(CF_CONFIG_NEEDED, &cam->flags);
1275 /*
1276 * Make sure the sensor's power state is correct
1277 */
1278 if (cam->users > 0)
1279 via_sensor_power_up(cam);
1280 else
1281 via_sensor_power_down(cam);
1282 /*
1283 * If it was operating, try to restart it.
1284 */
1285 if (cam->opstate != S_IDLE) {
1286 mutex_lock(&cam->lock);
1287 ret = viacam_configure_sensor(cam);
1288 if (!ret)
1289 ret = viacam_config_controller(cam);
1290 mutex_unlock(&cam->lock);
1291 if (!ret)
1292 viacam_start_engine(cam);
1293 }
1294
1295 return ret;
1296}
1297
1298static struct viafb_pm_hooks viacam_pm_hooks = {
1299 .suspend = viacam_suspend,
1300 .resume = viacam_resume
1301};
1302
1303#endif /* CONFIG_PM */
1249 1304
1250/* 1305/*
1251 * Setup stuff. 1306 * Setup stuff.
@@ -1261,6 +1316,37 @@ static struct video_device viacam_v4l_template = {
1261 .release = video_device_release_empty, /* Check this */ 1316 .release = video_device_release_empty, /* Check this */
1262}; 1317};
1263 1318
1319/*
1320 * The OLPC folks put the serial port on the same pin as
1321 * the camera. They also get grumpy if we break the
1322 * serial port and keep them from using it. So we have
1323 * to check the serial enable bit and not step on it.
1324 */
1325#define VIACAM_SERIAL_DEVFN 0x88
1326#define VIACAM_SERIAL_CREG 0x46
1327#define VIACAM_SERIAL_BIT 0x40
1328
1329static __devinit bool viacam_serial_is_enabled(void)
1330{
1331 struct pci_bus *pbus = pci_find_bus(0, 0);
1332 u8 cbyte;
1333
1334 pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1335 VIACAM_SERIAL_CREG, &cbyte);
1336 if ((cbyte & VIACAM_SERIAL_BIT) == 0)
1337 return false; /* Not enabled */
1338 if (override_serial == 0) {
1339 printk(KERN_NOTICE "Via camera: serial port is enabled, " \
1340 "refusing to load.\n");
1341 printk(KERN_NOTICE "Specify override_serial=1 to force " \
1342 "module loading.\n");
1343 return true;
1344 }
1345 printk(KERN_NOTICE "Via camera: overriding serial port\n");
1346 pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1347 VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
1348 return false;
1349}
1264 1350
1265static __devinit int viacam_probe(struct platform_device *pdev) 1351static __devinit int viacam_probe(struct platform_device *pdev)
1266{ 1352{
@@ -1292,6 +1378,10 @@ static __devinit int viacam_probe(struct platform_device *pdev)
1292 printk(KERN_ERR "viacam: No I/O memory, so no pictures\n"); 1378 printk(KERN_ERR "viacam: No I/O memory, so no pictures\n");
1293 return -ENOMEM; 1379 return -ENOMEM;
1294 } 1380 }
1381
1382 if (machine_is_olpc() && viacam_serial_is_enabled())
1383 return -EBUSY;
1384
1295 /* 1385 /*
1296 * Basic structure initialization. 1386 * Basic structure initialization.
1297 */ 1387 */
@@ -1369,6 +1459,14 @@ static __devinit int viacam_probe(struct platform_device *pdev)
1369 goto out_irq; 1459 goto out_irq;
1370 video_set_drvdata(&cam->vdev, cam); 1460 video_set_drvdata(&cam->vdev, cam);
1371 1461
1462#ifdef CONFIG_PM
1463 /*
1464 * Hook into PM events
1465 */
1466 viacam_pm_hooks.private = cam;
1467 viafb_pm_register(&viacam_pm_hooks);
1468#endif
1469
1372 /* Power the sensor down until somebody opens the device */ 1470 /* Power the sensor down until somebody opens the device */
1373 via_sensor_power_down(cam); 1471 via_sensor_power_down(cam);
1374 return 0; 1472 return 0;
@@ -1395,7 +1493,6 @@ static __devexit int viacam_remove(struct platform_device *pdev)
1395 return 0; 1493 return 0;
1396} 1494}
1397 1495
1398
1399static struct platform_driver viacam_driver = { 1496static struct platform_driver viacam_driver = {
1400 .driver = { 1497 .driver = {
1401 .name = "viafb-camera", 1498 .name = "viafb-camera",
@@ -1404,50 +1501,8 @@ static struct platform_driver viacam_driver = {
1404 .remove = viacam_remove, 1501 .remove = viacam_remove,
1405}; 1502};
1406 1503
1407
1408#ifdef CONFIG_OLPC_XO_1_5
1409/*
1410 * The OLPC folks put the serial port on the same pin as
1411 * the camera. They also get grumpy if we break the
1412 * serial port and keep them from using it. So we have
1413 * to check the serial enable bit and not step on it.
1414 */
1415#define VIACAM_SERIAL_DEVFN 0x88
1416#define VIACAM_SERIAL_CREG 0x46
1417#define VIACAM_SERIAL_BIT 0x40
1418
1419static __devinit int viacam_check_serial_port(void)
1420{
1421 struct pci_bus *pbus = pci_find_bus(0, 0);
1422 u8 cbyte;
1423
1424 pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1425 VIACAM_SERIAL_CREG, &cbyte);
1426 if ((cbyte & VIACAM_SERIAL_BIT) == 0)
1427 return 0; /* Not enabled */
1428 if (override_serial == 0) {
1429 printk(KERN_NOTICE "Via camera: serial port is enabled, " \
1430 "refusing to load.\n");
1431 printk(KERN_NOTICE "Specify override_serial=1 to force " \
1432 "module loading.\n");
1433 return -EBUSY;
1434 }
1435 printk(KERN_NOTICE "Via camera: overriding serial port\n");
1436 pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1437 VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
1438 return 0;
1439}
1440#endif
1441
1442
1443
1444
1445static int viacam_init(void) 1504static int viacam_init(void)
1446{ 1505{
1447#ifdef CONFIG_OLPC_XO_1_5
1448 if (viacam_check_serial_port())
1449 return -EBUSY;
1450#endif
1451 return platform_driver_register(&viacam_driver); 1506 return platform_driver_register(&viacam_driver);
1452} 1507}
1453module_init(viacam_init); 1508module_init(viacam_init);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index c9691115f2d2..c4742fc15529 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -300,7 +300,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
300 300
301 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 301 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
302 retval = remap_pfn_range(vma, vma->vm_start, 302 retval = remap_pfn_range(vma, vma->vm_start,
303 mem->dma_handle >> PAGE_SHIFT, 303 PFN_DOWN(virt_to_phys(mem->vaddr)),
304 size, vma->vm_page_prot); 304 size, vma->vm_page_prot);
305 if (retval) { 305 if (retval) {
306 dev_err(q->dev, "mmap: remap failed with error %d. ", retval); 306 dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
new file mode 100644
index 000000000000..6698c77e0f64
--- /dev/null
+++ b/drivers/media/video/videobuf2-core.c
@@ -0,0 +1,1819 @@
1/*
2 * videobuf2-core.c - V4L2 driver helper framework
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 * Marek Szyprowski <m.szyprowski@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation.
12 */
13
14#include <linux/err.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/mm.h>
18#include <linux/poll.h>
19#include <linux/slab.h>
20#include <linux/sched.h>
21
22#include <media/videobuf2-core.h>
23
24static int debug;
25module_param(debug, int, 0644);
26
27#define dprintk(level, fmt, arg...) \
28 do { \
29 if (debug >= level) \
30 printk(KERN_DEBUG "vb2: " fmt, ## arg); \
31 } while (0)
32
33#define call_memop(q, plane, op, args...) \
34 (((q)->mem_ops->op) ? \
35 ((q)->mem_ops->op(args)) : 0)
36
37#define call_qop(q, op, args...) \
38 (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
39
40/**
41 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
42 */
43static int __vb2_buf_mem_alloc(struct vb2_buffer *vb,
44 unsigned long *plane_sizes)
45{
46 struct vb2_queue *q = vb->vb2_queue;
47 void *mem_priv;
48 int plane;
49
50 /* Allocate memory for all planes in this buffer */
51 for (plane = 0; plane < vb->num_planes; ++plane) {
52 mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane],
53 plane_sizes[plane]);
54 if (!mem_priv)
55 goto free;
56
57 /* Associate allocator private data with this plane */
58 vb->planes[plane].mem_priv = mem_priv;
59 vb->v4l2_planes[plane].length = plane_sizes[plane];
60 }
61
62 return 0;
63free:
64 /* Free already allocated memory if one of the allocations failed */
65 for (; plane > 0; --plane)
66 call_memop(q, plane, put, vb->planes[plane - 1].mem_priv);
67
68 return -ENOMEM;
69}
70
71/**
72 * __vb2_buf_mem_free() - free memory of the given buffer
73 */
74static void __vb2_buf_mem_free(struct vb2_buffer *vb)
75{
76 struct vb2_queue *q = vb->vb2_queue;
77 unsigned int plane;
78
79 for (plane = 0; plane < vb->num_planes; ++plane) {
80 call_memop(q, plane, put, vb->planes[plane].mem_priv);
81 vb->planes[plane].mem_priv = NULL;
82 dprintk(3, "Freed plane %d of buffer %d\n",
83 plane, vb->v4l2_buf.index);
84 }
85}
86
87/**
88 * __vb2_buf_userptr_put() - release userspace memory associated with
89 * a USERPTR buffer
90 */
91static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
92{
93 struct vb2_queue *q = vb->vb2_queue;
94 unsigned int plane;
95
96 for (plane = 0; plane < vb->num_planes; ++plane) {
97 void *mem_priv = vb->planes[plane].mem_priv;
98
99 if (mem_priv) {
100 call_memop(q, plane, put_userptr, mem_priv);
101 vb->planes[plane].mem_priv = NULL;
102 }
103 }
104}
105
106/**
107 * __setup_offsets() - setup unique offsets ("cookies") for every plane in
108 * every buffer on the queue
109 */
110static void __setup_offsets(struct vb2_queue *q)
111{
112 unsigned int buffer, plane;
113 struct vb2_buffer *vb;
114 unsigned long off = 0;
115
116 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
117 vb = q->bufs[buffer];
118 if (!vb)
119 continue;
120
121 for (plane = 0; plane < vb->num_planes; ++plane) {
122 vb->v4l2_planes[plane].m.mem_offset = off;
123
124 dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n",
125 buffer, plane, off);
126
127 off += vb->v4l2_planes[plane].length;
128 off = PAGE_ALIGN(off);
129 }
130 }
131}
132
133/**
134 * __vb2_queue_alloc() - allocate videobuf buffer structures and (for MMAP type)
135 * video buffer memory for all buffers/planes on the queue and initializes the
136 * queue
137 *
138 * Returns the number of buffers successfully allocated.
139 */
140static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
141 unsigned int num_buffers, unsigned int num_planes,
142 unsigned long plane_sizes[])
143{
144 unsigned int buffer;
145 struct vb2_buffer *vb;
146 int ret;
147
148 for (buffer = 0; buffer < num_buffers; ++buffer) {
149 /* Allocate videobuf buffer structures */
150 vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
151 if (!vb) {
152 dprintk(1, "Memory alloc for buffer struct failed\n");
153 break;
154 }
155
156 /* Length stores number of planes for multiplanar buffers */
157 if (V4L2_TYPE_IS_MULTIPLANAR(q->type))
158 vb->v4l2_buf.length = num_planes;
159
160 vb->state = VB2_BUF_STATE_DEQUEUED;
161 vb->vb2_queue = q;
162 vb->num_planes = num_planes;
163 vb->v4l2_buf.index = buffer;
164 vb->v4l2_buf.type = q->type;
165 vb->v4l2_buf.memory = memory;
166
167 /* Allocate video buffer memory for the MMAP type */
168 if (memory == V4L2_MEMORY_MMAP) {
169 ret = __vb2_buf_mem_alloc(vb, plane_sizes);
170 if (ret) {
171 dprintk(1, "Failed allocating memory for "
172 "buffer %d\n", buffer);
173 kfree(vb);
174 break;
175 }
176 /*
177 * Call the driver-provided buffer initialization
178 * callback, if given. An error in initialization
179 * results in queue setup failure.
180 */
181 ret = call_qop(q, buf_init, vb);
182 if (ret) {
183 dprintk(1, "Buffer %d %p initialization"
184 " failed\n", buffer, vb);
185 __vb2_buf_mem_free(vb);
186 kfree(vb);
187 break;
188 }
189 }
190
191 q->bufs[buffer] = vb;
192 }
193
194 q->num_buffers = buffer;
195
196 __setup_offsets(q);
197
198 dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
199 q->num_buffers, num_planes);
200
201 return buffer;
202}
203
204/**
205 * __vb2_free_mem() - release all video buffer memory for a given queue
206 */
207static void __vb2_free_mem(struct vb2_queue *q)
208{
209 unsigned int buffer;
210 struct vb2_buffer *vb;
211
212 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
213 vb = q->bufs[buffer];
214 if (!vb)
215 continue;
216
217 /* Free MMAP buffers or release USERPTR buffers */
218 if (q->memory == V4L2_MEMORY_MMAP)
219 __vb2_buf_mem_free(vb);
220 else
221 __vb2_buf_userptr_put(vb);
222 }
223}
224
225/**
226 * __vb2_queue_free() - free the queue - video memory and related information
227 * and return the queue to an uninitialized state. Might be called even if the
228 * queue has already been freed.
229 */
230static void __vb2_queue_free(struct vb2_queue *q)
231{
232 unsigned int buffer;
233
234 /* Call driver-provided cleanup function for each buffer, if provided */
235 if (q->ops->buf_cleanup) {
236 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
237 if (NULL == q->bufs[buffer])
238 continue;
239 q->ops->buf_cleanup(q->bufs[buffer]);
240 }
241 }
242
243 /* Release video buffer memory */
244 __vb2_free_mem(q);
245
246 /* Free videobuf buffers */
247 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
248 kfree(q->bufs[buffer]);
249 q->bufs[buffer] = NULL;
250 }
251
252 q->num_buffers = 0;
253 q->memory = 0;
254}
255
256/**
257 * __verify_planes_array() - verify that the planes array passed in struct
258 * v4l2_buffer from userspace can be safely used
259 */
260static int __verify_planes_array(struct vb2_buffer *vb, struct v4l2_buffer *b)
261{
262 /* Is memory for copying plane information present? */
263 if (NULL == b->m.planes) {
264 dprintk(1, "Multi-planar buffer passed but "
265 "planes array not provided\n");
266 return -EINVAL;
267 }
268
269 if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) {
270 dprintk(1, "Incorrect planes array length, "
271 "expected %d, got %d\n", vb->num_planes, b->length);
272 return -EINVAL;
273 }
274
275 return 0;
276}
277
278/**
279 * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
280 * returned to userspace
281 */
282static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
283{
284 struct vb2_queue *q = vb->vb2_queue;
285 int ret = 0;
286
287 /* Copy back data such as timestamp, input, etc. */
288 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
289 b->input = vb->v4l2_buf.input;
290 b->reserved = vb->v4l2_buf.reserved;
291
292 if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) {
293 ret = __verify_planes_array(vb, b);
294 if (ret)
295 return ret;
296
297 /*
298 * Fill in plane-related data if userspace provided an array
299 * for it. The memory and size is verified above.
300 */
301 memcpy(b->m.planes, vb->v4l2_planes,
302 b->length * sizeof(struct v4l2_plane));
303 } else {
304 /*
305 * We use length and offset in v4l2_planes array even for
306 * single-planar buffers, but userspace does not.
307 */
308 b->length = vb->v4l2_planes[0].length;
309 b->bytesused = vb->v4l2_planes[0].bytesused;
310 if (q->memory == V4L2_MEMORY_MMAP)
311 b->m.offset = vb->v4l2_planes[0].m.mem_offset;
312 else if (q->memory == V4L2_MEMORY_USERPTR)
313 b->m.userptr = vb->v4l2_planes[0].m.userptr;
314 }
315
316 b->flags = 0;
317
318 switch (vb->state) {
319 case VB2_BUF_STATE_QUEUED:
320 case VB2_BUF_STATE_ACTIVE:
321 b->flags |= V4L2_BUF_FLAG_QUEUED;
322 break;
323 case VB2_BUF_STATE_ERROR:
324 b->flags |= V4L2_BUF_FLAG_ERROR;
325 /* fall through */
326 case VB2_BUF_STATE_DONE:
327 b->flags |= V4L2_BUF_FLAG_DONE;
328 break;
329 case VB2_BUF_STATE_DEQUEUED:
330 /* nothing */
331 break;
332 }
333
334 if (vb->num_planes_mapped == vb->num_planes)
335 b->flags |= V4L2_BUF_FLAG_MAPPED;
336
337 return ret;
338}
339
340/**
341 * vb2_querybuf() - query video buffer information
342 * @q: videobuf queue
343 * @b: buffer struct passed from userspace to vidioc_querybuf handler
344 * in driver
345 *
346 * Should be called from vidioc_querybuf ioctl handler in driver.
347 * This function will verify the passed v4l2_buffer structure and fill the
348 * relevant information for the userspace.
349 *
350 * The return values from this function are intended to be directly returned
351 * from vidioc_querybuf handler in driver.
352 */
353int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
354{
355 struct vb2_buffer *vb;
356
357 if (b->type != q->type) {
358 dprintk(1, "querybuf: wrong buffer type\n");
359 return -EINVAL;
360 }
361
362 if (b->index >= q->num_buffers) {
363 dprintk(1, "querybuf: buffer index out of range\n");
364 return -EINVAL;
365 }
366 vb = q->bufs[b->index];
367
368 return __fill_v4l2_buffer(vb, b);
369}
370EXPORT_SYMBOL(vb2_querybuf);
371
372/**
373 * __verify_userptr_ops() - verify that all memory operations required for
374 * USERPTR queue type have been provided
375 */
376static int __verify_userptr_ops(struct vb2_queue *q)
377{
378 if (!(q->io_modes & VB2_USERPTR) || !q->mem_ops->get_userptr ||
379 !q->mem_ops->put_userptr)
380 return -EINVAL;
381
382 return 0;
383}
384
385/**
386 * __verify_mmap_ops() - verify that all memory operations required for
387 * MMAP queue type have been provided
388 */
389static int __verify_mmap_ops(struct vb2_queue *q)
390{
391 if (!(q->io_modes & VB2_MMAP) || !q->mem_ops->alloc ||
392 !q->mem_ops->put || !q->mem_ops->mmap)
393 return -EINVAL;
394
395 return 0;
396}
397
398/**
399 * __buffers_in_use() - return true if any buffers on the queue are in use and
400 * the queue cannot be freed (by the means of REQBUFS(0)) call
401 */
402static bool __buffers_in_use(struct vb2_queue *q)
403{
404 unsigned int buffer, plane;
405 struct vb2_buffer *vb;
406
407 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
408 vb = q->bufs[buffer];
409 for (plane = 0; plane < vb->num_planes; ++plane) {
410 /*
411 * If num_users() has not been provided, call_memop
412 * will return 0, apparently nobody cares about this
413 * case anyway. If num_users() returns more than 1,
414 * we are not the only user of the plane's memory.
415 */
416 if (call_memop(q, plane, num_users,
417 vb->planes[plane].mem_priv) > 1)
418 return true;
419 }
420 }
421
422 return false;
423}
424
425/**
426 * vb2_reqbufs() - Initiate streaming
427 * @q: videobuf2 queue
428 * @req: struct passed from userspace to vidioc_reqbufs handler in driver
429 *
430 * Should be called from vidioc_reqbufs ioctl handler of a driver.
431 * This function:
432 * 1) verifies streaming parameters passed from the userspace,
433 * 2) sets up the queue,
434 * 3) negotiates number of buffers and planes per buffer with the driver
435 * to be used during streaming,
436 * 4) allocates internal buffer structures (struct vb2_buffer), according to
437 * the agreed parameters,
438 * 5) for MMAP memory type, allocates actual video memory, using the
439 * memory handling/allocation routines provided during queue initialization
440 *
441 * If req->count is 0, all the memory will be freed instead.
442 * If the queue has been allocated previously (by a previous vb2_reqbufs) call
443 * and the queue is not busy, memory will be reallocated.
444 *
445 * The return values from this function are intended to be directly returned
446 * from vidioc_reqbufs handler in driver.
447 */
448int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
449{
450 unsigned int num_buffers, num_planes;
451 unsigned long plane_sizes[VIDEO_MAX_PLANES];
452 int ret = 0;
453
454 if (q->fileio) {
455 dprintk(1, "reqbufs: file io in progress\n");
456 return -EBUSY;
457 }
458
459 if (req->memory != V4L2_MEMORY_MMAP
460 && req->memory != V4L2_MEMORY_USERPTR) {
461 dprintk(1, "reqbufs: unsupported memory type\n");
462 return -EINVAL;
463 }
464
465 if (req->type != q->type) {
466 dprintk(1, "reqbufs: requested type is incorrect\n");
467 return -EINVAL;
468 }
469
470 if (q->streaming) {
471 dprintk(1, "reqbufs: streaming active\n");
472 return -EBUSY;
473 }
474
475 /*
476 * Make sure all the required memory ops for given memory type
477 * are available.
478 */
479 if (req->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
480 dprintk(1, "reqbufs: MMAP for current setup unsupported\n");
481 return -EINVAL;
482 }
483
484 if (req->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
485 dprintk(1, "reqbufs: USERPTR for current setup unsupported\n");
486 return -EINVAL;
487 }
488
489 /*
490 * If the same number of buffers and memory access method is requested
491 * then return immediately.
492 */
493 if (q->memory == req->memory && req->count == q->num_buffers)
494 return 0;
495
496 if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) {
497 /*
498 * We already have buffers allocated, so first check if they
499 * are not in use and can be freed.
500 */
501 if (q->memory == V4L2_MEMORY_MMAP && __buffers_in_use(q)) {
502 dprintk(1, "reqbufs: memory in use, cannot free\n");
503 return -EBUSY;
504 }
505
506 __vb2_queue_free(q);
507
508 /*
509 * In case of REQBUFS(0) return immediately without calling
510 * driver's queue_setup() callback and allocating resources.
511 */
512 if (req->count == 0)
513 return 0;
514 }
515
516 /*
517 * Make sure the requested values and current defaults are sane.
518 */
519 num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
520 memset(plane_sizes, 0, sizeof(plane_sizes));
521 memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
522
523 /*
524 * Ask the driver how many buffers and planes per buffer it requires.
525 * Driver also sets the size and allocator context for each plane.
526 */
527 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
528 plane_sizes, q->alloc_ctx);
529 if (ret)
530 return ret;
531
532 /* Finally, allocate buffers and video memory */
533 ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes,
534 plane_sizes);
535 if (ret < 0) {
536 dprintk(1, "Memory allocation failed with error: %d\n", ret);
537 return ret;
538 }
539
540 /*
541 * Check if driver can handle the allocated number of buffers.
542 */
543 if (ret < num_buffers) {
544 unsigned int orig_num_buffers;
545
546 orig_num_buffers = num_buffers = ret;
547 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
548 plane_sizes, q->alloc_ctx);
549 if (ret)
550 goto free_mem;
551
552 if (orig_num_buffers < num_buffers) {
553 ret = -ENOMEM;
554 goto free_mem;
555 }
556
557 /*
558 * Ok, driver accepted smaller number of buffers.
559 */
560 ret = num_buffers;
561 }
562
563 q->memory = req->memory;
564
565 /*
566 * Return the number of successfully allocated buffers
567 * to the userspace.
568 */
569 req->count = ret;
570
571 return 0;
572
573free_mem:
574 __vb2_queue_free(q);
575 return ret;
576}
577EXPORT_SYMBOL_GPL(vb2_reqbufs);
578
579/**
580 * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
581 * @vb: vb2_buffer to which the plane in question belongs to
582 * @plane_no: plane number for which the address is to be returned
583 *
584 * This function returns a kernel virtual address of a given plane if
585 * such a mapping exist, NULL otherwise.
586 */
587void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
588{
589 struct vb2_queue *q = vb->vb2_queue;
590
591 if (plane_no > vb->num_planes)
592 return NULL;
593
594 return call_memop(q, plane_no, vaddr, vb->planes[plane_no].mem_priv);
595
596}
597EXPORT_SYMBOL_GPL(vb2_plane_vaddr);
598
599/**
600 * vb2_plane_cookie() - Return allocator specific cookie for the given plane
601 * @vb: vb2_buffer to which the plane in question belongs to
602 * @plane_no: plane number for which the cookie is to be returned
603 *
604 * This function returns an allocator specific cookie for a given plane if
605 * available, NULL otherwise. The allocator should provide some simple static
606 * inline function, which would convert this cookie to the allocator specific
607 * type that can be used directly by the driver to access the buffer. This can
608 * be for example physical address, pointer to scatter list or IOMMU mapping.
609 */
610void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
611{
612 struct vb2_queue *q = vb->vb2_queue;
613
614 if (plane_no > vb->num_planes)
615 return NULL;
616
617 return call_memop(q, plane_no, cookie, vb->planes[plane_no].mem_priv);
618}
619EXPORT_SYMBOL_GPL(vb2_plane_cookie);
620
621/**
622 * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
623 * @vb: vb2_buffer returned from the driver
624 * @state: either VB2_BUF_STATE_DONE if the operation finished successfully
625 * or VB2_BUF_STATE_ERROR if the operation finished with an error
626 *
627 * This function should be called by the driver after a hardware operation on
628 * a buffer is finished and the buffer may be returned to userspace. The driver
629 * cannot use this buffer anymore until it is queued back to it by videobuf
630 * by the means of buf_queue callback. Only buffers previously queued to the
631 * driver by buf_queue can be passed to this function.
632 */
633void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
634{
635 struct vb2_queue *q = vb->vb2_queue;
636 unsigned long flags;
637
638 if (vb->state != VB2_BUF_STATE_ACTIVE)
639 return;
640
641 if (state != VB2_BUF_STATE_DONE && state != VB2_BUF_STATE_ERROR)
642 return;
643
644 dprintk(4, "Done processing on buffer %d, state: %d\n",
645 vb->v4l2_buf.index, vb->state);
646
647 /* Add the buffer to the done buffers list */
648 spin_lock_irqsave(&q->done_lock, flags);
649 vb->state = state;
650 list_add_tail(&vb->done_entry, &q->done_list);
651 atomic_dec(&q->queued_count);
652 spin_unlock_irqrestore(&q->done_lock, flags);
653
654 /* Inform any processes that may be waiting for buffers */
655 wake_up(&q->done_wq);
656}
657EXPORT_SYMBOL_GPL(vb2_buffer_done);
658
659/**
660 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
661 * a v4l2_buffer by the userspace
662 */
663static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
664 struct v4l2_plane *v4l2_planes)
665{
666 unsigned int plane;
667 int ret;
668
669 if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
670 /*
671 * Verify that the userspace gave us a valid array for
672 * plane information.
673 */
674 ret = __verify_planes_array(vb, b);
675 if (ret)
676 return ret;
677
678 /* Fill in driver-provided information for OUTPUT types */
679 if (V4L2_TYPE_IS_OUTPUT(b->type)) {
680 /*
681 * Will have to go up to b->length when API starts
682 * accepting variable number of planes.
683 */
684 for (plane = 0; plane < vb->num_planes; ++plane) {
685 v4l2_planes[plane].bytesused =
686 b->m.planes[plane].bytesused;
687 v4l2_planes[plane].data_offset =
688 b->m.planes[plane].data_offset;
689 }
690 }
691
692 if (b->memory == V4L2_MEMORY_USERPTR) {
693 for (plane = 0; plane < vb->num_planes; ++plane) {
694 v4l2_planes[plane].m.userptr =
695 b->m.planes[plane].m.userptr;
696 v4l2_planes[plane].length =
697 b->m.planes[plane].length;
698 }
699 }
700 } else {
701 /*
702 * Single-planar buffers do not use planes array,
703 * so fill in relevant v4l2_buffer struct fields instead.
704 * In videobuf we use our internal V4l2_planes struct for
705 * single-planar buffers as well, for simplicity.
706 */
707 if (V4L2_TYPE_IS_OUTPUT(b->type))
708 v4l2_planes[0].bytesused = b->bytesused;
709
710 if (b->memory == V4L2_MEMORY_USERPTR) {
711 v4l2_planes[0].m.userptr = b->m.userptr;
712 v4l2_planes[0].length = b->length;
713 }
714 }
715
716 vb->v4l2_buf.field = b->field;
717 vb->v4l2_buf.timestamp = b->timestamp;
718
719 return 0;
720}
721
722/**
723 * __qbuf_userptr() - handle qbuf of a USERPTR buffer
724 */
725static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b)
726{
727 struct v4l2_plane planes[VIDEO_MAX_PLANES];
728 struct vb2_queue *q = vb->vb2_queue;
729 void *mem_priv;
730 unsigned int plane;
731 int ret;
732 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
733
734 /* Verify and copy relevant information provided by the userspace */
735 ret = __fill_vb2_buffer(vb, b, planes);
736 if (ret)
737 return ret;
738
739 for (plane = 0; plane < vb->num_planes; ++plane) {
740 /* Skip the plane if already verified */
741 if (vb->v4l2_planes[plane].m.userptr == planes[plane].m.userptr
742 && vb->v4l2_planes[plane].length == planes[plane].length)
743 continue;
744
745 dprintk(3, "qbuf: userspace address for plane %d changed, "
746 "reacquiring memory\n", plane);
747
748 /* Release previously acquired memory if present */
749 if (vb->planes[plane].mem_priv)
750 call_memop(q, plane, put_userptr,
751 vb->planes[plane].mem_priv);
752
753 vb->planes[plane].mem_priv = NULL;
754
755 /* Acquire each plane's memory */
756 if (q->mem_ops->get_userptr) {
757 mem_priv = q->mem_ops->get_userptr(q->alloc_ctx[plane],
758 planes[plane].m.userptr,
759 planes[plane].length,
760 write);
761 if (IS_ERR(mem_priv)) {
762 dprintk(1, "qbuf: failed acquiring userspace "
763 "memory for plane %d\n", plane);
764 ret = PTR_ERR(mem_priv);
765 goto err;
766 }
767 vb->planes[plane].mem_priv = mem_priv;
768 }
769 }
770
771 /*
772 * Call driver-specific initialization on the newly acquired buffer,
773 * if provided.
774 */
775 ret = call_qop(q, buf_init, vb);
776 if (ret) {
777 dprintk(1, "qbuf: buffer initialization failed\n");
778 goto err;
779 }
780
781 /*
782 * Now that everything is in order, copy relevant information
783 * provided by userspace.
784 */
785 for (plane = 0; plane < vb->num_planes; ++plane)
786 vb->v4l2_planes[plane] = planes[plane];
787
788 return 0;
789err:
790 /* In case of errors, release planes that were already acquired */
791 for (; plane > 0; --plane) {
792 call_memop(q, plane, put_userptr,
793 vb->planes[plane - 1].mem_priv);
794 vb->planes[plane - 1].mem_priv = NULL;
795 }
796
797 return ret;
798}
799
800/**
801 * __qbuf_mmap() - handle qbuf of an MMAP buffer
802 */
803static int __qbuf_mmap(struct vb2_buffer *vb, struct v4l2_buffer *b)
804{
805 return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
806}
807
808/**
809 * __enqueue_in_driver() - enqueue a vb2_buffer in driver for processing
810 */
811static void __enqueue_in_driver(struct vb2_buffer *vb)
812{
813 struct vb2_queue *q = vb->vb2_queue;
814
815 vb->state = VB2_BUF_STATE_ACTIVE;
816 atomic_inc(&q->queued_count);
817 q->ops->buf_queue(vb);
818}
819
820/**
821 * vb2_qbuf() - Queue a buffer from userspace
822 * @q: videobuf2 queue
823 * @b: buffer structure passed from userspace to vidioc_qbuf handler
824 * in driver
825 *
826 * Should be called from vidioc_qbuf ioctl handler of a driver.
827 * This function:
828 * 1) verifies the passed buffer,
829 * 2) calls buf_prepare callback in the driver (if provided), in which
830 * driver-specific buffer initialization can be performed,
831 * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
832 * callback for processing.
833 *
834 * The return values from this function are intended to be directly returned
835 * from vidioc_qbuf handler in driver.
836 */
837int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
838{
839 struct vb2_buffer *vb;
840 int ret = 0;
841
842 if (q->fileio) {
843 dprintk(1, "qbuf: file io in progress\n");
844 return -EBUSY;
845 }
846
847 if (b->type != q->type) {
848 dprintk(1, "qbuf: invalid buffer type\n");
849 return -EINVAL;
850 }
851
852 if (b->index >= q->num_buffers) {
853 dprintk(1, "qbuf: buffer index out of range\n");
854 return -EINVAL;
855 }
856
857 vb = q->bufs[b->index];
858 if (NULL == vb) {
859 /* Should never happen */
860 dprintk(1, "qbuf: buffer is NULL\n");
861 return -EINVAL;
862 }
863
864 if (b->memory != q->memory) {
865 dprintk(1, "qbuf: invalid memory type\n");
866 return -EINVAL;
867 }
868
869 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
870 dprintk(1, "qbuf: buffer already in use\n");
871 return -EINVAL;
872 }
873
874 if (q->memory == V4L2_MEMORY_MMAP)
875 ret = __qbuf_mmap(vb, b);
876 else if (q->memory == V4L2_MEMORY_USERPTR)
877 ret = __qbuf_userptr(vb, b);
878 else {
879 WARN(1, "Invalid queue type\n");
880 return -EINVAL;
881 }
882
883 if (ret)
884 return ret;
885
886 ret = call_qop(q, buf_prepare, vb);
887 if (ret) {
888 dprintk(1, "qbuf: buffer preparation failed\n");
889 return ret;
890 }
891
892 /*
893 * Add to the queued buffers list, a buffer will stay on it until
894 * dequeued in dqbuf.
895 */
896 list_add_tail(&vb->queued_entry, &q->queued_list);
897 vb->state = VB2_BUF_STATE_QUEUED;
898
899 /*
900 * If already streaming, give the buffer to driver for processing.
901 * If not, the buffer will be given to driver on next streamon.
902 */
903 if (q->streaming)
904 __enqueue_in_driver(vb);
905
906 dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
907 return 0;
908}
909EXPORT_SYMBOL_GPL(vb2_qbuf);
910
911/**
912 * __vb2_wait_for_done_vb() - wait for a buffer to become available
913 * for dequeuing
914 *
915 * Will sleep if required for nonblocking == false.
916 */
917static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
918{
919 /*
920 * All operations on vb_done_list are performed under done_lock
921 * spinlock protection. However, buffers may be removed from
922 * it and returned to userspace only while holding both driver's
923 * lock and the done_lock spinlock. Thus we can be sure that as
924 * long as we hold the driver's lock, the list will remain not
925 * empty if list_empty() check succeeds.
926 */
927
928 for (;;) {
929 int ret;
930
931 if (!q->streaming) {
932 dprintk(1, "Streaming off, will not wait for buffers\n");
933 return -EINVAL;
934 }
935
936 if (!list_empty(&q->done_list)) {
937 /*
938 * Found a buffer that we were waiting for.
939 */
940 break;
941 }
942
943 if (nonblocking) {
944 dprintk(1, "Nonblocking and no buffers to dequeue, "
945 "will not wait\n");
946 return -EAGAIN;
947 }
948
949 /*
950 * We are streaming and blocking, wait for another buffer to
951 * become ready or for streamoff. Driver's lock is released to
952 * allow streamoff or qbuf to be called while waiting.
953 */
954 call_qop(q, wait_prepare, q);
955
956 /*
957 * All locks have been released, it is safe to sleep now.
958 */
959 dprintk(3, "Will sleep waiting for buffers\n");
960 ret = wait_event_interruptible(q->done_wq,
961 !list_empty(&q->done_list) || !q->streaming);
962
963 /*
964 * We need to reevaluate both conditions again after reacquiring
965 * the locks or return an error if one occurred.
966 */
967 call_qop(q, wait_finish, q);
968 if (ret)
969 return ret;
970 }
971 return 0;
972}
973
974/**
975 * __vb2_get_done_vb() - get a buffer ready for dequeuing
976 *
977 * Will sleep if required for nonblocking == false.
978 */
979static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
980 int nonblocking)
981{
982 unsigned long flags;
983 int ret;
984
985 /*
986 * Wait for at least one buffer to become available on the done_list.
987 */
988 ret = __vb2_wait_for_done_vb(q, nonblocking);
989 if (ret)
990 return ret;
991
992 /*
993 * Driver's lock has been held since we last verified that done_list
994 * is not empty, so no need for another list_empty(done_list) check.
995 */
996 spin_lock_irqsave(&q->done_lock, flags);
997 *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);
998 list_del(&(*vb)->done_entry);
999 spin_unlock_irqrestore(&q->done_lock, flags);
1000
1001 return 0;
1002}
1003
1004/**
1005 * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2
1006 * @q: videobuf2 queue
1007 *
1008 * This function will wait until all buffers that have been given to the driver
1009 * by buf_queue() are given back to vb2 with vb2_buffer_done(). It doesn't call
1010 * wait_prepare, wait_finish pair. It is intended to be called with all locks
1011 * taken, for example from stop_streaming() callback.
1012 */
1013int vb2_wait_for_all_buffers(struct vb2_queue *q)
1014{
1015 if (!q->streaming) {
1016 dprintk(1, "Streaming off, will not wait for buffers\n");
1017 return -EINVAL;
1018 }
1019
1020 wait_event(q->done_wq, !atomic_read(&q->queued_count));
1021 return 0;
1022}
1023EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
1024
1025/**
1026 * vb2_dqbuf() - Dequeue a buffer to the userspace
1027 * @q: videobuf2 queue
1028 * @b: buffer structure passed from userspace to vidioc_dqbuf handler
1029 * in driver
1030 * @nonblocking: if true, this call will not sleep waiting for a buffer if no
1031 * buffers ready for dequeuing are present. Normally the driver
1032 * would be passing (file->f_flags & O_NONBLOCK) here
1033 *
1034 * Should be called from vidioc_dqbuf ioctl handler of a driver.
1035 * This function:
1036 * 1) verifies the passed buffer,
1037 * 2) calls buf_finish callback in the driver (if provided), in which
1038 * driver can perform any additional operations that may be required before
1039 * returning the buffer to userspace, such as cache sync,
1040 * 3) the buffer struct members are filled with relevant information for
1041 * the userspace.
1042 *
1043 * The return values from this function are intended to be directly returned
1044 * from vidioc_dqbuf handler in driver.
1045 */
1046int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1047{
1048 struct vb2_buffer *vb = NULL;
1049 int ret;
1050
1051 if (q->fileio) {
1052 dprintk(1, "dqbuf: file io in progress\n");
1053 return -EBUSY;
1054 }
1055
1056 if (b->type != q->type) {
1057 dprintk(1, "dqbuf: invalid buffer type\n");
1058 return -EINVAL;
1059 }
1060
1061 ret = __vb2_get_done_vb(q, &vb, nonblocking);
1062 if (ret < 0) {
1063 dprintk(1, "dqbuf: error getting next done buffer\n");
1064 return ret;
1065 }
1066
1067 ret = call_qop(q, buf_finish, vb);
1068 if (ret) {
1069 dprintk(1, "dqbuf: buffer finish failed\n");
1070 return ret;
1071 }
1072
1073 switch (vb->state) {
1074 case VB2_BUF_STATE_DONE:
1075 dprintk(3, "dqbuf: Returning done buffer\n");
1076 break;
1077 case VB2_BUF_STATE_ERROR:
1078 dprintk(3, "dqbuf: Returning done buffer with errors\n");
1079 break;
1080 default:
1081 dprintk(1, "dqbuf: Invalid buffer state\n");
1082 return -EINVAL;
1083 }
1084
1085 /* Fill buffer information for the userspace */
1086 __fill_v4l2_buffer(vb, b);
1087 /* Remove from videobuf queue */
1088 list_del(&vb->queued_entry);
1089
1090 dprintk(1, "dqbuf of buffer %d, with state %d\n",
1091 vb->v4l2_buf.index, vb->state);
1092
1093 vb->state = VB2_BUF_STATE_DEQUEUED;
1094 return 0;
1095}
1096EXPORT_SYMBOL_GPL(vb2_dqbuf);
1097
1098/**
1099 * vb2_streamon - start streaming
1100 * @q: videobuf2 queue
1101 * @type: type argument passed from userspace to vidioc_streamon handler
1102 *
1103 * Should be called from vidioc_streamon handler of a driver.
1104 * This function:
1105 * 1) verifies current state
1106 * 2) starts streaming and passes any previously queued buffers to the driver
1107 *
1108 * The return values from this function are intended to be directly returned
1109 * from vidioc_streamon handler in the driver.
1110 */
1111int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1112{
1113 struct vb2_buffer *vb;
1114 int ret;
1115
1116 if (q->fileio) {
1117 dprintk(1, "streamon: file io in progress\n");
1118 return -EBUSY;
1119 }
1120
1121 if (type != q->type) {
1122 dprintk(1, "streamon: invalid stream type\n");
1123 return -EINVAL;
1124 }
1125
1126 if (q->streaming) {
1127 dprintk(1, "streamon: already streaming\n");
1128 return -EBUSY;
1129 }
1130
1131 /*
1132 * Cannot start streaming on an OUTPUT device if no buffers have
1133 * been queued yet.
1134 */
1135 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1136 if (list_empty(&q->queued_list)) {
1137 dprintk(1, "streamon: no output buffers queued\n");
1138 return -EINVAL;
1139 }
1140 }
1141
1142 /*
1143 * Let driver notice that streaming state has been enabled.
1144 */
1145 ret = call_qop(q, start_streaming, q);
1146 if (ret) {
1147 dprintk(1, "streamon: driver refused to start streaming\n");
1148 return ret;
1149 }
1150
1151 q->streaming = 1;
1152
1153 /*
1154 * If any buffers were queued before streamon,
1155 * we can now pass them to driver for processing.
1156 */
1157 list_for_each_entry(vb, &q->queued_list, queued_entry)
1158 __enqueue_in_driver(vb);
1159
1160 dprintk(3, "Streamon successful\n");
1161 return 0;
1162}
1163EXPORT_SYMBOL_GPL(vb2_streamon);
1164
1165/**
1166 * __vb2_queue_cancel() - cancel and stop (pause) streaming
1167 *
1168 * Removes all queued buffers from driver's queue and all buffers queued by
1169 * userspace from videobuf's queue. Returns to state after reqbufs.
1170 */
1171static void __vb2_queue_cancel(struct vb2_queue *q)
1172{
1173 unsigned int i;
1174
1175 /*
1176 * Tell driver to stop all transactions and release all queued
1177 * buffers.
1178 */
1179 if (q->streaming)
1180 call_qop(q, stop_streaming, q);
1181 q->streaming = 0;
1182
1183 /*
1184 * Remove all buffers from videobuf's list...
1185 */
1186 INIT_LIST_HEAD(&q->queued_list);
1187 /*
1188 * ...and done list; userspace will not receive any buffers it
1189 * has not already dequeued before initiating cancel.
1190 */
1191 INIT_LIST_HEAD(&q->done_list);
1192 wake_up_all(&q->done_wq);
1193
1194 /*
1195 * Reinitialize all buffers for next use.
1196 */
1197 for (i = 0; i < q->num_buffers; ++i)
1198 q->bufs[i]->state = VB2_BUF_STATE_DEQUEUED;
1199}
1200
1201/**
1202 * vb2_streamoff - stop streaming
1203 * @q: videobuf2 queue
1204 * @type: type argument passed from userspace to vidioc_streamoff handler
1205 *
1206 * Should be called from vidioc_streamoff handler of a driver.
1207 * This function:
1208 * 1) verifies current state,
1209 * 2) stop streaming and dequeues any queued buffers, including those previously
1210 * passed to the driver (after waiting for the driver to finish).
1211 *
1212 * This call can be used for pausing playback.
1213 * The return values from this function are intended to be directly returned
1214 * from vidioc_streamoff handler in the driver
1215 */
1216int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
1217{
1218 if (q->fileio) {
1219 dprintk(1, "streamoff: file io in progress\n");
1220 return -EBUSY;
1221 }
1222
1223 if (type != q->type) {
1224 dprintk(1, "streamoff: invalid stream type\n");
1225 return -EINVAL;
1226 }
1227
1228 if (!q->streaming) {
1229 dprintk(1, "streamoff: not streaming\n");
1230 return -EINVAL;
1231 }
1232
1233 /*
1234 * Cancel will pause streaming and remove all buffers from the driver
1235 * and videobuf, effectively returning control over them to userspace.
1236 */
1237 __vb2_queue_cancel(q);
1238
1239 dprintk(3, "Streamoff successful\n");
1240 return 0;
1241}
1242EXPORT_SYMBOL_GPL(vb2_streamoff);
1243
1244/**
1245 * __find_plane_by_offset() - find plane associated with the given offset off
1246 */
1247static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
1248 unsigned int *_buffer, unsigned int *_plane)
1249{
1250 struct vb2_buffer *vb;
1251 unsigned int buffer, plane;
1252
1253 /*
1254 * Go over all buffers and their planes, comparing the given offset
1255 * with an offset assigned to each plane. If a match is found,
1256 * return its buffer and plane numbers.
1257 */
1258 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
1259 vb = q->bufs[buffer];
1260
1261 for (plane = 0; plane < vb->num_planes; ++plane) {
1262 if (vb->v4l2_planes[plane].m.mem_offset == off) {
1263 *_buffer = buffer;
1264 *_plane = plane;
1265 return 0;
1266 }
1267 }
1268 }
1269
1270 return -EINVAL;
1271}
1272
1273/**
1274 * vb2_mmap() - map video buffers into application address space
1275 * @q: videobuf2 queue
1276 * @vma: vma passed to the mmap file operation handler in the driver
1277 *
1278 * Should be called from mmap file operation handler of a driver.
1279 * This function maps one plane of one of the available video buffers to
1280 * userspace. To map whole video memory allocated on reqbufs, this function
1281 * has to be called once per each plane per each buffer previously allocated.
1282 *
1283 * When the userspace application calls mmap, it passes to it an offset returned
1284 * to it earlier by the means of vidioc_querybuf handler. That offset acts as
1285 * a "cookie", which is then used to identify the plane to be mapped.
1286 * This function finds a plane with a matching offset and a mapping is performed
1287 * by the means of a provided memory operation.
1288 *
1289 * The return values from this function are intended to be directly returned
1290 * from the mmap handler in driver.
1291 */
1292int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
1293{
1294 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
1295 struct vb2_plane *vb_plane;
1296 struct vb2_buffer *vb;
1297 unsigned int buffer, plane;
1298 int ret;
1299
1300 if (q->memory != V4L2_MEMORY_MMAP) {
1301 dprintk(1, "Queue is not currently set up for mmap\n");
1302 return -EINVAL;
1303 }
1304
1305 /*
1306 * Check memory area access mode.
1307 */
1308 if (!(vma->vm_flags & VM_SHARED)) {
1309 dprintk(1, "Invalid vma flags, VM_SHARED needed\n");
1310 return -EINVAL;
1311 }
1312 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1313 if (!(vma->vm_flags & VM_WRITE)) {
1314 dprintk(1, "Invalid vma flags, VM_WRITE needed\n");
1315 return -EINVAL;
1316 }
1317 } else {
1318 if (!(vma->vm_flags & VM_READ)) {
1319 dprintk(1, "Invalid vma flags, VM_READ needed\n");
1320 return -EINVAL;
1321 }
1322 }
1323
1324 /*
1325 * Find the plane corresponding to the offset passed by userspace.
1326 */
1327 ret = __find_plane_by_offset(q, off, &buffer, &plane);
1328 if (ret)
1329 return ret;
1330
1331 vb = q->bufs[buffer];
1332 vb_plane = &vb->planes[plane];
1333
1334 ret = q->mem_ops->mmap(vb_plane->mem_priv, vma);
1335 if (ret)
1336 return ret;
1337
1338 vb_plane->mapped = 1;
1339 vb->num_planes_mapped++;
1340
1341 dprintk(3, "Buffer %d, plane %d successfully mapped\n", buffer, plane);
1342 return 0;
1343}
1344EXPORT_SYMBOL_GPL(vb2_mmap);
1345
1346static int __vb2_init_fileio(struct vb2_queue *q, int read);
1347static int __vb2_cleanup_fileio(struct vb2_queue *q);
1348
1349/**
1350 * vb2_poll() - implements poll userspace operation
1351 * @q: videobuf2 queue
1352 * @file: file argument passed to the poll file operation handler
1353 * @wait: wait argument passed to the poll file operation handler
1354 *
1355 * This function implements poll file operation handler for a driver.
1356 * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
1357 * be informed that the file descriptor of a video device is available for
1358 * reading.
1359 * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
1360 * will be reported as available for writing.
1361 *
1362 * The return values from this function are intended to be directly returned
1363 * from poll handler in driver.
1364 */
1365unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
1366{
1367 unsigned long flags;
1368 unsigned int ret;
1369 struct vb2_buffer *vb = NULL;
1370
1371 /*
1372 * Start file I/O emulator only if streaming API has not been used yet.
1373 */
1374 if (q->num_buffers == 0 && q->fileio == NULL) {
1375 if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ)) {
1376 ret = __vb2_init_fileio(q, 1);
1377 if (ret)
1378 return POLLERR;
1379 }
1380 if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE)) {
1381 ret = __vb2_init_fileio(q, 0);
1382 if (ret)
1383 return POLLERR;
1384 /*
1385 * Write to OUTPUT queue can be done immediately.
1386 */
1387 return POLLOUT | POLLWRNORM;
1388 }
1389 }
1390
1391 /*
1392 * There is nothing to wait for if no buffers have already been queued.
1393 */
1394 if (list_empty(&q->queued_list))
1395 return POLLERR;
1396
1397 poll_wait(file, &q->done_wq, wait);
1398
1399 /*
1400 * Take first buffer available for dequeuing.
1401 */
1402 spin_lock_irqsave(&q->done_lock, flags);
1403 if (!list_empty(&q->done_list))
1404 vb = list_first_entry(&q->done_list, struct vb2_buffer,
1405 done_entry);
1406 spin_unlock_irqrestore(&q->done_lock, flags);
1407
1408 if (vb && (vb->state == VB2_BUF_STATE_DONE
1409 || vb->state == VB2_BUF_STATE_ERROR)) {
1410 return (V4L2_TYPE_IS_OUTPUT(q->type)) ? POLLOUT | POLLWRNORM :
1411 POLLIN | POLLRDNORM;
1412 }
1413 return 0;
1414}
1415EXPORT_SYMBOL_GPL(vb2_poll);
1416
1417/**
1418 * vb2_queue_init() - initialize a videobuf2 queue
1419 * @q: videobuf2 queue; this structure should be allocated in driver
1420 *
1421 * The vb2_queue structure should be allocated by the driver. The driver is
1422 * responsible of clearing it's content and setting initial values for some
1423 * required entries before calling this function.
1424 * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
1425 * to the struct vb2_queue description in include/media/videobuf2-core.h
1426 * for more information.
1427 */
1428int vb2_queue_init(struct vb2_queue *q)
1429{
1430 BUG_ON(!q);
1431 BUG_ON(!q->ops);
1432 BUG_ON(!q->mem_ops);
1433 BUG_ON(!q->type);
1434 BUG_ON(!q->io_modes);
1435
1436 BUG_ON(!q->ops->queue_setup);
1437 BUG_ON(!q->ops->buf_queue);
1438
1439 INIT_LIST_HEAD(&q->queued_list);
1440 INIT_LIST_HEAD(&q->done_list);
1441 spin_lock_init(&q->done_lock);
1442 init_waitqueue_head(&q->done_wq);
1443
1444 if (q->buf_struct_size == 0)
1445 q->buf_struct_size = sizeof(struct vb2_buffer);
1446
1447 return 0;
1448}
1449EXPORT_SYMBOL_GPL(vb2_queue_init);
1450
1451/**
1452 * vb2_queue_release() - stop streaming, release the queue and free memory
1453 * @q: videobuf2 queue
1454 *
1455 * This function stops streaming and performs necessary clean ups, including
1456 * freeing video buffer memory. The driver is responsible for freeing
1457 * the vb2_queue structure itself.
1458 */
1459void vb2_queue_release(struct vb2_queue *q)
1460{
1461 __vb2_cleanup_fileio(q);
1462 __vb2_queue_cancel(q);
1463 __vb2_queue_free(q);
1464}
1465EXPORT_SYMBOL_GPL(vb2_queue_release);
1466
1467/**
1468 * struct vb2_fileio_buf - buffer context used by file io emulator
1469 *
1470 * vb2 provides a compatibility layer and emulator of file io (read and
1471 * write) calls on top of streaming API. This structure is used for
1472 * tracking context related to the buffers.
1473 */
1474struct vb2_fileio_buf {
1475 void *vaddr;
1476 unsigned int size;
1477 unsigned int pos;
1478 unsigned int queued:1;
1479};
1480
1481/**
1482 * struct vb2_fileio_data - queue context used by file io emulator
1483 *
1484 * vb2 provides a compatibility layer and emulator of file io (read and
1485 * write) calls on top of streaming API. For proper operation it required
1486 * this structure to save the driver state between each call of the read
1487 * or write function.
1488 */
1489struct vb2_fileio_data {
1490 struct v4l2_requestbuffers req;
1491 struct v4l2_buffer b;
1492 struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME];
1493 unsigned int index;
1494 unsigned int q_count;
1495 unsigned int dq_count;
1496 unsigned int flags;
1497};
1498
1499/**
1500 * __vb2_init_fileio() - initialize file io emulator
1501 * @q: videobuf2 queue
1502 * @read: mode selector (1 means read, 0 means write)
1503 */
1504static int __vb2_init_fileio(struct vb2_queue *q, int read)
1505{
1506 struct vb2_fileio_data *fileio;
1507 int i, ret;
1508 unsigned int count = 0;
1509
1510 /*
1511 * Sanity check
1512 */
1513 if ((read && !(q->io_modes & VB2_READ)) ||
1514 (!read && !(q->io_modes & VB2_WRITE)))
1515 BUG();
1516
1517 /*
1518 * Check if device supports mapping buffers to kernel virtual space.
1519 */
1520 if (!q->mem_ops->vaddr)
1521 return -EBUSY;
1522
1523 /*
1524 * Check if streaming api has not been already activated.
1525 */
1526 if (q->streaming || q->num_buffers > 0)
1527 return -EBUSY;
1528
1529 /*
1530 * Start with count 1, driver can increase it in queue_setup()
1531 */
1532 count = 1;
1533
1534 dprintk(3, "setting up file io: mode %s, count %d, flags %08x\n",
1535 (read) ? "read" : "write", count, q->io_flags);
1536
1537 fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
1538 if (fileio == NULL)
1539 return -ENOMEM;
1540
1541 fileio->flags = q->io_flags;
1542
1543 /*
1544 * Request buffers and use MMAP type to force driver
1545 * to allocate buffers by itself.
1546 */
1547 fileio->req.count = count;
1548 fileio->req.memory = V4L2_MEMORY_MMAP;
1549 fileio->req.type = q->type;
1550 ret = vb2_reqbufs(q, &fileio->req);
1551 if (ret)
1552 goto err_kfree;
1553
1554 /*
1555 * Check if plane_count is correct
1556 * (multiplane buffers are not supported).
1557 */
1558 if (q->bufs[0]->num_planes != 1) {
1559 fileio->req.count = 0;
1560 ret = -EBUSY;
1561 goto err_reqbufs;
1562 }
1563
1564 /*
1565 * Get kernel address of each buffer.
1566 */
1567 for (i = 0; i < q->num_buffers; i++) {
1568 fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
1569 if (fileio->bufs[i].vaddr == NULL)
1570 goto err_reqbufs;
1571 fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
1572 }
1573
1574 /*
1575 * Read mode requires pre queuing of all buffers.
1576 */
1577 if (read) {
1578 /*
1579 * Queue all buffers.
1580 */
1581 for (i = 0; i < q->num_buffers; i++) {
1582 struct v4l2_buffer *b = &fileio->b;
1583 memset(b, 0, sizeof(*b));
1584 b->type = q->type;
1585 b->memory = q->memory;
1586 b->index = i;
1587 ret = vb2_qbuf(q, b);
1588 if (ret)
1589 goto err_reqbufs;
1590 fileio->bufs[i].queued = 1;
1591 }
1592
1593 /*
1594 * Start streaming.
1595 */
1596 ret = vb2_streamon(q, q->type);
1597 if (ret)
1598 goto err_reqbufs;
1599 }
1600
1601 q->fileio = fileio;
1602
1603 return ret;
1604
1605err_reqbufs:
1606 vb2_reqbufs(q, &fileio->req);
1607
1608err_kfree:
1609 kfree(fileio);
1610 return ret;
1611}
1612
1613/**
1614 * __vb2_cleanup_fileio() - free resourced used by file io emulator
1615 * @q: videobuf2 queue
1616 */
1617static int __vb2_cleanup_fileio(struct vb2_queue *q)
1618{
1619 struct vb2_fileio_data *fileio = q->fileio;
1620
1621 if (fileio) {
1622 /*
1623 * Hack fileio context to enable direct calls to vb2 ioctl
1624 * interface.
1625 */
1626 q->fileio = NULL;
1627
1628 vb2_streamoff(q, q->type);
1629 fileio->req.count = 0;
1630 vb2_reqbufs(q, &fileio->req);
1631 kfree(fileio);
1632 dprintk(3, "file io emulator closed\n");
1633 }
1634 return 0;
1635}
1636
1637/**
1638 * __vb2_perform_fileio() - perform a single file io (read or write) operation
1639 * @q: videobuf2 queue
1640 * @data: pointed to target userspace buffer
1641 * @count: number of bytes to read or write
1642 * @ppos: file handle position tracking pointer
1643 * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
1644 * @read: access mode selector (1 means read, 0 means write)
1645 */
1646static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
1647 loff_t *ppos, int nonblock, int read)
1648{
1649 struct vb2_fileio_data *fileio;
1650 struct vb2_fileio_buf *buf;
1651 int ret, index;
1652
1653 dprintk(3, "file io: mode %s, offset %ld, count %zd, %sblocking\n",
1654 read ? "read" : "write", (long)*ppos, count,
1655 nonblock ? "non" : "");
1656
1657 if (!data)
1658 return -EINVAL;
1659
1660 /*
1661 * Initialize emulator on first call.
1662 */
1663 if (!q->fileio) {
1664 ret = __vb2_init_fileio(q, read);
1665 dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
1666 if (ret)
1667 return ret;
1668 }
1669 fileio = q->fileio;
1670
1671 /*
1672 * Hack fileio context to enable direct calls to vb2 ioctl interface.
1673 * The pointer will be restored before returning from this function.
1674 */
1675 q->fileio = NULL;
1676
1677 index = fileio->index;
1678 buf = &fileio->bufs[index];
1679
1680 /*
1681 * Check if we need to dequeue the buffer.
1682 */
1683 if (buf->queued) {
1684 struct vb2_buffer *vb;
1685
1686 /*
1687 * Call vb2_dqbuf to get buffer back.
1688 */
1689 memset(&fileio->b, 0, sizeof(fileio->b));
1690 fileio->b.type = q->type;
1691 fileio->b.memory = q->memory;
1692 fileio->b.index = index;
1693 ret = vb2_dqbuf(q, &fileio->b, nonblock);
1694 dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
1695 if (ret)
1696 goto end;
1697 fileio->dq_count += 1;
1698
1699 /*
1700 * Get number of bytes filled by the driver
1701 */
1702 vb = q->bufs[index];
1703 buf->size = vb2_get_plane_payload(vb, 0);
1704 buf->queued = 0;
1705 }
1706
1707 /*
1708 * Limit count on last few bytes of the buffer.
1709 */
1710 if (buf->pos + count > buf->size) {
1711 count = buf->size - buf->pos;
1712 dprintk(5, "reducing read count: %zd\n", count);
1713 }
1714
1715 /*
1716 * Transfer data to userspace.
1717 */
1718 dprintk(3, "file io: copying %zd bytes - buffer %d, offset %u\n",
1719 count, index, buf->pos);
1720 if (read)
1721 ret = copy_to_user(data, buf->vaddr + buf->pos, count);
1722 else
1723 ret = copy_from_user(buf->vaddr + buf->pos, data, count);
1724 if (ret) {
1725 dprintk(3, "file io: error copying data\n");
1726 ret = -EFAULT;
1727 goto end;
1728 }
1729
1730 /*
1731 * Update counters.
1732 */
1733 buf->pos += count;
1734 *ppos += count;
1735
1736 /*
1737 * Queue next buffer if required.
1738 */
1739 if (buf->pos == buf->size ||
1740 (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) {
1741 /*
1742 * Check if this is the last buffer to read.
1743 */
1744 if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) &&
1745 fileio->dq_count == 1) {
1746 dprintk(3, "file io: read limit reached\n");
1747 /*
1748 * Restore fileio pointer and release the context.
1749 */
1750 q->fileio = fileio;
1751 return __vb2_cleanup_fileio(q);
1752 }
1753
1754 /*
1755 * Call vb2_qbuf and give buffer to the driver.
1756 */
1757 memset(&fileio->b, 0, sizeof(fileio->b));
1758 fileio->b.type = q->type;
1759 fileio->b.memory = q->memory;
1760 fileio->b.index = index;
1761 fileio->b.bytesused = buf->pos;
1762 ret = vb2_qbuf(q, &fileio->b);
1763 dprintk(5, "file io: vb2_dbuf result: %d\n", ret);
1764 if (ret)
1765 goto end;
1766
1767 /*
1768 * Buffer has been queued, update the status
1769 */
1770 buf->pos = 0;
1771 buf->queued = 1;
1772 buf->size = q->bufs[0]->v4l2_planes[0].length;
1773 fileio->q_count += 1;
1774
1775 /*
1776 * Switch to the next buffer
1777 */
1778 fileio->index = (index + 1) % q->num_buffers;
1779
1780 /*
1781 * Start streaming if required.
1782 */
1783 if (!read && !q->streaming) {
1784 ret = vb2_streamon(q, q->type);
1785 if (ret)
1786 goto end;
1787 }
1788 }
1789
1790 /*
1791 * Return proper number of bytes processed.
1792 */
1793 if (ret == 0)
1794 ret = count;
1795end:
1796 /*
1797 * Restore the fileio context and block vb2 ioctl interface.
1798 */
1799 q->fileio = fileio;
1800 return ret;
1801}
1802
1803size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
1804 loff_t *ppos, int nonblocking)
1805{
1806 return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
1807}
1808EXPORT_SYMBOL_GPL(vb2_read);
1809
1810size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
1811 loff_t *ppos, int nonblocking)
1812{
1813 return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 0);
1814}
1815EXPORT_SYMBOL_GPL(vb2_write);
1816
1817MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
1818MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski");
1819MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
new file mode 100644
index 000000000000..58205d596138
--- /dev/null
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -0,0 +1,185 @@
1/*
2 * videobuf2-dma-contig.c - DMA contig memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/dma-mapping.h>
16
17#include <media/videobuf2-core.h>
18#include <media/videobuf2-memops.h>
19
20struct vb2_dc_conf {
21 struct device *dev;
22};
23
24struct vb2_dc_buf {
25 struct vb2_dc_conf *conf;
26 void *vaddr;
27 dma_addr_t paddr;
28 unsigned long size;
29 struct vm_area_struct *vma;
30 atomic_t refcount;
31 struct vb2_vmarea_handler handler;
32};
33
34static void vb2_dma_contig_put(void *buf_priv);
35
36static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
37{
38 struct vb2_dc_conf *conf = alloc_ctx;
39 struct vb2_dc_buf *buf;
40
41 buf = kzalloc(sizeof *buf, GFP_KERNEL);
42 if (!buf)
43 return ERR_PTR(-ENOMEM);
44
45 buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->paddr,
46 GFP_KERNEL);
47 if (!buf->vaddr) {
48 dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
49 buf->size);
50 kfree(buf);
51 return ERR_PTR(-ENOMEM);
52 }
53
54 buf->conf = conf;
55 buf->size = size;
56
57 buf->handler.refcount = &buf->refcount;
58 buf->handler.put = vb2_dma_contig_put;
59 buf->handler.arg = buf;
60
61 atomic_inc(&buf->refcount);
62
63 return buf;
64}
65
66static void vb2_dma_contig_put(void *buf_priv)
67{
68 struct vb2_dc_buf *buf = buf_priv;
69
70 if (atomic_dec_and_test(&buf->refcount)) {
71 dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
72 buf->paddr);
73 kfree(buf);
74 }
75}
76
77static void *vb2_dma_contig_cookie(void *buf_priv)
78{
79 struct vb2_dc_buf *buf = buf_priv;
80
81 return &buf->paddr;
82}
83
84static void *vb2_dma_contig_vaddr(void *buf_priv)
85{
86 struct vb2_dc_buf *buf = buf_priv;
87 if (!buf)
88 return 0;
89
90 return buf->vaddr;
91}
92
93static unsigned int vb2_dma_contig_num_users(void *buf_priv)
94{
95 struct vb2_dc_buf *buf = buf_priv;
96
97 return atomic_read(&buf->refcount);
98}
99
100static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
101{
102 struct vb2_dc_buf *buf = buf_priv;
103
104 if (!buf) {
105 printk(KERN_ERR "No buffer to map\n");
106 return -EINVAL;
107 }
108
109 return vb2_mmap_pfn_range(vma, buf->paddr, buf->size,
110 &vb2_common_vm_ops, &buf->handler);
111}
112
113static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
114 unsigned long size, int write)
115{
116 struct vb2_dc_buf *buf;
117 struct vm_area_struct *vma;
118 dma_addr_t paddr = 0;
119 int ret;
120
121 buf = kzalloc(sizeof *buf, GFP_KERNEL);
122 if (!buf)
123 return ERR_PTR(-ENOMEM);
124
125 ret = vb2_get_contig_userptr(vaddr, size, &vma, &paddr);
126 if (ret) {
127 printk(KERN_ERR "Failed acquiring VMA for vaddr 0x%08lx\n",
128 vaddr);
129 kfree(buf);
130 return ERR_PTR(ret);
131 }
132
133 buf->size = size;
134 buf->paddr = paddr;
135 buf->vma = vma;
136
137 return buf;
138}
139
140static void vb2_dma_contig_put_userptr(void *mem_priv)
141{
142 struct vb2_dc_buf *buf = mem_priv;
143
144 if (!buf)
145 return;
146
147 vb2_put_vma(buf->vma);
148 kfree(buf);
149}
150
151const struct vb2_mem_ops vb2_dma_contig_memops = {
152 .alloc = vb2_dma_contig_alloc,
153 .put = vb2_dma_contig_put,
154 .cookie = vb2_dma_contig_cookie,
155 .vaddr = vb2_dma_contig_vaddr,
156 .mmap = vb2_dma_contig_mmap,
157 .get_userptr = vb2_dma_contig_get_userptr,
158 .put_userptr = vb2_dma_contig_put_userptr,
159 .num_users = vb2_dma_contig_num_users,
160};
161EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
162
163void *vb2_dma_contig_init_ctx(struct device *dev)
164{
165 struct vb2_dc_conf *conf;
166
167 conf = kzalloc(sizeof *conf, GFP_KERNEL);
168 if (!conf)
169 return ERR_PTR(-ENOMEM);
170
171 conf->dev = dev;
172
173 return conf;
174}
175EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx);
176
177void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
178{
179 kfree(alloc_ctx);
180}
181EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
182
183MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
184MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
185MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-dma-sg.c b/drivers/media/video/videobuf2-dma-sg.c
new file mode 100644
index 000000000000..b2d9485aac75
--- /dev/null
+++ b/drivers/media/video/videobuf2-dma-sg.c
@@ -0,0 +1,294 @@
1/*
2 * videobuf2-dma-sg.c - dma scatter/gather memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/mm.h>
15#include <linux/scatterlist.h>
16#include <linux/sched.h>
17#include <linux/slab.h>
18#include <linux/vmalloc.h>
19
20#include <media/videobuf2-core.h>
21#include <media/videobuf2-memops.h>
22#include <media/videobuf2-dma-sg.h>
23
24struct vb2_dma_sg_buf {
25 void *vaddr;
26 struct page **pages;
27 int write;
28 int offset;
29 struct vb2_dma_sg_desc sg_desc;
30 atomic_t refcount;
31 struct vb2_vmarea_handler handler;
32};
33
34static void vb2_dma_sg_put(void *buf_priv);
35
36static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size)
37{
38 struct vb2_dma_sg_buf *buf;
39 int i;
40
41 buf = kzalloc(sizeof *buf, GFP_KERNEL);
42 if (!buf)
43 return NULL;
44
45 buf->vaddr = NULL;
46 buf->write = 0;
47 buf->offset = 0;
48 buf->sg_desc.size = size;
49 buf->sg_desc.num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
50
51 buf->sg_desc.sglist = vmalloc(buf->sg_desc.num_pages *
52 sizeof(*buf->sg_desc.sglist));
53 if (!buf->sg_desc.sglist)
54 goto fail_sglist_alloc;
55 memset(buf->sg_desc.sglist, 0, buf->sg_desc.num_pages *
56 sizeof(*buf->sg_desc.sglist));
57 sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
58
59 buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *),
60 GFP_KERNEL);
61 if (!buf->pages)
62 goto fail_pages_array_alloc;
63
64 for (i = 0; i < buf->sg_desc.num_pages; ++i) {
65 buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
66 if (NULL == buf->pages[i])
67 goto fail_pages_alloc;
68 sg_set_page(&buf->sg_desc.sglist[i],
69 buf->pages[i], PAGE_SIZE, 0);
70 }
71
72 buf->handler.refcount = &buf->refcount;
73 buf->handler.put = vb2_dma_sg_put;
74 buf->handler.arg = buf;
75
76 atomic_inc(&buf->refcount);
77
78 printk(KERN_DEBUG "%s: Allocated buffer of %d pages\n",
79 __func__, buf->sg_desc.num_pages);
80
81 if (!buf->vaddr)
82 buf->vaddr = vm_map_ram(buf->pages,
83 buf->sg_desc.num_pages,
84 -1,
85 PAGE_KERNEL);
86 return buf;
87
88fail_pages_alloc:
89 while (--i >= 0)
90 __free_page(buf->pages[i]);
91 kfree(buf->pages);
92
93fail_pages_array_alloc:
94 vfree(buf->sg_desc.sglist);
95
96fail_sglist_alloc:
97 kfree(buf);
98 return NULL;
99}
100
101static void vb2_dma_sg_put(void *buf_priv)
102{
103 struct vb2_dma_sg_buf *buf = buf_priv;
104 int i = buf->sg_desc.num_pages;
105
106 if (atomic_dec_and_test(&buf->refcount)) {
107 printk(KERN_DEBUG "%s: Freeing buffer of %d pages\n", __func__,
108 buf->sg_desc.num_pages);
109 if (buf->vaddr)
110 vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages);
111 vfree(buf->sg_desc.sglist);
112 while (--i >= 0)
113 __free_page(buf->pages[i]);
114 kfree(buf->pages);
115 kfree(buf);
116 }
117}
118
119static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
120 unsigned long size, int write)
121{
122 struct vb2_dma_sg_buf *buf;
123 unsigned long first, last;
124 int num_pages_from_user, i;
125
126 buf = kzalloc(sizeof *buf, GFP_KERNEL);
127 if (!buf)
128 return NULL;
129
130 buf->vaddr = NULL;
131 buf->write = write;
132 buf->offset = vaddr & ~PAGE_MASK;
133 buf->sg_desc.size = size;
134
135 first = (vaddr & PAGE_MASK) >> PAGE_SHIFT;
136 last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT;
137 buf->sg_desc.num_pages = last - first + 1;
138
139 buf->sg_desc.sglist = vmalloc(
140 buf->sg_desc.num_pages * sizeof(*buf->sg_desc.sglist));
141 if (!buf->sg_desc.sglist)
142 goto userptr_fail_sglist_alloc;
143
144 memset(buf->sg_desc.sglist, 0,
145 buf->sg_desc.num_pages * sizeof(*buf->sg_desc.sglist));
146 sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
147
148 buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *),
149 GFP_KERNEL);
150 if (!buf->pages)
151 goto userptr_fail_pages_array_alloc;
152
153 down_read(&current->mm->mmap_sem);
154 num_pages_from_user = get_user_pages(current, current->mm,
155 vaddr & PAGE_MASK,
156 buf->sg_desc.num_pages,
157 write,
158 1, /* force */
159 buf->pages,
160 NULL);
161 up_read(&current->mm->mmap_sem);
162 if (num_pages_from_user != buf->sg_desc.num_pages)
163 goto userptr_fail_get_user_pages;
164
165 sg_set_page(&buf->sg_desc.sglist[0], buf->pages[0],
166 PAGE_SIZE - buf->offset, buf->offset);
167 size -= PAGE_SIZE - buf->offset;
168 for (i = 1; i < buf->sg_desc.num_pages; ++i) {
169 sg_set_page(&buf->sg_desc.sglist[i], buf->pages[i],
170 min_t(size_t, PAGE_SIZE, size), 0);
171 size -= min_t(size_t, PAGE_SIZE, size);
172 }
173 return buf;
174
175userptr_fail_get_user_pages:
176 printk(KERN_DEBUG "get_user_pages requested/got: %d/%d]\n",
177 num_pages_from_user, buf->sg_desc.num_pages);
178 while (--num_pages_from_user >= 0)
179 put_page(buf->pages[num_pages_from_user]);
180 kfree(buf->pages);
181
182userptr_fail_pages_array_alloc:
183 vfree(buf->sg_desc.sglist);
184
185userptr_fail_sglist_alloc:
186 kfree(buf);
187 return NULL;
188}
189
190/*
191 * @put_userptr: inform the allocator that a USERPTR buffer will no longer
192 * be used
193 */
194static void vb2_dma_sg_put_userptr(void *buf_priv)
195{
196 struct vb2_dma_sg_buf *buf = buf_priv;
197 int i = buf->sg_desc.num_pages;
198
199 printk(KERN_DEBUG "%s: Releasing userspace buffer of %d pages\n",
200 __func__, buf->sg_desc.num_pages);
201 if (buf->vaddr)
202 vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages);
203 while (--i >= 0) {
204 if (buf->write)
205 set_page_dirty_lock(buf->pages[i]);
206 put_page(buf->pages[i]);
207 }
208 vfree(buf->sg_desc.sglist);
209 kfree(buf->pages);
210 kfree(buf);
211}
212
213static void *vb2_dma_sg_vaddr(void *buf_priv)
214{
215 struct vb2_dma_sg_buf *buf = buf_priv;
216
217 BUG_ON(!buf);
218
219 if (!buf->vaddr)
220 buf->vaddr = vm_map_ram(buf->pages,
221 buf->sg_desc.num_pages,
222 -1,
223 PAGE_KERNEL);
224
225 /* add offset in case userptr is not page-aligned */
226 return buf->vaddr + buf->offset;
227}
228
229static unsigned int vb2_dma_sg_num_users(void *buf_priv)
230{
231 struct vb2_dma_sg_buf *buf = buf_priv;
232
233 return atomic_read(&buf->refcount);
234}
235
236static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
237{
238 struct vb2_dma_sg_buf *buf = buf_priv;
239 unsigned long uaddr = vma->vm_start;
240 unsigned long usize = vma->vm_end - vma->vm_start;
241 int i = 0;
242
243 if (!buf) {
244 printk(KERN_ERR "No memory to map\n");
245 return -EINVAL;
246 }
247
248 do {
249 int ret;
250
251 ret = vm_insert_page(vma, uaddr, buf->pages[i++]);
252 if (ret) {
253 printk(KERN_ERR "Remapping memory, error: %d\n", ret);
254 return ret;
255 }
256
257 uaddr += PAGE_SIZE;
258 usize -= PAGE_SIZE;
259 } while (usize > 0);
260
261
262 /*
263 * Use common vm_area operations to track buffer refcount.
264 */
265 vma->vm_private_data = &buf->handler;
266 vma->vm_ops = &vb2_common_vm_ops;
267
268 vma->vm_ops->open(vma);
269
270 return 0;
271}
272
273static void *vb2_dma_sg_cookie(void *buf_priv)
274{
275 struct vb2_dma_sg_buf *buf = buf_priv;
276
277 return &buf->sg_desc;
278}
279
280const struct vb2_mem_ops vb2_dma_sg_memops = {
281 .alloc = vb2_dma_sg_alloc,
282 .put = vb2_dma_sg_put,
283 .get_userptr = vb2_dma_sg_get_userptr,
284 .put_userptr = vb2_dma_sg_put_userptr,
285 .vaddr = vb2_dma_sg_vaddr,
286 .mmap = vb2_dma_sg_mmap,
287 .num_users = vb2_dma_sg_num_users,
288 .cookie = vb2_dma_sg_cookie,
289};
290EXPORT_SYMBOL_GPL(vb2_dma_sg_memops);
291
292MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2");
293MODULE_AUTHOR("Andrzej Pietrasiewicz");
294MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-memops.c b/drivers/media/video/videobuf2-memops.c
new file mode 100644
index 000000000000..5370a3a7ee25
--- /dev/null
+++ b/drivers/media/video/videobuf2-memops.c
@@ -0,0 +1,235 @@
1/*
2 * videobuf2-memops.c - generic memory handling routines for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 * Marek Szyprowski <m.szyprowski@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation.
12 */
13
14#include <linux/slab.h>
15#include <linux/module.h>
16#include <linux/dma-mapping.h>
17#include <linux/vmalloc.h>
18#include <linux/mm.h>
19#include <linux/sched.h>
20#include <linux/file.h>
21#include <linux/slab.h>
22
23#include <media/videobuf2-core.h>
24#include <media/videobuf2-memops.h>
25
26/**
27 * vb2_get_vma() - acquire and lock the virtual memory area
28 * @vma: given virtual memory area
29 *
30 * This function attempts to acquire an area mapped in the userspace for
31 * the duration of a hardware operation. The area is "locked" by performing
32 * the same set of operation that are done when process calls fork() and
33 * memory areas are duplicated.
34 *
35 * Returns a copy of a virtual memory region on success or NULL.
36 */
37struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma)
38{
39 struct vm_area_struct *vma_copy;
40
41 vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL);
42 if (vma_copy == NULL)
43 return NULL;
44
45 if (vma->vm_ops && vma->vm_ops->open)
46 vma->vm_ops->open(vma);
47
48 if (vma->vm_file)
49 get_file(vma->vm_file);
50
51 memcpy(vma_copy, vma, sizeof(*vma));
52
53 vma_copy->vm_mm = NULL;
54 vma_copy->vm_next = NULL;
55 vma_copy->vm_prev = NULL;
56
57 return vma_copy;
58}
59
60/**
61 * vb2_put_userptr() - release a userspace virtual memory area
62 * @vma: virtual memory region associated with the area to be released
63 *
64 * This function releases the previously acquired memory area after a hardware
65 * operation.
66 */
67void vb2_put_vma(struct vm_area_struct *vma)
68{
69 if (!vma)
70 return;
71
72 if (vma->vm_file)
73 fput(vma->vm_file);
74
75 if (vma->vm_ops && vma->vm_ops->close)
76 vma->vm_ops->close(vma);
77
78 kfree(vma);
79}
80EXPORT_SYMBOL_GPL(vb2_put_vma);
81
82/**
83 * vb2_get_contig_userptr() - lock physically contiguous userspace mapped memory
84 * @vaddr: starting virtual address of the area to be verified
85 * @size: size of the area
86 * @res_paddr: will return physical address for the given vaddr
87 * @res_vma: will return locked copy of struct vm_area for the given area
88 *
89 * This function will go through memory area of size @size mapped at @vaddr and
90 * verify that the underlying physical pages are contiguous. If they are
91 * contiguous the virtual memory area is locked and a @res_vma is filled with
92 * the copy and @res_pa set to the physical address of the buffer.
93 *
94 * Returns 0 on success.
95 */
96int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
97 struct vm_area_struct **res_vma, dma_addr_t *res_pa)
98{
99 struct mm_struct *mm = current->mm;
100 struct vm_area_struct *vma;
101 unsigned long offset, start, end;
102 unsigned long this_pfn, prev_pfn;
103 dma_addr_t pa = 0;
104 int ret = -EFAULT;
105
106 start = vaddr;
107 offset = start & ~PAGE_MASK;
108 end = start + size;
109
110 down_read(&mm->mmap_sem);
111 vma = find_vma(mm, start);
112
113 if (vma == NULL || vma->vm_end < end)
114 goto done;
115
116 for (prev_pfn = 0; start < end; start += PAGE_SIZE) {
117 ret = follow_pfn(vma, start, &this_pfn);
118 if (ret)
119 goto done;
120
121 if (prev_pfn == 0)
122 pa = this_pfn << PAGE_SHIFT;
123 else if (this_pfn != prev_pfn + 1) {
124 ret = -EFAULT;
125 goto done;
126 }
127 prev_pfn = this_pfn;
128 }
129
130 /*
131 * Memory is contigous, lock vma and return to the caller
132 */
133 *res_vma = vb2_get_vma(vma);
134 if (*res_vma == NULL) {
135 ret = -ENOMEM;
136 goto done;
137 }
138 *res_pa = pa + offset;
139 ret = 0;
140
141done:
142 up_read(&mm->mmap_sem);
143 return ret;
144}
145EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
146
147/**
148 * vb2_mmap_pfn_range() - map physical pages to userspace
149 * @vma: virtual memory region for the mapping
150 * @paddr: starting physical address of the memory to be mapped
151 * @size: size of the memory to be mapped
152 * @vm_ops: vm operations to be assigned to the created area
153 * @priv: private data to be associated with the area
154 *
155 * Returns 0 on success.
156 */
157int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
158 unsigned long size,
159 const struct vm_operations_struct *vm_ops,
160 void *priv)
161{
162 int ret;
163
164 size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
165
166 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
167 ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
168 size, vma->vm_page_prot);
169 if (ret) {
170 printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
171 return ret;
172 }
173
174 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
175 vma->vm_private_data = priv;
176 vma->vm_ops = vm_ops;
177
178 vma->vm_ops->open(vma);
179
180 printk(KERN_DEBUG "%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
181 __func__, paddr, vma->vm_start, size);
182
183 return 0;
184}
185EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
186
187/**
188 * vb2_common_vm_open() - increase refcount of the vma
189 * @vma: virtual memory region for the mapping
190 *
191 * This function adds another user to the provided vma. It expects
192 * struct vb2_vmarea_handler pointer in vma->vm_private_data.
193 */
194static void vb2_common_vm_open(struct vm_area_struct *vma)
195{
196 struct vb2_vmarea_handler *h = vma->vm_private_data;
197
198 printk(KERN_DEBUG "%s: %p, refcount: %d, vma: %08lx-%08lx\n",
199 __func__, h, atomic_read(h->refcount), vma->vm_start,
200 vma->vm_end);
201
202 atomic_inc(h->refcount);
203}
204
205/**
206 * vb2_common_vm_close() - decrease refcount of the vma
207 * @vma: virtual memory region for the mapping
208 *
209 * This function releases the user from the provided vma. It expects
210 * struct vb2_vmarea_handler pointer in vma->vm_private_data.
211 */
212static void vb2_common_vm_close(struct vm_area_struct *vma)
213{
214 struct vb2_vmarea_handler *h = vma->vm_private_data;
215
216 printk(KERN_DEBUG "%s: %p, refcount: %d, vma: %08lx-%08lx\n",
217 __func__, h, atomic_read(h->refcount), vma->vm_start,
218 vma->vm_end);
219
220 h->put(h->arg);
221}
222
223/**
224 * vb2_common_vm_ops - common vm_ops used for tracking refcount of mmaped
225 * video buffers
226 */
227const struct vm_operations_struct vb2_common_vm_ops = {
228 .open = vb2_common_vm_open,
229 .close = vb2_common_vm_close,
230};
231EXPORT_SYMBOL_GPL(vb2_common_vm_ops);
232
233MODULE_DESCRIPTION("common memory handling routines for videobuf2");
234MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
235MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-vmalloc.c b/drivers/media/video/videobuf2-vmalloc.c
new file mode 100644
index 000000000000..a3a884234059
--- /dev/null
+++ b/drivers/media/video/videobuf2-vmalloc.c
@@ -0,0 +1,132 @@
1/*
2 * videobuf2-vmalloc.c - vmalloc memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/mm.h>
15#include <linux/slab.h>
16#include <linux/vmalloc.h>
17
18#include <media/videobuf2-core.h>
19#include <media/videobuf2-memops.h>
20
21struct vb2_vmalloc_buf {
22 void *vaddr;
23 unsigned long size;
24 atomic_t refcount;
25 struct vb2_vmarea_handler handler;
26};
27
28static void vb2_vmalloc_put(void *buf_priv);
29
30static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size)
31{
32 struct vb2_vmalloc_buf *buf;
33
34 buf = kzalloc(sizeof *buf, GFP_KERNEL);
35 if (!buf)
36 return NULL;
37
38 buf->size = size;
39 buf->vaddr = vmalloc_user(buf->size);
40 buf->handler.refcount = &buf->refcount;
41 buf->handler.put = vb2_vmalloc_put;
42 buf->handler.arg = buf;
43
44 if (!buf->vaddr) {
45 printk(KERN_ERR "vmalloc of size %ld failed\n", buf->size);
46 kfree(buf);
47 return NULL;
48 }
49
50 atomic_inc(&buf->refcount);
51 printk(KERN_DEBUG "Allocated vmalloc buffer of size %ld at vaddr=%p\n",
52 buf->size, buf->vaddr);
53
54 return buf;
55}
56
57static void vb2_vmalloc_put(void *buf_priv)
58{
59 struct vb2_vmalloc_buf *buf = buf_priv;
60
61 if (atomic_dec_and_test(&buf->refcount)) {
62 printk(KERN_DEBUG "%s: Freeing vmalloc mem at vaddr=%p\n",
63 __func__, buf->vaddr);
64 vfree(buf->vaddr);
65 kfree(buf);
66 }
67}
68
69static void *vb2_vmalloc_vaddr(void *buf_priv)
70{
71 struct vb2_vmalloc_buf *buf = buf_priv;
72
73 BUG_ON(!buf);
74
75 if (!buf->vaddr) {
76 printk(KERN_ERR "Address of an unallocated plane requested\n");
77 return NULL;
78 }
79
80 return buf->vaddr;
81}
82
83static unsigned int vb2_vmalloc_num_users(void *buf_priv)
84{
85 struct vb2_vmalloc_buf *buf = buf_priv;
86 return atomic_read(&buf->refcount);
87}
88
89static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
90{
91 struct vb2_vmalloc_buf *buf = buf_priv;
92 int ret;
93
94 if (!buf) {
95 printk(KERN_ERR "No memory to map\n");
96 return -EINVAL;
97 }
98
99 ret = remap_vmalloc_range(vma, buf->vaddr, 0);
100 if (ret) {
101 printk(KERN_ERR "Remapping vmalloc memory, error: %d\n", ret);
102 return ret;
103 }
104
105 /*
106 * Make sure that vm_areas for 2 buffers won't be merged together
107 */
108 vma->vm_flags |= VM_DONTEXPAND;
109
110 /*
111 * Use common vm_area operations to track buffer refcount.
112 */
113 vma->vm_private_data = &buf->handler;
114 vma->vm_ops = &vb2_common_vm_ops;
115
116 vma->vm_ops->open(vma);
117
118 return 0;
119}
120
121const struct vb2_mem_ops vb2_vmalloc_memops = {
122 .alloc = vb2_vmalloc_alloc,
123 .put = vb2_vmalloc_put,
124 .vaddr = vb2_vmalloc_vaddr,
125 .mmap = vb2_vmalloc_mmap,
126 .num_users = vb2_vmalloc_num_users,
127};
128EXPORT_SYMBOL_GPL(vb2_vmalloc_memops);
129
130MODULE_DESCRIPTION("vmalloc memory handling routines for videobuf2");
131MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
132MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index c49c39386bd0..2238a613d664 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -7,6 +7,9 @@
7 * John Sokol <sokol--a.t--videotechnology.com> 7 * John Sokol <sokol--a.t--videotechnology.com>
8 * http://v4l.videotechnology.com/ 8 * http://v4l.videotechnology.com/
9 * 9 *
10 * Conversion to videobuf2 by Pawel Osciak & Marek Szyprowski
11 * Copyright (c) 2010 Samsung Electronics
12 *
10 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the BSD Licence, GNU General Public License 14 * it under the terms of the BSD Licence, GNU General Public License
12 * as published by the Free Software Foundation; either version 2 of the 15 * as published by the Free Software Foundation; either version 2 of the
@@ -23,12 +26,12 @@
23#include <linux/mutex.h> 26#include <linux/mutex.h>
24#include <linux/videodev2.h> 27#include <linux/videodev2.h>
25#include <linux/kthread.h> 28#include <linux/kthread.h>
26#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
27#include <linux/freezer.h> 29#include <linux/freezer.h>
28#endif 30#include <media/videobuf2-vmalloc.h>
29#include <media/videobuf-vmalloc.h>
30#include <media/v4l2-device.h> 31#include <media/v4l2-device.h>
31#include <media/v4l2-ioctl.h> 32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-ctrls.h>
34#include <media/v4l2-fh.h>
32#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
33 36
34#define VIVI_MODULE_NAME "vivi" 37#define VIVI_MODULE_NAME "vivi"
@@ -42,7 +45,7 @@
42#define MAX_HEIGHT 1200 45#define MAX_HEIGHT 1200
43 46
44#define VIVI_MAJOR_VERSION 0 47#define VIVI_MAJOR_VERSION 0
45#define VIVI_MINOR_VERSION 7 48#define VIVI_MINOR_VERSION 8
46#define VIVI_RELEASE 0 49#define VIVI_RELEASE 0
47#define VIVI_VERSION \ 50#define VIVI_VERSION \
48 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) 51 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
@@ -133,16 +136,11 @@ static struct vivi_fmt *get_format(struct v4l2_format *f)
133 return &formats[k]; 136 return &formats[k];
134} 137}
135 138
136struct sg_to_addr {
137 int pos;
138 struct scatterlist *sg;
139};
140
141/* buffer for one video frame */ 139/* buffer for one video frame */
142struct vivi_buffer { 140struct vivi_buffer {
143 /* common v4l buffer stuff -- must be first */ 141 /* common v4l buffer stuff -- must be first */
144 struct videobuf_buffer vb; 142 struct vb2_buffer vb;
145 143 struct list_head list;
146 struct vivi_fmt *fmt; 144 struct vivi_fmt *fmt;
147}; 145};
148 146
@@ -162,13 +160,20 @@ static LIST_HEAD(vivi_devlist);
162struct vivi_dev { 160struct vivi_dev {
163 struct list_head vivi_devlist; 161 struct list_head vivi_devlist;
164 struct v4l2_device v4l2_dev; 162 struct v4l2_device v4l2_dev;
163 struct v4l2_ctrl_handler ctrl_handler;
165 164
166 /* controls */ 165 /* controls */
167 int brightness; 166 struct v4l2_ctrl *brightness;
168 int contrast; 167 struct v4l2_ctrl *contrast;
169 int saturation; 168 struct v4l2_ctrl *saturation;
170 int hue; 169 struct v4l2_ctrl *hue;
171 int volume; 170 struct v4l2_ctrl *volume;
171 struct v4l2_ctrl *button;
172 struct v4l2_ctrl *boolean;
173 struct v4l2_ctrl *int32;
174 struct v4l2_ctrl *int64;
175 struct v4l2_ctrl *menu;
176 struct v4l2_ctrl *string;
172 177
173 spinlock_t slock; 178 spinlock_t slock;
174 struct mutex mutex; 179 struct mutex mutex;
@@ -181,6 +186,7 @@ struct vivi_dev {
181 /* Several counters */ 186 /* Several counters */
182 unsigned ms; 187 unsigned ms;
183 unsigned long jiffies; 188 unsigned long jiffies;
189 unsigned button_pressed;
184 190
185 int mv_count; /* Controls bars movement */ 191 int mv_count; /* Controls bars movement */
186 192
@@ -190,9 +196,10 @@ struct vivi_dev {
190 /* video capture */ 196 /* video capture */
191 struct vivi_fmt *fmt; 197 struct vivi_fmt *fmt;
192 unsigned int width, height; 198 unsigned int width, height;
193 struct videobuf_queue vb_vidq; 199 struct vb2_queue vb_vidq;
200 enum v4l2_field field;
201 unsigned int field_count;
194 202
195 unsigned long generating;
196 u8 bars[9][3]; 203 u8 bars[9][3];
197 u8 line[MAX_WIDTH * 4]; 204 u8 line[MAX_WIDTH * 4];
198}; 205};
@@ -443,10 +450,10 @@ static void gen_text(struct vivi_dev *dev, char *basep,
443 450
444static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) 451static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
445{ 452{
446 int hmax = buf->vb.height; 453 int wmax = dev->width;
447 int wmax = buf->vb.width; 454 int hmax = dev->height;
448 struct timeval ts; 455 struct timeval ts;
449 void *vbuf = videobuf_to_vmalloc(&buf->vb); 456 void *vbuf = vb2_plane_vaddr(&buf->vb, 0);
450 unsigned ms; 457 unsigned ms;
451 char str[100]; 458 char str[100];
452 int h, line = 1; 459 int h, line = 1;
@@ -472,22 +479,38 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
472 dev->width, dev->height, dev->input); 479 dev->width, dev->height, dev->input);
473 gen_text(dev, vbuf, line++ * 16, 16, str); 480 gen_text(dev, vbuf, line++ * 16, 16, str);
474 481
482 mutex_lock(&dev->ctrl_handler.lock);
475 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", 483 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
476 dev->brightness, 484 dev->brightness->cur.val,
477 dev->contrast, 485 dev->contrast->cur.val,
478 dev->saturation, 486 dev->saturation->cur.val,
479 dev->hue); 487 dev->hue->cur.val);
480 gen_text(dev, vbuf, line++ * 16, 16, str); 488 gen_text(dev, vbuf, line++ * 16, 16, str);
481 snprintf(str, sizeof(str), " volume %3d ", dev->volume); 489 snprintf(str, sizeof(str), " volume %3d ", dev->volume->cur.val);
482 gen_text(dev, vbuf, line++ * 16, 16, str); 490 gen_text(dev, vbuf, line++ * 16, 16, str);
491 snprintf(str, sizeof(str), " int32 %d, int64 %lld ",
492 dev->int32->cur.val,
493 dev->int64->cur.val64);
494 gen_text(dev, vbuf, line++ * 16, 16, str);
495 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
496 dev->boolean->cur.val,
497 dev->menu->qmenu[dev->menu->cur.val],
498 dev->string->cur.string);
499 mutex_unlock(&dev->ctrl_handler.lock);
500 gen_text(dev, vbuf, line++ * 16, 16, str);
501 if (dev->button_pressed) {
502 dev->button_pressed--;
503 snprintf(str, sizeof(str), " button pressed!");
504 gen_text(dev, vbuf, line++ * 16, 16, str);
505 }
483 506
484 dev->mv_count += 2; 507 dev->mv_count += 2;
485 508
486 /* Advice that buffer was filled */ 509 buf->vb.v4l2_buf.field = dev->field;
487 buf->vb.field_count++; 510 dev->field_count++;
511 buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
488 do_gettimeofday(&ts); 512 do_gettimeofday(&ts);
489 buf->vb.ts = ts; 513 buf->vb.v4l2_buf.timestamp = ts;
490 buf->vb.state = VIDEOBUF_DONE;
491} 514}
492 515
493static void vivi_thread_tick(struct vivi_dev *dev) 516static void vivi_thread_tick(struct vivi_dev *dev)
@@ -504,23 +527,17 @@ static void vivi_thread_tick(struct vivi_dev *dev)
504 goto unlock; 527 goto unlock;
505 } 528 }
506 529
507 buf = list_entry(dma_q->active.next, 530 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
508 struct vivi_buffer, vb.queue); 531 list_del(&buf->list);
509 532
510 /* Nobody is waiting on this buffer, return */ 533 do_gettimeofday(&buf->vb.v4l2_buf.timestamp);
511 if (!waitqueue_active(&buf->vb.done))
512 goto unlock;
513
514 list_del(&buf->vb.queue);
515
516 do_gettimeofday(&buf->vb.ts);
517 534
518 /* Fill buffer */ 535 /* Fill buffer */
519 vivi_fillbuff(dev, buf); 536 vivi_fillbuff(dev, buf);
520 dprintk(dev, 1, "filled buffer %p\n", buf); 537 dprintk(dev, 1, "filled buffer %p\n", buf);
521 538
522 wake_up(&buf->vb.done); 539 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
523 dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); 540 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
524unlock: 541unlock:
525 spin_unlock_irqrestore(&dev->slock, flags); 542 spin_unlock_irqrestore(&dev->slock, flags);
526} 543}
@@ -571,17 +588,12 @@ static int vivi_thread(void *data)
571 return 0; 588 return 0;
572} 589}
573 590
574static void vivi_start_generating(struct file *file) 591static int vivi_start_generating(struct vivi_dev *dev)
575{ 592{
576 struct vivi_dev *dev = video_drvdata(file);
577 struct vivi_dmaqueue *dma_q = &dev->vidq; 593 struct vivi_dmaqueue *dma_q = &dev->vidq;
578 594
579 dprintk(dev, 1, "%s\n", __func__); 595 dprintk(dev, 1, "%s\n", __func__);
580 596
581 if (test_and_set_bit(0, &dev->generating))
582 return;
583 file->private_data = dev;
584
585 /* Resets frame counters */ 597 /* Resets frame counters */
586 dev->ms = 0; 598 dev->ms = 0;
587 dev->mv_count = 0; 599 dev->mv_count = 0;
@@ -593,146 +605,200 @@ static void vivi_start_generating(struct file *file)
593 605
594 if (IS_ERR(dma_q->kthread)) { 606 if (IS_ERR(dma_q->kthread)) {
595 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); 607 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
596 clear_bit(0, &dev->generating); 608 return PTR_ERR(dma_q->kthread);
597 return;
598 } 609 }
599 /* Wakes thread */ 610 /* Wakes thread */
600 wake_up_interruptible(&dma_q->wq); 611 wake_up_interruptible(&dma_q->wq);
601 612
602 dprintk(dev, 1, "returning from %s\n", __func__); 613 dprintk(dev, 1, "returning from %s\n", __func__);
614 return 0;
603} 615}
604 616
605static void vivi_stop_generating(struct file *file) 617static void vivi_stop_generating(struct vivi_dev *dev)
606{ 618{
607 struct vivi_dev *dev = video_drvdata(file);
608 struct vivi_dmaqueue *dma_q = &dev->vidq; 619 struct vivi_dmaqueue *dma_q = &dev->vidq;
609 620
610 dprintk(dev, 1, "%s\n", __func__); 621 dprintk(dev, 1, "%s\n", __func__);
611 622
612 if (!file->private_data)
613 return;
614 if (!test_and_clear_bit(0, &dev->generating))
615 return;
616
617 /* shutdown control thread */ 623 /* shutdown control thread */
618 if (dma_q->kthread) { 624 if (dma_q->kthread) {
619 kthread_stop(dma_q->kthread); 625 kthread_stop(dma_q->kthread);
620 dma_q->kthread = NULL; 626 dma_q->kthread = NULL;
621 } 627 }
622 videobuf_stop(&dev->vb_vidq);
623 videobuf_mmap_free(&dev->vb_vidq);
624}
625 628
626static int vivi_is_generating(struct vivi_dev *dev) 629 /*
627{ 630 * Typical driver might need to wait here until dma engine stops.
628 return test_bit(0, &dev->generating); 631 * In this case we can abort imiedetly, so it's just a noop.
632 */
633
634 /* Release all active buffers */
635 while (!list_empty(&dma_q->active)) {
636 struct vivi_buffer *buf;
637 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
638 list_del(&buf->list);
639 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
640 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
641 }
629} 642}
630
631/* ------------------------------------------------------------------ 643/* ------------------------------------------------------------------
632 Videobuf operations 644 Videobuf operations
633 ------------------------------------------------------------------*/ 645 ------------------------------------------------------------------*/
634static int 646static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
635buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) 647 unsigned int *nplanes, unsigned long sizes[],
648 void *alloc_ctxs[])
636{ 649{
637 struct vivi_dev *dev = vq->priv_data; 650 struct vivi_dev *dev = vb2_get_drv_priv(vq);
651 unsigned long size;
652
653 size = dev->width * dev->height * 2;
654
655 if (0 == *nbuffers)
656 *nbuffers = 32;
638 657
639 *size = dev->width * dev->height * 2; 658 while (size * *nbuffers > vid_limit * 1024 * 1024)
659 (*nbuffers)--;
640 660
641 if (0 == *count) 661 *nplanes = 1;
642 *count = 32;
643 662
644 while (*size * *count > vid_limit * 1024 * 1024) 663 sizes[0] = size;
645 (*count)--;
646 664
647 dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, 665 /*
648 *count, *size); 666 * videobuf2-vmalloc allocator is context-less so no need to set
667 * alloc_ctxs array.
668 */
669
670 dprintk(dev, 1, "%s, count=%d, size=%ld\n", __func__,
671 *nbuffers, size);
649 672
650 return 0; 673 return 0;
651} 674}
652 675
653static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) 676static int buffer_init(struct vb2_buffer *vb)
654{ 677{
655 struct vivi_dev *dev = vq->priv_data; 678 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
679
680 BUG_ON(NULL == dev->fmt);
656 681
657 dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); 682 /*
683 * This callback is called once per buffer, after its allocation.
684 *
685 * Vivi does not allow changing format during streaming, but it is
686 * possible to do so when streaming is paused (i.e. in streamoff state).
687 * Buffers however are not freed when going into streamoff and so
688 * buffer size verification has to be done in buffer_prepare, on each
689 * qbuf.
690 * It would be best to move verification code here to buf_init and
691 * s_fmt though.
692 */
658 693
659 videobuf_vmalloc_free(&buf->vb); 694 return 0;
660 dprintk(dev, 1, "free_buffer: freed\n");
661 buf->vb.state = VIDEOBUF_NEEDS_INIT;
662} 695}
663 696
664static int 697static int buffer_prepare(struct vb2_buffer *vb)
665buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
666 enum v4l2_field field)
667{ 698{
668 struct vivi_dev *dev = vq->priv_data; 699 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
669 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 700 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
670 int rc; 701 unsigned long size;
671 702
672 dprintk(dev, 1, "%s, field=%d\n", __func__, field); 703 dprintk(dev, 1, "%s, field=%d\n", __func__, vb->v4l2_buf.field);
673 704
674 BUG_ON(NULL == dev->fmt); 705 BUG_ON(NULL == dev->fmt);
675 706
707 /*
708 * Theses properties only change when queue is idle, see s_fmt.
709 * The below checks should not be performed here, on each
710 * buffer_prepare (i.e. on each qbuf). Most of the code in this function
711 * should thus be moved to buffer_init and s_fmt.
712 */
676 if (dev->width < 48 || dev->width > MAX_WIDTH || 713 if (dev->width < 48 || dev->width > MAX_WIDTH ||
677 dev->height < 32 || dev->height > MAX_HEIGHT) 714 dev->height < 32 || dev->height > MAX_HEIGHT)
678 return -EINVAL; 715 return -EINVAL;
679 716
680 buf->vb.size = dev->width * dev->height * 2; 717 size = dev->width * dev->height * 2;
681 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 718 if (vb2_plane_size(vb, 0) < size) {
719 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
720 __func__, vb2_plane_size(vb, 0), size);
682 return -EINVAL; 721 return -EINVAL;
722 }
683 723
684 /* These properties only change when queue is idle, see s_fmt */ 724 vb2_set_plane_payload(&buf->vb, 0, size);
685 buf->fmt = dev->fmt; 725
686 buf->vb.width = dev->width; 726 buf->fmt = dev->fmt;
687 buf->vb.height = dev->height;
688 buf->vb.field = field;
689 727
690 precalculate_bars(dev); 728 precalculate_bars(dev);
691 precalculate_line(dev); 729 precalculate_line(dev);
692 730
693 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 731 return 0;
694 rc = videobuf_iolock(vq, &buf->vb, NULL); 732}
695 if (rc < 0)
696 goto fail;
697 }
698 733
699 buf->vb.state = VIDEOBUF_PREPARED; 734static int buffer_finish(struct vb2_buffer *vb)
735{
736 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
737 dprintk(dev, 1, "%s\n", __func__);
700 return 0; 738 return 0;
739}
740
741static void buffer_cleanup(struct vb2_buffer *vb)
742{
743 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
744 dprintk(dev, 1, "%s\n", __func__);
701 745
702fail:
703 free_buffer(vq, buf);
704 return rc;
705} 746}
706 747
707static void 748static void buffer_queue(struct vb2_buffer *vb)
708buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
709{ 749{
710 struct vivi_dev *dev = vq->priv_data; 750 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
711 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 751 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
712 struct vivi_dmaqueue *vidq = &dev->vidq; 752 struct vivi_dmaqueue *vidq = &dev->vidq;
753 unsigned long flags = 0;
713 754
714 dprintk(dev, 1, "%s\n", __func__); 755 dprintk(dev, 1, "%s\n", __func__);
715 756
716 buf->vb.state = VIDEOBUF_QUEUED; 757 spin_lock_irqsave(&dev->slock, flags);
717 list_add_tail(&buf->vb.queue, &vidq->active); 758 list_add_tail(&buf->list, &vidq->active);
759 spin_unlock_irqrestore(&dev->slock, flags);
718} 760}
719 761
720static void buffer_release(struct videobuf_queue *vq, 762static int start_streaming(struct vb2_queue *vq)
721 struct videobuf_buffer *vb)
722{ 763{
723 struct vivi_dev *dev = vq->priv_data; 764 struct vivi_dev *dev = vb2_get_drv_priv(vq);
724 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 765 dprintk(dev, 1, "%s\n", __func__);
766 return vivi_start_generating(dev);
767}
725 768
769/* abort streaming and wait for last buffer */
770static int stop_streaming(struct vb2_queue *vq)
771{
772 struct vivi_dev *dev = vb2_get_drv_priv(vq);
726 dprintk(dev, 1, "%s\n", __func__); 773 dprintk(dev, 1, "%s\n", __func__);
774 vivi_stop_generating(dev);
775 return 0;
776}
727 777
728 free_buffer(vq, buf); 778static void vivi_lock(struct vb2_queue *vq)
779{
780 struct vivi_dev *dev = vb2_get_drv_priv(vq);
781 mutex_lock(&dev->mutex);
729} 782}
730 783
731static struct videobuf_queue_ops vivi_video_qops = { 784static void vivi_unlock(struct vb2_queue *vq)
732 .buf_setup = buffer_setup, 785{
733 .buf_prepare = buffer_prepare, 786 struct vivi_dev *dev = vb2_get_drv_priv(vq);
734 .buf_queue = buffer_queue, 787 mutex_unlock(&dev->mutex);
735 .buf_release = buffer_release, 788}
789
790
791static struct vb2_ops vivi_video_qops = {
792 .queue_setup = queue_setup,
793 .buf_init = buffer_init,
794 .buf_prepare = buffer_prepare,
795 .buf_finish = buffer_finish,
796 .buf_cleanup = buffer_cleanup,
797 .buf_queue = buffer_queue,
798 .start_streaming = start_streaming,
799 .stop_streaming = stop_streaming,
800 .wait_prepare = vivi_unlock,
801 .wait_finish = vivi_lock,
736}; 802};
737 803
738/* ------------------------------------------------------------------ 804/* ------------------------------------------------------------------
@@ -774,7 +840,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
774 840
775 f->fmt.pix.width = dev->width; 841 f->fmt.pix.width = dev->width;
776 f->fmt.pix.height = dev->height; 842 f->fmt.pix.height = dev->height;
777 f->fmt.pix.field = dev->vb_vidq.field; 843 f->fmt.pix.field = dev->field;
778 f->fmt.pix.pixelformat = dev->fmt->fourcc; 844 f->fmt.pix.pixelformat = dev->fmt->fourcc;
779 f->fmt.pix.bytesperline = 845 f->fmt.pix.bytesperline =
780 (f->fmt.pix.width * dev->fmt->depth) >> 3; 846 (f->fmt.pix.width * dev->fmt->depth) >> 3;
@@ -820,82 +886,60 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
820 struct v4l2_format *f) 886 struct v4l2_format *f)
821{ 887{
822 struct vivi_dev *dev = video_drvdata(file); 888 struct vivi_dev *dev = video_drvdata(file);
889 struct vb2_queue *q = &dev->vb_vidq;
823 890
824 int ret = vidioc_try_fmt_vid_cap(file, priv, f); 891 int ret = vidioc_try_fmt_vid_cap(file, priv, f);
825 if (ret < 0) 892 if (ret < 0)
826 return ret; 893 return ret;
827 894
828 if (vivi_is_generating(dev)) { 895 if (vb2_is_streaming(q)) {
829 dprintk(dev, 1, "%s device busy\n", __func__); 896 dprintk(dev, 1, "%s device busy\n", __func__);
830 ret = -EBUSY; 897 return -EBUSY;
831 goto out;
832 } 898 }
833 899
834 dev->fmt = get_format(f); 900 dev->fmt = get_format(f);
835 dev->width = f->fmt.pix.width; 901 dev->width = f->fmt.pix.width;
836 dev->height = f->fmt.pix.height; 902 dev->height = f->fmt.pix.height;
837 dev->vb_vidq.field = f->fmt.pix.field; 903 dev->field = f->fmt.pix.field;
838 ret = 0; 904
839out: 905 return 0;
840 return ret;
841} 906}
842 907
843static int vidioc_reqbufs(struct file *file, void *priv, 908static int vidioc_reqbufs(struct file *file, void *priv,
844 struct v4l2_requestbuffers *p) 909 struct v4l2_requestbuffers *p)
845{ 910{
846 struct vivi_dev *dev = video_drvdata(file); 911 struct vivi_dev *dev = video_drvdata(file);
847 912 return vb2_reqbufs(&dev->vb_vidq, p);
848 return videobuf_reqbufs(&dev->vb_vidq, p);
849} 913}
850 914
851static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) 915static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
852{ 916{
853 struct vivi_dev *dev = video_drvdata(file); 917 struct vivi_dev *dev = video_drvdata(file);
854 918 return vb2_querybuf(&dev->vb_vidq, p);
855 return videobuf_querybuf(&dev->vb_vidq, p);
856} 919}
857 920
858static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) 921static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
859{ 922{
860 struct vivi_dev *dev = video_drvdata(file); 923 struct vivi_dev *dev = video_drvdata(file);
861 924 return vb2_qbuf(&dev->vb_vidq, p);
862 return videobuf_qbuf(&dev->vb_vidq, p);
863} 925}
864 926
865static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) 927static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
866{ 928{
867 struct vivi_dev *dev = video_drvdata(file); 929 struct vivi_dev *dev = video_drvdata(file);
868 930 return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
869 return videobuf_dqbuf(&dev->vb_vidq, p,
870 file->f_flags & O_NONBLOCK);
871} 931}
872 932
873static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) 933static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
874{ 934{
875 struct vivi_dev *dev = video_drvdata(file); 935 struct vivi_dev *dev = video_drvdata(file);
876 int ret; 936 return vb2_streamon(&dev->vb_vidq, i);
877
878 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
879 return -EINVAL;
880 ret = videobuf_streamon(&dev->vb_vidq);
881 if (ret)
882 return ret;
883
884 vivi_start_generating(file);
885 return 0;
886} 937}
887 938
888static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) 939static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
889{ 940{
890 struct vivi_dev *dev = video_drvdata(file); 941 struct vivi_dev *dev = video_drvdata(file);
891 int ret; 942 return vb2_streamoff(&dev->vb_vidq, i);
892
893 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
894 return -EINVAL;
895 ret = videobuf_streamoff(&dev->vb_vidq);
896 if (!ret)
897 vivi_stop_generating(file);
898 return ret;
899} 943}
900 944
901static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) 945static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
@@ -938,80 +982,14 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
938} 982}
939 983
940/* --- controls ---------------------------------------------- */ 984/* --- controls ---------------------------------------------- */
941static int vidioc_queryctrl(struct file *file, void *priv,
942 struct v4l2_queryctrl *qc)
943{
944 switch (qc->id) {
945 case V4L2_CID_AUDIO_VOLUME:
946 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 200);
947 case V4L2_CID_BRIGHTNESS:
948 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
949 case V4L2_CID_CONTRAST:
950 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 16);
951 case V4L2_CID_SATURATION:
952 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
953 case V4L2_CID_HUE:
954 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
955 }
956 return -EINVAL;
957}
958 985
959static int vidioc_g_ctrl(struct file *file, void *priv, 986static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
960 struct v4l2_control *ctrl)
961{ 987{
962 struct vivi_dev *dev = video_drvdata(file); 988 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
963 989
964 switch (ctrl->id) { 990 if (ctrl == dev->button)
965 case V4L2_CID_AUDIO_VOLUME: 991 dev->button_pressed = 30;
966 ctrl->value = dev->volume; 992 return 0;
967 return 0;
968 case V4L2_CID_BRIGHTNESS:
969 ctrl->value = dev->brightness;
970 return 0;
971 case V4L2_CID_CONTRAST:
972 ctrl->value = dev->contrast;
973 return 0;
974 case V4L2_CID_SATURATION:
975 ctrl->value = dev->saturation;
976 return 0;
977 case V4L2_CID_HUE:
978 ctrl->value = dev->hue;
979 return 0;
980 }
981 return -EINVAL;
982}
983
984static int vidioc_s_ctrl(struct file *file, void *priv,
985 struct v4l2_control *ctrl)
986{
987 struct vivi_dev *dev = video_drvdata(file);
988 struct v4l2_queryctrl qc;
989 int err;
990
991 qc.id = ctrl->id;
992 err = vidioc_queryctrl(file, priv, &qc);
993 if (err < 0)
994 return err;
995 if (ctrl->value < qc.minimum || ctrl->value > qc.maximum)
996 return -ERANGE;
997 switch (ctrl->id) {
998 case V4L2_CID_AUDIO_VOLUME:
999 dev->volume = ctrl->value;
1000 return 0;
1001 case V4L2_CID_BRIGHTNESS:
1002 dev->brightness = ctrl->value;
1003 return 0;
1004 case V4L2_CID_CONTRAST:
1005 dev->contrast = ctrl->value;
1006 return 0;
1007 case V4L2_CID_SATURATION:
1008 dev->saturation = ctrl->value;
1009 return 0;
1010 case V4L2_CID_HUE:
1011 dev->hue = ctrl->value;
1012 return 0;
1013 }
1014 return -EINVAL;
1015} 993}
1016 994
1017/* ------------------------------------------------------------------ 995/* ------------------------------------------------------------------
@@ -1023,21 +1001,19 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1023{ 1001{
1024 struct vivi_dev *dev = video_drvdata(file); 1002 struct vivi_dev *dev = video_drvdata(file);
1025 1003
1026 vivi_start_generating(file); 1004 dprintk(dev, 1, "read called\n");
1027 return videobuf_read_stream(&dev->vb_vidq, data, count, ppos, 0, 1005 return vb2_read(&dev->vb_vidq, data, count, ppos,
1028 file->f_flags & O_NONBLOCK); 1006 file->f_flags & O_NONBLOCK);
1029} 1007}
1030 1008
1031static unsigned int 1009static unsigned int
1032vivi_poll(struct file *file, struct poll_table_struct *wait) 1010vivi_poll(struct file *file, struct poll_table_struct *wait)
1033{ 1011{
1034 struct vivi_dev *dev = video_drvdata(file); 1012 struct vivi_dev *dev = video_drvdata(file);
1035 struct videobuf_queue *q = &dev->vb_vidq; 1013 struct vb2_queue *q = &dev->vb_vidq;
1036 1014
1037 dprintk(dev, 1, "%s\n", __func__); 1015 dprintk(dev, 1, "%s\n", __func__);
1038 1016 return vb2_poll(q, file, wait);
1039 vivi_start_generating(file);
1040 return videobuf_poll_stream(file, q, wait);
1041} 1017}
1042 1018
1043static int vivi_close(struct file *file) 1019static int vivi_close(struct file *file)
@@ -1045,11 +1021,12 @@ static int vivi_close(struct file *file)
1045 struct video_device *vdev = video_devdata(file); 1021 struct video_device *vdev = video_devdata(file);
1046 struct vivi_dev *dev = video_drvdata(file); 1022 struct vivi_dev *dev = video_drvdata(file);
1047 1023
1048 vivi_stop_generating(file); 1024 dprintk(dev, 1, "close called (dev=%s), file %p\n",
1025 video_device_node_name(vdev), file);
1049 1026
1050 dprintk(dev, 1, "close called (dev=%s)\n", 1027 if (v4l2_fh_is_singular_file(file))
1051 video_device_node_name(vdev)); 1028 vb2_queue_release(&dev->vb_vidq);
1052 return 0; 1029 return v4l2_fh_release(file);
1053} 1030}
1054 1031
1055static int vivi_mmap(struct file *file, struct vm_area_struct *vma) 1032static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1059,8 +1036,7 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
1059 1036
1060 dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 1037 dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1061 1038
1062 ret = videobuf_mmap_mapper(&dev->vb_vidq, vma); 1039 ret = vb2_mmap(&dev->vb_vidq, vma);
1063
1064 dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", 1040 dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n",
1065 (unsigned long)vma->vm_start, 1041 (unsigned long)vma->vm_start,
1066 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, 1042 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
@@ -1068,8 +1044,82 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
1068 return ret; 1044 return ret;
1069} 1045}
1070 1046
1047static const struct v4l2_ctrl_ops vivi_ctrl_ops = {
1048 .s_ctrl = vivi_s_ctrl,
1049};
1050
1051#define VIVI_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
1052
1053static const struct v4l2_ctrl_config vivi_ctrl_button = {
1054 .ops = &vivi_ctrl_ops,
1055 .id = VIVI_CID_CUSTOM_BASE + 0,
1056 .name = "Button",
1057 .type = V4L2_CTRL_TYPE_BUTTON,
1058};
1059
1060static const struct v4l2_ctrl_config vivi_ctrl_boolean = {
1061 .ops = &vivi_ctrl_ops,
1062 .id = VIVI_CID_CUSTOM_BASE + 1,
1063 .name = "Boolean",
1064 .type = V4L2_CTRL_TYPE_BOOLEAN,
1065 .min = 0,
1066 .max = 1,
1067 .step = 1,
1068 .def = 1,
1069};
1070
1071static const struct v4l2_ctrl_config vivi_ctrl_int32 = {
1072 .ops = &vivi_ctrl_ops,
1073 .id = VIVI_CID_CUSTOM_BASE + 2,
1074 .name = "Integer 32 Bits",
1075 .type = V4L2_CTRL_TYPE_INTEGER,
1076 .min = 0x80000000,
1077 .max = 0x7fffffff,
1078 .step = 1,
1079};
1080
1081static const struct v4l2_ctrl_config vivi_ctrl_int64 = {
1082 .ops = &vivi_ctrl_ops,
1083 .id = VIVI_CID_CUSTOM_BASE + 3,
1084 .name = "Integer 64 Bits",
1085 .type = V4L2_CTRL_TYPE_INTEGER64,
1086};
1087
1088static const char * const vivi_ctrl_menu_strings[] = {
1089 "Menu Item 0 (Skipped)",
1090 "Menu Item 1",
1091 "Menu Item 2 (Skipped)",
1092 "Menu Item 3",
1093 "Menu Item 4",
1094 "Menu Item 5 (Skipped)",
1095 NULL,
1096};
1097
1098static const struct v4l2_ctrl_config vivi_ctrl_menu = {
1099 .ops = &vivi_ctrl_ops,
1100 .id = VIVI_CID_CUSTOM_BASE + 4,
1101 .name = "Menu",
1102 .type = V4L2_CTRL_TYPE_MENU,
1103 .min = 1,
1104 .max = 4,
1105 .def = 3,
1106 .menu_skip_mask = 0x04,
1107 .qmenu = vivi_ctrl_menu_strings,
1108};
1109
1110static const struct v4l2_ctrl_config vivi_ctrl_string = {
1111 .ops = &vivi_ctrl_ops,
1112 .id = VIVI_CID_CUSTOM_BASE + 5,
1113 .name = "String",
1114 .type = V4L2_CTRL_TYPE_STRING,
1115 .min = 2,
1116 .max = 4,
1117 .step = 1,
1118};
1119
1071static const struct v4l2_file_operations vivi_fops = { 1120static const struct v4l2_file_operations vivi_fops = {
1072 .owner = THIS_MODULE, 1121 .owner = THIS_MODULE,
1122 .open = v4l2_fh_open,
1073 .release = vivi_close, 1123 .release = vivi_close,
1074 .read = vivi_read, 1124 .read = vivi_read,
1075 .poll = vivi_poll, 1125 .poll = vivi_poll,
@@ -1093,9 +1143,6 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
1093 .vidioc_s_input = vidioc_s_input, 1143 .vidioc_s_input = vidioc_s_input,
1094 .vidioc_streamon = vidioc_streamon, 1144 .vidioc_streamon = vidioc_streamon,
1095 .vidioc_streamoff = vidioc_streamoff, 1145 .vidioc_streamoff = vidioc_streamoff,
1096 .vidioc_queryctrl = vidioc_queryctrl,
1097 .vidioc_g_ctrl = vidioc_g_ctrl,
1098 .vidioc_s_ctrl = vidioc_s_ctrl,
1099}; 1146};
1100 1147
1101static struct video_device vivi_template = { 1148static struct video_device vivi_template = {
@@ -1126,6 +1173,7 @@ static int vivi_release(void)
1126 video_device_node_name(dev->vfd)); 1173 video_device_node_name(dev->vfd));
1127 video_unregister_device(dev->vfd); 1174 video_unregister_device(dev->vfd);
1128 v4l2_device_unregister(&dev->v4l2_dev); 1175 v4l2_device_unregister(&dev->v4l2_dev);
1176 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1129 kfree(dev); 1177 kfree(dev);
1130 } 1178 }
1131 1179
@@ -1136,6 +1184,8 @@ static int __init vivi_create_instance(int inst)
1136{ 1184{
1137 struct vivi_dev *dev; 1185 struct vivi_dev *dev;
1138 struct video_device *vfd; 1186 struct video_device *vfd;
1187 struct v4l2_ctrl_handler *hdl;
1188 struct vb2_queue *q;
1139 int ret; 1189 int ret;
1140 1190
1141 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1191 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -1151,20 +1201,46 @@ static int __init vivi_create_instance(int inst)
1151 dev->fmt = &formats[0]; 1201 dev->fmt = &formats[0];
1152 dev->width = 640; 1202 dev->width = 640;
1153 dev->height = 480; 1203 dev->height = 480;
1154 dev->volume = 200; 1204 hdl = &dev->ctrl_handler;
1155 dev->brightness = 127; 1205 v4l2_ctrl_handler_init(hdl, 11);
1156 dev->contrast = 16; 1206 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1157 dev->saturation = 127; 1207 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1158 dev->hue = 0; 1208 dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1209 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1210 dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1211 V4L2_CID_CONTRAST, 0, 255, 1, 16);
1212 dev->saturation = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1213 V4L2_CID_SATURATION, 0, 255, 1, 127);
1214 dev->hue = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1215 V4L2_CID_HUE, -128, 127, 1, 0);
1216 dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
1217 dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
1218 dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
1219 dev->boolean = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_boolean, NULL);
1220 dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
1221 dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
1222 if (hdl->error) {
1223 ret = hdl->error;
1224 goto unreg_dev;
1225 }
1226 dev->v4l2_dev.ctrl_handler = hdl;
1159 1227
1160 /* initialize locks */ 1228 /* initialize locks */
1161 spin_lock_init(&dev->slock); 1229 spin_lock_init(&dev->slock);
1162 mutex_init(&dev->mutex);
1163 1230
1164 videobuf_queue_vmalloc_init(&dev->vb_vidq, &vivi_video_qops, 1231 /* initialize queue */
1165 NULL, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, 1232 q = &dev->vb_vidq;
1166 V4L2_FIELD_INTERLACED, 1233 memset(q, 0, sizeof(dev->vb_vidq));
1167 sizeof(struct vivi_buffer), dev, &dev->mutex); 1234 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1235 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1236 q->drv_priv = dev;
1237 q->buf_struct_size = sizeof(struct vivi_buffer);
1238 q->ops = &vivi_video_qops;
1239 q->mem_ops = &vb2_vmalloc_memops;
1240
1241 vb2_queue_init(q);
1242
1243 mutex_init(&dev->mutex);
1168 1244
1169 /* init video dma queues */ 1245 /* init video dma queues */
1170 INIT_LIST_HEAD(&dev->vidq.active); 1246 INIT_LIST_HEAD(&dev->vidq.active);
@@ -1178,6 +1254,12 @@ static int __init vivi_create_instance(int inst)
1178 *vfd = vivi_template; 1254 *vfd = vivi_template;
1179 vfd->debug = debug; 1255 vfd->debug = debug;
1180 vfd->v4l2_dev = &dev->v4l2_dev; 1256 vfd->v4l2_dev = &dev->v4l2_dev;
1257 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
1258
1259 /*
1260 * Provide a mutex to v4l2 core. It will be used to protect
1261 * all fops and v4l2 ioctls.
1262 */
1181 vfd->lock = &dev->mutex; 1263 vfd->lock = &dev->mutex;
1182 1264
1183 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); 1265 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
@@ -1200,6 +1282,7 @@ static int __init vivi_create_instance(int inst)
1200rel_vdev: 1282rel_vdev:
1201 video_device_release(vfd); 1283 video_device_release(vfd);
1202unreg_dev: 1284unreg_dev:
1285 v4l2_ctrl_handler_free(hdl);
1203 v4l2_device_unregister(&dev->v4l2_dev); 1286 v4l2_device_unregister(&dev->v4l2_dev);
1204free_dev: 1287free_dev:
1205 kfree(dev); 1288 kfree(dev);
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 91a01b3cdf8c..75301d10a838 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -28,6 +28,7 @@
28#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-chip-ident.h> 30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-ctrls.h>
31 32
32MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); 33MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
33MODULE_AUTHOR("Laurent Pinchart"); 34MODULE_AUTHOR("Laurent Pinchart");
@@ -44,16 +45,13 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
44 45
45struct vpx3220 { 46struct vpx3220 {
46 struct v4l2_subdev sd; 47 struct v4l2_subdev sd;
48 struct v4l2_ctrl_handler hdl;
47 unsigned char reg[255]; 49 unsigned char reg[255];
48 50
49 v4l2_std_id norm; 51 v4l2_std_id norm;
50 int ident; 52 int ident;
51 int input; 53 int input;
52 int enable; 54 int enable;
53 int bright;
54 int contrast;
55 int hue;
56 int sat;
57}; 55};
58 56
59static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd) 57static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
@@ -61,6 +59,11 @@ static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
61 return container_of(sd, struct vpx3220, sd); 59 return container_of(sd, struct vpx3220, sd);
62} 60}
63 61
62static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
63{
64 return &container_of(ctrl->handler, struct vpx3220, hdl)->sd;
65}
66
64static char *inputs[] = { "internal", "composite", "svideo" }; 67static char *inputs[] = { "internal", "composite", "svideo" };
65 68
66/* ----------------------------------------------------------------------- */ 69/* ----------------------------------------------------------------------- */
@@ -417,88 +420,26 @@ static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
417 return 0; 420 return 0;
418} 421}
419 422
420static int vpx3220_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 423static int vpx3220_s_ctrl(struct v4l2_ctrl *ctrl)
421{
422 switch (qc->id) {
423 case V4L2_CID_BRIGHTNESS:
424 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
425 break;
426
427 case V4L2_CID_CONTRAST:
428 v4l2_ctrl_query_fill(qc, 0, 63, 1, 32);
429 break;
430
431 case V4L2_CID_SATURATION:
432 v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048);
433 break;
434
435 case V4L2_CID_HUE:
436 v4l2_ctrl_query_fill(qc, -512, 511, 1, 0);
437 break;
438
439 default:
440 return -EINVAL;
441 }
442 return 0;
443}
444
445static int vpx3220_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
446{ 424{
447 struct vpx3220 *decoder = to_vpx3220(sd); 425 struct v4l2_subdev *sd = to_sd(ctrl);
448 426
449 switch (ctrl->id) { 427 switch (ctrl->id) {
450 case V4L2_CID_BRIGHTNESS: 428 case V4L2_CID_BRIGHTNESS:
451 ctrl->value = decoder->bright; 429 vpx3220_write(sd, 0xe6, ctrl->val);
452 break; 430 return 0;
453 case V4L2_CID_CONTRAST: 431 case V4L2_CID_CONTRAST:
454 ctrl->value = decoder->contrast; 432 /* Bit 7 and 8 is for noise shaping */
455 break; 433 vpx3220_write(sd, 0xe7, ctrl->val + 192);
434 return 0;
456 case V4L2_CID_SATURATION: 435 case V4L2_CID_SATURATION:
457 ctrl->value = decoder->sat; 436 vpx3220_fp_write(sd, 0xa0, ctrl->val);
458 break; 437 return 0;
459 case V4L2_CID_HUE: 438 case V4L2_CID_HUE:
460 ctrl->value = decoder->hue; 439 vpx3220_fp_write(sd, 0x1c, ctrl->val);
461 break; 440 return 0;
462 default:
463 return -EINVAL;
464 } 441 }
465 return 0; 442 return -EINVAL;
466}
467
468static int vpx3220_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
469{
470 struct vpx3220 *decoder = to_vpx3220(sd);
471
472 switch (ctrl->id) {
473 case V4L2_CID_BRIGHTNESS:
474 if (decoder->bright != ctrl->value) {
475 decoder->bright = ctrl->value;
476 vpx3220_write(sd, 0xe6, decoder->bright);
477 }
478 break;
479 case V4L2_CID_CONTRAST:
480 if (decoder->contrast != ctrl->value) {
481 /* Bit 7 and 8 is for noise shaping */
482 decoder->contrast = ctrl->value;
483 vpx3220_write(sd, 0xe7, decoder->contrast + 192);
484 }
485 break;
486 case V4L2_CID_SATURATION:
487 if (decoder->sat != ctrl->value) {
488 decoder->sat = ctrl->value;
489 vpx3220_fp_write(sd, 0xa0, decoder->sat);
490 }
491 break;
492 case V4L2_CID_HUE:
493 if (decoder->hue != ctrl->value) {
494 decoder->hue = ctrl->value;
495 vpx3220_fp_write(sd, 0x1c, decoder->hue);
496 }
497 break;
498 default:
499 return -EINVAL;
500 }
501 return 0;
502} 443}
503 444
504static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) 445static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
@@ -511,12 +452,20 @@ static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
511 452
512/* ----------------------------------------------------------------------- */ 453/* ----------------------------------------------------------------------- */
513 454
455static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
456 .s_ctrl = vpx3220_s_ctrl,
457};
458
514static const struct v4l2_subdev_core_ops vpx3220_core_ops = { 459static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
515 .g_chip_ident = vpx3220_g_chip_ident, 460 .g_chip_ident = vpx3220_g_chip_ident,
516 .init = vpx3220_init, 461 .init = vpx3220_init,
517 .g_ctrl = vpx3220_g_ctrl, 462 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
518 .s_ctrl = vpx3220_s_ctrl, 463 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
519 .queryctrl = vpx3220_queryctrl, 464 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
465 .g_ctrl = v4l2_subdev_g_ctrl,
466 .s_ctrl = v4l2_subdev_s_ctrl,
467 .queryctrl = v4l2_subdev_queryctrl,
468 .querymenu = v4l2_subdev_querymenu,
520 .s_std = vpx3220_s_std, 469 .s_std = vpx3220_s_std,
521}; 470};
522 471
@@ -558,10 +507,24 @@ static int vpx3220_probe(struct i2c_client *client,
558 decoder->norm = V4L2_STD_PAL; 507 decoder->norm = V4L2_STD_PAL;
559 decoder->input = 0; 508 decoder->input = 0;
560 decoder->enable = 1; 509 decoder->enable = 1;
561 decoder->bright = 32768; 510 v4l2_ctrl_handler_init(&decoder->hdl, 4);
562 decoder->contrast = 32768; 511 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
563 decoder->hue = 32768; 512 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
564 decoder->sat = 32768; 513 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
514 V4L2_CID_CONTRAST, 0, 63, 1, 32);
515 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
516 V4L2_CID_SATURATION, 0, 4095, 1, 2048);
517 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
518 V4L2_CID_HUE, -512, 511, 1, 0);
519 sd->ctrl_handler = &decoder->hdl;
520 if (decoder->hdl.error) {
521 int err = decoder->hdl.error;
522
523 v4l2_ctrl_handler_free(&decoder->hdl);
524 kfree(decoder);
525 return err;
526 }
527 v4l2_ctrl_handler_setup(&decoder->hdl);
565 528
566 ver = i2c_smbus_read_byte_data(client, 0x00); 529 ver = i2c_smbus_read_byte_data(client, 0x00);
567 pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) + 530 pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
@@ -599,9 +562,11 @@ static int vpx3220_probe(struct i2c_client *client,
599static int vpx3220_remove(struct i2c_client *client) 562static int vpx3220_remove(struct i2c_client *client)
600{ 563{
601 struct v4l2_subdev *sd = i2c_get_clientdata(client); 564 struct v4l2_subdev *sd = i2c_get_clientdata(client);
565 struct vpx3220 *decoder = to_vpx3220(sd);
602 566
603 v4l2_device_unregister_subdev(sd); 567 v4l2_device_unregister_subdev(sd);
604 kfree(to_vpx3220(sd)); 568 v4l2_ctrl_handler_free(&decoder->hdl);
569 kfree(decoder);
605 return 0; 570 return 0;
606} 571}
607 572
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index fe8ef6419f83..9cedb1e69b58 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -35,6 +35,7 @@
35#include <media/v4l2-device.h> 35#include <media/v4l2-device.h>
36#include <media/v4l2-chip-ident.h> 36#include <media/v4l2-chip-ident.h>
37#include <media/v4l2-ctrls.h> 37#include <media/v4l2-ctrls.h>
38#include <media/wm8775.h>
38 39
39MODULE_DESCRIPTION("wm8775 driver"); 40MODULE_DESCRIPTION("wm8775 driver");
40MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); 41MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
@@ -50,10 +51,16 @@ enum {
50 TOT_REGS 51 TOT_REGS
51}; 52};
52 53
54#define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */
55#define ALC_EN 0x100 /* R17: ALC enable */
56
53struct wm8775_state { 57struct wm8775_state {
54 struct v4l2_subdev sd; 58 struct v4l2_subdev sd;
55 struct v4l2_ctrl_handler hdl; 59 struct v4l2_ctrl_handler hdl;
56 struct v4l2_ctrl *mute; 60 struct v4l2_ctrl *mute;
61 struct v4l2_ctrl *vol;
62 struct v4l2_ctrl *bal;
63 struct v4l2_ctrl *loud;
57 u8 input; /* Last selected input (0-0xf) */ 64 u8 input; /* Last selected input (0-0xf) */
58}; 65};
59 66
@@ -85,6 +92,30 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
85 return -1; 92 return -1;
86} 93}
87 94
95static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly)
96{
97 struct wm8775_state *state = to_state(sd);
98 u8 vol_l, vol_r;
99 int muted = 0 != state->mute->val;
100 u16 volume = (u16)state->vol->val;
101 u16 balance = (u16)state->bal->val;
102
103 /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */
104 vol_l = (min(65536 - balance, 32768) * volume) >> 23;
105 vol_r = (min(balance, (u16)32768) * volume) >> 23;
106
107 /* Mute */
108 if (muted || quietly)
109 wm8775_write(sd, R21, 0x0c0 | state->input);
110
111 wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */
112 wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */
113
114 /* Un-mute */
115 if (!muted)
116 wm8775_write(sd, R21, state->input);
117}
118
88static int wm8775_s_routing(struct v4l2_subdev *sd, 119static int wm8775_s_routing(struct v4l2_subdev *sd,
89 u32 input, u32 output, u32 config) 120 u32 input, u32 output, u32 config)
90{ 121{
@@ -102,25 +133,26 @@ static int wm8775_s_routing(struct v4l2_subdev *sd,
102 state->input = input; 133 state->input = input;
103 if (!v4l2_ctrl_g_ctrl(state->mute)) 134 if (!v4l2_ctrl_g_ctrl(state->mute))
104 return 0; 135 return 0;
105 wm8775_write(sd, R21, 0x0c0); 136 if (!v4l2_ctrl_g_ctrl(state->vol))
106 wm8775_write(sd, R14, 0x1d4); 137 return 0;
107 wm8775_write(sd, R15, 0x1d4); 138 if (!v4l2_ctrl_g_ctrl(state->bal))
108 wm8775_write(sd, R21, 0x100 + state->input); 139 return 0;
140 wm8775_set_audio(sd, 1);
109 return 0; 141 return 0;
110} 142}
111 143
112static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl) 144static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl)
113{ 145{
114 struct v4l2_subdev *sd = to_sd(ctrl); 146 struct v4l2_subdev *sd = to_sd(ctrl);
115 struct wm8775_state *state = to_state(sd);
116 147
117 switch (ctrl->id) { 148 switch (ctrl->id) {
118 case V4L2_CID_AUDIO_MUTE: 149 case V4L2_CID_AUDIO_MUTE:
119 wm8775_write(sd, R21, 0x0c0); 150 case V4L2_CID_AUDIO_VOLUME:
120 wm8775_write(sd, R14, 0x1d4); 151 case V4L2_CID_AUDIO_BALANCE:
121 wm8775_write(sd, R15, 0x1d4); 152 wm8775_set_audio(sd, 0);
122 if (!ctrl->val) 153 return 0;
123 wm8775_write(sd, R21, 0x100 + state->input); 154 case V4L2_CID_AUDIO_LOUDNESS:
155 wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD);
124 return 0; 156 return 0;
125 } 157 }
126 return -EINVAL; 158 return -EINVAL;
@@ -144,16 +176,7 @@ static int wm8775_log_status(struct v4l2_subdev *sd)
144 176
145static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) 177static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
146{ 178{
147 struct wm8775_state *state = to_state(sd); 179 wm8775_set_audio(sd, 0);
148
149 /* If I remove this, then it can happen that I have no
150 sound the first time I tune from static to a valid channel.
151 It's difficult to reproduce and is almost certainly related
152 to the zero cross detect circuit. */
153 wm8775_write(sd, R21, 0x0c0);
154 wm8775_write(sd, R14, 0x1d4);
155 wm8775_write(sd, R15, 0x1d4);
156 wm8775_write(sd, R21, 0x100 + state->input);
157 return 0; 180 return 0;
158} 181}
159 182
@@ -203,6 +226,13 @@ static int wm8775_probe(struct i2c_client *client,
203{ 226{
204 struct wm8775_state *state; 227 struct wm8775_state *state;
205 struct v4l2_subdev *sd; 228 struct v4l2_subdev *sd;
229 int err;
230 bool is_nova_s = false;
231
232 if (client->dev.platform_data) {
233 struct wm8775_platform_data *data = client->dev.platform_data;
234 is_nova_s = data->is_nova_s;
235 }
206 236
207 /* Check if the adapter supports the needed features */ 237 /* Check if the adapter supports the needed features */
208 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 238 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -218,13 +248,18 @@ static int wm8775_probe(struct i2c_client *client,
218 v4l2_i2c_subdev_init(sd, client, &wm8775_ops); 248 v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
219 state->input = 2; 249 state->input = 2;
220 250
221 v4l2_ctrl_handler_init(&state->hdl, 1); 251 v4l2_ctrl_handler_init(&state->hdl, 4);
222 state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, 252 state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
223 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); 253 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
254 state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
255 V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/
256 state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
257 V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768);
258 state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
259 V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1);
224 sd->ctrl_handler = &state->hdl; 260 sd->ctrl_handler = &state->hdl;
225 if (state->hdl.error) { 261 err = state->hdl.error;
226 int err = state->hdl.error; 262 if (err) {
227
228 v4l2_ctrl_handler_free(&state->hdl); 263 v4l2_ctrl_handler_free(&state->hdl);
229 kfree(state); 264 kfree(state);
230 return err; 265 return err;
@@ -236,29 +271,44 @@ static int wm8775_probe(struct i2c_client *client,
236 wm8775_write(sd, R23, 0x000); 271 wm8775_write(sd, R23, 0x000);
237 /* Disable zero cross detect timeout */ 272 /* Disable zero cross detect timeout */
238 wm8775_write(sd, R7, 0x000); 273 wm8775_write(sd, R7, 0x000);
239 /* Left justified, 24-bit mode */ 274 /* HPF enable, left justified, 24-bit (Philips) mode */
240 wm8775_write(sd, R11, 0x021); 275 wm8775_write(sd, R11, 0x021);
241 /* Master mode, clock ratio 256fs */ 276 /* Master mode, clock ratio 256fs */
242 wm8775_write(sd, R12, 0x102); 277 wm8775_write(sd, R12, 0x102);
243 /* Powered up */ 278 /* Powered up */
244 wm8775_write(sd, R13, 0x000); 279 wm8775_write(sd, R13, 0x000);
245 /* ADC gain +2.5dB, enable zero cross */ 280
246 wm8775_write(sd, R14, 0x1d4); 281 if (!is_nova_s) {
247 /* ADC gain +2.5dB, enable zero cross */ 282 /* ADC gain +2.5dB, enable zero cross */
248 wm8775_write(sd, R15, 0x1d4); 283 wm8775_write(sd, R14, 0x1d4);
249 /* ALC Stereo, ALC target level -1dB FS max gain +8dB */ 284 /* ADC gain +2.5dB, enable zero cross */
250 wm8775_write(sd, R16, 0x1bf); 285 wm8775_write(sd, R15, 0x1d4);
251 /* Enable gain control, use zero cross detection, 286 /* ALC Stereo, ALC target level -1dB FS max gain +8dB */
252 ALC hold time 42.6 ms */ 287 wm8775_write(sd, R16, 0x1bf);
253 wm8775_write(sd, R17, 0x185); 288 /* Enable gain control, use zero cross detection,
289 ALC hold time 42.6 ms */
290 wm8775_write(sd, R17, 0x185);
291 } else {
292 /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */
293 wm8775_write(sd, R16, 0x1bb);
294 /* Set ALC mode and hold time */
295 wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD);
296 }
254 /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ 297 /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
255 wm8775_write(sd, R18, 0x0a2); 298 wm8775_write(sd, R18, 0x0a2);
256 /* Enable noise gate, threshold -72dBfs */ 299 /* Enable noise gate, threshold -72dBfs */
257 wm8775_write(sd, R19, 0x005); 300 wm8775_write(sd, R19, 0x005);
258 /* Transient window 4ms, lower PGA gain limit -1dB */ 301 if (!is_nova_s) {
259 wm8775_write(sd, R20, 0x07a); 302 /* Transient window 4ms, lower PGA gain limit -1dB */
260 /* LRBOTH = 1, use input 2. */ 303 wm8775_write(sd, R20, 0x07a);
261 wm8775_write(sd, R21, 0x102); 304 /* LRBOTH = 1, use input 2. */
305 wm8775_write(sd, R21, 0x102);
306 } else {
307 /* Transient window 4ms, ALC min gain -5dB */
308 wm8775_write(sd, R20, 0x0fb);
309
310 wm8775_set_audio(sd, 1); /* set volume/mute/mux */
311 }
262 return 0; 312 return 0;
263} 313}
264 314
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index ae7cad185898..47ec5bc0ed21 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -695,20 +695,22 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,
695}; 695};
696 696
697/** 697/**
698 * i2o_block_media_changed - Have we seen a media change? 698 * i2o_block_check_events - Have we seen a media change?
699 * @disk: gendisk which should be verified 699 * @disk: gendisk which should be verified
700 * @clearing: events being cleared
700 * 701 *
701 * Verifies if the media has changed. 702 * Verifies if the media has changed.
702 * 703 *
703 * Returns 1 if the media was changed or 0 otherwise. 704 * Returns 1 if the media was changed or 0 otherwise.
704 */ 705 */
705static int i2o_block_media_changed(struct gendisk *disk) 706static unsigned int i2o_block_check_events(struct gendisk *disk,
707 unsigned int clearing)
706{ 708{
707 struct i2o_block_device *p = disk->private_data; 709 struct i2o_block_device *p = disk->private_data;
708 710
709 if (p->media_change_flag) { 711 if (p->media_change_flag) {
710 p->media_change_flag = 0; 712 p->media_change_flag = 0;
711 return 1; 713 return DISK_EVENT_MEDIA_CHANGE;
712 } 714 }
713 return 0; 715 return 0;
714} 716}
@@ -895,11 +897,7 @@ static void i2o_block_request_fn(struct request_queue *q)
895{ 897{
896 struct request *req; 898 struct request *req;
897 899
898 while (!blk_queue_plugged(q)) { 900 while ((req = blk_peek_request(q)) != NULL) {
899 req = blk_peek_request(q);
900 if (!req)
901 break;
902
903 if (req->cmd_type == REQ_TYPE_FS) { 901 if (req->cmd_type == REQ_TYPE_FS) {
904 struct i2o_block_delayed_request *dreq; 902 struct i2o_block_delayed_request *dreq;
905 struct i2o_block_request *ireq = req->special; 903 struct i2o_block_request *ireq = req->special;
@@ -950,7 +948,7 @@ static const struct block_device_operations i2o_block_fops = {
950 .ioctl = i2o_block_ioctl, 948 .ioctl = i2o_block_ioctl,
951 .compat_ioctl = i2o_block_ioctl, 949 .compat_ioctl = i2o_block_ioctl,
952 .getgeo = i2o_block_getgeo, 950 .getgeo = i2o_block_getgeo,
953 .media_changed = i2o_block_media_changed 951 .check_events = i2o_block_check_events,
954}; 952};
955 953
956/** 954/**
@@ -1002,6 +1000,7 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
1002 gd->major = I2O_MAJOR; 1000 gd->major = I2O_MAJOR;
1003 gd->queue = queue; 1001 gd->queue = queue;
1004 gd->fops = &i2o_block_fops; 1002 gd->fops = &i2o_block_fops;
1003 gd->events = DISK_EVENT_MEDIA_CHANGE;
1005 gd->private_data = dev; 1004 gd->private_data = dev;
1006 1005
1007 dev->gd = gd; 1006 dev->gd = gd;
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 793300c554b4..9c511c1604a5 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -17,230 +17,138 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/mfd/core.h> 18#include <linux/mfd/core.h>
19#include <linux/mfd/88pm860x.h> 19#include <linux/mfd/88pm860x.h>
20#include <linux/regulator/machine.h>
20 21
21#define INT_STATUS_NUM 3 22#define INT_STATUS_NUM 3
22 23
23char pm860x_backlight_name[][MFD_NAME_SIZE] = { 24static struct resource bk_resources[] __initdata = {
24 "backlight-0", 25 {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,},
25 "backlight-1", 26 {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,},
26 "backlight-2", 27 {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,},
27}; 28};
28EXPORT_SYMBOL(pm860x_backlight_name);
29
30char pm860x_led_name[][MFD_NAME_SIZE] = {
31 "led0-red",
32 "led0-green",
33 "led0-blue",
34 "led1-red",
35 "led1-green",
36 "led1-blue",
37};
38EXPORT_SYMBOL(pm860x_led_name);
39
40#define PM8606_BACKLIGHT_RESOURCE(_i, _x) \
41{ \
42 .name = pm860x_backlight_name[_i], \
43 .start = PM8606_##_x, \
44 .end = PM8606_##_x, \
45 .flags = IORESOURCE_IO, \
46}
47 29
48static struct resource backlight_resources[] = { 30static struct resource led_resources[] __initdata = {
49 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT1, WLED1A), 31 {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_IO,},
50 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT2, WLED2A), 32 {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,},
51 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT3, WLED3A), 33 {PM8606_LED1_BLUE, PM8606_LED1_BLUE, "led0-blue", IORESOURCE_IO,},
34 {PM8606_LED2_RED, PM8606_LED2_RED, "led1-red", IORESOURCE_IO,},
35 {PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_IO,},
36 {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO,},
52}; 37};
53 38
54#define PM8606_BACKLIGHT_DEVS(_i) \ 39static struct resource regulator_resources[] __initdata = {
55{ \ 40 {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,},
56 .name = "88pm860x-backlight", \ 41 {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,},
57 .num_resources = 1, \ 42 {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,},
58 .resources = &backlight_resources[_i], \ 43 {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO,},
59 .id = _i, \ 44 {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO,},
60} 45 {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO,},
61 46 {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO,},
62static struct mfd_cell backlight_devs[] = { 47 {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO,},
63 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT1), 48 {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO,},
64 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT2), 49 {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO,},
65 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT3), 50 {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_IO,},
51 {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_IO,},
52 {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO,},
53 {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO,},
54 {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO,},
55 {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO,},
56 {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO,},
57 {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,},
66}; 58};
67 59
68#define PM8606_LED_RESOURCE(_i, _x) \ 60static struct resource touch_resources[] __initdata = {
69{ \ 61 {PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,},
70 .name = pm860x_led_name[_i], \
71 .start = PM8606_##_x, \
72 .end = PM8606_##_x, \
73 .flags = IORESOURCE_IO, \
74}
75
76static struct resource led_resources[] = {
77 PM8606_LED_RESOURCE(PM8606_LED1_RED, RGB1B),
78 PM8606_LED_RESOURCE(PM8606_LED1_GREEN, RGB1C),
79 PM8606_LED_RESOURCE(PM8606_LED1_BLUE, RGB1D),
80 PM8606_LED_RESOURCE(PM8606_LED2_RED, RGB2B),
81 PM8606_LED_RESOURCE(PM8606_LED2_GREEN, RGB2C),
82 PM8606_LED_RESOURCE(PM8606_LED2_BLUE, RGB2D),
83}; 62};
84 63
85#define PM8606_LED_DEVS(_i) \ 64static struct resource onkey_resources[] __initdata = {
86{ \ 65 {PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,},
87 .name = "88pm860x-led", \
88 .num_resources = 1, \
89 .resources = &led_resources[_i], \
90 .id = _i, \
91}
92
93static struct mfd_cell led_devs[] = {
94 PM8606_LED_DEVS(PM8606_LED1_RED),
95 PM8606_LED_DEVS(PM8606_LED1_GREEN),
96 PM8606_LED_DEVS(PM8606_LED1_BLUE),
97 PM8606_LED_DEVS(PM8606_LED2_RED),
98 PM8606_LED_DEVS(PM8606_LED2_GREEN),
99 PM8606_LED_DEVS(PM8606_LED2_BLUE),
100}; 66};
101 67
102static struct resource touch_resources[] = { 68static struct resource codec_resources[] __initdata = {
103 { 69 /* Headset microphone insertion or removal */
104 .start = PM8607_IRQ_PEN, 70 {PM8607_IRQ_MICIN, PM8607_IRQ_MICIN, "micin", IORESOURCE_IRQ,},
105 .end = PM8607_IRQ_PEN, 71 /* Hook-switch press or release */
106 .flags = IORESOURCE_IRQ, 72 {PM8607_IRQ_HOOK, PM8607_IRQ_HOOK, "hook", IORESOURCE_IRQ,},
107 }, 73 /* Headset insertion or removal */
74 {PM8607_IRQ_HEADSET, PM8607_IRQ_HEADSET, "headset", IORESOURCE_IRQ,},
75 /* Audio short */
76 {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
108}; 77};
109 78
110static struct mfd_cell touch_devs[] = { 79static struct resource battery_resources[] __initdata = {
111 { 80 {PM8607_IRQ_CC, PM8607_IRQ_CC, "columb counter", IORESOURCE_IRQ,},
112 .name = "88pm860x-touch", 81 {PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery", IORESOURCE_IRQ,},
113 .num_resources = 1,
114 .resources = &touch_resources[0],
115 },
116}; 82};
117 83
118#define PM8607_REG_RESOURCE(_start, _end) \ 84static struct resource charger_resources[] __initdata = {
119{ \ 85 {PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,},
120 .start = PM8607_##_start, \ 86 {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,},
121 .end = PM8607_##_end, \ 87 {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout", IORESOURCE_IRQ,},
122 .flags = IORESOURCE_IO, \ 88 {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,},
123} 89 {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,},
124 90 {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,},
125static struct resource power_supply_resources[] = {
126 {
127 .name = "88pm860x-power",
128 .start = PM8607_IRQ_CHG,
129 .end = PM8607_IRQ_CHG,
130 .flags = IORESOURCE_IRQ,
131 },
132}; 91};
133 92
134static struct mfd_cell power_devs[] = { 93static struct mfd_cell bk_devs[] __initdata = {
135 { 94 {"88pm860x-backlight", 0,},
136 .name = "88pm860x-power", 95 {"88pm860x-backlight", 1,},
137 .num_resources = 1, 96 {"88pm860x-backlight", 2,},
138 .resources = &power_supply_resources[0],
139 .id = -1,
140 },
141}; 97};
142 98
143static struct resource onkey_resources[] = { 99static struct mfd_cell led_devs[] __initdata = {
144 { 100 {"88pm860x-led", 0,},
145 .name = "88pm860x-onkey", 101 {"88pm860x-led", 1,},
146 .start = PM8607_IRQ_ONKEY, 102 {"88pm860x-led", 2,},
147 .end = PM8607_IRQ_ONKEY, 103 {"88pm860x-led", 3,},
148 .flags = IORESOURCE_IRQ, 104 {"88pm860x-led", 4,},
149 }, 105 {"88pm860x-led", 5,},
150}; 106};
151 107
152static struct mfd_cell onkey_devs[] = { 108static struct mfd_cell regulator_devs[] __initdata = {
153 { 109 {"88pm860x-regulator", 0,},
154 .name = "88pm860x-onkey", 110 {"88pm860x-regulator", 1,},
155 .num_resources = 1, 111 {"88pm860x-regulator", 2,},
156 .resources = &onkey_resources[0], 112 {"88pm860x-regulator", 3,},
157 .id = -1, 113 {"88pm860x-regulator", 4,},
158 }, 114 {"88pm860x-regulator", 5,},
115 {"88pm860x-regulator", 6,},
116 {"88pm860x-regulator", 7,},
117 {"88pm860x-regulator", 8,},
118 {"88pm860x-regulator", 9,},
119 {"88pm860x-regulator", 10,},
120 {"88pm860x-regulator", 11,},
121 {"88pm860x-regulator", 12,},
122 {"88pm860x-regulator", 13,},
123 {"88pm860x-regulator", 14,},
124 {"88pm860x-regulator", 15,},
125 {"88pm860x-regulator", 16,},
126 {"88pm860x-regulator", 17,},
159}; 127};
160 128
161static struct resource codec_resources[] = { 129static struct mfd_cell touch_devs[] __initdata = {
162 { 130 {"88pm860x-touch", -1,},
163 /* Headset microphone insertion or removal */
164 .name = "micin",
165 .start = PM8607_IRQ_MICIN,
166 .end = PM8607_IRQ_MICIN,
167 .flags = IORESOURCE_IRQ,
168 }, {
169 /* Hook-switch press or release */
170 .name = "hook",
171 .start = PM8607_IRQ_HOOK,
172 .end = PM8607_IRQ_HOOK,
173 .flags = IORESOURCE_IRQ,
174 }, {
175 /* Headset insertion or removal */
176 .name = "headset",
177 .start = PM8607_IRQ_HEADSET,
178 .end = PM8607_IRQ_HEADSET,
179 .flags = IORESOURCE_IRQ,
180 }, {
181 /* Audio short */
182 .name = "audio-short",
183 .start = PM8607_IRQ_AUDIO_SHORT,
184 .end = PM8607_IRQ_AUDIO_SHORT,
185 .flags = IORESOURCE_IRQ,
186 },
187}; 131};
188 132
189static struct mfd_cell codec_devs[] = { 133static struct mfd_cell onkey_devs[] __initdata = {
190 { 134 {"88pm860x-onkey", -1,},
191 .name = "88pm860x-codec",
192 .num_resources = ARRAY_SIZE(codec_resources),
193 .resources = &codec_resources[0],
194 .id = -1,
195 },
196}; 135};
197 136
198static struct resource regulator_resources[] = { 137static struct mfd_cell codec_devs[] __initdata = {
199 PM8607_REG_RESOURCE(BUCK1, BUCK1), 138 {"88pm860x-codec", -1,},
200 PM8607_REG_RESOURCE(BUCK2, BUCK2),
201 PM8607_REG_RESOURCE(BUCK3, BUCK3),
202 PM8607_REG_RESOURCE(LDO1, LDO1),
203 PM8607_REG_RESOURCE(LDO2, LDO2),
204 PM8607_REG_RESOURCE(LDO3, LDO3),
205 PM8607_REG_RESOURCE(LDO4, LDO4),
206 PM8607_REG_RESOURCE(LDO5, LDO5),
207 PM8607_REG_RESOURCE(LDO6, LDO6),
208 PM8607_REG_RESOURCE(LDO7, LDO7),
209 PM8607_REG_RESOURCE(LDO8, LDO8),
210 PM8607_REG_RESOURCE(LDO9, LDO9),
211 PM8607_REG_RESOURCE(LDO10, LDO10),
212 PM8607_REG_RESOURCE(LDO12, LDO12),
213 PM8607_REG_RESOURCE(VIBRATOR_SET, VIBRATOR_SET),
214 PM8607_REG_RESOURCE(LDO14, LDO14),
215}; 139};
216 140
217#define PM8607_REG_DEVS(_id) \ 141static struct mfd_cell power_devs[] = {
218{ \ 142 {"88pm860x-battery", -1,},
219 .name = "88pm860x-regulator", \ 143 {"88pm860x-charger", -1,},
220 .num_resources = 1, \
221 .resources = &regulator_resources[PM8607_ID_##_id], \
222 .id = PM8607_ID_##_id, \
223}
224
225static struct mfd_cell regulator_devs[] = {
226 PM8607_REG_DEVS(BUCK1),
227 PM8607_REG_DEVS(BUCK2),
228 PM8607_REG_DEVS(BUCK3),
229 PM8607_REG_DEVS(LDO1),
230 PM8607_REG_DEVS(LDO2),
231 PM8607_REG_DEVS(LDO3),
232 PM8607_REG_DEVS(LDO4),
233 PM8607_REG_DEVS(LDO5),
234 PM8607_REG_DEVS(LDO6),
235 PM8607_REG_DEVS(LDO7),
236 PM8607_REG_DEVS(LDO8),
237 PM8607_REG_DEVS(LDO9),
238 PM8607_REG_DEVS(LDO10),
239 PM8607_REG_DEVS(LDO12),
240 PM8607_REG_DEVS(LDO13),
241 PM8607_REG_DEVS(LDO14),
242}; 144};
243 145
146static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)];
147static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)];
148static struct regulator_init_data regulator_pdata[ARRAY_SIZE(regulator_devs)];
149static struct pm860x_touch_pdata touch_pdata;
150static struct pm860x_power_pdata power_pdata;
151
244struct pm860x_irq_data { 152struct pm860x_irq_data {
245 int reg; 153 int reg;
246 int mask_reg; 154 int mask_reg;
@@ -595,37 +503,212 @@ static void device_irq_exit(struct pm860x_chip *chip)
595 free_irq(chip->core_irq, chip); 503 free_irq(chip->core_irq, chip);
596} 504}
597 505
598static void __devinit device_8606_init(struct pm860x_chip *chip, 506static void __devinit device_bk_init(struct pm860x_chip *chip,
599 struct i2c_client *i2c, 507 struct i2c_client *i2c,
600 struct pm860x_platform_data *pdata) 508 struct pm860x_platform_data *pdata)
601{ 509{
602 int ret; 510 int ret;
511 int i, j, id;
512
513 if ((pdata == NULL) || (pdata->backlight == NULL))
514 return;
515
516 if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
517 pdata->num_backlights = ARRAY_SIZE(bk_devs);
518
519 for (i = 0; i < pdata->num_backlights; i++) {
520 memcpy(&bk_pdata[i], &pdata->backlight[i],
521 sizeof(struct pm860x_backlight_pdata));
522 bk_devs[i].mfd_data = &bk_pdata[i];
523
524 for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
525 id = bk_resources[j].start;
526 if (bk_pdata[i].flags != id)
527 continue;
528
529 bk_devs[i].num_resources = 1;
530 bk_devs[i].resources = &bk_resources[j];
531 ret = mfd_add_devices(chip->dev, 0,
532 &bk_devs[i], 1,
533 &bk_resources[j], 0);
534 if (ret < 0) {
535 dev_err(chip->dev, "Failed to add "
536 "backlight subdev\n");
537 return;
538 }
539 }
540 }
541}
603 542
604 if (pdata && pdata->backlight) { 543static void __devinit device_led_init(struct pm860x_chip *chip,
605 ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], 544 struct i2c_client *i2c,
606 ARRAY_SIZE(backlight_devs), 545 struct pm860x_platform_data *pdata)
607 &backlight_resources[0], 0); 546{
608 if (ret < 0) { 547 int ret;
609 dev_err(chip->dev, "Failed to add backlight " 548 int i, j, id;
610 "subdev\n"); 549
611 goto out_dev; 550 if ((pdata == NULL) || (pdata->led == NULL))
551 return;
552
553 if (pdata->num_leds > ARRAY_SIZE(led_devs))
554 pdata->num_leds = ARRAY_SIZE(led_devs);
555
556 for (i = 0; i < pdata->num_leds; i++) {
557 memcpy(&led_pdata[i], &pdata->led[i],
558 sizeof(struct pm860x_led_pdata));
559 led_devs[i].mfd_data = &led_pdata[i];
560
561 for (j = 0; j < ARRAY_SIZE(led_devs); j++) {
562 id = led_resources[j].start;
563 if (led_pdata[i].flags != id)
564 continue;
565
566 led_devs[i].num_resources = 1;
567 led_devs[i].resources = &led_resources[j],
568 ret = mfd_add_devices(chip->dev, 0,
569 &led_devs[i], 1,
570 &led_resources[j], 0);
571 if (ret < 0) {
572 dev_err(chip->dev, "Failed to add "
573 "led subdev\n");
574 return;
575 }
612 } 576 }
613 } 577 }
578}
614 579
615 if (pdata && pdata->led) { 580static void __devinit device_regulator_init(struct pm860x_chip *chip,
616 ret = mfd_add_devices(chip->dev, 0, &led_devs[0], 581 struct i2c_client *i2c,
617 ARRAY_SIZE(led_devs), 582 struct pm860x_platform_data *pdata)
618 &led_resources[0], 0); 583{
584 struct regulator_init_data *initdata;
585 int ret;
586 int i, j;
587
588 if ((pdata == NULL) || (pdata->regulator == NULL))
589 return;
590
591 if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
592 pdata->num_regulators = ARRAY_SIZE(regulator_devs);
593
594 for (i = 0, j = -1; i < pdata->num_regulators; i++) {
595 initdata = &pdata->regulator[i];
596 if (strstr(initdata->constraints.name, "BUCK")) {
597 sscanf(initdata->constraints.name, "BUCK%d", &j);
598 /* BUCK1 ~ BUCK3 */
599 if ((j < 1) || (j > 3)) {
600 dev_err(chip->dev, "Failed to add constraint "
601 "(%s)\n", initdata->constraints.name);
602 goto out;
603 }
604 j = (j - 1) + PM8607_ID_BUCK1;
605 }
606 if (strstr(initdata->constraints.name, "LDO")) {
607 sscanf(initdata->constraints.name, "LDO%d", &j);
608 /* LDO1 ~ LDO15 */
609 if ((j < 1) || (j > 15)) {
610 dev_err(chip->dev, "Failed to add constraint "
611 "(%s)\n", initdata->constraints.name);
612 goto out;
613 }
614 j = (j - 1) + PM8607_ID_LDO1;
615 }
616 if (j == -1) {
617 dev_err(chip->dev, "Failed to add constraint (%s)\n",
618 initdata->constraints.name);
619 goto out;
620 }
621 memcpy(&regulator_pdata[i], &pdata->regulator[i],
622 sizeof(struct regulator_init_data));
623 regulator_devs[i].mfd_data = &regulator_pdata[i];
624 regulator_devs[i].num_resources = 1;
625 regulator_devs[i].resources = &regulator_resources[j];
626
627 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
628 &regulator_resources[j], 0);
619 if (ret < 0) { 629 if (ret < 0) {
620 dev_err(chip->dev, "Failed to add led " 630 dev_err(chip->dev, "Failed to add regulator subdev\n");
621 "subdev\n"); 631 goto out;
622 goto out_dev;
623 } 632 }
624 } 633 }
634out:
625 return; 635 return;
626out_dev: 636}
627 mfd_remove_devices(chip->dev); 637
628 device_irq_exit(chip); 638static void __devinit device_touch_init(struct pm860x_chip *chip,
639 struct i2c_client *i2c,
640 struct pm860x_platform_data *pdata)
641{
642 int ret;
643
644 if ((pdata == NULL) || (pdata->touch == NULL))
645 return;
646
647 memcpy(&touch_pdata, pdata->touch, sizeof(struct pm860x_touch_pdata));
648 touch_devs[0].mfd_data = &touch_pdata;
649 touch_devs[0].num_resources = ARRAY_SIZE(touch_resources);
650 touch_devs[0].resources = &touch_resources[0];
651 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
652 ARRAY_SIZE(touch_devs), &touch_resources[0],
653 chip->irq_base);
654 if (ret < 0)
655 dev_err(chip->dev, "Failed to add touch subdev\n");
656}
657
658static void __devinit device_power_init(struct pm860x_chip *chip,
659 struct i2c_client *i2c,
660 struct pm860x_platform_data *pdata)
661{
662 int ret;
663
664 if ((pdata == NULL) || (pdata->power == NULL))
665 return;
666
667 memcpy(&power_pdata, pdata->power, sizeof(struct pm860x_power_pdata));
668 power_devs[0].mfd_data = &power_pdata;
669 power_devs[0].num_resources = ARRAY_SIZE(battery_resources);
670 power_devs[0].resources = &battery_resources[0],
671 ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1,
672 &battery_resources[0], chip->irq_base);
673 if (ret < 0)
674 dev_err(chip->dev, "Failed to add battery subdev\n");
675
676 power_devs[1].mfd_data = &power_pdata;
677 power_devs[1].num_resources = ARRAY_SIZE(charger_resources);
678 power_devs[1].resources = &charger_resources[0],
679 ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1,
680 &charger_resources[0], chip->irq_base);
681 if (ret < 0)
682 dev_err(chip->dev, "Failed to add charger subdev\n");
683}
684
685static void __devinit device_onkey_init(struct pm860x_chip *chip,
686 struct i2c_client *i2c,
687 struct pm860x_platform_data *pdata)
688{
689 int ret;
690
691 onkey_devs[0].num_resources = ARRAY_SIZE(onkey_resources);
692 onkey_devs[0].resources = &onkey_resources[0],
693 ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
694 ARRAY_SIZE(onkey_devs), &onkey_resources[0],
695 chip->irq_base);
696 if (ret < 0)
697 dev_err(chip->dev, "Failed to add onkey subdev\n");
698}
699
700static void __devinit device_codec_init(struct pm860x_chip *chip,
701 struct i2c_client *i2c,
702 struct pm860x_platform_data *pdata)
703{
704 int ret;
705
706 codec_devs[0].num_resources = ARRAY_SIZE(codec_resources);
707 codec_devs[0].resources = &codec_resources[0],
708 ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
709 ARRAY_SIZE(codec_devs), &codec_resources[0], 0);
710 if (ret < 0)
711 dev_err(chip->dev, "Failed to add codec subdev\n");
629} 712}
630 713
631static void __devinit device_8607_init(struct pm860x_chip *chip, 714static void __devinit device_8607_init(struct pm860x_chip *chip,
@@ -683,55 +766,11 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
683 if (ret < 0) 766 if (ret < 0)
684 goto out; 767 goto out;
685 768
686 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0], 769 device_regulator_init(chip, i2c, pdata);
687 ARRAY_SIZE(regulator_devs), 770 device_onkey_init(chip, i2c, pdata);
688 &regulator_resources[0], 0); 771 device_touch_init(chip, i2c, pdata);
689 if (ret < 0) { 772 device_power_init(chip, i2c, pdata);
690 dev_err(chip->dev, "Failed to add regulator subdev\n"); 773 device_codec_init(chip, i2c, pdata);
691 goto out_dev;
692 }
693
694 if (pdata && pdata->touch) {
695 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
696 ARRAY_SIZE(touch_devs),
697 &touch_resources[0], 0);
698 if (ret < 0) {
699 dev_err(chip->dev, "Failed to add touch "
700 "subdev\n");
701 goto out_dev;
702 }
703 }
704
705 if (pdata && pdata->power) {
706 ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
707 ARRAY_SIZE(power_devs),
708 &power_supply_resources[0], 0);
709 if (ret < 0) {
710 dev_err(chip->dev, "Failed to add power supply "
711 "subdev\n");
712 goto out_dev;
713 }
714 }
715
716 ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
717 ARRAY_SIZE(onkey_devs),
718 &onkey_resources[0], 0);
719 if (ret < 0) {
720 dev_err(chip->dev, "Failed to add onkey subdev\n");
721 goto out_dev;
722 }
723
724 ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
725 ARRAY_SIZE(codec_devs),
726 &codec_resources[0], 0);
727 if (ret < 0) {
728 dev_err(chip->dev, "Failed to add codec subdev\n");
729 goto out_dev;
730 }
731 return;
732out_dev:
733 mfd_remove_devices(chip->dev);
734 device_irq_exit(chip);
735out: 774out:
736 return; 775 return;
737} 776}
@@ -743,7 +782,8 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
743 782
744 switch (chip->id) { 783 switch (chip->id) {
745 case CHIP_PM8606: 784 case CHIP_PM8606:
746 device_8606_init(chip, chip->client, pdata); 785 device_bk_init(chip, chip->client, pdata);
786 device_led_init(chip, chip->client, pdata);
747 break; 787 break;
748 case CHIP_PM8607: 788 case CHIP_PM8607:
749 device_8607_init(chip, chip->client, pdata); 789 device_8607_init(chip, chip->client, pdata);
@@ -753,7 +793,8 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
753 if (chip->companion) { 793 if (chip->companion) {
754 switch (chip->id) { 794 switch (chip->id) {
755 case CHIP_PM8607: 795 case CHIP_PM8607:
756 device_8606_init(chip, chip->companion, pdata); 796 device_bk_init(chip, chip->companion, pdata);
797 device_led_init(chip, chip->companion, pdata);
757 break; 798 break;
758 case CHIP_PM8606: 799 case CHIP_PM8606:
759 device_8607_init(chip, chip->companion, pdata); 800 device_8607_init(chip, chip->companion, pdata);
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index bc02e6b21608..e017dc88622a 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -126,6 +126,109 @@ out:
126} 126}
127EXPORT_SYMBOL(pm860x_set_bits); 127EXPORT_SYMBOL(pm860x_set_bits);
128 128
129int pm860x_page_reg_read(struct i2c_client *i2c, int reg)
130{
131 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
132 unsigned char zero = 0;
133 unsigned char data;
134 int ret;
135
136 mutex_lock(&chip->io_lock);
137 pm860x_write_device(i2c, 0xFA, 0, &zero);
138 pm860x_write_device(i2c, 0xFB, 0, &zero);
139 pm860x_write_device(i2c, 0xFF, 0, &zero);
140 ret = pm860x_read_device(i2c, reg, 1, &data);
141 if (ret >= 0)
142 ret = (int)data;
143 pm860x_write_device(i2c, 0xFE, 0, &zero);
144 pm860x_write_device(i2c, 0xFC, 0, &zero);
145 mutex_unlock(&chip->io_lock);
146 return ret;
147}
148EXPORT_SYMBOL(pm860x_page_reg_read);
149
150int pm860x_page_reg_write(struct i2c_client *i2c, int reg,
151 unsigned char data)
152{
153 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
154 unsigned char zero;
155 int ret;
156
157 mutex_lock(&chip->io_lock);
158 pm860x_write_device(i2c, 0xFA, 0, &zero);
159 pm860x_write_device(i2c, 0xFB, 0, &zero);
160 pm860x_write_device(i2c, 0xFF, 0, &zero);
161 ret = pm860x_write_device(i2c, reg, 1, &data);
162 pm860x_write_device(i2c, 0xFE, 0, &zero);
163 pm860x_write_device(i2c, 0xFC, 0, &zero);
164 mutex_unlock(&chip->io_lock);
165 return ret;
166}
167EXPORT_SYMBOL(pm860x_page_reg_write);
168
169int pm860x_page_bulk_read(struct i2c_client *i2c, int reg,
170 int count, unsigned char *buf)
171{
172 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
173 unsigned char zero = 0;
174 int ret;
175
176 mutex_lock(&chip->io_lock);
177 pm860x_write_device(i2c, 0xFA, 0, &zero);
178 pm860x_write_device(i2c, 0xFB, 0, &zero);
179 pm860x_write_device(i2c, 0xFF, 0, &zero);
180 ret = pm860x_read_device(i2c, reg, count, buf);
181 pm860x_write_device(i2c, 0xFE, 0, &zero);
182 pm860x_write_device(i2c, 0xFC, 0, &zero);
183 mutex_unlock(&chip->io_lock);
184 return ret;
185}
186EXPORT_SYMBOL(pm860x_page_bulk_read);
187
188int pm860x_page_bulk_write(struct i2c_client *i2c, int reg,
189 int count, unsigned char *buf)
190{
191 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
192 unsigned char zero = 0;
193 int ret;
194
195 mutex_lock(&chip->io_lock);
196 pm860x_write_device(i2c, 0xFA, 0, &zero);
197 pm860x_write_device(i2c, 0xFB, 0, &zero);
198 pm860x_write_device(i2c, 0xFF, 0, &zero);
199 ret = pm860x_write_device(i2c, reg, count, buf);
200 pm860x_write_device(i2c, 0xFE, 0, &zero);
201 pm860x_write_device(i2c, 0xFC, 0, &zero);
202 mutex_unlock(&chip->io_lock);
203 return ret;
204}
205EXPORT_SYMBOL(pm860x_page_bulk_write);
206
207int pm860x_page_set_bits(struct i2c_client *i2c, int reg,
208 unsigned char mask, unsigned char data)
209{
210 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
211 unsigned char zero;
212 unsigned char value;
213 int ret;
214
215 mutex_lock(&chip->io_lock);
216 pm860x_write_device(i2c, 0xFA, 0, &zero);
217 pm860x_write_device(i2c, 0xFB, 0, &zero);
218 pm860x_write_device(i2c, 0xFF, 0, &zero);
219 ret = pm860x_read_device(i2c, reg, 1, &value);
220 if (ret < 0)
221 goto out;
222 value &= ~mask;
223 value |= data;
224 ret = pm860x_write_device(i2c, reg, 1, &value);
225out:
226 pm860x_write_device(i2c, 0xFE, 0, &zero);
227 pm860x_write_device(i2c, 0xFC, 0, &zero);
228 mutex_unlock(&chip->io_lock);
229 return ret;
230}
231EXPORT_SYMBOL(pm860x_page_set_bits);
129 232
130static const struct i2c_device_id pm860x_id_table[] = { 233static const struct i2c_device_id pm860x_id_table[] = {
131 { "88PM860x", 0 }, 234 { "88PM860x", 0 },
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fdca643249e1..a9a1af49281e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -129,6 +129,17 @@ config UCB1400_CORE
129 To compile this driver as a module, choose M here: the 129 To compile this driver as a module, choose M here: the
130 module will be called ucb1400_core. 130 module will be called ucb1400_core.
131 131
132config TPS6105X
133 tristate "TPS61050/61052 Boost Converters"
134 depends on I2C
135 select REGULATOR
136 select REGULATOR_FIXED_VOLTAGE
137 help
138 This option enables a driver for the TP61050/TPS61052
139 high-power "white LED driver". This boost converter is
140 sometimes used for other things than white LEDs, and
141 also contains a GPIO pin.
142
132config TPS65010 143config TPS65010
133 tristate "TPS6501x Power Management chips" 144 tristate "TPS6501x Power Management chips"
134 depends on I2C && GPIOLIB 145 depends on I2C && GPIOLIB
@@ -178,6 +189,16 @@ config TWL4030_CORE
178 high speed USB OTG transceiver, an audio codec (on most 189 high speed USB OTG transceiver, an audio codec (on most
179 versions) and many other features. 190 versions) and many other features.
180 191
192config TWL4030_MADC
193 tristate "Texas Instruments TWL4030 MADC"
194 depends on TWL4030_CORE
195 help
196 This driver provides support for triton TWL4030-MADC. The
197 driver supports both RT and SW conversion methods.
198
199 This driver can be built as a module. If so it will be
200 named twl4030-madc
201
181config TWL4030_POWER 202config TWL4030_POWER
182 bool "Support power resources on TWL4030 family chips" 203 bool "Support power resources on TWL4030 family chips"
183 depends on TWL4030_CORE && ARM 204 depends on TWL4030_CORE && ARM
@@ -304,6 +325,18 @@ config MFD_MAX8925
304 accessing the device, additional drivers must be enabled in order 325 accessing the device, additional drivers must be enabled in order
305 to use the functionality of the device. 326 to use the functionality of the device.
306 327
328config MFD_MAX8997
329 bool "Maxim Semiconductor MAX8997/8966 PMIC Support"
330 depends on I2C=y && GENERIC_HARDIRQS
331 select MFD_CORE
332 help
333 Say yes here to support for Maxim Semiconductor MAX8998/8966.
334 This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
335 MUIC controls on chip.
336 This driver provides common support for accessing the device;
337 additional drivers must be enabled in order to use the functionality
338 of the device.
339
307config MFD_MAX8998 340config MFD_MAX8998
308 bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support" 341 bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support"
309 depends on I2C=y && GENERIC_HARDIRQS 342 depends on I2C=y && GENERIC_HARDIRQS
@@ -534,6 +567,13 @@ config AB8500_DEBUG
534 Select this option if you want debug information using the debug 567 Select this option if you want debug information using the debug
535 filesystem, debugfs. 568 filesystem, debugfs.
536 569
570config AB8500_GPADC
571 bool "AB8500 GPADC driver"
572 depends on AB8500_CORE && REGULATOR_AB8500
573 default y
574 help
575 AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage
576
537config AB3550_CORE 577config AB3550_CORE
538 bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions" 578 bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions"
539 select MFD_CORE 579 select MFD_CORE
@@ -626,7 +666,7 @@ config MFD_VX855
626 and/or vx855_gpio drivers for this to do anything useful. 666 and/or vx855_gpio drivers for this to do anything useful.
627 667
628config MFD_WL1273_CORE 668config MFD_WL1273_CORE
629 tristate 669 tristate "Support for TI WL1273 FM radio."
630 depends on I2C 670 depends on I2C
631 select MFD_CORE 671 select MFD_CORE
632 default n 672 default n
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f0e25cad762e..47f5709f3828 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -33,11 +33,13 @@ obj-$(CONFIG_MFD_WM8350) += wm8350.o
33obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o 33obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
34obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o 34obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o
35 35
36obj-$(CONFIG_TPS6105X) += tps6105x.o
36obj-$(CONFIG_TPS65010) += tps65010.o 37obj-$(CONFIG_TPS65010) += tps65010.o
37obj-$(CONFIG_TPS6507X) += tps6507x.o 38obj-$(CONFIG_TPS6507X) += tps6507x.o
38obj-$(CONFIG_MENELAUS) += menelaus.o 39obj-$(CONFIG_MENELAUS) += menelaus.o
39 40
40obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o 41obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
42obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
41obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o 43obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
42obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o 44obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o
43obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o 45obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
@@ -61,6 +63,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
61obj-$(CONFIG_PMIC_DA903X) += da903x.o 63obj-$(CONFIG_PMIC_DA903X) += da903x.o
62max8925-objs := max8925-core.o max8925-i2c.o 64max8925-objs := max8925-core.o max8925-i2c.o
63obj-$(CONFIG_MFD_MAX8925) += max8925.o 65obj-$(CONFIG_MFD_MAX8925) += max8925.o
66obj-$(CONFIG_MFD_MAX8997) += max8997.o
64obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o 67obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o
65 68
66pcf50633-objs := pcf50633-core.o pcf50633-irq.o 69pcf50633-objs := pcf50633-core.o pcf50633-irq.o
@@ -71,9 +74,10 @@ obj-$(CONFIG_ABX500_CORE) += abx500-core.o
71obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 74obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
72obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 75obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
73obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 76obj-$(CONFIG_AB3550_CORE) += ab3550-core.o
74obj-$(CONFIG_AB8500_CORE) += ab8500-core.o 77obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
75obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o 78obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o
76obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 79obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
80obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
77obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 81obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
78obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 82obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
79obj-$(CONFIG_LPC_SCH) += lpc_sch.o 83obj-$(CONFIG_LPC_SCH) += lpc_sch.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 4193af5f2743..a751927047ac 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -613,7 +613,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100)
613 ab3100_get_priv.ab3100 = ab3100; 613 ab3100_get_priv.ab3100 = ab3100;
614 ab3100_get_priv.mode = false; 614 ab3100_get_priv.mode = false;
615 ab3100_get_reg_file = debugfs_create_file("get_reg", 615 ab3100_get_reg_file = debugfs_create_file("get_reg",
616 S_IWUGO, ab3100_dir, &ab3100_get_priv, 616 S_IWUSR, ab3100_dir, &ab3100_get_priv,
617 &ab3100_get_set_reg_fops); 617 &ab3100_get_set_reg_fops);
618 if (!ab3100_get_reg_file) { 618 if (!ab3100_get_reg_file) {
619 err = -ENOMEM; 619 err = -ENOMEM;
@@ -623,7 +623,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100)
623 ab3100_set_priv.ab3100 = ab3100; 623 ab3100_set_priv.ab3100 = ab3100;
624 ab3100_set_priv.mode = true; 624 ab3100_set_priv.mode = true;
625 ab3100_set_reg_file = debugfs_create_file("set_reg", 625 ab3100_set_reg_file = debugfs_create_file("set_reg",
626 S_IWUGO, ab3100_dir, &ab3100_set_priv, 626 S_IWUSR, ab3100_dir, &ab3100_set_priv,
627 &ab3100_get_set_reg_fops); 627 &ab3100_get_set_reg_fops);
628 if (!ab3100_set_reg_file) { 628 if (!ab3100_set_reg_file) {
629 err = -ENOMEM; 629 err = -ENOMEM;
@@ -949,10 +949,8 @@ static int __devinit ab3100_probe(struct i2c_client *client,
949 goto exit_no_ops; 949 goto exit_no_ops;
950 950
951 /* Set up and register the platform devices. */ 951 /* Set up and register the platform devices. */
952 for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) { 952 for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++)
953 ab3100_devs[i].platform_data = ab3100_plf_data; 953 ab3100_devs[i].mfd_data = ab3100_plf_data;
954 ab3100_devs[i].data_size = sizeof(struct ab3100_platform_data);
955 }
956 954
957 err = mfd_add_devices(&client->dev, 0, ab3100_devs, 955 err = mfd_add_devices(&client->dev, 0, ab3100_devs,
958 ARRAY_SIZE(ab3100_devs), NULL, 0); 956 ARRAY_SIZE(ab3100_devs), NULL, 0);
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c
index 5fbca346b998..c12d04285226 100644
--- a/drivers/mfd/ab3550-core.c
+++ b/drivers/mfd/ab3550-core.c
@@ -1053,17 +1053,17 @@ static inline void ab3550_setup_debugfs(struct ab3550 *ab)
1053 goto exit_destroy_dir; 1053 goto exit_destroy_dir;
1054 1054
1055 ab3550_bank_file = debugfs_create_file("register-bank", 1055 ab3550_bank_file = debugfs_create_file("register-bank",
1056 (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_bank_fops); 1056 (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_bank_fops);
1057 if (!ab3550_bank_file) 1057 if (!ab3550_bank_file)
1058 goto exit_destroy_reg; 1058 goto exit_destroy_reg;
1059 1059
1060 ab3550_address_file = debugfs_create_file("register-address", 1060 ab3550_address_file = debugfs_create_file("register-address",
1061 (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_address_fops); 1061 (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_address_fops);
1062 if (!ab3550_address_file) 1062 if (!ab3550_address_file)
1063 goto exit_destroy_bank; 1063 goto exit_destroy_bank;
1064 1064
1065 ab3550_val_file = debugfs_create_file("register-value", 1065 ab3550_val_file = debugfs_create_file("register-value",
1066 (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_val_fops); 1066 (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_val_fops);
1067 if (!ab3550_val_file) 1067 if (!ab3550_val_file)
1068 goto exit_destroy_address; 1068 goto exit_destroy_address;
1069 1069
@@ -1320,10 +1320,8 @@ static int __init ab3550_probe(struct i2c_client *client,
1320 goto exit_no_ops; 1320 goto exit_no_ops;
1321 1321
1322 /* Set up and register the platform devices. */ 1322 /* Set up and register the platform devices. */
1323 for (i = 0; i < AB3550_NUM_DEVICES; i++) { 1323 for (i = 0; i < AB3550_NUM_DEVICES; i++)
1324 ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i]; 1324 ab3550_devs[i].mfd_data = ab3550_plf_data->dev_data[i];
1325 ab3550_devs[i].data_size = ab3550_plf_data->dev_data_sz[i];
1326 }
1327 1325
1328 err = mfd_add_devices(&client->dev, 0, ab3550_devs, 1326 err = mfd_add_devices(&client->dev, 0, ab3550_devs,
1329 ARRAY_SIZE(ab3550_devs), NULL, 1327 ARRAY_SIZE(ab3550_devs), NULL,
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index b6887014d687..6e185b272d00 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -4,7 +4,7 @@
4 * License Terms: GNU General Public License v2 4 * License Terms: GNU General Public License v2
5 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 5 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
6 * Author: Rabin Vincent <rabin.vincent@stericsson.com> 6 * Author: Rabin Vincent <rabin.vincent@stericsson.com>
7 * Changes: Mattias Wallin <mattias.wallin@stericsson.com> 7 * Author: Mattias Wallin <mattias.wallin@stericsson.com>
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -90,6 +90,7 @@
90#define AB8500_IT_MASK24_REG 0x57 90#define AB8500_IT_MASK24_REG 0x57
91 91
92#define AB8500_REV_REG 0x80 92#define AB8500_REV_REG 0x80
93#define AB8500_SWITCH_OFF_STATUS 0x00
93 94
94/* 95/*
95 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt 96 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
@@ -652,10 +653,38 @@ static ssize_t show_chip_id(struct device *dev,
652 return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); 653 return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL);
653} 654}
654 655
656/*
657 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
658 * 0x01 Swoff bit programming
659 * 0x02 Thermal protection activation
660 * 0x04 Vbat lower then BattOk falling threshold
661 * 0x08 Watchdog expired
662 * 0x10 Non presence of 32kHz clock
663 * 0x20 Battery level lower than power on reset threshold
664 * 0x40 Power on key 1 pressed longer than 10 seconds
665 * 0x80 DB8500 thermal shutdown
666 */
667static ssize_t show_switch_off_status(struct device *dev,
668 struct device_attribute *attr, char *buf)
669{
670 int ret;
671 u8 value;
672 struct ab8500 *ab8500;
673
674 ab8500 = dev_get_drvdata(dev);
675 ret = get_register_interruptible(ab8500, AB8500_RTC,
676 AB8500_SWITCH_OFF_STATUS, &value);
677 if (ret < 0)
678 return ret;
679 return sprintf(buf, "%#x\n", value);
680}
681
655static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); 682static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
683static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
656 684
657static struct attribute *ab8500_sysfs_entries[] = { 685static struct attribute *ab8500_sysfs_entries[] = {
658 &dev_attr_chip_id.attr, 686 &dev_attr_chip_id.attr,
687 &dev_attr_switch_off_status.attr,
659 NULL, 688 NULL,
660}; 689};
661 690
@@ -686,9 +715,10 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
686 * 0x10 - Cut 1.0 715 * 0x10 - Cut 1.0
687 * 0x11 - Cut 1.1 716 * 0x11 - Cut 1.1
688 * 0x20 - Cut 2.0 717 * 0x20 - Cut 2.0
718 * 0x30 - Cut 3.0
689 */ 719 */
690 if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20) { 720 if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20 ||
691 ab8500->revision = value; 721 value == 0x30) {
692 dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); 722 dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
693 } else { 723 } else {
694 dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value); 724 dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
@@ -696,6 +726,24 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
696 } 726 }
697 ab8500->chip_id = value; 727 ab8500->chip_id = value;
698 728
729 /*
730 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
731 * 0x01 Swoff bit programming
732 * 0x02 Thermal protection activation
733 * 0x04 Vbat lower then BattOk falling threshold
734 * 0x08 Watchdog expired
735 * 0x10 Non presence of 32kHz clock
736 * 0x20 Battery level lower than power on reset threshold
737 * 0x40 Power on key 1 pressed longer than 10 seconds
738 * 0x80 DB8500 thermal shutdown
739 */
740
741 ret = get_register_interruptible(ab8500, AB8500_RTC,
742 AB8500_SWITCH_OFF_STATUS, &value);
743 if (ret < 0)
744 return ret;
745 dev_info(ab8500->dev, "switch off status: %#x", value);
746
699 if (plat && plat->init) 747 if (plat && plat->init)
700 plat->init(ab8500); 748 plat->init(ab8500);
701 749
@@ -764,6 +812,6 @@ int __devexit ab8500_exit(struct ab8500 *ab8500)
764 return 0; 812 return 0;
765} 813}
766 814
767MODULE_AUTHOR("Srinidhi Kasagar, Rabin Vincent"); 815MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent");
768MODULE_DESCRIPTION("AB8500 MFD core"); 816MODULE_DESCRIPTION("AB8500 MFD core");
769MODULE_LICENSE("GPL v2"); 817MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 3c1541ae7223..64748e42ac03 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -585,18 +585,18 @@ static int __devinit ab8500_debug_probe(struct platform_device *plf)
585 goto exit_destroy_dir; 585 goto exit_destroy_dir;
586 586
587 ab8500_bank_file = debugfs_create_file("register-bank", 587 ab8500_bank_file = debugfs_create_file("register-bank",
588 (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); 588 (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_bank_fops);
589 if (!ab8500_bank_file) 589 if (!ab8500_bank_file)
590 goto exit_destroy_reg; 590 goto exit_destroy_reg;
591 591
592 ab8500_address_file = debugfs_create_file("register-address", 592 ab8500_address_file = debugfs_create_file("register-address",
593 (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, 593 (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev,
594 &ab8500_address_fops); 594 &ab8500_address_fops);
595 if (!ab8500_address_file) 595 if (!ab8500_address_file)
596 goto exit_destroy_bank; 596 goto exit_destroy_bank;
597 597
598 ab8500_val_file = debugfs_create_file("register-value", 598 ab8500_val_file = debugfs_create_file("register-value",
599 (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); 599 (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_val_fops);
600 if (!ab8500_val_file) 600 if (!ab8500_val_file)
601 goto exit_destroy_address; 601 goto exit_destroy_address;
602 602
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
new file mode 100644
index 000000000000..bc93b2e8230c
--- /dev/null
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -0,0 +1,614 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2010
3 *
4 * License Terms: GNU General Public License v2
5 * Author: Arun R Murthy <arun.murthy@stericsson.com>
6 * Author: Daniel Willerud <daniel.willerud@stericsson.com>
7 * Author: Johan Palsson <johan.palsson@stericsson.com>
8 */
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/device.h>
12#include <linux/interrupt.h>
13#include <linux/spinlock.h>
14#include <linux/delay.h>
15#include <linux/platform_device.h>
16#include <linux/completion.h>
17#include <linux/regulator/consumer.h>
18#include <linux/err.h>
19#include <linux/slab.h>
20#include <linux/list.h>
21#include <linux/mfd/ab8500.h>
22#include <linux/mfd/abx500.h>
23#include <linux/mfd/ab8500/gpadc.h>
24
25/*
26 * GPADC register offsets
27 * Bank : 0x0A
28 */
29#define AB8500_GPADC_CTRL1_REG 0x00
30#define AB8500_GPADC_CTRL2_REG 0x01
31#define AB8500_GPADC_CTRL3_REG 0x02
32#define AB8500_GPADC_AUTO_TIMER_REG 0x03
33#define AB8500_GPADC_STAT_REG 0x04
34#define AB8500_GPADC_MANDATAL_REG 0x05
35#define AB8500_GPADC_MANDATAH_REG 0x06
36#define AB8500_GPADC_AUTODATAL_REG 0x07
37#define AB8500_GPADC_AUTODATAH_REG 0x08
38#define AB8500_GPADC_MUX_CTRL_REG 0x09
39
40/*
41 * OTP register offsets
42 * Bank : 0x15
43 */
44#define AB8500_GPADC_CAL_1 0x0F
45#define AB8500_GPADC_CAL_2 0x10
46#define AB8500_GPADC_CAL_3 0x11
47#define AB8500_GPADC_CAL_4 0x12
48#define AB8500_GPADC_CAL_5 0x13
49#define AB8500_GPADC_CAL_6 0x14
50#define AB8500_GPADC_CAL_7 0x15
51
52/* gpadc constants */
53#define EN_VINTCORE12 0x04
54#define EN_VTVOUT 0x02
55#define EN_GPADC 0x01
56#define DIS_GPADC 0x00
57#define SW_AVG_16 0x60
58#define ADC_SW_CONV 0x04
59#define EN_ICHAR 0x80
60#define EN_BUF 0x40
61#define DIS_ZERO 0x00
62#define GPADC_BUSY 0x01
63
64/* GPADC constants from AB8500 spec, UM0836 */
65#define ADC_RESOLUTION 1024
66#define ADC_CH_BTEMP_MIN 0
67#define ADC_CH_BTEMP_MAX 1350
68#define ADC_CH_DIETEMP_MIN 0
69#define ADC_CH_DIETEMP_MAX 1350
70#define ADC_CH_CHG_V_MIN 0
71#define ADC_CH_CHG_V_MAX 20030
72#define ADC_CH_ACCDET2_MIN 0
73#define ADC_CH_ACCDET2_MAX 2500
74#define ADC_CH_VBAT_MIN 2300
75#define ADC_CH_VBAT_MAX 4800
76#define ADC_CH_CHG_I_MIN 0
77#define ADC_CH_CHG_I_MAX 1500
78#define ADC_CH_BKBAT_MIN 0
79#define ADC_CH_BKBAT_MAX 3200
80
81/* This is used to not lose precision when dividing to get gain and offset */
82#define CALIB_SCALE 1000
83
84enum cal_channels {
85 ADC_INPUT_VMAIN = 0,
86 ADC_INPUT_BTEMP,
87 ADC_INPUT_VBAT,
88 NBR_CAL_INPUTS,
89};
90
91/**
92 * struct adc_cal_data - Table for storing gain and offset for the calibrated
93 * ADC channels
94 * @gain: Gain of the ADC channel
95 * @offset: Offset of the ADC channel
96 */
97struct adc_cal_data {
98 u64 gain;
99 u64 offset;
100};
101
102/**
103 * struct ab8500_gpadc - AB8500 GPADC device information
104 * @dev: pointer to the struct device
105 * @node: a list of AB8500 GPADCs, hence prepared for
106 reentrance
107 * @ab8500_gpadc_complete: pointer to the struct completion, to indicate
108 * the completion of gpadc conversion
109 * @ab8500_gpadc_lock: structure of type mutex
110 * @regu: pointer to the struct regulator
111 * @irq: interrupt number that is used by gpadc
112 * @cal_data array of ADC calibration data structs
113 */
114struct ab8500_gpadc {
115 struct device *dev;
116 struct list_head node;
117 struct completion ab8500_gpadc_complete;
118 struct mutex ab8500_gpadc_lock;
119 struct regulator *regu;
120 int irq;
121 struct adc_cal_data cal_data[NBR_CAL_INPUTS];
122};
123
124static LIST_HEAD(ab8500_gpadc_list);
125
126/**
127 * ab8500_gpadc_get() - returns a reference to the primary AB8500 GPADC
128 * (i.e. the first GPADC in the instance list)
129 */
130struct ab8500_gpadc *ab8500_gpadc_get(char *name)
131{
132 struct ab8500_gpadc *gpadc;
133
134 list_for_each_entry(gpadc, &ab8500_gpadc_list, node) {
135 if (!strcmp(name, dev_name(gpadc->dev)))
136 return gpadc;
137 }
138
139 return ERR_PTR(-ENOENT);
140}
141EXPORT_SYMBOL(ab8500_gpadc_get);
142
143static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
144 int ad_value)
145{
146 int res;
147
148 switch (input) {
149 case MAIN_CHARGER_V:
150 /* For some reason we don't have calibrated data */
151 if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
152 res = ADC_CH_CHG_V_MIN + (ADC_CH_CHG_V_MAX -
153 ADC_CH_CHG_V_MIN) * ad_value /
154 ADC_RESOLUTION;
155 break;
156 }
157 /* Here we can use the calibrated data */
158 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VMAIN].gain +
159 gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE;
160 break;
161
162 case BAT_CTRL:
163 case BTEMP_BALL:
164 case ACC_DETECT1:
165 case ADC_AUX1:
166 case ADC_AUX2:
167 /* For some reason we don't have calibrated data */
168 if (!gpadc->cal_data[ADC_INPUT_BTEMP].gain) {
169 res = ADC_CH_BTEMP_MIN + (ADC_CH_BTEMP_MAX -
170 ADC_CH_BTEMP_MIN) * ad_value /
171 ADC_RESOLUTION;
172 break;
173 }
174 /* Here we can use the calibrated data */
175 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_BTEMP].gain +
176 gpadc->cal_data[ADC_INPUT_BTEMP].offset) / CALIB_SCALE;
177 break;
178
179 case MAIN_BAT_V:
180 /* For some reason we don't have calibrated data */
181 if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) {
182 res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX -
183 ADC_CH_VBAT_MIN) * ad_value /
184 ADC_RESOLUTION;
185 break;
186 }
187 /* Here we can use the calibrated data */
188 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VBAT].gain +
189 gpadc->cal_data[ADC_INPUT_VBAT].offset) / CALIB_SCALE;
190 break;
191
192 case DIE_TEMP:
193 res = ADC_CH_DIETEMP_MIN +
194 (ADC_CH_DIETEMP_MAX - ADC_CH_DIETEMP_MIN) * ad_value /
195 ADC_RESOLUTION;
196 break;
197
198 case ACC_DETECT2:
199 res = ADC_CH_ACCDET2_MIN +
200 (ADC_CH_ACCDET2_MAX - ADC_CH_ACCDET2_MIN) * ad_value /
201 ADC_RESOLUTION;
202 break;
203
204 case VBUS_V:
205 res = ADC_CH_CHG_V_MIN +
206 (ADC_CH_CHG_V_MAX - ADC_CH_CHG_V_MIN) * ad_value /
207 ADC_RESOLUTION;
208 break;
209
210 case MAIN_CHARGER_C:
211 case USB_CHARGER_C:
212 res = ADC_CH_CHG_I_MIN +
213 (ADC_CH_CHG_I_MAX - ADC_CH_CHG_I_MIN) * ad_value /
214 ADC_RESOLUTION;
215 break;
216
217 case BK_BAT_V:
218 res = ADC_CH_BKBAT_MIN +
219 (ADC_CH_BKBAT_MAX - ADC_CH_BKBAT_MIN) * ad_value /
220 ADC_RESOLUTION;
221 break;
222
223 default:
224 dev_err(gpadc->dev,
225 "unknown channel, not possible to convert\n");
226 res = -EINVAL;
227 break;
228
229 }
230 return res;
231}
232
233/**
234 * ab8500_gpadc_convert() - gpadc conversion
235 * @input: analog input to be converted to digital data
236 *
237 * This function converts the selected analog i/p to digital
238 * data.
239 */
240int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
241{
242 int ret;
243 u16 data = 0;
244 int looplimit = 0;
245 u8 val, low_data, high_data;
246
247 if (!gpadc)
248 return -ENODEV;
249
250 mutex_lock(&gpadc->ab8500_gpadc_lock);
251 /* Enable VTVout LDO this is required for GPADC */
252 regulator_enable(gpadc->regu);
253
254 /* Check if ADC is not busy, lock and proceed */
255 do {
256 ret = abx500_get_register_interruptible(gpadc->dev,
257 AB8500_GPADC, AB8500_GPADC_STAT_REG, &val);
258 if (ret < 0)
259 goto out;
260 if (!(val & GPADC_BUSY))
261 break;
262 msleep(10);
263 } while (++looplimit < 10);
264 if (looplimit >= 10 && (val & GPADC_BUSY)) {
265 dev_err(gpadc->dev, "gpadc_conversion: GPADC busy");
266 ret = -EINVAL;
267 goto out;
268 }
269
270 /* Enable GPADC */
271 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
272 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC);
273 if (ret < 0) {
274 dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n");
275 goto out;
276 }
277 /* Select the input source and set average samples to 16 */
278 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
279 AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
280 if (ret < 0) {
281 dev_err(gpadc->dev,
282 "gpadc_conversion: set avg samples failed\n");
283 goto out;
284 }
285 /*
286 * Enable ADC, buffering, select rising edge and enable ADC path
287 * charging current sense if it needed
288 */
289 switch (input) {
290 case MAIN_CHARGER_C:
291 case USB_CHARGER_C:
292 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
293 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
294 EN_BUF | EN_ICHAR,
295 EN_BUF | EN_ICHAR);
296 break;
297 default:
298 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
299 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
300 break;
301 }
302 if (ret < 0) {
303 dev_err(gpadc->dev,
304 "gpadc_conversion: select falling edge failed\n");
305 goto out;
306 }
307 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
308 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV);
309 if (ret < 0) {
310 dev_err(gpadc->dev,
311 "gpadc_conversion: start s/w conversion failed\n");
312 goto out;
313 }
314 /* wait for completion of conversion */
315 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 2*HZ)) {
316 dev_err(gpadc->dev,
317 "timeout: didnt recieve GPADC conversion interrupt\n");
318 ret = -EINVAL;
319 goto out;
320 }
321
322 /* Read the converted RAW data */
323 ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC,
324 AB8500_GPADC_MANDATAL_REG, &low_data);
325 if (ret < 0) {
326 dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n");
327 goto out;
328 }
329
330 ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC,
331 AB8500_GPADC_MANDATAH_REG, &high_data);
332 if (ret < 0) {
333 dev_err(gpadc->dev,
334 "gpadc_conversion: read high data failed\n");
335 goto out;
336 }
337
338 data = (high_data << 8) | low_data;
339 /* Disable GPADC */
340 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
341 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
342 if (ret < 0) {
343 dev_err(gpadc->dev, "gpadc_conversion: disable gpadc failed\n");
344 goto out;
345 }
346 /* Disable VTVout LDO this is required for GPADC */
347 regulator_disable(gpadc->regu);
348 mutex_unlock(&gpadc->ab8500_gpadc_lock);
349 ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data);
350 return ret;
351
352out:
353 /*
354 * It has shown to be needed to turn off the GPADC if an error occurs,
355 * otherwise we might have problem when waiting for the busy bit in the
356 * GPADC status register to go low. In V1.1 there wait_for_completion
357 * seems to timeout when waiting for an interrupt.. Not seen in V2.0
358 */
359 (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
360 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
361 regulator_disable(gpadc->regu);
362 mutex_unlock(&gpadc->ab8500_gpadc_lock);
363 dev_err(gpadc->dev,
364 "gpadc_conversion: Failed to AD convert channel %d\n", input);
365 return ret;
366}
367EXPORT_SYMBOL(ab8500_gpadc_convert);
368
369/**
370 * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion
371 * @irq: irq number
372 * @data: pointer to the data passed during request irq
373 *
374 * This is a interrupt service routine for s/w gpadc conversion completion.
375 * Notifies the gpadc completion is completed and the converted raw value
376 * can be read from the registers.
377 * Returns IRQ status(IRQ_HANDLED)
378 */
379static irqreturn_t ab8500_bm_gpswadcconvend_handler(int irq, void *_gpadc)
380{
381 struct ab8500_gpadc *gpadc = _gpadc;
382
383 complete(&gpadc->ab8500_gpadc_complete);
384
385 return IRQ_HANDLED;
386}
387
388static int otp_cal_regs[] = {
389 AB8500_GPADC_CAL_1,
390 AB8500_GPADC_CAL_2,
391 AB8500_GPADC_CAL_3,
392 AB8500_GPADC_CAL_4,
393 AB8500_GPADC_CAL_5,
394 AB8500_GPADC_CAL_6,
395 AB8500_GPADC_CAL_7,
396};
397
398static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
399{
400 int i;
401 int ret[ARRAY_SIZE(otp_cal_regs)];
402 u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)];
403
404 int vmain_high, vmain_low;
405 int btemp_high, btemp_low;
406 int vbat_high, vbat_low;
407
408 /* First we read all OTP registers and store the error code */
409 for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) {
410 ret[i] = abx500_get_register_interruptible(gpadc->dev,
411 AB8500_OTP_EMUL, otp_cal_regs[i], &gpadc_cal[i]);
412 if (ret[i] < 0)
413 dev_err(gpadc->dev, "%s: read otp reg 0x%02x failed\n",
414 __func__, otp_cal_regs[i]);
415 }
416
417 /*
418 * The ADC calibration data is stored in OTP registers.
419 * The layout of the calibration data is outlined below and a more
420 * detailed description can be found in UM0836
421 *
422 * vm_h/l = vmain_high/low
423 * bt_h/l = btemp_high/low
424 * vb_h/l = vbat_high/low
425 *
426 * Data bits:
427 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
428 * |.......|.......|.......|.......|.......|.......|.......|.......
429 * | | vm_h9 | vm_h8
430 * |.......|.......|.......|.......|.......|.......|.......|.......
431 * | | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2
432 * |.......|.......|.......|.......|.......|.......|.......|.......
433 * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9
434 * |.......|.......|.......|.......|.......|.......|.......|.......
435 * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1
436 * |.......|.......|.......|.......|.......|.......|.......|.......
437 * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8
438 * |.......|.......|.......|.......|.......|.......|.......|.......
439 * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0
440 * |.......|.......|.......|.......|.......|.......|.......|.......
441 * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
442 * |.......|.......|.......|.......|.......|.......|.......|.......
443 *
444 *
445 * Ideal output ADC codes corresponding to injected input voltages
446 * during manufacturing is:
447 *
448 * vmain_high: Vin = 19500mV / ADC ideal code = 997
449 * vmain_low: Vin = 315mV / ADC ideal code = 16
450 * btemp_high: Vin = 1300mV / ADC ideal code = 985
451 * btemp_low: Vin = 21mV / ADC ideal code = 16
452 * vbat_high: Vin = 4700mV / ADC ideal code = 982
453 * vbat_low: Vin = 2380mV / ADC ideal code = 33
454 */
455
456 /* Calculate gain and offset for VMAIN if all reads succeeded */
457 if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) {
458 vmain_high = (((gpadc_cal[0] & 0x03) << 8) |
459 ((gpadc_cal[1] & 0x3F) << 2) |
460 ((gpadc_cal[2] & 0xC0) >> 6));
461
462 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1);
463
464 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE *
465 (19500 - 315) / (vmain_high - vmain_low);
466
467 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * 19500 -
468 (CALIB_SCALE * (19500 - 315) /
469 (vmain_high - vmain_low)) * vmain_high;
470 } else {
471 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0;
472 }
473
474 /* Calculate gain and offset for BTEMP if all reads succeeded */
475 if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) {
476 btemp_high = (((gpadc_cal[2] & 0x01) << 9) |
477 (gpadc_cal[3] << 1) |
478 ((gpadc_cal[4] & 0x80) >> 7));
479
480 btemp_low = ((gpadc_cal[4] & 0x7C) >> 2);
481
482 gpadc->cal_data[ADC_INPUT_BTEMP].gain =
483 CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low);
484
485 gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 -
486 (CALIB_SCALE * (1300 - 21) /
487 (btemp_high - btemp_low)) * btemp_high;
488 } else {
489 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0;
490 }
491
492 /* Calculate gain and offset for VBAT if all reads succeeded */
493 if (!(ret[4] < 0 || ret[5] < 0 || ret[6] < 0)) {
494 vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]);
495 vbat_low = ((gpadc_cal[6] & 0xFC) >> 2);
496
497 gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE *
498 (4700 - 2380) / (vbat_high - vbat_low);
499
500 gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 -
501 (CALIB_SCALE * (4700 - 2380) /
502 (vbat_high - vbat_low)) * vbat_high;
503 } else {
504 gpadc->cal_data[ADC_INPUT_VBAT].gain = 0;
505 }
506
507 dev_dbg(gpadc->dev, "VMAIN gain %llu offset %llu\n",
508 gpadc->cal_data[ADC_INPUT_VMAIN].gain,
509 gpadc->cal_data[ADC_INPUT_VMAIN].offset);
510
511 dev_dbg(gpadc->dev, "BTEMP gain %llu offset %llu\n",
512 gpadc->cal_data[ADC_INPUT_BTEMP].gain,
513 gpadc->cal_data[ADC_INPUT_BTEMP].offset);
514
515 dev_dbg(gpadc->dev, "VBAT gain %llu offset %llu\n",
516 gpadc->cal_data[ADC_INPUT_VBAT].gain,
517 gpadc->cal_data[ADC_INPUT_VBAT].offset);
518}
519
520static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
521{
522 int ret = 0;
523 struct ab8500_gpadc *gpadc;
524
525 gpadc = kzalloc(sizeof(struct ab8500_gpadc), GFP_KERNEL);
526 if (!gpadc) {
527 dev_err(&pdev->dev, "Error: No memory\n");
528 return -ENOMEM;
529 }
530
531 gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END");
532 if (gpadc->irq < 0) {
533 dev_err(gpadc->dev, "failed to get platform irq-%d\n",
534 gpadc->irq);
535 ret = gpadc->irq;
536 goto fail;
537 }
538
539 gpadc->dev = &pdev->dev;
540 mutex_init(&gpadc->ab8500_gpadc_lock);
541
542 /* Initialize completion used to notify completion of conversion */
543 init_completion(&gpadc->ab8500_gpadc_complete);
544
545 /* Register interrupt - SwAdcComplete */
546 ret = request_threaded_irq(gpadc->irq, NULL,
547 ab8500_bm_gpswadcconvend_handler,
548 IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc", gpadc);
549 if (ret < 0) {
550 dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n",
551 gpadc->irq);
552 goto fail;
553 }
554
555 /* VTVout LDO used to power up ab8500-GPADC */
556 gpadc->regu = regulator_get(&pdev->dev, "vddadc");
557 if (IS_ERR(gpadc->regu)) {
558 ret = PTR_ERR(gpadc->regu);
559 dev_err(gpadc->dev, "failed to get vtvout LDO\n");
560 goto fail_irq;
561 }
562 ab8500_gpadc_read_calibration_data(gpadc);
563 list_add_tail(&gpadc->node, &ab8500_gpadc_list);
564 dev_dbg(gpadc->dev, "probe success\n");
565 return 0;
566fail_irq:
567 free_irq(gpadc->irq, gpadc);
568fail:
569 kfree(gpadc);
570 gpadc = NULL;
571 return ret;
572}
573
574static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
575{
576 struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev);
577
578 /* remove this gpadc entry from the list */
579 list_del(&gpadc->node);
580 /* remove interrupt - completion of Sw ADC conversion */
581 free_irq(gpadc->irq, gpadc);
582 /* disable VTVout LDO that is being used by GPADC */
583 regulator_put(gpadc->regu);
584 kfree(gpadc);
585 gpadc = NULL;
586 return 0;
587}
588
589static struct platform_driver ab8500_gpadc_driver = {
590 .probe = ab8500_gpadc_probe,
591 .remove = __devexit_p(ab8500_gpadc_remove),
592 .driver = {
593 .name = "ab8500-gpadc",
594 .owner = THIS_MODULE,
595 },
596};
597
598static int __init ab8500_gpadc_init(void)
599{
600 return platform_driver_register(&ab8500_gpadc_driver);
601}
602
603static void __exit ab8500_gpadc_exit(void)
604{
605 platform_driver_unregister(&ab8500_gpadc_driver);
606}
607
608subsys_initcall_sync(ab8500_gpadc_init);
609module_exit(ab8500_gpadc_exit);
610
611MODULE_LICENSE("GPL v2");
612MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson");
613MODULE_ALIAS("platform:ab8500_gpadc");
614MODULE_DESCRIPTION("AB8500 GPADC driver");
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
new file mode 100644
index 000000000000..392185965b39
--- /dev/null
+++ b/drivers/mfd/ab8500-sysctrl.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2010
3 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST Ericsson.
4 * License terms: GNU General Public License (GPL) version 2
5 */
6
7#include <linux/err.h>
8#include <linux/platform_device.h>
9#include <linux/mfd/ab8500.h>
10#include <linux/mfd/abx500.h>
11#include <linux/mfd/ab8500/sysctrl.h>
12
13static struct device *sysctrl_dev;
14
15static inline bool valid_bank(u8 bank)
16{
17 return ((bank == AB8500_SYS_CTRL1_BLOCK) ||
18 (bank == AB8500_SYS_CTRL2_BLOCK));
19}
20
21int ab8500_sysctrl_read(u16 reg, u8 *value)
22{
23 u8 bank;
24
25 if (sysctrl_dev == NULL)
26 return -EAGAIN;
27
28 bank = (reg >> 8);
29 if (!valid_bank(bank))
30 return -EINVAL;
31
32 return abx500_get_register_interruptible(sysctrl_dev, bank,
33 (u8)(reg & 0xFF), value);
34}
35
36int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
37{
38 u8 bank;
39
40 if (sysctrl_dev == NULL)
41 return -EAGAIN;
42
43 bank = (reg >> 8);
44 if (!valid_bank(bank))
45 return -EINVAL;
46
47 return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank,
48 (u8)(reg & 0xFF), mask, value);
49}
50
51static int __devinit ab8500_sysctrl_probe(struct platform_device *pdev)
52{
53 sysctrl_dev = &pdev->dev;
54 return 0;
55}
56
57static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev)
58{
59 sysctrl_dev = NULL;
60 return 0;
61}
62
63static struct platform_driver ab8500_sysctrl_driver = {
64 .driver = {
65 .name = "ab8500-sysctrl",
66 .owner = THIS_MODULE,
67 },
68 .probe = ab8500_sysctrl_probe,
69 .remove = __devexit_p(ab8500_sysctrl_remove),
70};
71
72static int __init ab8500_sysctrl_init(void)
73{
74 return platform_driver_register(&ab8500_sysctrl_driver);
75}
76subsys_initcall(ab8500_sysctrl_init);
77
78MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com");
79MODULE_DESCRIPTION("AB8500 system control driver");
80MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index 3122139b4300..f1d88483112c 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -321,27 +321,27 @@ static int __devexit adp5520_remove(struct i2c_client *client)
321} 321}
322 322
323#ifdef CONFIG_PM 323#ifdef CONFIG_PM
324static int adp5520_suspend(struct i2c_client *client, 324static int adp5520_suspend(struct device *dev)
325 pm_message_t state)
326{ 325{
326 struct i2c_client *client = to_i2c_client(dev);
327 struct adp5520_chip *chip = dev_get_drvdata(&client->dev); 327 struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
328 328
329 adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); 329 adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
330 return 0; 330 return 0;
331} 331}
332 332
333static int adp5520_resume(struct i2c_client *client) 333static int adp5520_resume(struct device *dev)
334{ 334{
335 struct i2c_client *client = to_i2c_client(dev);
335 struct adp5520_chip *chip = dev_get_drvdata(&client->dev); 336 struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
336 337
337 adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); 338 adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
338 return 0; 339 return 0;
339} 340}
340#else
341#define adp5520_suspend NULL
342#define adp5520_resume NULL
343#endif 341#endif
344 342
343static SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume);
344
345static const struct i2c_device_id adp5520_id[] = { 345static const struct i2c_device_id adp5520_id[] = {
346 { "pmic-adp5520", ID_ADP5520 }, 346 { "pmic-adp5520", ID_ADP5520 },
347 { "pmic-adp5501", ID_ADP5501 }, 347 { "pmic-adp5501", ID_ADP5501 },
@@ -353,11 +353,10 @@ static struct i2c_driver adp5520_driver = {
353 .driver = { 353 .driver = {
354 .name = "adp5520", 354 .name = "adp5520",
355 .owner = THIS_MODULE, 355 .owner = THIS_MODULE,
356 .pm = &adp5520_pm,
356 }, 357 },
357 .probe = adp5520_probe, 358 .probe = adp5520_probe,
358 .remove = __devexit_p(adp5520_remove), 359 .remove = __devexit_p(adp5520_remove),
359 .suspend = adp5520_suspend,
360 .resume = adp5520_resume,
361 .id_table = adp5520_id, 360 .id_table = adp5520_id,
362}; 361};
363 362
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index c45e6305b26f..0241f08fc00d 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -682,7 +682,7 @@ static struct mfd_cell asic3_cell_ds1wm = {
682 .name = "ds1wm", 682 .name = "ds1wm",
683 .enable = ds1wm_enable, 683 .enable = ds1wm_enable,
684 .disable = ds1wm_disable, 684 .disable = ds1wm_disable,
685 .driver_data = &ds1wm_pdata, 685 .mfd_data = &ds1wm_pdata,
686 .num_resources = ARRAY_SIZE(ds1wm_resources), 686 .num_resources = ARRAY_SIZE(ds1wm_resources),
687 .resources = ds1wm_resources, 687 .resources = ds1wm_resources,
688}; 688};
@@ -783,7 +783,7 @@ static struct mfd_cell asic3_cell_mmc = {
783 .name = "tmio-mmc", 783 .name = "tmio-mmc",
784 .enable = asic3_mmc_enable, 784 .enable = asic3_mmc_enable,
785 .disable = asic3_mmc_disable, 785 .disable = asic3_mmc_disable,
786 .driver_data = &asic3_mmc_data, 786 .mfd_data = &asic3_mmc_data,
787 .num_resources = ARRAY_SIZE(asic3_mmc_resources), 787 .num_resources = ARRAY_SIZE(asic3_mmc_resources),
788 .resources = asic3_mmc_resources, 788 .resources = asic3_mmc_resources,
789}; 789};
@@ -810,9 +810,6 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
810 ds1wm_resources[0].start >>= asic->bus_shift; 810 ds1wm_resources[0].start >>= asic->bus_shift;
811 ds1wm_resources[0].end >>= asic->bus_shift; 811 ds1wm_resources[0].end >>= asic->bus_shift;
812 812
813 asic3_cell_ds1wm.platform_data = &asic3_cell_ds1wm;
814 asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm);
815
816 /* MMC */ 813 /* MMC */
817 asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + 814 asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) +
818 mem_sdio->start, 0x400 >> asic->bus_shift); 815 mem_sdio->start, 0x400 >> asic->bus_shift);
@@ -824,9 +821,6 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
824 asic3_mmc_resources[0].start >>= asic->bus_shift; 821 asic3_mmc_resources[0].start >>= asic->bus_shift;
825 asic3_mmc_resources[0].end >>= asic->bus_shift; 822 asic3_mmc_resources[0].end >>= asic->bus_shift;
826 823
827 asic3_cell_mmc.platform_data = &asic3_cell_mmc;
828 asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc);
829
830 ret = mfd_add_devices(&pdev->dev, pdev->id, 824 ret = mfd_add_devices(&pdev->dev, pdev->id,
831 &asic3_cell_ds1wm, 1, mem, asic->irq_base); 825 &asic3_cell_ds1wm, 1, mem, asic->irq_base);
832 if (ret < 0) 826 if (ret < 0)
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index 59ca6f151e78..886a06871065 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -39,6 +39,37 @@ enum cs5535_mfd_bars {
39 NR_BARS, 39 NR_BARS,
40}; 40};
41 41
42static int cs5535_mfd_res_enable(struct platform_device *pdev)
43{
44 struct resource *res;
45
46 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
47 if (!res) {
48 dev_err(&pdev->dev, "can't fetch device resource info\n");
49 return -EIO;
50 }
51
52 if (!request_region(res->start, resource_size(res), DRV_NAME)) {
53 dev_err(&pdev->dev, "can't request region\n");
54 return -EIO;
55 }
56
57 return 0;
58}
59
60static int cs5535_mfd_res_disable(struct platform_device *pdev)
61{
62 struct resource *res;
63 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
64 if (!res) {
65 dev_err(&pdev->dev, "can't fetch device resource info\n");
66 return -EIO;
67 }
68
69 release_region(res->start, resource_size(res));
70 return 0;
71}
72
42static __devinitdata struct resource cs5535_mfd_resources[NR_BARS]; 73static __devinitdata struct resource cs5535_mfd_resources[NR_BARS];
43 74
44static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { 75static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
@@ -65,12 +96,18 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
65 .name = "cs5535-pms", 96 .name = "cs5535-pms",
66 .num_resources = 1, 97 .num_resources = 1,
67 .resources = &cs5535_mfd_resources[PMS_BAR], 98 .resources = &cs5535_mfd_resources[PMS_BAR],
99
100 .enable = cs5535_mfd_res_enable,
101 .disable = cs5535_mfd_res_disable,
68 }, 102 },
69 { 103 {
70 .id = ACPI_BAR, 104 .id = ACPI_BAR,
71 .name = "cs5535-acpi", 105 .name = "cs5535-acpi",
72 .num_resources = 1, 106 .num_resources = 1,
73 .resources = &cs5535_mfd_resources[ACPI_BAR], 107 .resources = &cs5535_mfd_resources[ACPI_BAR],
108
109 .enable = cs5535_mfd_res_enable,
110 .disable = cs5535_mfd_res_disable,
74 }, 111 },
75}; 112};
76 113
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
index fdd8a1b8bc67..414783b04849 100644
--- a/drivers/mfd/davinci_voicecodec.c
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -119,12 +119,12 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
119 /* Voice codec interface client */ 119 /* Voice codec interface client */
120 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; 120 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL];
121 cell->name = "davinci-vcif"; 121 cell->name = "davinci-vcif";
122 cell->driver_data = davinci_vc; 122 cell->mfd_data = davinci_vc;
123 123
124 /* Voice codec CQ93VC client */ 124 /* Voice codec CQ93VC client */
125 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; 125 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL];
126 cell->name = "cq93vc-codec"; 126 cell->name = "cq93vc-codec";
127 cell->driver_data = davinci_vc; 127 cell->mfd_data = davinci_vc;
128 128
129 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, 129 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,
130 DAVINCI_VC_CELLS, NULL, 0); 130 DAVINCI_VC_CELLS, NULL, 0);
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 7bc752272dc1..fb9770b39a32 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -117,7 +117,7 @@ static struct mfd_cell ds1wm_cell __initdata = {
117 .name = "ds1wm", 117 .name = "ds1wm",
118 .enable = ds1wm_enable, 118 .enable = ds1wm_enable,
119 .disable = ds1wm_disable, 119 .disable = ds1wm_disable,
120 .driver_data = &ds1wm_pdata, 120 .mfd_data = &ds1wm_pdata,
121 .num_resources = 2, 121 .num_resources = 2,
122 .resources = ds1wm_resources, 122 .resources = ds1wm_resources,
123}; 123};
@@ -165,8 +165,6 @@ static int __init pasic3_probe(struct platform_device *pdev)
165 ds1wm_pdata.clock_rate = pdata->clock_rate; 165 ds1wm_pdata.clock_rate = pdata->clock_rate;
166 /* the first 5 PASIC3 registers control the DS1WM */ 166 /* the first 5 PASIC3 registers control the DS1WM */
167 ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; 167 ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
168 ds1wm_cell.platform_data = &ds1wm_cell;
169 ds1wm_cell.data_size = sizeof(ds1wm_cell);
170 ret = mfd_add_devices(&pdev->dev, pdev->id, 168 ret = mfd_add_devices(&pdev->dev, pdev->id,
171 &ds1wm_cell, 1, r, irq); 169 &ds1wm_cell, 1, r, irq);
172 if (ret < 0) 170 if (ret < 0)
@@ -174,9 +172,6 @@ static int __init pasic3_probe(struct platform_device *pdev)
174 } 172 }
175 173
176 if (pdata && pdata->led_pdata) { 174 if (pdata && pdata->led_pdata) {
177 led_cell.driver_data = pdata->led_pdata;
178 led_cell.platform_data = &led_cell;
179 led_cell.data_size = sizeof(ds1wm_cell);
180 ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); 175 ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
181 if (ret < 0) 176 if (ret < 0)
182 dev_warn(dev, "failed to register LED device\n"); 177 dev_warn(dev, "failed to register LED device\n");
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c
index 36a166bcdb08..fc4191137e90 100644
--- a/drivers/mfd/janz-cmodio.c
+++ b/drivers/mfd/janz-cmodio.c
@@ -86,8 +86,7 @@ static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv,
86 86
87 /* Add platform data */ 87 /* Add platform data */
88 pdata->modno = modno; 88 pdata->modno = modno;
89 cell->platform_data = pdata; 89 cell->mfd_data = pdata;
90 cell->data_size = sizeof(*pdata);
91 90
92 /* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */ 91 /* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */
93 res->flags = IORESOURCE_MEM; 92 res->flags = IORESOURCE_MEM;
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
index 0cc59795f600..aa518b9beaf5 100644
--- a/drivers/mfd/jz4740-adc.c
+++ b/drivers/mfd/jz4740-adc.c
@@ -232,8 +232,6 @@ const struct mfd_cell jz4740_adc_cells[] = {
232 .name = "jz4740-hwmon", 232 .name = "jz4740-hwmon",
233 .num_resources = ARRAY_SIZE(jz4740_hwmon_resources), 233 .num_resources = ARRAY_SIZE(jz4740_hwmon_resources),
234 .resources = jz4740_hwmon_resources, 234 .resources = jz4740_hwmon_resources,
235 .platform_data = (void *)&jz4740_adc_cells[0],
236 .data_size = sizeof(struct mfd_cell),
237 235
238 .enable = jz4740_adc_cell_enable, 236 .enable = jz4740_adc_cell_enable,
239 .disable = jz4740_adc_cell_disable, 237 .disable = jz4740_adc_cell_disable,
@@ -243,8 +241,6 @@ const struct mfd_cell jz4740_adc_cells[] = {
243 .name = "jz4740-battery", 241 .name = "jz4740-battery",
244 .num_resources = ARRAY_SIZE(jz4740_battery_resources), 242 .num_resources = ARRAY_SIZE(jz4740_battery_resources),
245 .resources = jz4740_battery_resources, 243 .resources = jz4740_battery_resources,
246 .platform_data = (void *)&jz4740_adc_cells[1],
247 .data_size = sizeof(struct mfd_cell),
248 244
249 .enable = jz4740_adc_cell_enable, 245 .enable = jz4740_adc_cell_enable,
250 .disable = jz4740_adc_cell_disable, 246 .disable = jz4740_adc_cell_disable,
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
index 51b2f6065a0b..ea3f52c07ef7 100644
--- a/drivers/mfd/lpc_sch.c
+++ b/drivers/mfd/lpc_sch.c
@@ -61,6 +61,7 @@ static struct mfd_cell lpc_sch_cells[] = {
61 61
62static struct pci_device_id lpc_sch_ids[] = { 62static struct pci_device_id lpc_sch_ids[] = {
63 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, 63 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
64 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) },
64 { 0, } 65 { 0, }
65}; 66};
66MODULE_DEVICE_TABLE(pci, lpc_sch_ids); 67MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
@@ -70,6 +71,7 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
70{ 71{
71 unsigned int base_addr_cfg; 72 unsigned int base_addr_cfg;
72 unsigned short base_addr; 73 unsigned short base_addr;
74 int i;
73 75
74 pci_read_config_dword(dev, SMBASE, &base_addr_cfg); 76 pci_read_config_dword(dev, SMBASE, &base_addr_cfg);
75 if (!(base_addr_cfg & (1 << 31))) { 77 if (!(base_addr_cfg & (1 << 31))) {
@@ -99,7 +101,10 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
99 gpio_sch_resource.start = base_addr; 101 gpio_sch_resource.start = base_addr;
100 gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; 102 gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
101 103
102 return mfd_add_devices(&dev->dev, -1, 104 for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++)
105 lpc_sch_cells[i].id = id->device;
106
107 return mfd_add_devices(&dev->dev, 0,
103 lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); 108 lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0);
104} 109}
105 110
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
new file mode 100644
index 000000000000..5d1fca0277ef
--- /dev/null
+++ b/drivers/mfd/max8997.c
@@ -0,0 +1,427 @@
1/*
2 * max8997.c - mfd core driver for the Maxim 8966 and 8997
3 *
4 * Copyright (C) 2011 Samsung Electronics
5 * MyungJoo Ham <myungjoo.ham@smasung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This driver is based on max8998.c
22 */
23
24#include <linux/slab.h>
25#include <linux/i2c.h>
26#include <linux/pm_runtime.h>
27#include <linux/mutex.h>
28#include <linux/mfd/core.h>
29#include <linux/mfd/max8997.h>
30#include <linux/mfd/max8997-private.h>
31
32#define I2C_ADDR_PMIC (0xCC >> 1)
33#define I2C_ADDR_MUIC (0x4A >> 1)
34#define I2C_ADDR_BATTERY (0x6C >> 1)
35#define I2C_ADDR_RTC (0x0C >> 1)
36#define I2C_ADDR_HAPTIC (0x90 >> 1)
37
38static struct mfd_cell max8997_devs[] = {
39 { .name = "max8997-pmic", },
40 { .name = "max8997-rtc", },
41 { .name = "max8997-battery", },
42 { .name = "max8997-haptic", },
43 { .name = "max8997-muic", },
44 { .name = "max8997-flash", },
45};
46
47int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
48{
49 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
50 int ret;
51
52 mutex_lock(&max8997->iolock);
53 ret = i2c_smbus_read_byte_data(i2c, reg);
54 mutex_unlock(&max8997->iolock);
55 if (ret < 0)
56 return ret;
57
58 ret &= 0xff;
59 *dest = ret;
60 return 0;
61}
62EXPORT_SYMBOL_GPL(max8997_read_reg);
63
64int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, u8 *buf)
65{
66 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
67 int ret;
68
69 mutex_lock(&max8997->iolock);
70 ret = i2c_smbus_read_i2c_block_data(i2c, reg, count, buf);
71 mutex_unlock(&max8997->iolock);
72 if (ret < 0)
73 return ret;
74
75 return 0;
76}
77EXPORT_SYMBOL_GPL(max8997_bulk_read);
78
79int max8997_write_reg(struct i2c_client *i2c, u8 reg, u8 value)
80{
81 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
82 int ret;
83
84 mutex_lock(&max8997->iolock);
85 ret = i2c_smbus_write_byte_data(i2c, reg, value);
86 mutex_unlock(&max8997->iolock);
87 return ret;
88}
89EXPORT_SYMBOL_GPL(max8997_write_reg);
90
91int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count, u8 *buf)
92{
93 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
94 int ret;
95
96 mutex_lock(&max8997->iolock);
97 ret = i2c_smbus_write_i2c_block_data(i2c, reg, count, buf);
98 mutex_unlock(&max8997->iolock);
99 if (ret < 0)
100 return ret;
101
102 return 0;
103}
104EXPORT_SYMBOL_GPL(max8997_bulk_write);
105
106int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
107{
108 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
109 int ret;
110
111 mutex_lock(&max8997->iolock);
112 ret = i2c_smbus_read_byte_data(i2c, reg);
113 if (ret >= 0) {
114 u8 old_val = ret & 0xff;
115 u8 new_val = (val & mask) | (old_val & (~mask));
116 ret = i2c_smbus_write_byte_data(i2c, reg, new_val);
117 }
118 mutex_unlock(&max8997->iolock);
119 return ret;
120}
121EXPORT_SYMBOL_GPL(max8997_update_reg);
122
123static int max8997_i2c_probe(struct i2c_client *i2c,
124 const struct i2c_device_id *id)
125{
126 struct max8997_dev *max8997;
127 struct max8997_platform_data *pdata = i2c->dev.platform_data;
128 int ret = 0;
129
130 max8997 = kzalloc(sizeof(struct max8997_dev), GFP_KERNEL);
131 if (max8997 == NULL)
132 return -ENOMEM;
133
134 i2c_set_clientdata(i2c, max8997);
135 max8997->dev = &i2c->dev;
136 max8997->i2c = i2c;
137 max8997->type = id->driver_data;
138
139 if (!pdata)
140 goto err;
141
142 max8997->wakeup = pdata->wakeup;
143
144 mutex_init(&max8997->iolock);
145
146 max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
147 i2c_set_clientdata(max8997->rtc, max8997);
148 max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
149 i2c_set_clientdata(max8997->haptic, max8997);
150 max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
151 i2c_set_clientdata(max8997->muic, max8997);
152
153 pm_runtime_set_active(max8997->dev);
154
155 mfd_add_devices(max8997->dev, -1, max8997_devs,
156 ARRAY_SIZE(max8997_devs),
157 NULL, 0);
158
159 /*
160 * TODO: enable others (flash, muic, rtc, battery, ...) and
161 * check the return value
162 */
163
164 if (ret < 0)
165 goto err_mfd;
166
167 return ret;
168
169err_mfd:
170 mfd_remove_devices(max8997->dev);
171 i2c_unregister_device(max8997->muic);
172 i2c_unregister_device(max8997->haptic);
173 i2c_unregister_device(max8997->rtc);
174err:
175 kfree(max8997);
176 return ret;
177}
178
179static int max8997_i2c_remove(struct i2c_client *i2c)
180{
181 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
182
183 mfd_remove_devices(max8997->dev);
184 i2c_unregister_device(max8997->muic);
185 i2c_unregister_device(max8997->haptic);
186 i2c_unregister_device(max8997->rtc);
187 kfree(max8997);
188
189 return 0;
190}
191
192static const struct i2c_device_id max8997_i2c_id[] = {
193 { "max8997", TYPE_MAX8997 },
194 { "max8966", TYPE_MAX8966 },
195 { }
196};
197MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
198
199u8 max8997_dumpaddr_pmic[] = {
200 MAX8997_REG_INT1MSK,
201 MAX8997_REG_INT2MSK,
202 MAX8997_REG_INT3MSK,
203 MAX8997_REG_INT4MSK,
204 MAX8997_REG_MAINCON1,
205 MAX8997_REG_MAINCON2,
206 MAX8997_REG_BUCKRAMP,
207 MAX8997_REG_BUCK1CTRL,
208 MAX8997_REG_BUCK1DVS1,
209 MAX8997_REG_BUCK1DVS2,
210 MAX8997_REG_BUCK1DVS3,
211 MAX8997_REG_BUCK1DVS4,
212 MAX8997_REG_BUCK1DVS5,
213 MAX8997_REG_BUCK1DVS6,
214 MAX8997_REG_BUCK1DVS7,
215 MAX8997_REG_BUCK1DVS8,
216 MAX8997_REG_BUCK2CTRL,
217 MAX8997_REG_BUCK2DVS1,
218 MAX8997_REG_BUCK2DVS2,
219 MAX8997_REG_BUCK2DVS3,
220 MAX8997_REG_BUCK2DVS4,
221 MAX8997_REG_BUCK2DVS5,
222 MAX8997_REG_BUCK2DVS6,
223 MAX8997_REG_BUCK2DVS7,
224 MAX8997_REG_BUCK2DVS8,
225 MAX8997_REG_BUCK3CTRL,
226 MAX8997_REG_BUCK3DVS,
227 MAX8997_REG_BUCK4CTRL,
228 MAX8997_REG_BUCK4DVS,
229 MAX8997_REG_BUCK5CTRL,
230 MAX8997_REG_BUCK5DVS1,
231 MAX8997_REG_BUCK5DVS2,
232 MAX8997_REG_BUCK5DVS3,
233 MAX8997_REG_BUCK5DVS4,
234 MAX8997_REG_BUCK5DVS5,
235 MAX8997_REG_BUCK5DVS6,
236 MAX8997_REG_BUCK5DVS7,
237 MAX8997_REG_BUCK5DVS8,
238 MAX8997_REG_BUCK6CTRL,
239 MAX8997_REG_BUCK6BPSKIPCTRL,
240 MAX8997_REG_BUCK7CTRL,
241 MAX8997_REG_BUCK7DVS,
242 MAX8997_REG_LDO1CTRL,
243 MAX8997_REG_LDO2CTRL,
244 MAX8997_REG_LDO3CTRL,
245 MAX8997_REG_LDO4CTRL,
246 MAX8997_REG_LDO5CTRL,
247 MAX8997_REG_LDO6CTRL,
248 MAX8997_REG_LDO7CTRL,
249 MAX8997_REG_LDO8CTRL,
250 MAX8997_REG_LDO9CTRL,
251 MAX8997_REG_LDO10CTRL,
252 MAX8997_REG_LDO11CTRL,
253 MAX8997_REG_LDO12CTRL,
254 MAX8997_REG_LDO13CTRL,
255 MAX8997_REG_LDO14CTRL,
256 MAX8997_REG_LDO15CTRL,
257 MAX8997_REG_LDO16CTRL,
258 MAX8997_REG_LDO17CTRL,
259 MAX8997_REG_LDO18CTRL,
260 MAX8997_REG_LDO21CTRL,
261 MAX8997_REG_MBCCTRL1,
262 MAX8997_REG_MBCCTRL2,
263 MAX8997_REG_MBCCTRL3,
264 MAX8997_REG_MBCCTRL4,
265 MAX8997_REG_MBCCTRL5,
266 MAX8997_REG_MBCCTRL6,
267 MAX8997_REG_OTPCGHCVS,
268 MAX8997_REG_SAFEOUTCTRL,
269 MAX8997_REG_LBCNFG1,
270 MAX8997_REG_LBCNFG2,
271 MAX8997_REG_BBCCTRL,
272
273 MAX8997_REG_FLASH1_CUR,
274 MAX8997_REG_FLASH2_CUR,
275 MAX8997_REG_MOVIE_CUR,
276 MAX8997_REG_GSMB_CUR,
277 MAX8997_REG_BOOST_CNTL,
278 MAX8997_REG_LEN_CNTL,
279 MAX8997_REG_FLASH_CNTL,
280 MAX8997_REG_WDT_CNTL,
281 MAX8997_REG_MAXFLASH1,
282 MAX8997_REG_MAXFLASH2,
283 MAX8997_REG_FLASHSTATUSMASK,
284
285 MAX8997_REG_GPIOCNTL1,
286 MAX8997_REG_GPIOCNTL2,
287 MAX8997_REG_GPIOCNTL3,
288 MAX8997_REG_GPIOCNTL4,
289 MAX8997_REG_GPIOCNTL5,
290 MAX8997_REG_GPIOCNTL6,
291 MAX8997_REG_GPIOCNTL7,
292 MAX8997_REG_GPIOCNTL8,
293 MAX8997_REG_GPIOCNTL9,
294 MAX8997_REG_GPIOCNTL10,
295 MAX8997_REG_GPIOCNTL11,
296 MAX8997_REG_GPIOCNTL12,
297
298 MAX8997_REG_LDO1CONFIG,
299 MAX8997_REG_LDO2CONFIG,
300 MAX8997_REG_LDO3CONFIG,
301 MAX8997_REG_LDO4CONFIG,
302 MAX8997_REG_LDO5CONFIG,
303 MAX8997_REG_LDO6CONFIG,
304 MAX8997_REG_LDO7CONFIG,
305 MAX8997_REG_LDO8CONFIG,
306 MAX8997_REG_LDO9CONFIG,
307 MAX8997_REG_LDO10CONFIG,
308 MAX8997_REG_LDO11CONFIG,
309 MAX8997_REG_LDO12CONFIG,
310 MAX8997_REG_LDO13CONFIG,
311 MAX8997_REG_LDO14CONFIG,
312 MAX8997_REG_LDO15CONFIG,
313 MAX8997_REG_LDO16CONFIG,
314 MAX8997_REG_LDO17CONFIG,
315 MAX8997_REG_LDO18CONFIG,
316 MAX8997_REG_LDO21CONFIG,
317
318 MAX8997_REG_DVSOKTIMER1,
319 MAX8997_REG_DVSOKTIMER2,
320 MAX8997_REG_DVSOKTIMER4,
321 MAX8997_REG_DVSOKTIMER5,
322};
323
324u8 max8997_dumpaddr_muic[] = {
325 MAX8997_MUIC_REG_INTMASK1,
326 MAX8997_MUIC_REG_INTMASK2,
327 MAX8997_MUIC_REG_INTMASK3,
328 MAX8997_MUIC_REG_CDETCTRL,
329 MAX8997_MUIC_REG_CONTROL1,
330 MAX8997_MUIC_REG_CONTROL2,
331 MAX8997_MUIC_REG_CONTROL3,
332};
333
334u8 max8997_dumpaddr_haptic[] = {
335 MAX8997_HAPTIC_REG_CONF1,
336 MAX8997_HAPTIC_REG_CONF2,
337 MAX8997_HAPTIC_REG_DRVCONF,
338 MAX8997_HAPTIC_REG_CYCLECONF1,
339 MAX8997_HAPTIC_REG_CYCLECONF2,
340 MAX8997_HAPTIC_REG_SIGCONF1,
341 MAX8997_HAPTIC_REG_SIGCONF2,
342 MAX8997_HAPTIC_REG_SIGCONF3,
343 MAX8997_HAPTIC_REG_SIGCONF4,
344 MAX8997_HAPTIC_REG_SIGDC1,
345 MAX8997_HAPTIC_REG_SIGDC2,
346 MAX8997_HAPTIC_REG_SIGPWMDC1,
347 MAX8997_HAPTIC_REG_SIGPWMDC2,
348 MAX8997_HAPTIC_REG_SIGPWMDC3,
349 MAX8997_HAPTIC_REG_SIGPWMDC4,
350};
351
352static int max8997_freeze(struct device *dev)
353{
354 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
355 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
356 int i;
357
358 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_pmic); i++)
359 max8997_read_reg(i2c, max8997_dumpaddr_pmic[i],
360 &max8997->reg_dump[i]);
361
362 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_muic); i++)
363 max8997_read_reg(i2c, max8997_dumpaddr_muic[i],
364 &max8997->reg_dump[i + MAX8997_REG_PMIC_END]);
365
366 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_haptic); i++)
367 max8997_read_reg(i2c, max8997_dumpaddr_haptic[i],
368 &max8997->reg_dump[i + MAX8997_REG_PMIC_END +
369 MAX8997_MUIC_REG_END]);
370
371 return 0;
372}
373
374static int max8997_restore(struct device *dev)
375{
376 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
377 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
378 int i;
379
380 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_pmic); i++)
381 max8997_write_reg(i2c, max8997_dumpaddr_pmic[i],
382 max8997->reg_dump[i]);
383
384 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_muic); i++)
385 max8997_write_reg(i2c, max8997_dumpaddr_muic[i],
386 max8997->reg_dump[i + MAX8997_REG_PMIC_END]);
387
388 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_haptic); i++)
389 max8997_write_reg(i2c, max8997_dumpaddr_haptic[i],
390 max8997->reg_dump[i + MAX8997_REG_PMIC_END +
391 MAX8997_MUIC_REG_END]);
392
393 return 0;
394}
395
396const struct dev_pm_ops max8997_pm = {
397 .freeze = max8997_freeze,
398 .restore = max8997_restore,
399};
400
401static struct i2c_driver max8997_i2c_driver = {
402 .driver = {
403 .name = "max8997",
404 .owner = THIS_MODULE,
405 .pm = &max8997_pm,
406 },
407 .probe = max8997_i2c_probe,
408 .remove = max8997_i2c_remove,
409 .id_table = max8997_i2c_id,
410};
411
412static int __init max8997_i2c_init(void)
413{
414 return i2c_add_driver(&max8997_i2c_driver);
415}
416/* init early so consumer devices can complete system boot */
417subsys_initcall(max8997_i2c_init);
418
419static void __exit max8997_i2c_exit(void)
420{
421 i2c_del_driver(&max8997_i2c_driver);
422}
423module_exit(max8997_i2c_exit);
424
425MODULE_DESCRIPTION("MAXIM 8997 multi-function core driver");
426MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
427MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index bbfe86732602..c00214257da2 100644
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -233,7 +233,7 @@ struct max8998_reg_dump {
233 u8 val; 233 u8 val;
234}; 234};
235#define SAVE_ITEM(x) { .addr = (x), .val = 0x0, } 235#define SAVE_ITEM(x) { .addr = (x), .val = 0x0, }
236struct max8998_reg_dump max8998_dump[] = { 236static struct max8998_reg_dump max8998_dump[] = {
237 SAVE_ITEM(MAX8998_REG_IRQM1), 237 SAVE_ITEM(MAX8998_REG_IRQM1),
238 SAVE_ITEM(MAX8998_REG_IRQM2), 238 SAVE_ITEM(MAX8998_REG_IRQM2),
239 SAVE_ITEM(MAX8998_REG_IRQM3), 239 SAVE_ITEM(MAX8998_REG_IRQM3),
@@ -298,7 +298,7 @@ static int max8998_restore(struct device *dev)
298 return 0; 298 return 0;
299} 299}
300 300
301const struct dev_pm_ops max8998_pm = { 301static const struct dev_pm_ops max8998_pm = {
302 .suspend = max8998_suspend, 302 .suspend = max8998_suspend,
303 .resume = max8998_resume, 303 .resume = max8998_resume,
304 .freeze = max8998_freeze, 304 .freeze = max8998_freeze,
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index b9fcaf0004da..668634e89e81 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -683,14 +683,13 @@ out:
683EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion); 683EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
684 684
685static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, 685static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
686 const char *format, void *pdata, size_t pdata_size) 686 const char *format, void *pdata)
687{ 687{
688 char buf[30]; 688 char buf[30];
689 const char *name = mc13xxx_get_chipname(mc13xxx); 689 const char *name = mc13xxx_get_chipname(mc13xxx);
690 690
691 struct mfd_cell cell = { 691 struct mfd_cell cell = {
692 .platform_data = pdata, 692 .mfd_data = pdata,
693 .data_size = pdata_size,
694 }; 693 };
695 694
696 /* there is no asnprintf in the kernel :-( */ 695 /* there is no asnprintf in the kernel :-( */
@@ -706,7 +705,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
706 705
707static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) 706static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
708{ 707{
709 return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); 708 return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL);
710} 709}
711 710
712static int mc13xxx_probe(struct spi_device *spi) 711static int mc13xxx_probe(struct spi_device *spi)
@@ -764,13 +763,8 @@ err_revision:
764 mc13xxx_add_subdevice(mc13xxx, "%s-codec"); 763 mc13xxx_add_subdevice(mc13xxx, "%s-codec");
765 764
766 if (pdata->flags & MC13XXX_USE_REGULATOR) { 765 if (pdata->flags & MC13XXX_USE_REGULATOR) {
767 struct mc13xxx_regulator_platform_data regulator_pdata = {
768 .num_regulators = pdata->num_regulators,
769 .regulators = pdata->regulators,
770 };
771
772 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", 766 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
773 &regulator_pdata, sizeof(regulator_pdata)); 767 &pdata->regulators);
774 } 768 }
775 769
776 if (pdata->flags & MC13XXX_USE_RTC) 770 if (pdata->flags & MC13XXX_USE_RTC)
@@ -779,10 +773,8 @@ err_revision:
779 if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) 773 if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
780 mc13xxx_add_subdevice(mc13xxx, "%s-ts"); 774 mc13xxx_add_subdevice(mc13xxx, "%s-ts");
781 775
782 if (pdata->flags & MC13XXX_USE_LED) { 776 if (pdata->flags & MC13XXX_USE_LED)
783 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", 777 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", pdata->leds);
784 pdata->leds, sizeof(*pdata->leds));
785 }
786 778
787 return 0; 779 return 0;
788} 780}
@@ -811,6 +803,7 @@ static const struct spi_device_id mc13xxx_device_id[] = {
811 /* sentinel */ 803 /* sentinel */
812 } 804 }
813}; 805};
806MODULE_DEVICE_TABLE(spi, mc13xxx_device_id);
814 807
815static struct spi_driver mc13xxx_driver = { 808static struct spi_driver mc13xxx_driver = {
816 .id_table = mc13xxx_device_id, 809 .id_table = mc13xxx_device_id,
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index d83ad0f141af..79eda0264fb2 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -18,6 +18,43 @@
18#include <linux/pm_runtime.h> 18#include <linux/pm_runtime.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20 20
21int mfd_cell_enable(struct platform_device *pdev)
22{
23 const struct mfd_cell *cell = mfd_get_cell(pdev);
24 int err = 0;
25
26 /* only call enable hook if the cell wasn't previously enabled */
27 if (atomic_inc_return(cell->usage_count) == 1)
28 err = cell->enable(pdev);
29
30 /* if the enable hook failed, decrement counter to allow retries */
31 if (err)
32 atomic_dec(cell->usage_count);
33
34 return err;
35}
36EXPORT_SYMBOL(mfd_cell_enable);
37
38int mfd_cell_disable(struct platform_device *pdev)
39{
40 const struct mfd_cell *cell = mfd_get_cell(pdev);
41 int err = 0;
42
43 /* only disable if no other clients are using it */
44 if (atomic_dec_return(cell->usage_count) == 0)
45 err = cell->disable(pdev);
46
47 /* if the disable hook failed, increment to allow retries */
48 if (err)
49 atomic_inc(cell->usage_count);
50
51 /* sanity check; did someone call disable too many times? */
52 WARN_ON(atomic_read(cell->usage_count) < 0);
53
54 return err;
55}
56EXPORT_SYMBOL(mfd_cell_disable);
57
21static int mfd_add_device(struct device *parent, int id, 58static int mfd_add_device(struct device *parent, int id,
22 const struct mfd_cell *cell, 59 const struct mfd_cell *cell,
23 struct resource *mem_base, 60 struct resource *mem_base,
@@ -37,14 +74,10 @@ static int mfd_add_device(struct device *parent, int id,
37 goto fail_device; 74 goto fail_device;
38 75
39 pdev->dev.parent = parent; 76 pdev->dev.parent = parent;
40 platform_set_drvdata(pdev, cell->driver_data);
41 77
42 if (cell->data_size) { 78 ret = platform_device_add_data(pdev, cell, sizeof(*cell));
43 ret = platform_device_add_data(pdev, 79 if (ret)
44 cell->platform_data, cell->data_size); 80 goto fail_res;
45 if (ret)
46 goto fail_res;
47 }
48 81
49 for (r = 0; r < cell->num_resources; r++) { 82 for (r = 0; r < cell->num_resources; r++) {
50 res[r].name = cell->resources[r].name; 83 res[r].name = cell->resources[r].name;
@@ -100,14 +133,22 @@ fail_alloc:
100} 133}
101 134
102int mfd_add_devices(struct device *parent, int id, 135int mfd_add_devices(struct device *parent, int id,
103 const struct mfd_cell *cells, int n_devs, 136 struct mfd_cell *cells, int n_devs,
104 struct resource *mem_base, 137 struct resource *mem_base,
105 int irq_base) 138 int irq_base)
106{ 139{
107 int i; 140 int i;
108 int ret = 0; 141 int ret = 0;
142 atomic_t *cnts;
143
144 /* initialize reference counting for all cells */
145 cnts = kcalloc(sizeof(*cnts), n_devs, GFP_KERNEL);
146 if (!cnts)
147 return -ENOMEM;
109 148
110 for (i = 0; i < n_devs; i++) { 149 for (i = 0; i < n_devs; i++) {
150 atomic_set(&cnts[i], 0);
151 cells[i].usage_count = &cnts[i];
111 ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); 152 ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base);
112 if (ret) 153 if (ret)
113 break; 154 break;
@@ -120,17 +161,89 @@ int mfd_add_devices(struct device *parent, int id,
120} 161}
121EXPORT_SYMBOL(mfd_add_devices); 162EXPORT_SYMBOL(mfd_add_devices);
122 163
123static int mfd_remove_devices_fn(struct device *dev, void *unused) 164static int mfd_remove_devices_fn(struct device *dev, void *c)
124{ 165{
125 platform_device_unregister(to_platform_device(dev)); 166 struct platform_device *pdev = to_platform_device(dev);
167 const struct mfd_cell *cell = mfd_get_cell(pdev);
168 atomic_t **usage_count = c;
169
170 /* find the base address of usage_count pointers (for freeing) */
171 if (!*usage_count || (cell->usage_count < *usage_count))
172 *usage_count = cell->usage_count;
173
174 platform_device_unregister(pdev);
126 return 0; 175 return 0;
127} 176}
128 177
129void mfd_remove_devices(struct device *parent) 178void mfd_remove_devices(struct device *parent)
130{ 179{
131 device_for_each_child(parent, NULL, mfd_remove_devices_fn); 180 atomic_t *cnts = NULL;
181
182 device_for_each_child(parent, &cnts, mfd_remove_devices_fn);
183 kfree(cnts);
132} 184}
133EXPORT_SYMBOL(mfd_remove_devices); 185EXPORT_SYMBOL(mfd_remove_devices);
134 186
187static int add_shared_platform_device(const char *cell, const char *name)
188{
189 struct mfd_cell cell_entry;
190 struct device *dev;
191 struct platform_device *pdev;
192 int err;
193
194 /* check if we've already registered a device (don't fail if we have) */
195 if (bus_find_device_by_name(&platform_bus_type, NULL, name))
196 return 0;
197
198 /* fetch the parent cell's device (should already be registered!) */
199 dev = bus_find_device_by_name(&platform_bus_type, NULL, cell);
200 if (!dev) {
201 printk(KERN_ERR "failed to find device for cell %s\n", cell);
202 return -ENODEV;
203 }
204 pdev = to_platform_device(dev);
205 memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry));
206
207 WARN_ON(!cell_entry.enable);
208
209 cell_entry.name = name;
210 err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0);
211 if (err)
212 dev_err(dev, "MFD add devices failed: %d\n", err);
213 return err;
214}
215
216int mfd_shared_platform_driver_register(struct platform_driver *drv,
217 const char *cellname)
218{
219 int err;
220
221 err = add_shared_platform_device(cellname, drv->driver.name);
222 if (err)
223 printk(KERN_ERR "failed to add platform device %s\n",
224 drv->driver.name);
225
226 err = platform_driver_register(drv);
227 if (err)
228 printk(KERN_ERR "failed to add platform driver %s\n",
229 drv->driver.name);
230
231 return err;
232}
233EXPORT_SYMBOL(mfd_shared_platform_driver_register);
234
235void mfd_shared_platform_driver_unregister(struct platform_driver *drv)
236{
237 struct device *dev;
238
239 dev = bus_find_device_by_name(&platform_bus_type, NULL,
240 drv->driver.name);
241 if (dev)
242 platform_device_unregister(to_platform_device(dev));
243
244 platform_driver_unregister(drv);
245}
246EXPORT_SYMBOL(mfd_shared_platform_driver_unregister);
247
135MODULE_LICENSE("GPL"); 248MODULE_LICENSE("GPL");
136MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); 249MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 501ce13b693e..c1306ed43e3c 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -21,6 +21,7 @@
21#include <linux/workqueue.h> 21#include <linux/workqueue.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/pm.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25 26
26#include <linux/mfd/pcf50633/core.h> 27#include <linux/mfd/pcf50633/core.h>
@@ -230,27 +231,26 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
230 } 231 }
231} 232}
232 233
233#ifdef CONFIG_PM 234#ifdef CONFIG_PM_SLEEP
234static int pcf50633_suspend(struct i2c_client *client, pm_message_t state) 235static int pcf50633_suspend(struct device *dev)
235{ 236{
236 struct pcf50633 *pcf; 237 struct i2c_client *client = to_i2c_client(dev);
237 pcf = i2c_get_clientdata(client); 238 struct pcf50633 *pcf = i2c_get_clientdata(client);
238 239
239 return pcf50633_irq_suspend(pcf); 240 return pcf50633_irq_suspend(pcf);
240} 241}
241 242
242static int pcf50633_resume(struct i2c_client *client) 243static int pcf50633_resume(struct device *dev)
243{ 244{
244 struct pcf50633 *pcf; 245 struct i2c_client *client = to_i2c_client(dev);
245 pcf = i2c_get_clientdata(client); 246 struct pcf50633 *pcf = i2c_get_clientdata(client);
246 247
247 return pcf50633_irq_resume(pcf); 248 return pcf50633_irq_resume(pcf);
248} 249}
249#else
250#define pcf50633_suspend NULL
251#define pcf50633_resume NULL
252#endif 250#endif
253 251
252static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
253
254static int __devinit pcf50633_probe(struct i2c_client *client, 254static int __devinit pcf50633_probe(struct i2c_client *client,
255 const struct i2c_device_id *ids) 255 const struct i2c_device_id *ids)
256{ 256{
@@ -360,16 +360,16 @@ static struct i2c_device_id pcf50633_id_table[] = {
360 {"pcf50633", 0x73}, 360 {"pcf50633", 0x73},
361 {/* end of list */} 361 {/* end of list */}
362}; 362};
363MODULE_DEVICE_TABLE(i2c, pcf50633_id_table);
363 364
364static struct i2c_driver pcf50633_driver = { 365static struct i2c_driver pcf50633_driver = {
365 .driver = { 366 .driver = {
366 .name = "pcf50633", 367 .name = "pcf50633",
368 .pm = &pcf50633_pm,
367 }, 369 },
368 .id_table = pcf50633_id_table, 370 .id_table = pcf50633_id_table,
369 .probe = pcf50633_probe, 371 .probe = pcf50633_probe,
370 .remove = __devexit_p(pcf50633_remove), 372 .remove = __devexit_p(pcf50633_remove),
371 .suspend = pcf50633_suspend,
372 .resume = pcf50633_resume,
373}; 373};
374 374
375static int __init pcf50633_init(void) 375static int __init pcf50633_init(void)
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c
index 50922975bda3..193c940225b5 100644
--- a/drivers/mfd/rdc321x-southbridge.c
+++ b/drivers/mfd/rdc321x-southbridge.c
@@ -61,12 +61,12 @@ static struct mfd_cell rdc321x_sb_cells[] = {
61 .name = "rdc321x-wdt", 61 .name = "rdc321x-wdt",
62 .resources = rdc321x_wdt_resource, 62 .resources = rdc321x_wdt_resource,
63 .num_resources = ARRAY_SIZE(rdc321x_wdt_resource), 63 .num_resources = ARRAY_SIZE(rdc321x_wdt_resource),
64 .driver_data = &rdc321x_wdt_pdata, 64 .mfd_data = &rdc321x_wdt_pdata,
65 }, { 65 }, {
66 .name = "rdc321x-gpio", 66 .name = "rdc321x-gpio",
67 .resources = rdc321x_gpio_resources, 67 .resources = rdc321x_gpio_resources,
68 .num_resources = ARRAY_SIZE(rdc321x_gpio_resources), 68 .num_resources = ARRAY_SIZE(rdc321x_gpio_resources),
69 .driver_data = &rdc321x_gpio_pdata, 69 .mfd_data = &rdc321x_gpio_pdata,
70 }, 70 },
71}; 71};
72 72
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
index 0a7df44a93c0..53a63024bf11 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -146,9 +146,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
146 } 146 }
147 147
148 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); 148 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
149 priv->cell_mmc.driver_data = mmc_data; 149 priv->cell_mmc.mfd_data = mmc_data;
150 priv->cell_mmc.platform_data = &priv->cell_mmc;
151 priv->cell_mmc.data_size = sizeof(priv->cell_mmc);
152 150
153 platform_set_drvdata(pdev, priv); 151 platform_set_drvdata(pdev, priv);
154 152
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 5de3a760ea1e..df3702c1756d 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -133,10 +133,10 @@ static unsigned long decode_div(unsigned long pll2, unsigned long val,
133 133
134static void sm501_dump_clk(struct sm501_devdata *sm) 134static void sm501_dump_clk(struct sm501_devdata *sm)
135{ 135{
136 unsigned long misct = readl(sm->regs + SM501_MISC_TIMING); 136 unsigned long misct = smc501_readl(sm->regs + SM501_MISC_TIMING);
137 unsigned long pm0 = readl(sm->regs + SM501_POWER_MODE_0_CLOCK); 137 unsigned long pm0 = smc501_readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
138 unsigned long pm1 = readl(sm->regs + SM501_POWER_MODE_1_CLOCK); 138 unsigned long pm1 = smc501_readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
139 unsigned long pmc = readl(sm->regs + SM501_POWER_MODE_CONTROL); 139 unsigned long pmc = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
140 unsigned long sdclk0, sdclk1; 140 unsigned long sdclk0, sdclk1;
141 unsigned long pll2 = 0; 141 unsigned long pll2 = 0;
142 142
@@ -193,29 +193,29 @@ static void sm501_dump_regs(struct sm501_devdata *sm)
193 void __iomem *regs = sm->regs; 193 void __iomem *regs = sm->regs;
194 194
195 dev_info(sm->dev, "System Control %08x\n", 195 dev_info(sm->dev, "System Control %08x\n",
196 readl(regs + SM501_SYSTEM_CONTROL)); 196 smc501_readl(regs + SM501_SYSTEM_CONTROL));
197 dev_info(sm->dev, "Misc Control %08x\n", 197 dev_info(sm->dev, "Misc Control %08x\n",
198 readl(regs + SM501_MISC_CONTROL)); 198 smc501_readl(regs + SM501_MISC_CONTROL));
199 dev_info(sm->dev, "GPIO Control Low %08x\n", 199 dev_info(sm->dev, "GPIO Control Low %08x\n",
200 readl(regs + SM501_GPIO31_0_CONTROL)); 200 smc501_readl(regs + SM501_GPIO31_0_CONTROL));
201 dev_info(sm->dev, "GPIO Control Hi %08x\n", 201 dev_info(sm->dev, "GPIO Control Hi %08x\n",
202 readl(regs + SM501_GPIO63_32_CONTROL)); 202 smc501_readl(regs + SM501_GPIO63_32_CONTROL));
203 dev_info(sm->dev, "DRAM Control %08x\n", 203 dev_info(sm->dev, "DRAM Control %08x\n",
204 readl(regs + SM501_DRAM_CONTROL)); 204 smc501_readl(regs + SM501_DRAM_CONTROL));
205 dev_info(sm->dev, "Arbitration Ctrl %08x\n", 205 dev_info(sm->dev, "Arbitration Ctrl %08x\n",
206 readl(regs + SM501_ARBTRTN_CONTROL)); 206 smc501_readl(regs + SM501_ARBTRTN_CONTROL));
207 dev_info(sm->dev, "Misc Timing %08x\n", 207 dev_info(sm->dev, "Misc Timing %08x\n",
208 readl(regs + SM501_MISC_TIMING)); 208 smc501_readl(regs + SM501_MISC_TIMING));
209} 209}
210 210
211static void sm501_dump_gate(struct sm501_devdata *sm) 211static void sm501_dump_gate(struct sm501_devdata *sm)
212{ 212{
213 dev_info(sm->dev, "CurrentGate %08x\n", 213 dev_info(sm->dev, "CurrentGate %08x\n",
214 readl(sm->regs + SM501_CURRENT_GATE)); 214 smc501_readl(sm->regs + SM501_CURRENT_GATE));
215 dev_info(sm->dev, "CurrentClock %08x\n", 215 dev_info(sm->dev, "CurrentClock %08x\n",
216 readl(sm->regs + SM501_CURRENT_CLOCK)); 216 smc501_readl(sm->regs + SM501_CURRENT_CLOCK));
217 dev_info(sm->dev, "PowerModeControl %08x\n", 217 dev_info(sm->dev, "PowerModeControl %08x\n",
218 readl(sm->regs + SM501_POWER_MODE_CONTROL)); 218 smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL));
219} 219}
220 220
221#else 221#else
@@ -231,7 +231,7 @@ static inline void sm501_dump_clk(struct sm501_devdata *sm) { }
231 231
232static void sm501_sync_regs(struct sm501_devdata *sm) 232static void sm501_sync_regs(struct sm501_devdata *sm)
233{ 233{
234 readl(sm->regs); 234 smc501_readl(sm->regs);
235} 235}
236 236
237static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay) 237static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay)
@@ -261,11 +261,11 @@ int sm501_misc_control(struct device *dev,
261 261
262 spin_lock_irqsave(&sm->reg_lock, save); 262 spin_lock_irqsave(&sm->reg_lock, save);
263 263
264 misc = readl(sm->regs + SM501_MISC_CONTROL); 264 misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
265 to = (misc & ~clear) | set; 265 to = (misc & ~clear) | set;
266 266
267 if (to != misc) { 267 if (to != misc) {
268 writel(to, sm->regs + SM501_MISC_CONTROL); 268 smc501_writel(to, sm->regs + SM501_MISC_CONTROL);
269 sm501_sync_regs(sm); 269 sm501_sync_regs(sm);
270 270
271 dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc); 271 dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc);
@@ -294,11 +294,11 @@ unsigned long sm501_modify_reg(struct device *dev,
294 294
295 spin_lock_irqsave(&sm->reg_lock, save); 295 spin_lock_irqsave(&sm->reg_lock, save);
296 296
297 data = readl(sm->regs + reg); 297 data = smc501_readl(sm->regs + reg);
298 data |= set; 298 data |= set;
299 data &= ~clear; 299 data &= ~clear;
300 300
301 writel(data, sm->regs + reg); 301 smc501_writel(data, sm->regs + reg);
302 sm501_sync_regs(sm); 302 sm501_sync_regs(sm);
303 303
304 spin_unlock_irqrestore(&sm->reg_lock, save); 304 spin_unlock_irqrestore(&sm->reg_lock, save);
@@ -322,9 +322,9 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
322 322
323 mutex_lock(&sm->clock_lock); 323 mutex_lock(&sm->clock_lock);
324 324
325 mode = readl(sm->regs + SM501_POWER_MODE_CONTROL); 325 mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
326 gate = readl(sm->regs + SM501_CURRENT_GATE); 326 gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
327 clock = readl(sm->regs + SM501_CURRENT_CLOCK); 327 clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
328 328
329 mode &= 3; /* get current power mode */ 329 mode &= 3; /* get current power mode */
330 330
@@ -356,14 +356,14 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
356 356
357 switch (mode) { 357 switch (mode) {
358 case 1: 358 case 1:
359 writel(gate, sm->regs + SM501_POWER_MODE_0_GATE); 359 smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
360 writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK); 360 smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
361 mode = 0; 361 mode = 0;
362 break; 362 break;
363 case 2: 363 case 2:
364 case 0: 364 case 0:
365 writel(gate, sm->regs + SM501_POWER_MODE_1_GATE); 365 smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
366 writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK); 366 smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
367 mode = 1; 367 mode = 1;
368 break; 368 break;
369 369
@@ -372,7 +372,7 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
372 goto already; 372 goto already;
373 } 373 }
374 374
375 writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); 375 smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
376 sm501_sync_regs(sm); 376 sm501_sync_regs(sm);
377 377
378 dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", 378 dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
@@ -519,9 +519,9 @@ unsigned long sm501_set_clock(struct device *dev,
519 unsigned long req_freq) 519 unsigned long req_freq)
520{ 520{
521 struct sm501_devdata *sm = dev_get_drvdata(dev); 521 struct sm501_devdata *sm = dev_get_drvdata(dev);
522 unsigned long mode = readl(sm->regs + SM501_POWER_MODE_CONTROL); 522 unsigned long mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
523 unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE); 523 unsigned long gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
524 unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); 524 unsigned long clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
525 unsigned char reg; 525 unsigned char reg;
526 unsigned int pll_reg = 0; 526 unsigned int pll_reg = 0;
527 unsigned long sm501_freq; /* the actual frequency achieved */ 527 unsigned long sm501_freq; /* the actual frequency achieved */
@@ -592,9 +592,9 @@ unsigned long sm501_set_clock(struct device *dev,
592 592
593 mutex_lock(&sm->clock_lock); 593 mutex_lock(&sm->clock_lock);
594 594
595 mode = readl(sm->regs + SM501_POWER_MODE_CONTROL); 595 mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
596 gate = readl(sm->regs + SM501_CURRENT_GATE); 596 gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
597 clock = readl(sm->regs + SM501_CURRENT_CLOCK); 597 clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
598 598
599 clock = clock & ~(0xFF << clksrc); 599 clock = clock & ~(0xFF << clksrc);
600 clock |= reg<<clksrc; 600 clock |= reg<<clksrc;
@@ -603,14 +603,14 @@ unsigned long sm501_set_clock(struct device *dev,
603 603
604 switch (mode) { 604 switch (mode) {
605 case 1: 605 case 1:
606 writel(gate, sm->regs + SM501_POWER_MODE_0_GATE); 606 smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
607 writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK); 607 smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
608 mode = 0; 608 mode = 0;
609 break; 609 break;
610 case 2: 610 case 2:
611 case 0: 611 case 0:
612 writel(gate, sm->regs + SM501_POWER_MODE_1_GATE); 612 smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
613 writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK); 613 smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
614 mode = 1; 614 mode = 1;
615 break; 615 break;
616 616
@@ -619,10 +619,11 @@ unsigned long sm501_set_clock(struct device *dev,
619 return -1; 619 return -1;
620 } 620 }
621 621
622 writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); 622 smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
623 623
624 if (pll_reg) 624 if (pll_reg)
625 writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL); 625 smc501_writel(pll_reg,
626 sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
626 627
627 sm501_sync_regs(sm); 628 sm501_sync_regs(sm);
628 629
@@ -902,7 +903,7 @@ static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
902 struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip); 903 struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip);
903 unsigned long result; 904 unsigned long result;
904 905
905 result = readl(smgpio->regbase + SM501_GPIO_DATA_LOW); 906 result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
906 result >>= offset; 907 result >>= offset;
907 908
908 return result & 1UL; 909 return result & 1UL;
@@ -915,13 +916,13 @@ static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
915 916
916 /* check and modify if this pin is not set as gpio. */ 917 /* check and modify if this pin is not set as gpio. */
917 918
918 if (readl(smchip->control) & bit) { 919 if (smc501_readl(smchip->control) & bit) {
919 dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev, 920 dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev,
920 "changing mode of gpio, bit %08lx\n", bit); 921 "changing mode of gpio, bit %08lx\n", bit);
921 922
922 ctrl = readl(smchip->control); 923 ctrl = smc501_readl(smchip->control);
923 ctrl &= ~bit; 924 ctrl &= ~bit;
924 writel(ctrl, smchip->control); 925 smc501_writel(ctrl, smchip->control);
925 926
926 sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio)); 927 sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio));
927 } 928 }
@@ -942,10 +943,10 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
942 943
943 spin_lock_irqsave(&smgpio->lock, save); 944 spin_lock_irqsave(&smgpio->lock, save);
944 945
945 val = readl(regs + SM501_GPIO_DATA_LOW) & ~bit; 946 val = smc501_readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
946 if (value) 947 if (value)
947 val |= bit; 948 val |= bit;
948 writel(val, regs); 949 smc501_writel(val, regs);
949 950
950 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 951 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
951 sm501_gpio_ensure_gpio(smchip, bit); 952 sm501_gpio_ensure_gpio(smchip, bit);
@@ -967,8 +968,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
967 968
968 spin_lock_irqsave(&smgpio->lock, save); 969 spin_lock_irqsave(&smgpio->lock, save);
969 970
970 ddr = readl(regs + SM501_GPIO_DDR_LOW); 971 ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
971 writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW); 972 smc501_writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
972 973
973 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 974 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
974 sm501_gpio_ensure_gpio(smchip, bit); 975 sm501_gpio_ensure_gpio(smchip, bit);
@@ -994,18 +995,18 @@ static int sm501_gpio_output(struct gpio_chip *chip,
994 995
995 spin_lock_irqsave(&smgpio->lock, save); 996 spin_lock_irqsave(&smgpio->lock, save);
996 997
997 val = readl(regs + SM501_GPIO_DATA_LOW); 998 val = smc501_readl(regs + SM501_GPIO_DATA_LOW);
998 if (value) 999 if (value)
999 val |= bit; 1000 val |= bit;
1000 else 1001 else
1001 val &= ~bit; 1002 val &= ~bit;
1002 writel(val, regs); 1003 smc501_writel(val, regs);
1003 1004
1004 ddr = readl(regs + SM501_GPIO_DDR_LOW); 1005 ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
1005 writel(ddr | bit, regs + SM501_GPIO_DDR_LOW); 1006 smc501_writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
1006 1007
1007 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 1008 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
1008 writel(val, regs + SM501_GPIO_DATA_LOW); 1009 smc501_writel(val, regs + SM501_GPIO_DATA_LOW);
1009 1010
1010 sm501_sync_regs(sm501_gpio_to_dev(smgpio)); 1011 sm501_sync_regs(sm501_gpio_to_dev(smgpio));
1011 spin_unlock_irqrestore(&smgpio->lock, save); 1012 spin_unlock_irqrestore(&smgpio->lock, save);
@@ -1231,7 +1232,7 @@ static ssize_t sm501_dbg_regs(struct device *dev,
1231 1232
1232 for (reg = 0x00; reg < 0x70; reg += 4) { 1233 for (reg = 0x00; reg < 0x70; reg += 4) {
1233 ret = sprintf(ptr, "%08x = %08x\n", 1234 ret = sprintf(ptr, "%08x = %08x\n",
1234 reg, readl(sm->regs + reg)); 1235 reg, smc501_readl(sm->regs + reg));
1235 ptr += ret; 1236 ptr += ret;
1236 } 1237 }
1237 1238
@@ -1255,10 +1256,10 @@ static inline void sm501_init_reg(struct sm501_devdata *sm,
1255{ 1256{
1256 unsigned long tmp; 1257 unsigned long tmp;
1257 1258
1258 tmp = readl(sm->regs + reg); 1259 tmp = smc501_readl(sm->regs + reg);
1259 tmp &= ~r->mask; 1260 tmp &= ~r->mask;
1260 tmp |= r->set; 1261 tmp |= r->set;
1261 writel(tmp, sm->regs + reg); 1262 smc501_writel(tmp, sm->regs + reg);
1262} 1263}
1263 1264
1264/* sm501_init_regs 1265/* sm501_init_regs
@@ -1299,7 +1300,7 @@ static void sm501_init_regs(struct sm501_devdata *sm,
1299 1300
1300static int sm501_check_clocks(struct sm501_devdata *sm) 1301static int sm501_check_clocks(struct sm501_devdata *sm)
1301{ 1302{
1302 unsigned long pwrmode = readl(sm->regs + SM501_CURRENT_CLOCK); 1303 unsigned long pwrmode = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
1303 unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC); 1304 unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC);
1304 unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC); 1305 unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC);
1305 1306
@@ -1334,7 +1335,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
1334 1335
1335 INIT_LIST_HEAD(&sm->devices); 1336 INIT_LIST_HEAD(&sm->devices);
1336 1337
1337 devid = readl(sm->regs + SM501_DEVICEID); 1338 devid = smc501_readl(sm->regs + SM501_DEVICEID);
1338 1339
1339 if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) { 1340 if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) {
1340 dev_err(sm->dev, "incorrect device id %08lx\n", devid); 1341 dev_err(sm->dev, "incorrect device id %08lx\n", devid);
@@ -1342,9 +1343,9 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
1342 } 1343 }
1343 1344
1344 /* disable irqs */ 1345 /* disable irqs */
1345 writel(0, sm->regs + SM501_IRQ_MASK); 1346 smc501_writel(0, sm->regs + SM501_IRQ_MASK);
1346 1347
1347 dramctrl = readl(sm->regs + SM501_DRAM_CONTROL); 1348 dramctrl = smc501_readl(sm->regs + SM501_DRAM_CONTROL);
1348 mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7]; 1349 mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7];
1349 1350
1350 dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n", 1351 dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n",
@@ -1376,7 +1377,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
1376 sm501_register_gpio(sm); 1377 sm501_register_gpio(sm);
1377 } 1378 }
1378 1379
1379 if (pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) { 1380 if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
1380 if (!sm501_gpio_isregistered(sm)) 1381 if (!sm501_gpio_isregistered(sm))
1381 dev_err(sm->dev, "no gpio available for i2c gpio.\n"); 1382 dev_err(sm->dev, "no gpio available for i2c gpio.\n");
1382 else 1383 else
@@ -1421,6 +1422,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
1421 1422
1422 sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1); 1423 sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
1423 sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0); 1424 sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
1425
1424 if (sm->io_res == NULL || sm->mem_res == NULL) { 1426 if (sm->io_res == NULL || sm->mem_res == NULL) {
1425 dev_err(&dev->dev, "failed to get IO resource\n"); 1427 dev_err(&dev->dev, "failed to get IO resource\n");
1426 ret = -ENOENT; 1428 ret = -ENOENT;
@@ -1489,7 +1491,7 @@ static int sm501_plat_suspend(struct platform_device *pdev, pm_message_t state)
1489 struct sm501_devdata *sm = platform_get_drvdata(pdev); 1491 struct sm501_devdata *sm = platform_get_drvdata(pdev);
1490 1492
1491 sm->in_suspend = 1; 1493 sm->in_suspend = 1;
1492 sm->pm_misc = readl(sm->regs + SM501_MISC_CONTROL); 1494 sm->pm_misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
1493 1495
1494 sm501_dump_regs(sm); 1496 sm501_dump_regs(sm);
1495 1497
@@ -1513,9 +1515,9 @@ static int sm501_plat_resume(struct platform_device *pdev)
1513 1515
1514 /* check to see if we are in the same state as when suspended */ 1516 /* check to see if we are in the same state as when suspended */
1515 1517
1516 if (readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) { 1518 if (smc501_readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
1517 dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n"); 1519 dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n");
1518 writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL); 1520 smc501_writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
1519 1521
1520 /* our suspend causes the controller state to change, 1522 /* our suspend causes the controller state to change,
1521 * either by something attempting setup, power loss, 1523 * either by something attempting setup, power loss,
@@ -1734,10 +1736,16 @@ static struct pci_driver sm501_pci_driver = {
1734 1736
1735MODULE_ALIAS("platform:sm501"); 1737MODULE_ALIAS("platform:sm501");
1736 1738
1739static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
1740 { .compatible = "smi,sm501", },
1741 { /* end */ }
1742};
1743
1737static struct platform_driver sm501_plat_driver = { 1744static struct platform_driver sm501_plat_driver = {
1738 .driver = { 1745 .driver = {
1739 .name = "sm501", 1746 .name = "sm501",
1740 .owner = THIS_MODULE, 1747 .owner = THIS_MODULE,
1748 .of_match_table = of_sm501_match_tbl,
1741 }, 1749 },
1742 .probe = sm501_plat_probe, 1750 .probe = sm501_plat_probe,
1743 .remove = sm501_plat_remove, 1751 .remove = sm501_plat_remove,
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 9caeb4ac6ea6..af57fc706a4c 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -170,7 +170,7 @@ static struct mfd_cell t7l66xb_cells[] = {
170 .name = "tmio-mmc", 170 .name = "tmio-mmc",
171 .enable = t7l66xb_mmc_enable, 171 .enable = t7l66xb_mmc_enable,
172 .disable = t7l66xb_mmc_disable, 172 .disable = t7l66xb_mmc_disable,
173 .driver_data = &t7166xb_mmc_data, 173 .mfd_data = &t7166xb_mmc_data,
174 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), 174 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources),
175 .resources = t7l66xb_mmc_resources, 175 .resources = t7l66xb_mmc_resources,
176 }, 176 },
@@ -383,16 +383,7 @@ static int t7l66xb_probe(struct platform_device *dev)
383 383
384 t7l66xb_attach_irq(dev); 384 t7l66xb_attach_irq(dev);
385 385
386 t7l66xb_cells[T7L66XB_CELL_NAND].driver_data = pdata->nand_data; 386 t7l66xb_cells[T7L66XB_CELL_NAND].mfd_data = pdata->nand_data;
387 t7l66xb_cells[T7L66XB_CELL_NAND].platform_data =
388 &t7l66xb_cells[T7L66XB_CELL_NAND];
389 t7l66xb_cells[T7L66XB_CELL_NAND].data_size =
390 sizeof(t7l66xb_cells[T7L66XB_CELL_NAND]);
391
392 t7l66xb_cells[T7L66XB_CELL_MMC].platform_data =
393 &t7l66xb_cells[T7L66XB_CELL_MMC];
394 t7l66xb_cells[T7L66XB_CELL_MMC].data_size =
395 sizeof(t7l66xb_cells[T7L66XB_CELL_MMC]);
396 387
397 ret = mfd_add_devices(&dev->dev, dev->id, 388 ret = mfd_add_devices(&dev->dev, dev->id,
398 t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), 389 t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells),
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 6315f63f017d..b006f7cee952 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -131,7 +131,7 @@ static struct mfd_cell tc6387xb_cells[] = {
131 .name = "tmio-mmc", 131 .name = "tmio-mmc",
132 .enable = tc6387xb_mmc_enable, 132 .enable = tc6387xb_mmc_enable,
133 .disable = tc6387xb_mmc_disable, 133 .disable = tc6387xb_mmc_disable,
134 .driver_data = &tc6387xb_mmc_data, 134 .mfd_data = &tc6387xb_mmc_data,
135 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), 135 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
136 .resources = tc6387xb_mmc_resources, 136 .resources = tc6387xb_mmc_resources,
137 }, 137 },
@@ -190,11 +190,6 @@ static int __devinit tc6387xb_probe(struct platform_device *dev)
190 190
191 printk(KERN_INFO "Toshiba tc6387xb initialised\n"); 191 printk(KERN_INFO "Toshiba tc6387xb initialised\n");
192 192
193 tc6387xb_cells[TC6387XB_CELL_MMC].platform_data =
194 &tc6387xb_cells[TC6387XB_CELL_MMC];
195 tc6387xb_cells[TC6387XB_CELL_MMC].data_size =
196 sizeof(tc6387xb_cells[TC6387XB_CELL_MMC]);
197
198 ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, 193 ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells,
199 ARRAY_SIZE(tc6387xb_cells), iomem, irq); 194 ARRAY_SIZE(tc6387xb_cells), iomem, irq);
200 195
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 9a238633a54d..3d62ded86a8f 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -393,7 +393,7 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = {
393 .name = "tmio-mmc", 393 .name = "tmio-mmc",
394 .enable = tc6393xb_mmc_enable, 394 .enable = tc6393xb_mmc_enable,
395 .resume = tc6393xb_mmc_resume, 395 .resume = tc6393xb_mmc_resume,
396 .driver_data = &tc6393xb_mmc_data, 396 .mfd_data = &tc6393xb_mmc_data,
397 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), 397 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
398 .resources = tc6393xb_mmc_resources, 398 .resources = tc6393xb_mmc_resources,
399 }, 399 },
@@ -693,27 +693,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
693 goto err_setup; 693 goto err_setup;
694 } 694 }
695 695
696 tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; 696 tc6393xb_cells[TC6393XB_CELL_NAND].mfd_data = tcpd->nand_data;
697 tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = 697 tc6393xb_cells[TC6393XB_CELL_FB].mfd_data = tcpd->fb_data;
698 &tc6393xb_cells[TC6393XB_CELL_NAND];
699 tc6393xb_cells[TC6393XB_CELL_NAND].data_size =
700 sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]);
701
702 tc6393xb_cells[TC6393XB_CELL_MMC].platform_data =
703 &tc6393xb_cells[TC6393XB_CELL_MMC];
704 tc6393xb_cells[TC6393XB_CELL_MMC].data_size =
705 sizeof(tc6393xb_cells[TC6393XB_CELL_MMC]);
706
707 tc6393xb_cells[TC6393XB_CELL_OHCI].platform_data =
708 &tc6393xb_cells[TC6393XB_CELL_OHCI];
709 tc6393xb_cells[TC6393XB_CELL_OHCI].data_size =
710 sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]);
711
712 tc6393xb_cells[TC6393XB_CELL_FB].driver_data = tcpd->fb_data;
713 tc6393xb_cells[TC6393XB_CELL_FB].platform_data =
714 &tc6393xb_cells[TC6393XB_CELL_FB];
715 tc6393xb_cells[TC6393XB_CELL_FB].data_size =
716 sizeof(tc6393xb_cells[TC6393XB_CELL_FB]);
717 698
718 ret = mfd_add_devices(&dev->dev, dev->id, 699 ret = mfd_add_devices(&dev->dev, dev->id,
719 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), 700 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 6ad8a7f8d390..94c6c8afad12 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -384,8 +384,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
384 .name = "timb-dma", 384 .name = "timb-dma",
385 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 385 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
386 .resources = timberdale_dma_resources, 386 .resources = timberdale_dma_resources,
387 .platform_data = &timb_dma_platform_data, 387 .mfd_data = &timb_dma_platform_data,
388 .data_size = sizeof(timb_dma_platform_data),
389 }, 388 },
390 { 389 {
391 .name = "timb-uart", 390 .name = "timb-uart",
@@ -396,43 +395,37 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
396 .name = "xiic-i2c", 395 .name = "xiic-i2c",
397 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 396 .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
398 .resources = timberdale_xiic_resources, 397 .resources = timberdale_xiic_resources,
399 .platform_data = &timberdale_xiic_platform_data, 398 .mfd_data = &timberdale_xiic_platform_data,
400 .data_size = sizeof(timberdale_xiic_platform_data),
401 }, 399 },
402 { 400 {
403 .name = "timb-gpio", 401 .name = "timb-gpio",
404 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 402 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
405 .resources = timberdale_gpio_resources, 403 .resources = timberdale_gpio_resources,
406 .platform_data = &timberdale_gpio_platform_data, 404 .mfd_data = &timberdale_gpio_platform_data,
407 .data_size = sizeof(timberdale_gpio_platform_data),
408 }, 405 },
409 { 406 {
410 .name = "timb-video", 407 .name = "timb-video",
411 .num_resources = ARRAY_SIZE(timberdale_video_resources), 408 .num_resources = ARRAY_SIZE(timberdale_video_resources),
412 .resources = timberdale_video_resources, 409 .resources = timberdale_video_resources,
413 .platform_data = &timberdale_video_platform_data, 410 .mfd_data = &timberdale_video_platform_data,
414 .data_size = sizeof(timberdale_video_platform_data),
415 }, 411 },
416 { 412 {
417 .name = "timb-radio", 413 .name = "timb-radio",
418 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 414 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
419 .resources = timberdale_radio_resources, 415 .resources = timberdale_radio_resources,
420 .platform_data = &timberdale_radio_platform_data, 416 .mfd_data = &timberdale_radio_platform_data,
421 .data_size = sizeof(timberdale_radio_platform_data),
422 }, 417 },
423 { 418 {
424 .name = "xilinx_spi", 419 .name = "xilinx_spi",
425 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 420 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
426 .resources = timberdale_spi_resources, 421 .resources = timberdale_spi_resources,
427 .platform_data = &timberdale_xspi_platform_data, 422 .mfd_data = &timberdale_xspi_platform_data,
428 .data_size = sizeof(timberdale_xspi_platform_data),
429 }, 423 },
430 { 424 {
431 .name = "ks8842", 425 .name = "ks8842",
432 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 426 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
433 .resources = timberdale_eth_resources, 427 .resources = timberdale_eth_resources,
434 .platform_data = &timberdale_ks8842_platform_data, 428 .mfd_data = &timberdale_ks8842_platform_data,
435 .data_size = sizeof(timberdale_ks8842_platform_data)
436 }, 429 },
437}; 430};
438 431
@@ -441,8 +434,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
441 .name = "timb-dma", 434 .name = "timb-dma",
442 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 435 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
443 .resources = timberdale_dma_resources, 436 .resources = timberdale_dma_resources,
444 .platform_data = &timb_dma_platform_data, 437 .mfd_data = &timb_dma_platform_data,
445 .data_size = sizeof(timb_dma_platform_data),
446 }, 438 },
447 { 439 {
448 .name = "timb-uart", 440 .name = "timb-uart",
@@ -458,15 +450,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
458 .name = "xiic-i2c", 450 .name = "xiic-i2c",
459 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 451 .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
460 .resources = timberdale_xiic_resources, 452 .resources = timberdale_xiic_resources,
461 .platform_data = &timberdale_xiic_platform_data, 453 .mfd_data = &timberdale_xiic_platform_data,
462 .data_size = sizeof(timberdale_xiic_platform_data),
463 }, 454 },
464 { 455 {
465 .name = "timb-gpio", 456 .name = "timb-gpio",
466 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 457 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
467 .resources = timberdale_gpio_resources, 458 .resources = timberdale_gpio_resources,
468 .platform_data = &timberdale_gpio_platform_data, 459 .mfd_data = &timberdale_gpio_platform_data,
469 .data_size = sizeof(timberdale_gpio_platform_data),
470 }, 460 },
471 { 461 {
472 .name = "timb-mlogicore", 462 .name = "timb-mlogicore",
@@ -477,29 +467,25 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
477 .name = "timb-video", 467 .name = "timb-video",
478 .num_resources = ARRAY_SIZE(timberdale_video_resources), 468 .num_resources = ARRAY_SIZE(timberdale_video_resources),
479 .resources = timberdale_video_resources, 469 .resources = timberdale_video_resources,
480 .platform_data = &timberdale_video_platform_data, 470 .mfd_data = &timberdale_video_platform_data,
481 .data_size = sizeof(timberdale_video_platform_data),
482 }, 471 },
483 { 472 {
484 .name = "timb-radio", 473 .name = "timb-radio",
485 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 474 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
486 .resources = timberdale_radio_resources, 475 .resources = timberdale_radio_resources,
487 .platform_data = &timberdale_radio_platform_data, 476 .mfd_data = &timberdale_radio_platform_data,
488 .data_size = sizeof(timberdale_radio_platform_data),
489 }, 477 },
490 { 478 {
491 .name = "xilinx_spi", 479 .name = "xilinx_spi",
492 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 480 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
493 .resources = timberdale_spi_resources, 481 .resources = timberdale_spi_resources,
494 .platform_data = &timberdale_xspi_platform_data, 482 .mfd_data = &timberdale_xspi_platform_data,
495 .data_size = sizeof(timberdale_xspi_platform_data),
496 }, 483 },
497 { 484 {
498 .name = "ks8842", 485 .name = "ks8842",
499 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 486 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
500 .resources = timberdale_eth_resources, 487 .resources = timberdale_eth_resources,
501 .platform_data = &timberdale_ks8842_platform_data, 488 .mfd_data = &timberdale_ks8842_platform_data,
502 .data_size = sizeof(timberdale_ks8842_platform_data)
503 }, 489 },
504}; 490};
505 491
@@ -508,8 +494,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
508 .name = "timb-dma", 494 .name = "timb-dma",
509 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 495 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
510 .resources = timberdale_dma_resources, 496 .resources = timberdale_dma_resources,
511 .platform_data = &timb_dma_platform_data, 497 .mfd_data = &timb_dma_platform_data,
512 .data_size = sizeof(timb_dma_platform_data),
513 }, 498 },
514 { 499 {
515 .name = "timb-uart", 500 .name = "timb-uart",
@@ -520,36 +505,31 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
520 .name = "xiic-i2c", 505 .name = "xiic-i2c",
521 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 506 .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
522 .resources = timberdale_xiic_resources, 507 .resources = timberdale_xiic_resources,
523 .platform_data = &timberdale_xiic_platform_data, 508 .mfd_data = &timberdale_xiic_platform_data,
524 .data_size = sizeof(timberdale_xiic_platform_data),
525 }, 509 },
526 { 510 {
527 .name = "timb-gpio", 511 .name = "timb-gpio",
528 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 512 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
529 .resources = timberdale_gpio_resources, 513 .resources = timberdale_gpio_resources,
530 .platform_data = &timberdale_gpio_platform_data, 514 .mfd_data = &timberdale_gpio_platform_data,
531 .data_size = sizeof(timberdale_gpio_platform_data),
532 }, 515 },
533 { 516 {
534 .name = "timb-video", 517 .name = "timb-video",
535 .num_resources = ARRAY_SIZE(timberdale_video_resources), 518 .num_resources = ARRAY_SIZE(timberdale_video_resources),
536 .resources = timberdale_video_resources, 519 .resources = timberdale_video_resources,
537 .platform_data = &timberdale_video_platform_data, 520 .mfd_data = &timberdale_video_platform_data,
538 .data_size = sizeof(timberdale_video_platform_data),
539 }, 521 },
540 { 522 {
541 .name = "timb-radio", 523 .name = "timb-radio",
542 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 524 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
543 .resources = timberdale_radio_resources, 525 .resources = timberdale_radio_resources,
544 .platform_data = &timberdale_radio_platform_data, 526 .mfd_data = &timberdale_radio_platform_data,
545 .data_size = sizeof(timberdale_radio_platform_data),
546 }, 527 },
547 { 528 {
548 .name = "xilinx_spi", 529 .name = "xilinx_spi",
549 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 530 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
550 .resources = timberdale_spi_resources, 531 .resources = timberdale_spi_resources,
551 .platform_data = &timberdale_xspi_platform_data, 532 .mfd_data = &timberdale_xspi_platform_data,
552 .data_size = sizeof(timberdale_xspi_platform_data),
553 }, 533 },
554}; 534};
555 535
@@ -558,8 +538,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
558 .name = "timb-dma", 538 .name = "timb-dma",
559 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 539 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
560 .resources = timberdale_dma_resources, 540 .resources = timberdale_dma_resources,
561 .platform_data = &timb_dma_platform_data, 541 .mfd_data = &timb_dma_platform_data,
562 .data_size = sizeof(timb_dma_platform_data),
563 }, 542 },
564 { 543 {
565 .name = "timb-uart", 544 .name = "timb-uart",
@@ -570,43 +549,37 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
570 .name = "ocores-i2c", 549 .name = "ocores-i2c",
571 .num_resources = ARRAY_SIZE(timberdale_ocores_resources), 550 .num_resources = ARRAY_SIZE(timberdale_ocores_resources),
572 .resources = timberdale_ocores_resources, 551 .resources = timberdale_ocores_resources,
573 .platform_data = &timberdale_ocores_platform_data, 552 .mfd_data = &timberdale_ocores_platform_data,
574 .data_size = sizeof(timberdale_ocores_platform_data),
575 }, 553 },
576 { 554 {
577 .name = "timb-gpio", 555 .name = "timb-gpio",
578 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 556 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
579 .resources = timberdale_gpio_resources, 557 .resources = timberdale_gpio_resources,
580 .platform_data = &timberdale_gpio_platform_data, 558 .mfd_data = &timberdale_gpio_platform_data,
581 .data_size = sizeof(timberdale_gpio_platform_data),
582 }, 559 },
583 { 560 {
584 .name = "timb-video", 561 .name = "timb-video",
585 .num_resources = ARRAY_SIZE(timberdale_video_resources), 562 .num_resources = ARRAY_SIZE(timberdale_video_resources),
586 .resources = timberdale_video_resources, 563 .resources = timberdale_video_resources,
587 .platform_data = &timberdale_video_platform_data, 564 .mfd_data = &timberdale_video_platform_data,
588 .data_size = sizeof(timberdale_video_platform_data),
589 }, 565 },
590 { 566 {
591 .name = "timb-radio", 567 .name = "timb-radio",
592 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 568 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
593 .resources = timberdale_radio_resources, 569 .resources = timberdale_radio_resources,
594 .platform_data = &timberdale_radio_platform_data, 570 .mfd_data = &timberdale_radio_platform_data,
595 .data_size = sizeof(timberdale_radio_platform_data),
596 }, 571 },
597 { 572 {
598 .name = "xilinx_spi", 573 .name = "xilinx_spi",
599 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 574 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
600 .resources = timberdale_spi_resources, 575 .resources = timberdale_spi_resources,
601 .platform_data = &timberdale_xspi_platform_data, 576 .mfd_data = &timberdale_xspi_platform_data,
602 .data_size = sizeof(timberdale_xspi_platform_data),
603 }, 577 },
604 { 578 {
605 .name = "ks8842", 579 .name = "ks8842",
606 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 580 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
607 .resources = timberdale_eth_resources, 581 .resources = timberdale_eth_resources,
608 .platform_data = &timberdale_ks8842_platform_data, 582 .mfd_data = &timberdale_ks8842_platform_data,
609 .data_size = sizeof(timberdale_ks8842_platform_data)
610 }, 583 },
611}; 584};
612 585
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
new file mode 100644
index 000000000000..46d8205646b6
--- /dev/null
+++ b/drivers/mfd/tps6105x.c
@@ -0,0 +1,246 @@
1/*
2 * Core driver for TPS61050/61052 boost converters, used for while LED
3 * driving, audio power amplification, white LED flash, and generic
4 * boost conversion. Additionally it provides a 1-bit GPIO pin (out or in)
5 * and a flash synchronization pin to synchronize flash events when used as
6 * flashgun.
7 *
8 * Copyright (C) 2011 ST-Ericsson SA
9 * Written on behalf of Linaro for ST-Ericsson
10 *
11 * Author: Linus Walleij <linus.walleij@linaro.org>
12 *
13 * License terms: GNU General Public License (GPL) version 2
14 */
15
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/i2c.h>
19#include <linux/mutex.h>
20#include <linux/gpio.h>
21#include <linux/spinlock.h>
22#include <linux/slab.h>
23#include <linux/err.h>
24#include <linux/regulator/driver.h>
25#include <linux/mfd/core.h>
26#include <linux/mfd/tps6105x.h>
27
28int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value)
29{
30 int ret;
31
32 ret = mutex_lock_interruptible(&tps6105x->lock);
33 if (ret)
34 return ret;
35 ret = i2c_smbus_write_byte_data(tps6105x->client, reg, value);
36 mutex_unlock(&tps6105x->lock);
37 if (ret < 0)
38 return ret;
39
40 return 0;
41}
42EXPORT_SYMBOL(tps6105x_set);
43
44int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf)
45{
46 int ret;
47
48 ret = mutex_lock_interruptible(&tps6105x->lock);
49 if (ret)
50 return ret;
51 ret = i2c_smbus_read_byte_data(tps6105x->client, reg);
52 mutex_unlock(&tps6105x->lock);
53 if (ret < 0)
54 return ret;
55
56 *buf = ret;
57 return 0;
58}
59EXPORT_SYMBOL(tps6105x_get);
60
61/*
62 * Masks off the bits in the mask and sets the bits in the bitvalues
63 * parameter in one atomic operation
64 */
65int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg,
66 u8 bitmask, u8 bitvalues)
67{
68 int ret;
69 u8 regval;
70
71 ret = mutex_lock_interruptible(&tps6105x->lock);
72 if (ret)
73 return ret;
74 ret = i2c_smbus_read_byte_data(tps6105x->client, reg);
75 if (ret < 0)
76 goto fail;
77 regval = ret;
78 regval = (~bitmask & regval) | (bitmask & bitvalues);
79 ret = i2c_smbus_write_byte_data(tps6105x->client, reg, regval);
80fail:
81 mutex_unlock(&tps6105x->lock);
82 if (ret < 0)
83 return ret;
84
85 return 0;
86}
87EXPORT_SYMBOL(tps6105x_mask_and_set);
88
89static int __devinit tps6105x_startup(struct tps6105x *tps6105x)
90{
91 int ret;
92 u8 regval;
93
94 ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
95 if (ret)
96 return ret;
97 switch (regval >> TPS6105X_REG0_MODE_SHIFT) {
98 case TPS6105X_REG0_MODE_SHUTDOWN:
99 dev_info(&tps6105x->client->dev,
100 "TPS6105x found in SHUTDOWN mode\n");
101 break;
102 case TPS6105X_REG0_MODE_TORCH:
103 dev_info(&tps6105x->client->dev,
104 "TPS6105x found in TORCH mode\n");
105 break;
106 case TPS6105X_REG0_MODE_TORCH_FLASH:
107 dev_info(&tps6105x->client->dev,
108 "TPS6105x found in FLASH mode\n");
109 break;
110 case TPS6105X_REG0_MODE_VOLTAGE:
111 dev_info(&tps6105x->client->dev,
112 "TPS6105x found in VOLTAGE mode\n");
113 break;
114 default:
115 break;
116 }
117
118 return ret;
119}
120
121/*
122 * MFD cells - we have one cell which is selected operation
123 * mode, and we always have a GPIO cell.
124 */
125static struct mfd_cell tps6105x_cells[] = {
126 {
127 /* name will be runtime assigned */
128 .id = -1,
129 },
130 {
131 .name = "tps6105x-gpio",
132 .id = -1,
133 },
134};
135
136static int __devinit tps6105x_probe(struct i2c_client *client,
137 const struct i2c_device_id *id)
138{
139 struct tps6105x *tps6105x;
140 struct tps6105x_platform_data *pdata;
141 int ret;
142 int i;
143
144 tps6105x = kmalloc(sizeof(*tps6105x), GFP_KERNEL);
145 if (!tps6105x)
146 return -ENOMEM;
147
148 i2c_set_clientdata(client, tps6105x);
149 tps6105x->client = client;
150 pdata = client->dev.platform_data;
151 tps6105x->pdata = pdata;
152 mutex_init(&tps6105x->lock);
153
154 ret = tps6105x_startup(tps6105x);
155 if (ret) {
156 dev_err(&client->dev, "chip initialization failed\n");
157 goto fail;
158 }
159
160 /* Remove warning texts when you implement new cell drivers */
161 switch (pdata->mode) {
162 case TPS6105X_MODE_SHUTDOWN:
163 dev_info(&client->dev,
164 "present, not used for anything, only GPIO\n");
165 break;
166 case TPS6105X_MODE_TORCH:
167 tps6105x_cells[0].name = "tps6105x-leds";
168 dev_warn(&client->dev,
169 "torch mode is unsupported\n");
170 break;
171 case TPS6105X_MODE_TORCH_FLASH:
172 tps6105x_cells[0].name = "tps6105x-flash";
173 dev_warn(&client->dev,
174 "flash mode is unsupported\n");
175 break;
176 case TPS6105X_MODE_VOLTAGE:
177 tps6105x_cells[0].name ="tps6105x-regulator";
178 break;
179 default:
180 break;
181 }
182
183 /* Set up and register the platform devices. */
184 for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) {
185 /* One state holder for all drivers, this is simple */
186 tps6105x_cells[i].mfd_data = tps6105x;
187 }
188
189 ret = mfd_add_devices(&client->dev, 0, tps6105x_cells,
190 ARRAY_SIZE(tps6105x_cells), NULL, 0);
191 if (ret)
192 goto fail;
193
194 return 0;
195
196fail:
197 kfree(tps6105x);
198 return ret;
199}
200
201static int __devexit tps6105x_remove(struct i2c_client *client)
202{
203 struct tps6105x *tps6105x = i2c_get_clientdata(client);
204
205 mfd_remove_devices(&client->dev);
206
207 /* Put chip in shutdown mode */
208 tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
209 TPS6105X_REG0_MODE_MASK,
210 TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);
211
212 kfree(tps6105x);
213 return 0;
214}
215
216static const struct i2c_device_id tps6105x_id[] = {
217 { "tps61050", 0 },
218 { "tps61052", 0 },
219 { }
220};
221MODULE_DEVICE_TABLE(i2c, tps6105x_id);
222
223static struct i2c_driver tps6105x_driver = {
224 .driver = {
225 .name = "tps6105x",
226 },
227 .probe = tps6105x_probe,
228 .remove = __devexit_p(tps6105x_remove),
229 .id_table = tps6105x_id,
230};
231
232static int __init tps6105x_init(void)
233{
234 return i2c_add_driver(&tps6105x_driver);
235}
236subsys_initcall(tps6105x_init);
237
238static void __exit tps6105x_exit(void)
239{
240 i2c_del_driver(&tps6105x_driver);
241}
242module_exit(tps6105x_exit);
243
244MODULE_AUTHOR("Linus Walleij");
245MODULE_DESCRIPTION("TPS6105x White LED Boost Converter Driver");
246MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index e9018d1394ee..0aa9186aec19 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -288,12 +288,10 @@ static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset,
288 return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask); 288 return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask);
289} 289}
290 290
291static void tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base) 291static int tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base)
292{ 292{
293 int ret;
294
295 if (!gpio_base) 293 if (!gpio_base)
296 return; 294 return 0;
297 295
298 tps6586x->gpio.owner = THIS_MODULE; 296 tps6586x->gpio.owner = THIS_MODULE;
299 tps6586x->gpio.label = tps6586x->client->name; 297 tps6586x->gpio.label = tps6586x->client->name;
@@ -307,9 +305,7 @@ static void tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base)
307 tps6586x->gpio.set = tps6586x_gpio_set; 305 tps6586x->gpio.set = tps6586x_gpio_set;
308 tps6586x->gpio.get = tps6586x_gpio_get; 306 tps6586x->gpio.get = tps6586x_gpio_get;
309 307
310 ret = gpiochip_add(&tps6586x->gpio); 308 return gpiochip_add(&tps6586x->gpio);
311 if (ret)
312 dev_warn(tps6586x->dev, "GPIO registration failed: %d\n", ret);
313} 309}
314 310
315static int __remove_subdev(struct device *dev, void *unused) 311static int __remove_subdev(struct device *dev, void *unused)
@@ -517,17 +513,28 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
517 } 513 }
518 } 514 }
519 515
516 ret = tps6586x_gpio_init(tps6586x, pdata->gpio_base);
517 if (ret) {
518 dev_err(&client->dev, "GPIO registration failed: %d\n", ret);
519 goto err_gpio_init;
520 }
521
520 ret = tps6586x_add_subdevs(tps6586x, pdata); 522 ret = tps6586x_add_subdevs(tps6586x, pdata);
521 if (ret) { 523 if (ret) {
522 dev_err(&client->dev, "add devices failed: %d\n", ret); 524 dev_err(&client->dev, "add devices failed: %d\n", ret);
523 goto err_add_devs; 525 goto err_add_devs;
524 } 526 }
525 527
526 tps6586x_gpio_init(tps6586x, pdata->gpio_base);
527
528 return 0; 528 return 0;
529 529
530err_add_devs: 530err_add_devs:
531 if (pdata->gpio_base) {
532 ret = gpiochip_remove(&tps6586x->gpio);
533 if (ret)
534 dev_err(&client->dev, "Can't remove gpio chip: %d\n",
535 ret);
536 }
537err_gpio_init:
531 if (client->irq) 538 if (client->irq)
532 free_irq(client->irq, tps6586x); 539 free_irq(client->irq, tps6586x);
533err_irq_init: 540err_irq_init:
@@ -587,4 +594,3 @@ module_exit(tps6586x_exit);
587MODULE_DESCRIPTION("TPS6586X core driver"); 594MODULE_DESCRIPTION("TPS6586X core driver");
588MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); 595MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
589MODULE_LICENSE("GPL"); 596MODULE_LICENSE("GPL");
590
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index a35fa7dcbf53..960b5bed7f52 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -721,13 +721,13 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
721 721
722 } 722 }
723 723
724 if (twl_has_watchdog()) { 724 if (twl_has_watchdog() && twl_class_is_4030()) {
725 child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); 725 child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
726 if (IS_ERR(child)) 726 if (IS_ERR(child))
727 return PTR_ERR(child); 727 return PTR_ERR(child);
728 } 728 }
729 729
730 if (twl_has_pwrbutton()) { 730 if (twl_has_pwrbutton() && twl_class_is_4030()) {
731 child = add_child(1, "twl4030_pwrbutton", 731 child = add_child(1, "twl4030_pwrbutton",
732 NULL, 0, true, pdata->irq_base + 8 + 0, 0); 732 NULL, 0, true, pdata->irq_base + 8 + 0, 0);
733 if (IS_ERR(child)) 733 if (IS_ERR(child))
@@ -864,6 +864,10 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
864 child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3); 864 child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3);
865 if (IS_ERR(child)) 865 if (IS_ERR(child))
866 return PTR_ERR(child); 866 return PTR_ERR(child);
867
868 child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg);
869 if (IS_ERR(child))
870 return PTR_ERR(child);
867 } 871 }
868 872
869 if (twl_has_bci() && pdata->bci && 873 if (twl_has_bci() && pdata->bci &&
diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
index 9a4b196d6deb..c02fded316c9 100644
--- a/drivers/mfd/twl4030-codec.c
+++ b/drivers/mfd/twl4030-codec.c
@@ -208,15 +208,13 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
208 if (pdata->audio) { 208 if (pdata->audio) {
209 cell = &codec->cells[childs]; 209 cell = &codec->cells[childs];
210 cell->name = "twl4030-codec"; 210 cell->name = "twl4030-codec";
211 cell->platform_data = pdata->audio; 211 cell->mfd_data = pdata->audio;
212 cell->data_size = sizeof(*pdata->audio);
213 childs++; 212 childs++;
214 } 213 }
215 if (pdata->vibra) { 214 if (pdata->vibra) {
216 cell = &codec->cells[childs]; 215 cell = &codec->cells[childs];
217 cell->name = "twl4030-vibra"; 216 cell->name = "twl4030-vibra";
218 cell->platform_data = pdata->vibra; 217 cell->mfd_data = pdata->vibra;
219 cell->data_size = sizeof(*pdata->vibra);
220 childs++; 218 childs++;
221 } 219 }
222 220
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
new file mode 100644
index 000000000000..3941ddcf15fe
--- /dev/null
+++ b/drivers/mfd/twl4030-madc.c
@@ -0,0 +1,802 @@
1/*
2 *
3 * TWL4030 MADC module driver-This driver monitors the real time
4 * conversion of analog signals like battery temperature,
5 * battery type, battery level etc.
6 *
7 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
8 * J Keerthy <j-keerthy@ti.com>
9 *
10 * Based on twl4030-madc.c
11 * Copyright (C) 2008 Nokia Corporation
12 * Mikko Ylinen <mikko.k.ylinen@nokia.com>
13 *
14 * Amit Kucheria <amit.kucheria@canonical.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * version 2 as published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * 02110-1301 USA
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/device.h>
34#include <linux/interrupt.h>
35#include <linux/kernel.h>
36#include <linux/delay.h>
37#include <linux/platform_device.h>
38#include <linux/slab.h>
39#include <linux/i2c/twl.h>
40#include <linux/i2c/twl4030-madc.h>
41#include <linux/module.h>
42#include <linux/stddef.h>
43#include <linux/mutex.h>
44#include <linux/bitops.h>
45#include <linux/jiffies.h>
46#include <linux/types.h>
47#include <linux/gfp.h>
48#include <linux/err.h>
49
50/*
51 * struct twl4030_madc_data - a container for madc info
52 * @dev - pointer to device structure for madc
53 * @lock - mutex protecting this data structure
54 * @requests - Array of request struct corresponding to SW1, SW2 and RT
55 * @imr - Interrupt mask register of MADC
56 * @isr - Interrupt status register of MADC
57 */
58struct twl4030_madc_data {
59 struct device *dev;
60 struct mutex lock; /* mutex protecting this data structure */
61 struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
62 int imr;
63 int isr;
64};
65
66static struct twl4030_madc_data *twl4030_madc;
67
68struct twl4030_prescale_divider_ratios {
69 s16 numerator;
70 s16 denominator;
71};
72
73static const struct twl4030_prescale_divider_ratios
74twl4030_divider_ratios[16] = {
75 {1, 1}, /* CHANNEL 0 No Prescaler */
76 {1, 1}, /* CHANNEL 1 No Prescaler */
77 {6, 10}, /* CHANNEL 2 */
78 {6, 10}, /* CHANNEL 3 */
79 {6, 10}, /* CHANNEL 4 */
80 {6, 10}, /* CHANNEL 5 */
81 {6, 10}, /* CHANNEL 6 */
82 {6, 10}, /* CHANNEL 7 */
83 {3, 14}, /* CHANNEL 8 */
84 {1, 3}, /* CHANNEL 9 */
85 {1, 1}, /* CHANNEL 10 No Prescaler */
86 {15, 100}, /* CHANNEL 11 */
87 {1, 4}, /* CHANNEL 12 */
88 {1, 1}, /* CHANNEL 13 Reserved channels */
89 {1, 1}, /* CHANNEL 14 Reseved channels */
90 {5, 11}, /* CHANNEL 15 */
91};
92
93
94/*
95 * Conversion table from -3 to 55 degree Celcius
96 */
97static int therm_tbl[] = {
9830800, 29500, 28300, 27100,
9926000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
10017200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
10111600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
1028020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
1035640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
1044040, 3910, 3790, 3670, 3550
105};
106
107/*
108 * Structure containing the registers
109 * of different conversion methods supported by MADC.
110 * Hardware or RT real time conversion request initiated by external host
111 * processor for RT Signal conversions.
112 * External host processors can also request for non RT conversions
113 * SW1 and SW2 software conversions also called asynchronous or GPC request.
114 */
115static
116const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
117 [TWL4030_MADC_RT] = {
118 .sel = TWL4030_MADC_RTSELECT_LSB,
119 .avg = TWL4030_MADC_RTAVERAGE_LSB,
120 .rbase = TWL4030_MADC_RTCH0_LSB,
121 },
122 [TWL4030_MADC_SW1] = {
123 .sel = TWL4030_MADC_SW1SELECT_LSB,
124 .avg = TWL4030_MADC_SW1AVERAGE_LSB,
125 .rbase = TWL4030_MADC_GPCH0_LSB,
126 .ctrl = TWL4030_MADC_CTRL_SW1,
127 },
128 [TWL4030_MADC_SW2] = {
129 .sel = TWL4030_MADC_SW2SELECT_LSB,
130 .avg = TWL4030_MADC_SW2AVERAGE_LSB,
131 .rbase = TWL4030_MADC_GPCH0_LSB,
132 .ctrl = TWL4030_MADC_CTRL_SW2,
133 },
134};
135
136/*
137 * Function to read a particular channel value.
138 * @madc - pointer to struct twl4030_madc_data
139 * @reg - lsb of ADC Channel
140 * If the i2c read fails it returns an error else returns 0.
141 */
142static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
143{
144 u8 msb, lsb;
145 int ret;
146 /*
147 * For each ADC channel, we have MSB and LSB register pair. MSB address
148 * is always LSB address+1. reg parameter is the address of LSB register
149 */
150 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1);
151 if (ret) {
152 dev_err(madc->dev, "unable to read MSB register 0x%X\n",
153 reg + 1);
154 return ret;
155 }
156 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg);
157 if (ret) {
158 dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg);
159 return ret;
160 }
161
162 return (int)(((msb << 8) | lsb) >> 6);
163}
164
165/*
166 * Return battery temperature
167 * Or < 0 on failure.
168 */
169static int twl4030battery_temperature(int raw_volt)
170{
171 u8 val;
172 int temp, curr, volt, res, ret;
173
174 volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
175 /* Getting and calculating the supply current in micro ampers */
176 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
177 REG_BCICTL2);
178 if (ret < 0)
179 return ret;
180 curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
181 /* Getting and calculating the thermistor resistance in ohms */
182 res = volt * 1000 / curr;
183 /* calculating temperature */
184 for (temp = 58; temp >= 0; temp--) {
185 int actual = therm_tbl[temp];
186
187 if ((actual - res) >= 0)
188 break;
189 }
190
191 return temp + 1;
192}
193
194static int twl4030battery_current(int raw_volt)
195{
196 int ret;
197 u8 val;
198
199 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
200 TWL4030_BCI_BCICTL1);
201 if (ret)
202 return ret;
203 if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
204 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
205 else /* slope of 0.88 mV/mA */
206 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
207}
208/*
209 * Function to read channel values
210 * @madc - pointer to twl4030_madc_data struct
211 * @reg_base - Base address of the first channel
212 * @Channels - 16 bit bitmap. If the bit is set, channel value is read
213 * @buf - The channel values are stored here. if read fails error
214 * value is stored
215 * Returns the number of successfully read channels.
216 */
217static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
218 u8 reg_base, unsigned
219 long channels, int *buf)
220{
221 int count = 0, count_req = 0, i;
222 u8 reg;
223
224 for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
225 reg = reg_base + 2 * i;
226 buf[i] = twl4030_madc_channel_raw_read(madc, reg);
227 if (buf[i] < 0) {
228 dev_err(madc->dev,
229 "Unable to read register 0x%X\n", reg);
230 count_req++;
231 continue;
232 }
233 switch (i) {
234 case 10:
235 buf[i] = twl4030battery_current(buf[i]);
236 if (buf[i] < 0) {
237 dev_err(madc->dev, "err reading current\n");
238 count_req++;
239 } else {
240 count++;
241 buf[i] = buf[i] - 750;
242 }
243 break;
244 case 1:
245 buf[i] = twl4030battery_temperature(buf[i]);
246 if (buf[i] < 0) {
247 dev_err(madc->dev, "err reading temperature\n");
248 count_req++;
249 } else {
250 buf[i] -= 3;
251 count++;
252 }
253 break;
254 default:
255 count++;
256 /* Analog Input (V) = conv_result * step_size / R
257 * conv_result = decimal value of 10-bit conversion
258 * result
259 * step size = 1.5 / (2 ^ 10 -1)
260 * R = Prescaler ratio for input channels.
261 * Result given in mV hence multiplied by 1000.
262 */
263 buf[i] = (buf[i] * 3 * 1000 *
264 twl4030_divider_ratios[i].denominator)
265 / (2 * 1023 *
266 twl4030_divider_ratios[i].numerator);
267 }
268 }
269 if (count_req)
270 dev_err(madc->dev, "%d channel conversion failed\n", count_req);
271
272 return count;
273}
274
275/*
276 * Enables irq.
277 * @madc - pointer to twl4030_madc_data struct
278 * @id - irq number to be enabled
279 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
280 * corresponding to RT, SW1, SW2 conversion requests.
281 * If the i2c read fails it returns an error else returns 0.
282 */
283static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
284{
285 u8 val;
286 int ret;
287
288 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
289 if (ret) {
290 dev_err(madc->dev, "unable to read imr register 0x%X\n",
291 madc->imr);
292 return ret;
293 }
294 val &= ~(1 << id);
295 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
296 if (ret) {
297 dev_err(madc->dev,
298 "unable to write imr register 0x%X\n", madc->imr);
299 return ret;
300
301 }
302
303 return 0;
304}
305
306/*
307 * Disables irq.
308 * @madc - pointer to twl4030_madc_data struct
309 * @id - irq number to be disabled
310 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
311 * corresponding to RT, SW1, SW2 conversion requests.
312 * Returns error if i2c read/write fails.
313 */
314static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
315{
316 u8 val;
317 int ret;
318
319 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
320 if (ret) {
321 dev_err(madc->dev, "unable to read imr register 0x%X\n",
322 madc->imr);
323 return ret;
324 }
325 val |= (1 << id);
326 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
327 if (ret) {
328 dev_err(madc->dev,
329 "unable to write imr register 0x%X\n", madc->imr);
330 return ret;
331 }
332
333 return 0;
334}
335
336static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
337{
338 struct twl4030_madc_data *madc = _madc;
339 const struct twl4030_madc_conversion_method *method;
340 u8 isr_val, imr_val;
341 int i, len, ret;
342 struct twl4030_madc_request *r;
343
344 mutex_lock(&madc->lock);
345 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
346 if (ret) {
347 dev_err(madc->dev, "unable to read isr register 0x%X\n",
348 madc->isr);
349 goto err_i2c;
350 }
351 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
352 if (ret) {
353 dev_err(madc->dev, "unable to read imr register 0x%X\n",
354 madc->imr);
355 goto err_i2c;
356 }
357 isr_val &= ~imr_val;
358 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
359 if (!(isr_val & (1 << i)))
360 continue;
361 ret = twl4030_madc_disable_irq(madc, i);
362 if (ret < 0)
363 dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
364 madc->requests[i].result_pending = 1;
365 }
366 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
367 r = &madc->requests[i];
368 /* No pending results for this method, move to next one */
369 if (!r->result_pending)
370 continue;
371 method = &twl4030_conversion_methods[r->method];
372 /* Read results */
373 len = twl4030_madc_read_channels(madc, method->rbase,
374 r->channels, r->rbuf);
375 /* Return results to caller */
376 if (r->func_cb != NULL) {
377 r->func_cb(len, r->channels, r->rbuf);
378 r->func_cb = NULL;
379 }
380 /* Free request */
381 r->result_pending = 0;
382 r->active = 0;
383 }
384 mutex_unlock(&madc->lock);
385
386 return IRQ_HANDLED;
387
388err_i2c:
389 /*
390 * In case of error check whichever request is active
391 * and service the same.
392 */
393 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
394 r = &madc->requests[i];
395 if (r->active == 0)
396 continue;
397 method = &twl4030_conversion_methods[r->method];
398 /* Read results */
399 len = twl4030_madc_read_channels(madc, method->rbase,
400 r->channels, r->rbuf);
401 /* Return results to caller */
402 if (r->func_cb != NULL) {
403 r->func_cb(len, r->channels, r->rbuf);
404 r->func_cb = NULL;
405 }
406 /* Free request */
407 r->result_pending = 0;
408 r->active = 0;
409 }
410 mutex_unlock(&madc->lock);
411
412 return IRQ_HANDLED;
413}
414
415static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
416 struct twl4030_madc_request *req)
417{
418 struct twl4030_madc_request *p;
419 int ret;
420
421 p = &madc->requests[req->method];
422 memcpy(p, req, sizeof(*req));
423 ret = twl4030_madc_enable_irq(madc, req->method);
424 if (ret < 0) {
425 dev_err(madc->dev, "enable irq failed!!\n");
426 return ret;
427 }
428
429 return 0;
430}
431
432/*
433 * Function which enables the madc conversion
434 * by writing to the control register.
435 * @madc - pointer to twl4030_madc_data struct
436 * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
437 * corresponding to RT SW1 or SW2 conversion methods.
438 * Returns 0 if succeeds else a negative error value
439 */
440static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
441 int conv_method)
442{
443 const struct twl4030_madc_conversion_method *method;
444 int ret = 0;
445 method = &twl4030_conversion_methods[conv_method];
446 switch (conv_method) {
447 case TWL4030_MADC_SW1:
448 case TWL4030_MADC_SW2:
449 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
450 TWL4030_MADC_SW_START, method->ctrl);
451 if (ret) {
452 dev_err(madc->dev,
453 "unable to write ctrl register 0x%X\n",
454 method->ctrl);
455 return ret;
456 }
457 break;
458 default:
459 break;
460 }
461
462 return 0;
463}
464
465/*
466 * Function that waits for conversion to be ready
467 * @madc - pointer to twl4030_madc_data struct
468 * @timeout_ms - timeout value in milliseconds
469 * @status_reg - ctrl register
470 * returns 0 if succeeds else a negative error value
471 */
472static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
473 unsigned int timeout_ms,
474 u8 status_reg)
475{
476 unsigned long timeout;
477 int ret;
478
479 timeout = jiffies + msecs_to_jiffies(timeout_ms);
480 do {
481 u8 reg;
482
483 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
484 if (ret) {
485 dev_err(madc->dev,
486 "unable to read status register 0x%X\n",
487 status_reg);
488 return ret;
489 }
490 if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
491 return 0;
492 usleep_range(500, 2000);
493 } while (!time_after(jiffies, timeout));
494 dev_err(madc->dev, "conversion timeout!\n");
495
496 return -EAGAIN;
497}
498
499/*
500 * An exported function which can be called from other kernel drivers.
501 * @req twl4030_madc_request structure
502 * req->rbuf will be filled with read values of channels based on the
503 * channel index. If a particular channel reading fails there will
504 * be a negative error value in the corresponding array element.
505 * returns 0 if succeeds else error value
506 */
507int twl4030_madc_conversion(struct twl4030_madc_request *req)
508{
509 const struct twl4030_madc_conversion_method *method;
510 u8 ch_msb, ch_lsb;
511 int ret;
512
513 if (!req)
514 return -EINVAL;
515 mutex_lock(&twl4030_madc->lock);
516 if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
517 ret = -EINVAL;
518 goto out;
519 }
520 /* Do we have a conversion request ongoing */
521 if (twl4030_madc->requests[req->method].active) {
522 ret = -EBUSY;
523 goto out;
524 }
525 ch_msb = (req->channels >> 8) & 0xff;
526 ch_lsb = req->channels & 0xff;
527 method = &twl4030_conversion_methods[req->method];
528 /* Select channels to be converted */
529 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
530 if (ret) {
531 dev_err(twl4030_madc->dev,
532 "unable to write sel register 0x%X\n", method->sel + 1);
533 return ret;
534 }
535 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
536 if (ret) {
537 dev_err(twl4030_madc->dev,
538 "unable to write sel register 0x%X\n", method->sel + 1);
539 return ret;
540 }
541 /* Select averaging for all channels if do_avg is set */
542 if (req->do_avg) {
543 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
544 ch_msb, method->avg + 1);
545 if (ret) {
546 dev_err(twl4030_madc->dev,
547 "unable to write avg register 0x%X\n",
548 method->avg + 1);
549 return ret;
550 }
551 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
552 ch_lsb, method->avg);
553 if (ret) {
554 dev_err(twl4030_madc->dev,
555 "unable to write sel reg 0x%X\n",
556 method->sel + 1);
557 return ret;
558 }
559 }
560 if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
561 ret = twl4030_madc_set_irq(twl4030_madc, req);
562 if (ret < 0)
563 goto out;
564 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
565 if (ret < 0)
566 goto out;
567 twl4030_madc->requests[req->method].active = 1;
568 ret = 0;
569 goto out;
570 }
571 /* With RT method we should not be here anymore */
572 if (req->method == TWL4030_MADC_RT) {
573 ret = -EINVAL;
574 goto out;
575 }
576 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
577 if (ret < 0)
578 goto out;
579 twl4030_madc->requests[req->method].active = 1;
580 /* Wait until conversion is ready (ctrl register returns EOC) */
581 ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
582 if (ret) {
583 twl4030_madc->requests[req->method].active = 0;
584 goto out;
585 }
586 ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
587 req->channels, req->rbuf);
588 twl4030_madc->requests[req->method].active = 0;
589
590out:
591 mutex_unlock(&twl4030_madc->lock);
592
593 return ret;
594}
595EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
596
597/*
598 * Return channel value
599 * Or < 0 on failure.
600 */
601int twl4030_get_madc_conversion(int channel_no)
602{
603 struct twl4030_madc_request req;
604 int temp = 0;
605 int ret;
606
607 req.channels = (1 << channel_no);
608 req.method = TWL4030_MADC_SW2;
609 req.active = 0;
610 req.func_cb = NULL;
611 ret = twl4030_madc_conversion(&req);
612 if (ret < 0)
613 return ret;
614 if (req.rbuf[channel_no] > 0)
615 temp = req.rbuf[channel_no];
616
617 return temp;
618}
619EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
620
621/*
622 * Function to enable or disable bias current for
623 * main battery type reading or temperature sensing
624 * @madc - pointer to twl4030_madc_data struct
625 * @chan - can be one of the two values
626 * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
627 * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
628 * sensing
629 * @on - enable or disable chan.
630 */
631static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
632 int chan, int on)
633{
634 int ret;
635 u8 regval;
636
637 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
638 &regval, TWL4030_BCI_BCICTL1);
639 if (ret) {
640 dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
641 TWL4030_BCI_BCICTL1);
642 return ret;
643 }
644 if (on)
645 regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
646 else
647 regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
648 ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
649 regval, TWL4030_BCI_BCICTL1);
650 if (ret) {
651 dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
652 TWL4030_BCI_BCICTL1);
653 return ret;
654 }
655
656 return 0;
657}
658
659/*
660 * Function that sets MADC software power on bit to enable MADC
661 * @madc - pointer to twl4030_madc_data struct
662 * @on - Enable or disable MADC software powen on bit.
663 * returns error if i2c read/write fails else 0
664 */
665static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
666{
667 u8 regval;
668 int ret;
669
670 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
671 &regval, TWL4030_MADC_CTRL1);
672 if (ret) {
673 dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
674 TWL4030_MADC_CTRL1);
675 return ret;
676 }
677 if (on)
678 regval |= TWL4030_MADC_MADCON;
679 else
680 regval &= ~TWL4030_MADC_MADCON;
681 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
682 if (ret) {
683 dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
684 TWL4030_MADC_CTRL1);
685 return ret;
686 }
687
688 return 0;
689}
690
691/*
692 * Initialize MADC and request for threaded irq
693 */
694static int __devinit twl4030_madc_probe(struct platform_device *pdev)
695{
696 struct twl4030_madc_data *madc;
697 struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
698 int ret;
699 u8 regval;
700
701 if (!pdata) {
702 dev_err(&pdev->dev, "platform_data not available\n");
703 return -EINVAL;
704 }
705 madc = kzalloc(sizeof(*madc), GFP_KERNEL);
706 if (!madc)
707 return -ENOMEM;
708
709 /*
710 * Phoenix provides 2 interrupt lines. The first one is connected to
711 * the OMAP. The other one can be connected to the other processor such
712 * as modem. Hence two separate ISR and IMR registers.
713 */
714 madc->imr = (pdata->irq_line == 1) ?
715 TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
716 madc->isr = (pdata->irq_line == 1) ?
717 TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
718 ret = twl4030_madc_set_power(madc, 1);
719 if (ret < 0)
720 goto err_power;
721 ret = twl4030_madc_set_current_generator(madc, 0, 1);
722 if (ret < 0)
723 goto err_current_generator;
724
725 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
726 &regval, TWL4030_BCI_BCICTL1);
727 if (ret) {
728 dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
729 TWL4030_BCI_BCICTL1);
730 goto err_i2c;
731 }
732 regval |= TWL4030_BCI_MESBAT;
733 ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
734 regval, TWL4030_BCI_BCICTL1);
735 if (ret) {
736 dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
737 TWL4030_BCI_BCICTL1);
738 goto err_i2c;
739 }
740 platform_set_drvdata(pdev, madc);
741 mutex_init(&madc->lock);
742 ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
743 twl4030_madc_threaded_irq_handler,
744 IRQF_TRIGGER_RISING, "twl4030_madc", madc);
745 if (ret) {
746 dev_dbg(&pdev->dev, "could not request irq\n");
747 goto err_irq;
748 }
749 twl4030_madc = madc;
750 return 0;
751err_irq:
752 platform_set_drvdata(pdev, NULL);
753err_i2c:
754 twl4030_madc_set_current_generator(madc, 0, 0);
755err_current_generator:
756 twl4030_madc_set_power(madc, 0);
757err_power:
758 kfree(madc);
759
760 return ret;
761}
762
763static int __devexit twl4030_madc_remove(struct platform_device *pdev)
764{
765 struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
766
767 free_irq(platform_get_irq(pdev, 0), madc);
768 platform_set_drvdata(pdev, NULL);
769 twl4030_madc_set_current_generator(madc, 0, 0);
770 twl4030_madc_set_power(madc, 0);
771 kfree(madc);
772
773 return 0;
774}
775
776static struct platform_driver twl4030_madc_driver = {
777 .probe = twl4030_madc_probe,
778 .remove = __exit_p(twl4030_madc_remove),
779 .driver = {
780 .name = "twl4030_madc",
781 .owner = THIS_MODULE,
782 },
783};
784
785static int __init twl4030_madc_init(void)
786{
787 return platform_driver_register(&twl4030_madc_driver);
788}
789
790module_init(twl4030_madc_init);
791
792static void __exit twl4030_madc_exit(void)
793{
794 platform_driver_unregister(&twl4030_madc_driver);
795}
796
797module_exit(twl4030_madc_exit);
798
799MODULE_DESCRIPTION("TWL4030 ADC driver");
800MODULE_LICENSE("GPL");
801MODULE_AUTHOR("J Keerthy");
802MODULE_ALIAS("platform:twl4030_madc");
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 92b85e28a15e..38ffbd50a0d2 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -60,6 +60,7 @@ static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x
60 input_report_abs(idev, ABS_X, x); 60 input_report_abs(idev, ABS_X, x);
61 input_report_abs(idev, ABS_Y, y); 61 input_report_abs(idev, ABS_Y, y);
62 input_report_abs(idev, ABS_PRESSURE, pressure); 62 input_report_abs(idev, ABS_PRESSURE, pressure);
63 input_report_key(idev, BTN_TOUCH, 1);
63 input_sync(idev); 64 input_sync(idev);
64} 65}
65 66
@@ -68,6 +69,7 @@ static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
68 struct input_dev *idev = ts->idev; 69 struct input_dev *idev = ts->idev;
69 70
70 input_report_abs(idev, ABS_PRESSURE, 0); 71 input_report_abs(idev, ABS_PRESSURE, 0);
72 input_report_key(idev, BTN_TOUCH, 0);
71 input_sync(idev); 73 input_sync(idev);
72} 74}
73 75
@@ -384,7 +386,8 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
384 idev->open = ucb1x00_ts_open; 386 idev->open = ucb1x00_ts_open;
385 idev->close = ucb1x00_ts_close; 387 idev->close = ucb1x00_ts_close;
386 388
387 __set_bit(EV_ABS, idev->evbit); 389 idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
390 idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
388 391
389 input_set_drvdata(idev, ts); 392 input_set_drvdata(idev, ts);
390 393
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c
index 348052aa5dbf..d698703dbd46 100644
--- a/drivers/mfd/vx855.c
+++ b/drivers/mfd/vx855.c
@@ -122,6 +122,7 @@ static struct pci_device_id vx855_pci_tbl[] = {
122 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, 122 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
123 { 0, } 123 { 0, }
124}; 124};
125MODULE_DEVICE_TABLE(pci, vx855_pci_tbl);
125 126
126static struct pci_driver vx855_pci_driver = { 127static struct pci_driver vx855_pci_driver = {
127 .name = "vx855", 128 .name = "vx855",
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
index d2ecc2435736..f76f6c798046 100644
--- a/drivers/mfd/wl1273-core.c
+++ b/drivers/mfd/wl1273-core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * MFD driver for wl1273 FM radio and audio codec submodules. 2 * MFD driver for wl1273 FM radio and audio codec submodules.
3 * 3 *
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2011 Nokia Corporation
5 * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com> 5 * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -31,6 +31,145 @@ static struct i2c_device_id wl1273_driver_id_table[] = {
31}; 31};
32MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table); 32MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
33 33
34static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
35{
36 struct i2c_client *client = core->client;
37 u8 b[2];
38 int r;
39
40 r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
41 if (r != 2) {
42 dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
43 return -EREMOTEIO;
44 }
45
46 *value = (u16)b[0] << 8 | b[1];
47
48 return 0;
49}
50
51static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
52{
53 struct i2c_client *client = core->client;
54 u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
55 int r;
56
57 r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
58 if (r) {
59 dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
60 return r;
61 }
62
63 return 0;
64}
65
66static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
67{
68 struct i2c_client *client = core->client;
69 struct i2c_msg msg;
70 int r;
71
72 msg.addr = client->addr;
73 msg.flags = 0;
74 msg.buf = data;
75 msg.len = len;
76
77 r = i2c_transfer(client->adapter, &msg, 1);
78 if (r != 1) {
79 dev_err(&client->dev, "%s: write error.\n", __func__);
80 return -EREMOTEIO;
81 }
82
83 return 0;
84}
85
86/**
87 * wl1273_fm_set_audio() - Set audio mode.
88 * @core: A pointer to the device struct.
89 * @new_mode: The new audio mode.
90 *
91 * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
92 */
93static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
94{
95 int r = 0;
96
97 if (core->mode == WL1273_MODE_OFF ||
98 core->mode == WL1273_MODE_SUSPENDED)
99 return -EPERM;
100
101 if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
102 r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
103 WL1273_PCM_DEF_MODE);
104 if (r)
105 goto out;
106
107 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
108 core->i2s_mode);
109 if (r)
110 goto out;
111
112 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
113 WL1273_AUDIO_ENABLE_I2S);
114 if (r)
115 goto out;
116
117 } else if (core->mode == WL1273_MODE_RX &&
118 new_mode == WL1273_AUDIO_ANALOG) {
119 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
120 WL1273_AUDIO_ENABLE_ANALOG);
121 if (r)
122 goto out;
123
124 } else if (core->mode == WL1273_MODE_TX &&
125 new_mode == WL1273_AUDIO_DIGITAL) {
126 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
127 core->i2s_mode);
128 if (r)
129 goto out;
130
131 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
132 WL1273_AUDIO_IO_SET_I2S);
133 if (r)
134 goto out;
135
136 } else if (core->mode == WL1273_MODE_TX &&
137 new_mode == WL1273_AUDIO_ANALOG) {
138 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
139 WL1273_AUDIO_IO_SET_ANALOG);
140 if (r)
141 goto out;
142 }
143
144 core->audio_mode = new_mode;
145out:
146 return r;
147}
148
149/**
150 * wl1273_fm_set_volume() - Set volume.
151 * @core: A pointer to the device struct.
152 * @volume: The new volume value.
153 */
154static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
155{
156 u16 val;
157 int r;
158
159 if (volume > WL1273_MAX_VOLUME)
160 return -EINVAL;
161
162 if (core->volume == volume)
163 return 0;
164
165 r = wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume);
166 if (r)
167 return r;
168
169 core->volume = volume;
170 return 0;
171}
172
34static int wl1273_core_remove(struct i2c_client *client) 173static int wl1273_core_remove(struct i2c_client *client)
35{ 174{
36 struct wl1273_core *core = i2c_get_clientdata(client); 175 struct wl1273_core *core = i2c_get_clientdata(client);
@@ -38,7 +177,6 @@ static int wl1273_core_remove(struct i2c_client *client)
38 dev_dbg(&client->dev, "%s\n", __func__); 177 dev_dbg(&client->dev, "%s\n", __func__);
39 178
40 mfd_remove_devices(&client->dev); 179 mfd_remove_devices(&client->dev);
41 i2c_set_clientdata(client, NULL);
42 kfree(core); 180 kfree(core);
43 181
44 return 0; 182 return 0;
@@ -79,17 +217,21 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
79 217
80 cell = &core->cells[children]; 218 cell = &core->cells[children];
81 cell->name = "wl1273_fm_radio"; 219 cell->name = "wl1273_fm_radio";
82 cell->platform_data = &core; 220 cell->mfd_data = &core;
83 cell->data_size = sizeof(core);
84 children++; 221 children++;
85 222
223 core->read = wl1273_fm_read_reg;
224 core->write = wl1273_fm_write_cmd;
225 core->write_data = wl1273_fm_write_data;
226 core->set_audio = wl1273_fm_set_audio;
227 core->set_volume = wl1273_fm_set_volume;
228
86 if (pdata->children & WL1273_CODEC_CHILD) { 229 if (pdata->children & WL1273_CODEC_CHILD) {
87 cell = &core->cells[children]; 230 cell = &core->cells[children];
88 231
89 dev_dbg(&client->dev, "%s: Have codec.\n", __func__); 232 dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
90 cell->name = "wl1273-codec"; 233 cell->name = "wl1273-codec";
91 cell->platform_data = &core; 234 cell->mfd_data = &core;
92 cell->data_size = sizeof(core);
93 children++; 235 children++;
94 } 236 }
95 237
@@ -104,7 +246,6 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
104 return 0; 246 return 0;
105 247
106err: 248err:
107 i2c_set_clientdata(client, NULL);
108 pdata->free_resources(); 249 pdata->free_resources();
109 kfree(core); 250 kfree(core);
110 251
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index 3853fa8e7cc2..a06cbc739716 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -51,17 +51,25 @@ static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
51 int bytes, void *src) 51 int bytes, void *src)
52{ 52{
53 struct i2c_client *i2c = wm831x->control_data; 53 struct i2c_client *i2c = wm831x->control_data;
54 unsigned char msg[bytes + 2]; 54 struct i2c_msg xfer[2];
55 int ret; 55 int ret;
56 56
57 reg = cpu_to_be16(reg); 57 reg = cpu_to_be16(reg);
58 memcpy(&msg[0], &reg, 2);
59 memcpy(&msg[2], src, bytes);
60 58
61 ret = i2c_master_send(i2c, msg, bytes + 2); 59 xfer[0].addr = i2c->addr;
60 xfer[0].flags = 0;
61 xfer[0].len = 2;
62 xfer[0].buf = (char *)&reg;
63
64 xfer[1].addr = i2c->addr;
65 xfer[1].flags = I2C_M_NOSTART;
66 xfer[1].len = bytes;
67 xfer[1].buf = (char *)src;
68
69 ret = i2c_transfer(i2c->adapter, xfer, 2);
62 if (ret < 0) 70 if (ret < 0)
63 return ret; 71 return ret;
64 if (ret < bytes + 2) 72 if (ret != 2)
65 return -EIO; 73 return -EIO;
66 74
67 return 0; 75 return 0;
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index f7192d438aab..a5cd17e18d09 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -26,15 +26,6 @@
26 26
27#include <linux/delay.h> 27#include <linux/delay.h>
28 28
29/*
30 * Since generic IRQs don't currently support interrupt controllers on
31 * interrupt driven buses we don't use genirq but instead provide an
32 * interface that looks very much like the standard ones. This leads
33 * to some bodges, including storing interrupt handler information in
34 * the static irq_data table we use to look up the data for individual
35 * interrupts, but hopefully won't last too long.
36 */
37
38struct wm831x_irq_data { 29struct wm831x_irq_data {
39 int primary; 30 int primary;
40 int reg; 31 int reg;
@@ -361,6 +352,10 @@ static void wm831x_irq_sync_unlock(struct irq_data *data)
361 /* If there's been a change in the mask write it back 352 /* If there's been a change in the mask write it back
362 * to the hardware. */ 353 * to the hardware. */
363 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { 354 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) {
355 dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n",
356 WM831X_INTERRUPT_STATUS_1_MASK + i,
357 wm831x->irq_masks_cur[i]);
358
364 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; 359 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i];
365 wm831x_reg_write(wm831x, 360 wm831x_reg_write(wm831x,
366 WM831X_INTERRUPT_STATUS_1_MASK + i, 361 WM831X_INTERRUPT_STATUS_1_MASK + i,
@@ -371,7 +366,7 @@ static void wm831x_irq_sync_unlock(struct irq_data *data)
371 mutex_unlock(&wm831x->irq_lock); 366 mutex_unlock(&wm831x->irq_lock);
372} 367}
373 368
374static void wm831x_irq_unmask(struct irq_data *data) 369static void wm831x_irq_enable(struct irq_data *data)
375{ 370{
376 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 371 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
377 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, 372 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
@@ -380,7 +375,7 @@ static void wm831x_irq_unmask(struct irq_data *data)
380 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 375 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
381} 376}
382 377
383static void wm831x_irq_mask(struct irq_data *data) 378static void wm831x_irq_disable(struct irq_data *data)
384{ 379{
385 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 380 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
386 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, 381 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
@@ -426,8 +421,8 @@ static struct irq_chip wm831x_irq_chip = {
426 .name = "wm831x", 421 .name = "wm831x",
427 .irq_bus_lock = wm831x_irq_lock, 422 .irq_bus_lock = wm831x_irq_lock,
428 .irq_bus_sync_unlock = wm831x_irq_sync_unlock, 423 .irq_bus_sync_unlock = wm831x_irq_sync_unlock,
429 .irq_mask = wm831x_irq_mask, 424 .irq_disable = wm831x_irq_disable,
430 .irq_unmask = wm831x_irq_unmask, 425 .irq_enable = wm831x_irq_enable,
431 .irq_set_type = wm831x_irq_set_type, 426 .irq_set_type = wm831x_irq_set_type,
432}; 427};
433 428
@@ -449,6 +444,18 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
449 goto out; 444 goto out;
450 } 445 }
451 446
447 /* The touch interrupts are visible in the primary register as
448 * an optimisation; open code this to avoid complicating the
449 * main handling loop and so we can also skip iterating the
450 * descriptors.
451 */
452 if (primary & WM831X_TCHPD_INT)
453 handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD);
454 if (primary & WM831X_TCHDATA_INT)
455 handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA);
456 if (primary & (WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT))
457 goto out;
458
452 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { 459 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
453 int offset = wm831x_irqs[i].reg - 1; 460 int offset = wm831x_irqs[i].reg - 1;
454 461
@@ -481,6 +488,9 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
481 } 488 }
482 489
483out: 490out:
491 /* Touchscreen interrupts are handled specially in the driver */
492 status_regs[0] &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
493
484 for (i = 0; i < ARRAY_SIZE(status_regs); i++) { 494 for (i = 0; i < ARRAY_SIZE(status_regs); i++) {
485 if (status_regs[i]) 495 if (status_regs[i])
486 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i, 496 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i,
@@ -517,6 +527,14 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
517 return 0; 527 return 0;
518 } 528 }
519 529
530 if (pdata->irq_cmos)
531 i = 0;
532 else
533 i = WM831X_IRQ_OD;
534
535 wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
536 WM831X_IRQ_OD, i);
537
520 /* Try to flag /IRQ as a wake source; there are a number of 538 /* Try to flag /IRQ as a wake source; there are a number of
521 * unconditional wake sources in the PMIC so this isn't 539 * unconditional wake sources in the PMIC so this isn't
522 * conditional but we don't actually care *too* much if it 540 * conditional but we don't actually care *too* much if it
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 0a8f772be88c..eed8e4f7a5a1 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/pm.h>
17#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
18 19
19#include <linux/mfd/wm831x/core.h> 20#include <linux/mfd/wm831x/core.h>
@@ -113,22 +114,27 @@ static int __devexit wm831x_spi_remove(struct spi_device *spi)
113 return 0; 114 return 0;
114} 115}
115 116
116static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m) 117static int wm831x_spi_suspend(struct device *dev)
117{ 118{
118 struct wm831x *wm831x = dev_get_drvdata(&spi->dev); 119 struct wm831x *wm831x = dev_get_drvdata(dev);
119 120
120 return wm831x_device_suspend(wm831x); 121 return wm831x_device_suspend(wm831x);
121} 122}
122 123
124static const struct dev_pm_ops wm831x_spi_pm = {
125 .freeze = wm831x_spi_suspend,
126 .suspend = wm831x_spi_suspend,
127};
128
123static struct spi_driver wm8310_spi_driver = { 129static struct spi_driver wm8310_spi_driver = {
124 .driver = { 130 .driver = {
125 .name = "wm8310", 131 .name = "wm8310",
126 .bus = &spi_bus_type, 132 .bus = &spi_bus_type,
127 .owner = THIS_MODULE, 133 .owner = THIS_MODULE,
134 .pm = &wm831x_spi_pm,
128 }, 135 },
129 .probe = wm831x_spi_probe, 136 .probe = wm831x_spi_probe,
130 .remove = __devexit_p(wm831x_spi_remove), 137 .remove = __devexit_p(wm831x_spi_remove),
131 .suspend = wm831x_spi_suspend,
132}; 138};
133 139
134static struct spi_driver wm8311_spi_driver = { 140static struct spi_driver wm8311_spi_driver = {
@@ -136,10 +142,10 @@ static struct spi_driver wm8311_spi_driver = {
136 .name = "wm8311", 142 .name = "wm8311",
137 .bus = &spi_bus_type, 143 .bus = &spi_bus_type,
138 .owner = THIS_MODULE, 144 .owner = THIS_MODULE,
145 .pm = &wm831x_spi_pm,
139 }, 146 },
140 .probe = wm831x_spi_probe, 147 .probe = wm831x_spi_probe,
141 .remove = __devexit_p(wm831x_spi_remove), 148 .remove = __devexit_p(wm831x_spi_remove),
142 .suspend = wm831x_spi_suspend,
143}; 149};
144 150
145static struct spi_driver wm8312_spi_driver = { 151static struct spi_driver wm8312_spi_driver = {
@@ -147,10 +153,10 @@ static struct spi_driver wm8312_spi_driver = {
147 .name = "wm8312", 153 .name = "wm8312",
148 .bus = &spi_bus_type, 154 .bus = &spi_bus_type,
149 .owner = THIS_MODULE, 155 .owner = THIS_MODULE,
156 .pm = &wm831x_spi_pm,
150 }, 157 },
151 .probe = wm831x_spi_probe, 158 .probe = wm831x_spi_probe,
152 .remove = __devexit_p(wm831x_spi_remove), 159 .remove = __devexit_p(wm831x_spi_remove),
153 .suspend = wm831x_spi_suspend,
154}; 160};
155 161
156static struct spi_driver wm8320_spi_driver = { 162static struct spi_driver wm8320_spi_driver = {
@@ -158,10 +164,10 @@ static struct spi_driver wm8320_spi_driver = {
158 .name = "wm8320", 164 .name = "wm8320",
159 .bus = &spi_bus_type, 165 .bus = &spi_bus_type,
160 .owner = THIS_MODULE, 166 .owner = THIS_MODULE,
167 .pm = &wm831x_spi_pm,
161 }, 168 },
162 .probe = wm831x_spi_probe, 169 .probe = wm831x_spi_probe,
163 .remove = __devexit_p(wm831x_spi_remove), 170 .remove = __devexit_p(wm831x_spi_remove),
164 .suspend = wm831x_spi_suspend,
165}; 171};
166 172
167static struct spi_driver wm8321_spi_driver = { 173static struct spi_driver wm8321_spi_driver = {
@@ -169,10 +175,10 @@ static struct spi_driver wm8321_spi_driver = {
169 .name = "wm8321", 175 .name = "wm8321",
170 .bus = &spi_bus_type, 176 .bus = &spi_bus_type,
171 .owner = THIS_MODULE, 177 .owner = THIS_MODULE,
178 .pm = &wm831x_spi_pm,
172 }, 179 },
173 .probe = wm831x_spi_probe, 180 .probe = wm831x_spi_probe,
174 .remove = __devexit_p(wm831x_spi_remove), 181 .remove = __devexit_p(wm831x_spi_remove),
175 .suspend = wm831x_spi_suspend,
176}; 182};
177 183
178static struct spi_driver wm8325_spi_driver = { 184static struct spi_driver wm8325_spi_driver = {
@@ -180,10 +186,10 @@ static struct spi_driver wm8325_spi_driver = {
180 .name = "wm8325", 186 .name = "wm8325",
181 .bus = &spi_bus_type, 187 .bus = &spi_bus_type,
182 .owner = THIS_MODULE, 188 .owner = THIS_MODULE,
189 .pm = &wm831x_spi_pm,
183 }, 190 },
184 .probe = wm831x_spi_probe, 191 .probe = wm831x_spi_probe,
185 .remove = __devexit_p(wm831x_spi_remove), 192 .remove = __devexit_p(wm831x_spi_remove),
186 .suspend = wm831x_spi_suspend,
187}; 193};
188 194
189static struct spi_driver wm8326_spi_driver = { 195static struct spi_driver wm8326_spi_driver = {
@@ -191,10 +197,10 @@ static struct spi_driver wm8326_spi_driver = {
191 .name = "wm8326", 197 .name = "wm8326",
192 .bus = &spi_bus_type, 198 .bus = &spi_bus_type,
193 .owner = THIS_MODULE, 199 .owner = THIS_MODULE,
200 .pm = &wm831x_spi_pm,
194 }, 201 },
195 .probe = wm831x_spi_probe, 202 .probe = wm831x_spi_probe,
196 .remove = __devexit_p(wm831x_spi_remove), 203 .remove = __devexit_p(wm831x_spi_remove),
197 .suspend = wm831x_spi_suspend,
198}; 204};
199 205
200static int __init wm831x_spi_init(void) 206static int __init wm831x_spi_init(void)
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index 1bfef4846b07..3a6e78cb0384 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -245,7 +245,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400)
245{ 245{
246 struct mfd_cell cell = { 246 struct mfd_cell cell = {
247 .name = "wm8400-codec", 247 .name = "wm8400-codec",
248 .driver_data = wm8400, 248 .mfd_data = wm8400,
249 }; 249 };
250 250
251 return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); 251 return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index f4016a075fd6..e198d40292e7 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -40,10 +40,8 @@ static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
40 return ret; 40 return ret;
41 41
42 for (i = 0; i < bytes / 2; i++) { 42 for (i = 0; i < bytes / 2; i++) {
43 buf[i] = be16_to_cpu(buf[i]);
44
45 dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n", 43 dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
46 buf[i], reg + i, reg + i); 44 be16_to_cpu(buf[i]), reg + i, reg + i);
47 } 45 }
48 46
49 return 0; 47 return 0;
@@ -69,7 +67,7 @@ int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
69 if (ret < 0) 67 if (ret < 0)
70 return ret; 68 return ret;
71 else 69 else
72 return val; 70 return be16_to_cpu(val);
73} 71}
74EXPORT_SYMBOL_GPL(wm8994_reg_read); 72EXPORT_SYMBOL_GPL(wm8994_reg_read);
75 73
@@ -79,7 +77,7 @@ EXPORT_SYMBOL_GPL(wm8994_reg_read);
79 * @wm8994: Device to read from 77 * @wm8994: Device to read from
80 * @reg: First register 78 * @reg: First register
81 * @count: Number of registers 79 * @count: Number of registers
82 * @buf: Buffer to fill. 80 * @buf: Buffer to fill. The data will be returned big endian.
83 */ 81 */
84int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 82int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
85 int count, u16 *buf) 83 int count, u16 *buf)
@@ -97,9 +95,9 @@ int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
97EXPORT_SYMBOL_GPL(wm8994_bulk_read); 95EXPORT_SYMBOL_GPL(wm8994_bulk_read);
98 96
99static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, 97static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
100 int bytes, void *src) 98 int bytes, const void *src)
101{ 99{
102 u16 *buf = src; 100 const u16 *buf = src;
103 int i; 101 int i;
104 102
105 BUG_ON(bytes % 2); 103 BUG_ON(bytes % 2);
@@ -107,9 +105,7 @@ static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
107 105
108 for (i = 0; i < bytes / 2; i++) { 106 for (i = 0; i < bytes / 2; i++) {
109 dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n", 107 dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
110 buf[i], reg + i, reg + i); 108 be16_to_cpu(buf[i]), reg + i, reg + i);
111
112 buf[i] = cpu_to_be16(buf[i]);
113 } 109 }
114 110
115 return wm8994->write_dev(wm8994, reg, bytes, src); 111 return wm8994->write_dev(wm8994, reg, bytes, src);
@@ -127,6 +123,8 @@ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
127{ 123{
128 int ret; 124 int ret;
129 125
126 val = cpu_to_be16(val);
127
130 mutex_lock(&wm8994->io_lock); 128 mutex_lock(&wm8994->io_lock);
131 129
132 ret = wm8994_write(wm8994, reg, 2, &val); 130 ret = wm8994_write(wm8994, reg, 2, &val);
@@ -138,6 +136,29 @@ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
138EXPORT_SYMBOL_GPL(wm8994_reg_write); 136EXPORT_SYMBOL_GPL(wm8994_reg_write);
139 137
140/** 138/**
139 * wm8994_bulk_write: Write multiple WM8994 registers
140 *
141 * @wm8994: Device to write to
142 * @reg: First register
143 * @count: Number of registers
144 * @buf: Buffer to write from. Data must be big-endian formatted.
145 */
146int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
147 int count, const u16 *buf)
148{
149 int ret;
150
151 mutex_lock(&wm8994->io_lock);
152
153 ret = wm8994_write(wm8994, reg, count * 2, buf);
154
155 mutex_unlock(&wm8994->io_lock);
156
157 return ret;
158}
159EXPORT_SYMBOL_GPL(wm8994_bulk_write);
160
161/**
141 * wm8994_set_bits: Set the value of a bitfield in a WM8994 register 162 * wm8994_set_bits: Set the value of a bitfield in a WM8994 register
142 * 163 *
143 * @wm8994: Device to write to. 164 * @wm8994: Device to write to.
@@ -157,9 +178,13 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
157 if (ret < 0) 178 if (ret < 0)
158 goto out; 179 goto out;
159 180
181 r = be16_to_cpu(r);
182
160 r &= ~mask; 183 r &= ~mask;
161 r |= val; 184 r |= val;
162 185
186 r = cpu_to_be16(r);
187
163 ret = wm8994_write(wm8994, reg, 2, &r); 188 ret = wm8994_write(wm8994, reg, 2, &r);
164 189
165out: 190out:
@@ -271,6 +296,11 @@ static int wm8994_suspend(struct device *dev)
271 if (ret < 0) 296 if (ret < 0)
272 dev_err(dev, "Failed to save LDO registers: %d\n", ret); 297 dev_err(dev, "Failed to save LDO registers: %d\n", ret);
273 298
299 /* Explicitly put the device into reset in case regulators
300 * don't get disabled in order to ensure consistent restart.
301 */
302 wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, 0x8994);
303
274 wm8994->suspended = true; 304 wm8994->suspended = true;
275 305
276 ret = regulator_bulk_disable(wm8994->num_supplies, 306 ret = regulator_bulk_disable(wm8994->num_supplies,
@@ -552,25 +582,29 @@ static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
552 return 0; 582 return 0;
553} 583}
554 584
555/* Currently we allocate the write buffer on the stack; this is OK for
556 * small writes - if we need to do large writes this will need to be
557 * revised.
558 */
559static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, 585static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
560 int bytes, void *src) 586 int bytes, const void *src)
561{ 587{
562 struct i2c_client *i2c = wm8994->control_data; 588 struct i2c_client *i2c = wm8994->control_data;
563 unsigned char msg[bytes + 2]; 589 struct i2c_msg xfer[2];
564 int ret; 590 int ret;
565 591
566 reg = cpu_to_be16(reg); 592 reg = cpu_to_be16(reg);
567 memcpy(&msg[0], &reg, 2);
568 memcpy(&msg[2], src, bytes);
569 593
570 ret = i2c_master_send(i2c, msg, bytes + 2); 594 xfer[0].addr = i2c->addr;
595 xfer[0].flags = 0;
596 xfer[0].len = 2;
597 xfer[0].buf = (char *)&reg;
598
599 xfer[1].addr = i2c->addr;
600 xfer[1].flags = I2C_M_NOSTART;
601 xfer[1].len = bytes;
602 xfer[1].buf = (char *)src;
603
604 ret = i2c_transfer(i2c->adapter, xfer, 2);
571 if (ret < 0) 605 if (ret < 0)
572 return ret; 606 return ret;
573 if (ret < bytes + 2) 607 if (ret != 2)
574 return -EIO; 608 return -EIO;
575 609
576 return 0; 610 return 0;
@@ -612,7 +646,8 @@ static const struct i2c_device_id wm8994_i2c_id[] = {
612}; 646};
613MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); 647MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
614 648
615UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); 649static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume,
650 NULL);
616 651
617static struct i2c_driver wm8994_i2c_driver = { 652static struct i2c_driver wm8994_i2c_driver = {
618 .driver = { 653 .driver = {
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c
index 29e8faf9c01c..1e3bf4a2ff8e 100644
--- a/drivers/mfd/wm8994-irq.c
+++ b/drivers/mfd/wm8994-irq.c
@@ -182,7 +182,7 @@ static void wm8994_irq_sync_unlock(struct irq_data *data)
182 mutex_unlock(&wm8994->irq_lock); 182 mutex_unlock(&wm8994->irq_lock);
183} 183}
184 184
185static void wm8994_irq_unmask(struct irq_data *data) 185static void wm8994_irq_enable(struct irq_data *data)
186{ 186{
187 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); 187 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
188 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, 188 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994,
@@ -191,7 +191,7 @@ static void wm8994_irq_unmask(struct irq_data *data)
191 wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 191 wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
192} 192}
193 193
194static void wm8994_irq_mask(struct irq_data *data) 194static void wm8994_irq_disable(struct irq_data *data)
195{ 195{
196 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); 196 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
197 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, 197 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994,
@@ -204,8 +204,8 @@ static struct irq_chip wm8994_irq_chip = {
204 .name = "wm8994", 204 .name = "wm8994",
205 .irq_bus_lock = wm8994_irq_lock, 205 .irq_bus_lock = wm8994_irq_lock,
206 .irq_bus_sync_unlock = wm8994_irq_sync_unlock, 206 .irq_bus_sync_unlock = wm8994_irq_sync_unlock,
207 .irq_mask = wm8994_irq_mask, 207 .irq_disable = wm8994_irq_disable,
208 .irq_unmask = wm8994_irq_unmask, 208 .irq_enable = wm8994_irq_enable,
209}; 209};
210 210
211/* The processing of the primary interrupt occurs in a thread so that 211/* The processing of the primary interrupt occurs in a thread so that
@@ -225,9 +225,11 @@ static irqreturn_t wm8994_irq_thread(int irq, void *data)
225 return IRQ_NONE; 225 return IRQ_NONE;
226 } 226 }
227 227
228 /* Apply masking */ 228 /* Bit swap and apply masking */
229 for (i = 0; i < WM8994_NUM_IRQ_REGS; i++) 229 for (i = 0; i < WM8994_NUM_IRQ_REGS; i++) {
230 status[i] = be16_to_cpu(status[i]);
230 status[i] &= ~wm8994->irq_masks_cur[i]; 231 status[i] &= ~wm8994->irq_masks_cur[i];
232 }
231 233
232 /* Report */ 234 /* Report */
233 for (i = 0; i < ARRAY_SIZE(wm8994_irqs); i++) { 235 for (i = 0; i < ARRAY_SIZE(wm8994_irqs); i++) {
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 4e42d030e097..2ae727568df9 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -55,8 +55,7 @@ static int mmc_queue_thread(void *d)
55 55
56 spin_lock_irq(q->queue_lock); 56 spin_lock_irq(q->queue_lock);
57 set_current_state(TASK_INTERRUPTIBLE); 57 set_current_state(TASK_INTERRUPTIBLE);
58 if (!blk_queue_plugged(q)) 58 req = blk_fetch_request(q);
59 req = blk_fetch_request(q);
60 mq->req = req; 59 mq->req = req;
61 spin_unlock_irq(q->queue_lock); 60 spin_unlock_irq(q->queue_lock);
62 61
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index ac52eb65395e..ab1adeabdd22 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -303,8 +303,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
303 303
304static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) 304static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
305{ 305{
306 struct mfd_cell *cell = host->pdev->dev.platform_data; 306 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
307 struct tmio_mmc_data *pdata = cell->driver_data;
308 307
309 /* 308 /*
310 * Testing on sh-mobile showed that SDIO IRQs are unmasked when 309 * Testing on sh-mobile showed that SDIO IRQs are unmasked when
@@ -327,8 +326,7 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
327 326
328static void tmio_mmc_clk_start(struct tmio_mmc_host *host) 327static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
329{ 328{
330 struct mfd_cell *cell = host->pdev->dev.platform_data; 329 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
331 struct tmio_mmc_data *pdata = cell->driver_data;
332 330
333 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | 331 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
334 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); 332 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
@@ -669,8 +667,7 @@ out:
669static irqreturn_t tmio_mmc_irq(int irq, void *devid) 667static irqreturn_t tmio_mmc_irq(int irq, void *devid)
670{ 668{
671 struct tmio_mmc_host *host = devid; 669 struct tmio_mmc_host *host = devid;
672 struct mfd_cell *cell = host->pdev->dev.platform_data; 670 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
673 struct tmio_mmc_data *pdata = cell->driver_data;
674 unsigned int ireg, irq_mask, status; 671 unsigned int ireg, irq_mask, status;
675 unsigned int sdio_ireg, sdio_irq_mask, sdio_status; 672 unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
676 673
@@ -799,8 +796,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
799 struct scatterlist *sg = host->sg_ptr, *sg_tmp; 796 struct scatterlist *sg = host->sg_ptr, *sg_tmp;
800 struct dma_async_tx_descriptor *desc = NULL; 797 struct dma_async_tx_descriptor *desc = NULL;
801 struct dma_chan *chan = host->chan_rx; 798 struct dma_chan *chan = host->chan_rx;
802 struct mfd_cell *cell = host->pdev->dev.platform_data; 799 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
803 struct tmio_mmc_data *pdata = cell->driver_data;
804 dma_cookie_t cookie; 800 dma_cookie_t cookie;
805 int ret, i; 801 int ret, i;
806 bool aligned = true, multiple = true; 802 bool aligned = true, multiple = true;
@@ -869,8 +865,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
869 struct scatterlist *sg = host->sg_ptr, *sg_tmp; 865 struct scatterlist *sg = host->sg_ptr, *sg_tmp;
870 struct dma_async_tx_descriptor *desc = NULL; 866 struct dma_async_tx_descriptor *desc = NULL;
871 struct dma_chan *chan = host->chan_tx; 867 struct dma_chan *chan = host->chan_tx;
872 struct mfd_cell *cell = host->pdev->dev.platform_data; 868 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
873 struct tmio_mmc_data *pdata = cell->driver_data;
874 dma_cookie_t cookie; 869 dma_cookie_t cookie;
875 int ret, i; 870 int ret, i;
876 bool aligned = true, multiple = true; 871 bool aligned = true, multiple = true;
@@ -1063,8 +1058,7 @@ static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
1063static int tmio_mmc_start_data(struct tmio_mmc_host *host, 1058static int tmio_mmc_start_data(struct tmio_mmc_host *host,
1064 struct mmc_data *data) 1059 struct mmc_data *data)
1065{ 1060{
1066 struct mfd_cell *cell = host->pdev->dev.platform_data; 1061 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
1067 struct tmio_mmc_data *pdata = cell->driver_data;
1068 1062
1069 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", 1063 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
1070 data->blksz, data->blocks); 1064 data->blksz, data->blocks);
@@ -1169,8 +1163,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1169static int tmio_mmc_get_ro(struct mmc_host *mmc) 1163static int tmio_mmc_get_ro(struct mmc_host *mmc)
1170{ 1164{
1171 struct tmio_mmc_host *host = mmc_priv(mmc); 1165 struct tmio_mmc_host *host = mmc_priv(mmc);
1172 struct mfd_cell *cell = host->pdev->dev.platform_data; 1166 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
1173 struct tmio_mmc_data *pdata = cell->driver_data;
1174 1167
1175 return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || 1168 return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
1176 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1; 1169 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1;
@@ -1179,8 +1172,7 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
1179static int tmio_mmc_get_cd(struct mmc_host *mmc) 1172static int tmio_mmc_get_cd(struct mmc_host *mmc)
1180{ 1173{
1181 struct tmio_mmc_host *host = mmc_priv(mmc); 1174 struct tmio_mmc_host *host = mmc_priv(mmc);
1182 struct mfd_cell *cell = host->pdev->dev.platform_data; 1175 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
1183 struct tmio_mmc_data *pdata = cell->driver_data;
1184 1176
1185 if (!pdata->get_cd) 1177 if (!pdata->get_cd)
1186 return -ENOSYS; 1178 return -ENOSYS;
@@ -1199,7 +1191,7 @@ static const struct mmc_host_ops tmio_mmc_ops = {
1199#ifdef CONFIG_PM 1191#ifdef CONFIG_PM
1200static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) 1192static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
1201{ 1193{
1202 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1194 const struct mfd_cell *cell = mfd_get_cell(dev);
1203 struct mmc_host *mmc = platform_get_drvdata(dev); 1195 struct mmc_host *mmc = platform_get_drvdata(dev);
1204 int ret; 1196 int ret;
1205 1197
@@ -1214,7 +1206,7 @@ static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
1214 1206
1215static int tmio_mmc_resume(struct platform_device *dev) 1207static int tmio_mmc_resume(struct platform_device *dev)
1216{ 1208{
1217 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1209 const struct mfd_cell *cell = mfd_get_cell(dev);
1218 struct mmc_host *mmc = platform_get_drvdata(dev); 1210 struct mmc_host *mmc = platform_get_drvdata(dev);
1219 int ret = 0; 1211 int ret = 0;
1220 1212
@@ -1237,7 +1229,7 @@ out:
1237 1229
1238static int __devinit tmio_mmc_probe(struct platform_device *dev) 1230static int __devinit tmio_mmc_probe(struct platform_device *dev)
1239{ 1231{
1240 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1232 const struct mfd_cell *cell = mfd_get_cell(dev);
1241 struct tmio_mmc_data *pdata; 1233 struct tmio_mmc_data *pdata;
1242 struct resource *res_ctl; 1234 struct resource *res_ctl;
1243 struct tmio_mmc_host *host; 1235 struct tmio_mmc_host *host;
@@ -1252,7 +1244,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
1252 if (!res_ctl) 1244 if (!res_ctl)
1253 goto out; 1245 goto out;
1254 1246
1255 pdata = cell->driver_data; 1247 pdata = mfd_get_data(dev);
1256 if (!pdata || !pdata->hclk) 1248 if (!pdata || !pdata->hclk)
1257 goto out; 1249 goto out;
1258 1250
@@ -1352,7 +1344,7 @@ out:
1352 1344
1353static int __devexit tmio_mmc_remove(struct platform_device *dev) 1345static int __devexit tmio_mmc_remove(struct platform_device *dev)
1354{ 1346{
1355 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1347 const struct mfd_cell *cell = mfd_get_cell(dev);
1356 struct mmc_host *mmc = platform_get_drvdata(dev); 1348 struct mmc_host *mmc = platform_get_drvdata(dev);
1357 1349
1358 platform_set_drvdata(dev, NULL); 1350 platform_set_drvdata(dev, NULL);
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
index 3041d1f7ae3f..38fb16771f85 100644
--- a/drivers/mtd/nand/tmio_nand.c
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -319,7 +319,7 @@ static int tmio_nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
319 319
320static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio) 320static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
321{ 321{
322 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 322 const struct mfd_cell *cell = mfd_get_cell(dev);
323 int ret; 323 int ret;
324 324
325 if (cell->enable) { 325 if (cell->enable) {
@@ -363,7 +363,7 @@ static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
363 363
364static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio) 364static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
365{ 365{
366 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 366 const struct mfd_cell *cell = mfd_get_cell(dev);
367 367
368 tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE); 368 tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE);
369 if (cell->disable) 369 if (cell->disable)
@@ -372,8 +372,7 @@ static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
372 372
373static int tmio_probe(struct platform_device *dev) 373static int tmio_probe(struct platform_device *dev)
374{ 374{
375 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 375 struct tmio_nand_data *data = mfd_get_data(dev);
376 struct tmio_nand_data *data = cell->driver_data;
377 struct resource *fcr = platform_get_resource(dev, 376 struct resource *fcr = platform_get_resource(dev,
378 IORESOURCE_MEM, 0); 377 IORESOURCE_MEM, 0);
379 struct resource *ccr = platform_get_resource(dev, 378 struct resource *ccr = platform_get_resource(dev,
@@ -516,7 +515,7 @@ static int tmio_remove(struct platform_device *dev)
516#ifdef CONFIG_PM 515#ifdef CONFIG_PM
517static int tmio_suspend(struct platform_device *dev, pm_message_t state) 516static int tmio_suspend(struct platform_device *dev, pm_message_t state)
518{ 517{
519 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 518 const struct mfd_cell *cell = mfd_get_cell(dev);
520 519
521 if (cell->suspend) 520 if (cell->suspend)
522 cell->suspend(dev); 521 cell->suspend(dev);
@@ -527,7 +526,7 @@ static int tmio_suspend(struct platform_device *dev, pm_message_t state)
527 526
528static int tmio_resume(struct platform_device *dev) 527static int tmio_resume(struct platform_device *dev)
529{ 528{
530 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 529 const struct mfd_cell *cell = mfd_get_cell(dev);
531 530
532 /* FIXME - is this required or merely another attack of the broken 531 /* FIXME - is this required or merely another attack of the broken
533 * SHARP platform? Looks suspicious. 532 * SHARP platform? Looks suspicious.
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index aaa6e1e83b29..eededf94f5a6 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -1345,7 +1345,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
1345 if (!(ubi_chk_flags & UBI_CHK_IO)) 1345 if (!(ubi_chk_flags & UBI_CHK_IO))
1346 return 0; 1346 return 0;
1347 1347
1348 buf1 = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 1348 buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
1349 if (!buf1) { 1349 if (!buf1) {
1350 ubi_err("cannot allocate memory to check writes"); 1350 ubi_err("cannot allocate memory to check writes");
1351 return 0; 1351 return 0;
@@ -1409,7 +1409,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
1409 if (!(ubi_chk_flags & UBI_CHK_IO)) 1409 if (!(ubi_chk_flags & UBI_CHK_IO))
1410 return 0; 1410 return 0;
1411 1411
1412 buf = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 1412 buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
1413 if (!buf) { 1413 if (!buf) {
1414 ubi_err("cannot allocate memory to check for 0xFFs"); 1414 ubi_err("cannot allocate memory to check for 0xFFs");
1415 return 0; 1415 return 0;
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 366f5cc050ae..102b16c6cc97 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -15,6 +15,7 @@
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/mfd/core.h>
18 19
19#include <linux/netdevice.h> 20#include <linux/netdevice.h>
20#include <linux/can.h> 21#include <linux/can.h>
@@ -1643,7 +1644,7 @@ static int __devinit ican3_probe(struct platform_device *pdev)
1643 struct device *dev; 1644 struct device *dev;
1644 int ret; 1645 int ret;
1645 1646
1646 pdata = pdev->dev.platform_data; 1647 pdata = mfd_get_data(pdev);
1647 if (!pdata) 1648 if (!pdata)
1648 return -ENXIO; 1649 return -ENXIO;
1649 1650
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c
index 928b2b83cef5..efd44afeae83 100644
--- a/drivers/net/ks8842.c
+++ b/drivers/net/ks8842.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/mfd/core.h>
29#include <linux/netdevice.h> 30#include <linux/netdevice.h>
30#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
31#include <linux/ethtool.h> 32#include <linux/ethtool.h>
@@ -1145,7 +1146,7 @@ static int __devinit ks8842_probe(struct platform_device *pdev)
1145 struct resource *iomem; 1146 struct resource *iomem;
1146 struct net_device *netdev; 1147 struct net_device *netdev;
1147 struct ks8842_adapter *adapter; 1148 struct ks8842_adapter *adapter;
1148 struct ks8842_platform_data *pdata = pdev->dev.platform_data; 1149 struct ks8842_platform_data *pdata = mfd_get_data(pdev);
1149 u16 id; 1150 u16 id;
1150 unsigned i; 1151 unsigned i;
1151 1152
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 2765a3ce9c24..c83501122d77 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1109,6 +1109,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1109 } 1109 }
1110 } 1110 }
1111 1111
1112 /* Allow large DMA segments, up to the firmware limit of 1 GB */
1113 dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
1114
1112 priv = kzalloc(sizeof *priv, GFP_KERNEL); 1115 priv = kzalloc(sizeof *priv, GFP_KERNEL);
1113 if (!priv) { 1116 if (!priv) {
1114 dev_err(&pdev->dev, "Device struct alloc failed, " 1117 dev_err(&pdev->dev, "Device struct alloc failed, "
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 710b53bfac6d..632ebae7f17a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -496,6 +496,9 @@ EXPORT_SYMBOL(of_find_node_with_property);
496const struct of_device_id *of_match_node(const struct of_device_id *matches, 496const struct of_device_id *of_match_node(const struct of_device_id *matches,
497 const struct device_node *node) 497 const struct device_node *node)
498{ 498{
499 if (!matches)
500 return NULL;
501
499 while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 502 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
500 int match = 1; 503 int match = 1;
501 if (matches->name[0]) 504 if (matches->name[0])
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index af824e7e0367..c9db49c10f45 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -139,12 +139,13 @@ static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
139/** 139/**
140 * unflatten_dt_node - Alloc and populate a device_node from the flat tree 140 * unflatten_dt_node - Alloc and populate a device_node from the flat tree
141 * @blob: The parent device tree blob 141 * @blob: The parent device tree blob
142 * @mem: Memory chunk to use for allocating device nodes and properties
142 * @p: pointer to node in flat tree 143 * @p: pointer to node in flat tree
143 * @dad: Parent struct device_node 144 * @dad: Parent struct device_node
144 * @allnextpp: pointer to ->allnext from last allocated device_node 145 * @allnextpp: pointer to ->allnext from last allocated device_node
145 * @fpsize: Size of the node path up at the current depth. 146 * @fpsize: Size of the node path up at the current depth.
146 */ 147 */
147unsigned long unflatten_dt_node(struct boot_param_header *blob, 148static unsigned long unflatten_dt_node(struct boot_param_header *blob,
148 unsigned long mem, 149 unsigned long mem,
149 unsigned long *p, 150 unsigned long *p,
150 struct device_node *dad, 151 struct device_node *dad,
@@ -230,6 +231,7 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
230 } 231 }
231 kref_init(&np->kref); 232 kref_init(&np->kref);
232 } 233 }
234 /* process properties */
233 while (1) { 235 while (1) {
234 u32 sz, noff; 236 u32 sz, noff;
235 char *pname; 237 char *pname;
@@ -351,7 +353,7 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
351 * @dt_alloc: An allocator that provides a virtual address to memory 353 * @dt_alloc: An allocator that provides a virtual address to memory
352 * for the resulting tree 354 * for the resulting tree
353 */ 355 */
354void __unflatten_device_tree(struct boot_param_header *blob, 356static void __unflatten_device_tree(struct boot_param_header *blob,
355 struct device_node **mynodes, 357 struct device_node **mynodes,
356 void * (*dt_alloc)(u64 size, u64 align)) 358 void * (*dt_alloc)(u64 size, u64 align))
357{ 359{
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 1ce4c45c4ab2..63d3cb73bdb9 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -210,13 +210,16 @@ struct platform_device *of_platform_device_create(struct device_node *np,
210EXPORT_SYMBOL(of_platform_device_create); 210EXPORT_SYMBOL(of_platform_device_create);
211 211
212/** 212/**
213 * of_platform_bus_create - Create an OF device for a bus node and all its 213 * of_platform_bus_create() - Create a device for a node and its children.
214 * children. Optionally recursively instantiate matching busses.
215 * @bus: device node of the bus to instantiate 214 * @bus: device node of the bus to instantiate
216 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to 215 * @matches: match table for bus nodes
217 * disallow recursive creation of child busses 216 * disallow recursive creation of child buses
217 * @parent: parent for new device, or NULL for top level.
218 *
219 * Creates a platform_device for the provided device_node, and optionally
220 * recursively create devices for all the child nodes.
218 */ 221 */
219static int of_platform_bus_create(const struct device_node *bus, 222static int of_platform_bus_create(struct device_node *bus,
220 const struct of_device_id *matches, 223 const struct of_device_id *matches,
221 struct device *parent) 224 struct device *parent)
222{ 225{
@@ -224,18 +227,13 @@ static int of_platform_bus_create(const struct device_node *bus,
224 struct platform_device *dev; 227 struct platform_device *dev;
225 int rc = 0; 228 int rc = 0;
226 229
230 dev = of_platform_device_create(bus, NULL, parent);
231 if (!dev || !of_match_node(matches, bus))
232 return 0;
233
227 for_each_child_of_node(bus, child) { 234 for_each_child_of_node(bus, child) {
228 pr_debug(" create child: %s\n", child->full_name); 235 pr_debug(" create child: %s\n", child->full_name);
229 dev = of_platform_device_create(child, NULL, parent); 236 rc = of_platform_bus_create(child, matches, &dev->dev);
230 if (dev == NULL)
231 continue;
232
233 if (!of_match_node(matches, child))
234 continue;
235 if (rc == 0) {
236 pr_debug(" and sub busses\n");
237 rc = of_platform_bus_create(child, matches, &dev->dev);
238 }
239 if (rc) { 237 if (rc) {
240 of_node_put(child); 238 of_node_put(child);
241 break; 239 break;
@@ -245,9 +243,9 @@ static int of_platform_bus_create(const struct device_node *bus,
245} 243}
246 244
247/** 245/**
248 * of_platform_bus_probe - Probe the device-tree for platform busses 246 * of_platform_bus_probe() - Probe the device-tree for platform buses
249 * @root: parent of the first level to probe or NULL for the root of the tree 247 * @root: parent of the first level to probe or NULL for the root of the tree
250 * @matches: match table, NULL to use the default 248 * @matches: match table for bus nodes
251 * @parent: parent to hook devices from, NULL for toplevel 249 * @parent: parent to hook devices from, NULL for toplevel
252 * 250 *
253 * Note that children of the provided root are not instantiated as devices 251 * Note that children of the provided root are not instantiated as devices
@@ -258,50 +256,26 @@ int of_platform_bus_probe(struct device_node *root,
258 struct device *parent) 256 struct device *parent)
259{ 257{
260 struct device_node *child; 258 struct device_node *child;
261 struct platform_device *dev;
262 int rc = 0; 259 int rc = 0;
263 260
264 if (WARN_ON(!matches || matches == OF_NO_DEEP_PROBE)) 261 root = root ? of_node_get(root) : of_find_node_by_path("/");
265 return -EINVAL; 262 if (!root)
266 if (root == NULL)
267 root = of_find_node_by_path("/");
268 else
269 of_node_get(root);
270 if (root == NULL)
271 return -EINVAL; 263 return -EINVAL;
272 264
273 pr_debug("of_platform_bus_probe()\n"); 265 pr_debug("of_platform_bus_probe()\n");
274 pr_debug(" starting at: %s\n", root->full_name); 266 pr_debug(" starting at: %s\n", root->full_name);
275 267
276 /* Do a self check of bus type, if there's a match, create 268 /* Do a self check of bus type, if there's a match, create children */
277 * children
278 */
279 if (of_match_node(matches, root)) { 269 if (of_match_node(matches, root)) {
280 pr_debug(" root match, create all sub devices\n"); 270 rc = of_platform_bus_create(root, matches, parent);
281 dev = of_platform_device_create(root, NULL, parent); 271 } else for_each_child_of_node(root, child) {
282 if (dev == NULL)
283 goto bail;
284
285 pr_debug(" create all sub busses\n");
286 rc = of_platform_bus_create(root, matches, &dev->dev);
287 goto bail;
288 }
289 for_each_child_of_node(root, child) {
290 if (!of_match_node(matches, child)) 272 if (!of_match_node(matches, child))
291 continue; 273 continue;
292 274 rc = of_platform_bus_create(child, matches, parent);
293 pr_debug(" match: %s\n", child->full_name); 275 if (rc)
294 dev = of_platform_device_create(child, NULL, parent);
295 if (dev == NULL)
296 continue;
297
298 rc = of_platform_bus_create(child, matches, &dev->dev);
299 if (rc) {
300 of_node_put(child);
301 break; 276 break;
302 }
303 } 277 }
304 bail: 278
305 of_node_put(root); 279 of_node_put(root);
306 return rc; 280 return rc;
307} 281}
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 6fe0772e0e7d..7c3b18e78cee 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -293,19 +293,11 @@ static int acpi_dev_run_wake(struct device *phys_dev, bool enable)
293 } 293 }
294 294
295 if (enable) { 295 if (enable) {
296 if (!dev->wakeup.run_wake_count++) { 296 acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
297 acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); 297 acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
298 acpi_enable_gpe(dev->wakeup.gpe_device,
299 dev->wakeup.gpe_number);
300 }
301 } else if (dev->wakeup.run_wake_count > 0) {
302 if (!--dev->wakeup.run_wake_count) {
303 acpi_disable_gpe(dev->wakeup.gpe_device,
304 dev->wakeup.gpe_number);
305 acpi_disable_wakeup_device_power(dev);
306 }
307 } else { 298 } else {
308 error = -EALREADY; 299 acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
300 acpi_disable_wakeup_device_power(dev);
309 } 301 }
310 302
311 return error; 303 return error;
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 80c11d131499..3eb77080366a 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -35,13 +35,6 @@
35 PCI_ERR_UNC_UNX_COMP| \ 35 PCI_ERR_UNC_UNX_COMP| \
36 PCI_ERR_UNC_MALF_TLP) 36 PCI_ERR_UNC_MALF_TLP)
37 37
38struct header_log_regs {
39 unsigned int dw0;
40 unsigned int dw1;
41 unsigned int dw2;
42 unsigned int dw3;
43};
44
45#define AER_MAX_MULTI_ERR_DEVICES 5 /* Not likely to have more */ 38#define AER_MAX_MULTI_ERR_DEVICES 5 /* Not likely to have more */
46struct aer_err_info { 39struct aer_err_info {
47 struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES]; 40 struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
@@ -59,7 +52,7 @@ struct aer_err_info {
59 52
60 unsigned int status; /* COR/UNCOR Error Status */ 53 unsigned int status; /* COR/UNCOR Error Status */
61 unsigned int mask; /* COR/UNCOR Error Mask */ 54 unsigned int mask; /* COR/UNCOR Error Mask */
62 struct header_log_regs tlp; /* TLP Header */ 55 struct aer_header_log_regs tlp; /* TLP Header */
63}; 56};
64 57
65struct aer_err_source { 58struct aer_err_source {
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 9d3e4c8d0184..b07a42e0b350 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -19,6 +19,7 @@
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/pm.h> 20#include <linux/pm.h>
21#include <linux/suspend.h> 21#include <linux/suspend.h>
22#include <linux/cper.h>
22 23
23#include "aerdrv.h" 24#include "aerdrv.h"
24 25
@@ -57,86 +58,44 @@
57 (e & AER_DATA_LINK_LAYER_ERROR_MASK(t)) ? AER_DATA_LINK_LAYER_ERROR : \ 58 (e & AER_DATA_LINK_LAYER_ERROR_MASK(t)) ? AER_DATA_LINK_LAYER_ERROR : \
58 AER_TRANSACTION_LAYER_ERROR) 59 AER_TRANSACTION_LAYER_ERROR)
59 60
60#define AER_PR(info, pdev, fmt, args...) \
61 printk("%s%s %s: " fmt, (info->severity == AER_CORRECTABLE) ? \
62 KERN_WARNING : KERN_ERR, dev_driver_string(&pdev->dev), \
63 dev_name(&pdev->dev), ## args)
64
65/* 61/*
66 * AER error strings 62 * AER error strings
67 */ 63 */
68static char *aer_error_severity_string[] = { 64static const char *aer_error_severity_string[] = {
69 "Uncorrected (Non-Fatal)", 65 "Uncorrected (Non-Fatal)",
70 "Uncorrected (Fatal)", 66 "Uncorrected (Fatal)",
71 "Corrected" 67 "Corrected"
72}; 68};
73 69
74static char *aer_error_layer[] = { 70static const char *aer_error_layer[] = {
75 "Physical Layer", 71 "Physical Layer",
76 "Data Link Layer", 72 "Data Link Layer",
77 "Transaction Layer" 73 "Transaction Layer"
78}; 74};
79static char *aer_correctable_error_string[] = { 75
80 "Receiver Error ", /* Bit Position 0 */ 76static const char *aer_correctable_error_string[] = {
81 NULL, 77 "Receiver Error", /* Bit Position 0 */
82 NULL,
83 NULL,
84 NULL,
85 NULL,
86 "Bad TLP ", /* Bit Position 6 */
87 "Bad DLLP ", /* Bit Position 7 */
88 "RELAY_NUM Rollover ", /* Bit Position 8 */
89 NULL,
90 NULL,
91 NULL,
92 "Replay Timer Timeout ", /* Bit Position 12 */
93 "Advisory Non-Fatal ", /* Bit Position 13 */
94 NULL,
95 NULL,
96 NULL,
97 NULL,
98 NULL,
99 NULL,
100 NULL,
101 NULL,
102 NULL,
103 NULL,
104 NULL, 78 NULL,
105 NULL, 79 NULL,
106 NULL, 80 NULL,
107 NULL, 81 NULL,
108 NULL, 82 NULL,
83 "Bad TLP", /* Bit Position 6 */
84 "Bad DLLP", /* Bit Position 7 */
85 "RELAY_NUM Rollover", /* Bit Position 8 */
109 NULL, 86 NULL,
110 NULL, 87 NULL,
111 NULL, 88 NULL,
89 "Replay Timer Timeout", /* Bit Position 12 */
90 "Advisory Non-Fatal", /* Bit Position 13 */
112}; 91};
113 92
114static char *aer_uncorrectable_error_string[] = { 93static const char *aer_uncorrectable_error_string[] = {
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 "Data Link Protocol ", /* Bit Position 4 */
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 "Poisoned TLP ", /* Bit Position 12 */
128 "Flow Control Protocol ", /* Bit Position 13 */
129 "Completion Timeout ", /* Bit Position 14 */
130 "Completer Abort ", /* Bit Position 15 */
131 "Unexpected Completion ", /* Bit Position 16 */
132 "Receiver Overflow ", /* Bit Position 17 */
133 "Malformed TLP ", /* Bit Position 18 */
134 "ECRC ", /* Bit Position 19 */
135 "Unsupported Request ", /* Bit Position 20 */
136 NULL, 94 NULL,
137 NULL, 95 NULL,
138 NULL, 96 NULL,
139 NULL, 97 NULL,
98 "Data Link Protocol", /* Bit Position 4 */
140 NULL, 99 NULL,
141 NULL, 100 NULL,
142 NULL, 101 NULL,
@@ -144,19 +103,29 @@ static char *aer_uncorrectable_error_string[] = {
144 NULL, 103 NULL,
145 NULL, 104 NULL,
146 NULL, 105 NULL,
106 "Poisoned TLP", /* Bit Position 12 */
107 "Flow Control Protocol", /* Bit Position 13 */
108 "Completion Timeout", /* Bit Position 14 */
109 "Completer Abort", /* Bit Position 15 */
110 "Unexpected Completion", /* Bit Position 16 */
111 "Receiver Overflow", /* Bit Position 17 */
112 "Malformed TLP", /* Bit Position 18 */
113 "ECRC", /* Bit Position 19 */
114 "Unsupported Request", /* Bit Position 20 */
147}; 115};
148 116
149static char *aer_agent_string[] = { 117static const char *aer_agent_string[] = {
150 "Receiver ID", 118 "Receiver ID",
151 "Requester ID", 119 "Requester ID",
152 "Completer ID", 120 "Completer ID",
153 "Transmitter ID" 121 "Transmitter ID"
154}; 122};
155 123
156static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev) 124static void __aer_print_error(const char *prefix,
125 struct aer_err_info *info)
157{ 126{
158 int i, status; 127 int i, status;
159 char *errmsg = NULL; 128 const char *errmsg = NULL;
160 129
161 status = (info->status & ~info->mask); 130 status = (info->status & ~info->mask);
162 131
@@ -165,15 +134,17 @@ static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev)
165 continue; 134 continue;
166 135
167 if (info->severity == AER_CORRECTABLE) 136 if (info->severity == AER_CORRECTABLE)
168 errmsg = aer_correctable_error_string[i]; 137 errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ?
138 aer_correctable_error_string[i] : NULL;
169 else 139 else
170 errmsg = aer_uncorrectable_error_string[i]; 140 errmsg = i < ARRAY_SIZE(aer_uncorrectable_error_string) ?
141 aer_uncorrectable_error_string[i] : NULL;
171 142
172 if (errmsg) 143 if (errmsg)
173 AER_PR(info, dev, " [%2d] %s%s\n", i, errmsg, 144 printk("%s"" [%2d] %-22s%s\n", prefix, i, errmsg,
174 info->first_error == i ? " (First)" : ""); 145 info->first_error == i ? " (First)" : "");
175 else 146 else
176 AER_PR(info, dev, " [%2d] Unknown Error Bit%s\n", i, 147 printk("%s"" [%2d] Unknown Error Bit%s\n", prefix, i,
177 info->first_error == i ? " (First)" : ""); 148 info->first_error == i ? " (First)" : "");
178 } 149 }
179} 150}
@@ -181,11 +152,15 @@ static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev)
181void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) 152void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
182{ 153{
183 int id = ((dev->bus->number << 8) | dev->devfn); 154 int id = ((dev->bus->number << 8) | dev->devfn);
155 char prefix[44];
156
157 snprintf(prefix, sizeof(prefix), "%s%s %s: ",
158 (info->severity == AER_CORRECTABLE) ? KERN_WARNING : KERN_ERR,
159 dev_driver_string(&dev->dev), dev_name(&dev->dev));
184 160
185 if (info->status == 0) { 161 if (info->status == 0) {
186 AER_PR(info, dev, 162 printk("%s""PCIe Bus Error: severity=%s, type=Unaccessible, "
187 "PCIe Bus Error: severity=%s, type=Unaccessible, " 163 "id=%04x(Unregistered Agent ID)\n", prefix,
188 "id=%04x(Unregistered Agent ID)\n",
189 aer_error_severity_string[info->severity], id); 164 aer_error_severity_string[info->severity], id);
190 } else { 165 } else {
191 int layer, agent; 166 int layer, agent;
@@ -193,23 +168,22 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
193 layer = AER_GET_LAYER_ERROR(info->severity, info->status); 168 layer = AER_GET_LAYER_ERROR(info->severity, info->status);
194 agent = AER_GET_AGENT(info->severity, info->status); 169 agent = AER_GET_AGENT(info->severity, info->status);
195 170
196 AER_PR(info, dev, 171 printk("%s""PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
197 "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", 172 prefix, aer_error_severity_string[info->severity],
198 aer_error_severity_string[info->severity],
199 aer_error_layer[layer], id, aer_agent_string[agent]); 173 aer_error_layer[layer], id, aer_agent_string[agent]);
200 174
201 AER_PR(info, dev, 175 printk("%s"" device [%04x:%04x] error status/mask=%08x/%08x\n",
202 " device [%04x:%04x] error status/mask=%08x/%08x\n", 176 prefix, dev->vendor, dev->device,
203 dev->vendor, dev->device, info->status, info->mask); 177 info->status, info->mask);
204 178
205 __aer_print_error(info, dev); 179 __aer_print_error(prefix, info);
206 180
207 if (info->tlp_header_valid) { 181 if (info->tlp_header_valid) {
208 unsigned char *tlp = (unsigned char *) &info->tlp; 182 unsigned char *tlp = (unsigned char *) &info->tlp;
209 AER_PR(info, dev, " TLP Header:" 183 printk("%s"" TLP Header:"
210 " %02x%02x%02x%02x %02x%02x%02x%02x" 184 " %02x%02x%02x%02x %02x%02x%02x%02x"
211 " %02x%02x%02x%02x %02x%02x%02x%02x\n", 185 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
212 *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, 186 prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
213 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), 187 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
214 *(tlp + 11), *(tlp + 10), *(tlp + 9), 188 *(tlp + 11), *(tlp + 10), *(tlp + 9),
215 *(tlp + 8), *(tlp + 15), *(tlp + 14), 189 *(tlp + 8), *(tlp + 15), *(tlp + 14),
@@ -218,8 +192,8 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
218 } 192 }
219 193
220 if (info->id && info->error_dev_num > 1 && info->id == id) 194 if (info->id && info->error_dev_num > 1 && info->id == id)
221 AER_PR(info, dev, 195 printk("%s"" Error of this Agent(%04x) is reported first\n",
222 " Error of this Agent(%04x) is reported first\n", id); 196 prefix, id);
223} 197}
224 198
225void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) 199void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
@@ -228,3 +202,61 @@ void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
228 info->multi_error_valid ? "Multiple " : "", 202 info->multi_error_valid ? "Multiple " : "",
229 aer_error_severity_string[info->severity], info->id); 203 aer_error_severity_string[info->severity], info->id);
230} 204}
205
206#ifdef CONFIG_ACPI_APEI_PCIEAER
207static int cper_severity_to_aer(int cper_severity)
208{
209 switch (cper_severity) {
210 case CPER_SEV_RECOVERABLE:
211 return AER_NONFATAL;
212 case CPER_SEV_FATAL:
213 return AER_FATAL;
214 default:
215 return AER_CORRECTABLE;
216 }
217}
218
219void cper_print_aer(const char *prefix, int cper_severity,
220 struct aer_capability_regs *aer)
221{
222 int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0;
223 u32 status, mask;
224 const char **status_strs;
225
226 aer_severity = cper_severity_to_aer(cper_severity);
227 if (aer_severity == AER_CORRECTABLE) {
228 status = aer->cor_status;
229 mask = aer->cor_mask;
230 status_strs = aer_correctable_error_string;
231 status_strs_size = ARRAY_SIZE(aer_correctable_error_string);
232 } else {
233 status = aer->uncor_status;
234 mask = aer->uncor_mask;
235 status_strs = aer_uncorrectable_error_string;
236 status_strs_size = ARRAY_SIZE(aer_uncorrectable_error_string);
237 tlp_header_valid = status & AER_LOG_TLP_MASKS;
238 }
239 layer = AER_GET_LAYER_ERROR(aer_severity, status);
240 agent = AER_GET_AGENT(aer_severity, status);
241 printk("%s""aer_status: 0x%08x, aer_mask: 0x%08x\n",
242 prefix, status, mask);
243 cper_print_bits(prefix, status, status_strs, status_strs_size);
244 printk("%s""aer_layer=%s, aer_agent=%s\n", prefix,
245 aer_error_layer[layer], aer_agent_string[agent]);
246 if (aer_severity != AER_CORRECTABLE)
247 printk("%s""aer_uncor_severity: 0x%08x\n",
248 prefix, aer->uncor_severity);
249 if (tlp_header_valid) {
250 const unsigned char *tlp;
251 tlp = (const unsigned char *)&aer->header_log;
252 printk("%s""aer_tlp_header:"
253 " %02x%02x%02x%02x %02x%02x%02x%02x"
254 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
255 prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
256 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
257 *(tlp + 11), *(tlp + 10), *(tlp + 9),
258 *(tlp + 8), *(tlp + 15), *(tlp + 14),
259 *(tlp + 13), *(tlp + 12));
260 }
261}
262#endif
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
index 02414db6a94c..763f894ed188 100644
--- a/drivers/power/jz4740-battery.c
+++ b/drivers/power/jz4740-battery.c
@@ -39,7 +39,7 @@ struct jz_battery {
39 int irq; 39 int irq;
40 int charge_irq; 40 int charge_irq;
41 41
42 struct mfd_cell *cell; 42 const struct mfd_cell *cell;
43 43
44 int status; 44 int status;
45 long voltage; 45 long voltage;
@@ -258,7 +258,7 @@ static int __devinit jz_battery_probe(struct platform_device *pdev)
258 return -ENOMEM; 258 return -ENOMEM;
259 } 259 }
260 260
261 jz_battery->cell = pdev->dev.platform_data; 261 jz_battery->cell = mfd_get_cell(pdev);
262 262
263 jz_battery->irq = platform_get_irq(pdev, 0); 263 jz_battery->irq = platform_get_irq(pdev, 0);
264 if (jz_battery->irq < 0) { 264 if (jz_battery->irq < 0) {
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index dd6308499bd4..859251250b55 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -15,6 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/regulator/driver.h> 16#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h> 17#include <linux/regulator/machine.h>
18#include <linux/mfd/core.h>
18#include <linux/mfd/88pm860x.h> 19#include <linux/mfd/88pm860x.h>
19 20
20struct pm8607_regulator_info { 21struct pm8607_regulator_info {
@@ -394,47 +395,48 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
394 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6), 395 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6),
395}; 396};
396 397
397static inline struct pm8607_regulator_info *find_regulator_info(int id) 398static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
398{ 399{
399 struct pm8607_regulator_info *info; 400 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
401 struct pm8607_regulator_info *info = NULL;
402 struct regulator_init_data *pdata;
403 struct mfd_cell *cell;
400 int i; 404 int i;
401 405
406 cell = pdev->dev.platform_data;
407 if (cell == NULL)
408 return -ENODEV;
409 pdata = cell->mfd_data;
410 if (pdata == NULL)
411 return -EINVAL;
412
402 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { 413 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
403 info = &pm8607_regulator_info[i]; 414 info = &pm8607_regulator_info[i];
404 if (info->desc.id == id) 415 if (!strcmp(info->desc.name, pdata->constraints.name))
405 return info; 416 break;
406 } 417 }
407 return NULL; 418 if (i > ARRAY_SIZE(pm8607_regulator_info)) {
408} 419 dev_err(&pdev->dev, "Failed to find regulator %s\n",
409 420 pdata->constraints.name);
410static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
411{
412 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
413 struct pm860x_platform_data *pdata = chip->dev->platform_data;
414 struct pm8607_regulator_info *info = NULL;
415
416 info = find_regulator_info(pdev->id);
417 if (info == NULL) {
418 dev_err(&pdev->dev, "invalid regulator ID specified\n");
419 return -EINVAL; 421 return -EINVAL;
420 } 422 }
421 423
422 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 424 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
423 info->chip = chip; 425 info->chip = chip;
424 426
427 /* check DVC ramp slope double */
428 if (!strcmp(info->desc.name, "BUCK3"))
429 if (info->chip->buck3_double)
430 info->slope_double = 1;
431
425 info->regulator = regulator_register(&info->desc, &pdev->dev, 432 info->regulator = regulator_register(&info->desc, &pdev->dev,
426 pdata->regulator[pdev->id], info); 433 pdata, info);
427 if (IS_ERR(info->regulator)) { 434 if (IS_ERR(info->regulator)) {
428 dev_err(&pdev->dev, "failed to register regulator %s\n", 435 dev_err(&pdev->dev, "failed to register regulator %s\n",
429 info->desc.name); 436 info->desc.name);
430 return PTR_ERR(info->regulator); 437 return PTR_ERR(info->regulator);
431 } 438 }
432 439
433 /* check DVC ramp slope double */
434 if (info->desc.id == PM8607_ID_BUCK3)
435 if (info->chip->buck3_double)
436 info->slope_double = 1;
437
438 platform_set_drvdata(pdev, info); 440 platform_set_drvdata(pdev, info);
439 return 0; 441 return 0;
440} 442}
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e1d943619ab8..de75f67f4cc3 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -108,6 +108,15 @@ config REGULATOR_MAX8952
108 via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS 108 via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS
109 modes ranging from 0.77V to 1.40V by 0.01V steps. 109 modes ranging from 0.77V to 1.40V by 0.01V steps.
110 110
111config REGULATOR_MAX8997
112 tristate "Maxim 8997/8966 regulator"
113 depends on MFD_MAX8997
114 help
115 This driver controls a Maxim 8997/8966 regulator
116 via I2C bus. The provided regulator is suitable for S5PC110,
117 S5PV210, and Exynos-4 chips to control VCC_CORE and
118 VCC_USIM voltages.
119
111config REGULATOR_MAX8998 120config REGULATOR_MAX8998
112 tristate "Maxim 8998 voltage regulator" 121 tristate "Maxim 8998 voltage regulator"
113 depends on MFD_MAX8998 122 depends on MFD_MAX8998
@@ -214,6 +223,15 @@ config REGULATOR_AB3100
214 AB3100 analog baseband dealing with power regulators 223 AB3100 analog baseband dealing with power regulators
215 for the system. 224 for the system.
216 225
226config REGULATOR_TPS6105X
227 tristate "TI TPS6105X Power regulators"
228 depends on TPS6105X
229 default y if TPS6105X
230 help
231 This driver supports TPS61050/TPS61052 voltage regulator chips.
232 It is a single boost converter primarily for white LEDs and
233 audio amplifiers.
234
217config REGULATOR_TPS65023 235config REGULATOR_TPS65023
218 tristate "TI TPS65023 Power regulators" 236 tristate "TI TPS65023 Power regulators"
219 depends on I2C 237 depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0b5e88c2b8d7..d72a42756778 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
18obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 18obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
19obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o 19obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
20obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o 20obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
21obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
21obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o 22obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
22obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 23obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
23obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o 24obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
@@ -33,7 +34,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
33obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o 34obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
34obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o 35obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
35obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o 36obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
36 37obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
37obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o 38obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
38obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o 39obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
39obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o 40obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index ed6feaf9398d..2dec589a8908 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/regulator/driver.h> 18#include <linux/regulator/driver.h>
19#include <linux/mfd/abx500.h> 19#include <linux/mfd/abx500.h>
20#include <linux/mfd/core.h>
20 21
21/* LDO registers and some handy masking definitions for AB3100 */ 22/* LDO registers and some handy masking definitions for AB3100 */
22#define AB3100_LDO_A 0x40 23#define AB3100_LDO_A 0x40
@@ -576,7 +577,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
576 577
577static int __devinit ab3100_regulators_probe(struct platform_device *pdev) 578static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
578{ 579{
579 struct ab3100_platform_data *plfdata = pdev->dev.platform_data; 580 struct ab3100_platform_data *plfdata = mfd_get_data(pdev);
580 int err = 0; 581 int err = 0;
581 u8 data; 582 u8 data;
582 int i; 583 int i;
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
new file mode 100644
index 000000000000..01ef7e9903bb
--- /dev/null
+++ b/drivers/regulator/max8997.c
@@ -0,0 +1,1213 @@
1/*
2 * max8997.c - Regulator driver for the Maxim 8997/8966
3 *
4 * Copyright (C) 2011 Samsung Electronics
5 * MyungJoo Ham <myungjoo.ham@smasung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This driver is based on max8998.c
22 */
23
24#include <linux/bug.h>
25#include <linux/delay.h>
26#include <linux/err.h>
27#include <linux/gpio.h>
28#include <linux/slab.h>
29#include <linux/platform_device.h>
30#include <linux/regulator/driver.h>
31#include <linux/regulator/machine.h>
32#include <linux/mfd/max8997.h>
33#include <linux/mfd/max8997-private.h>
34
35struct max8997_data {
36 struct device *dev;
37 struct max8997_dev *iodev;
38 int num_regulators;
39 struct regulator_dev **rdev;
40 int ramp_delay; /* in mV/us */
41
42 u8 buck1_vol[8];
43 u8 buck2_vol[8];
44 u8 buck5_vol[8];
45 int buck125_gpioindex;
46
47 u8 saved_states[MAX8997_REG_MAX];
48};
49
50static inline void max8997_set_gpio(struct max8997_data *max8997)
51{
52 struct max8997_platform_data *pdata =
53 dev_get_platdata(max8997->iodev->dev);
54 int set3 = (max8997->buck125_gpioindex) & 0x1;
55 int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1;
56 int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1;
57
58 gpio_set_value(pdata->buck125_gpios[0], set1);
59 gpio_set_value(pdata->buck125_gpios[1], set2);
60 gpio_set_value(pdata->buck125_gpios[2], set3);
61}
62
63struct voltage_map_desc {
64 int min;
65 int max;
66 int step;
67 unsigned int n_bits;
68};
69
70/* Voltage maps in mV */
71static const struct voltage_map_desc ldo_voltage_map_desc = {
72 .min = 800, .max = 3950, .step = 50, .n_bits = 6,
73}; /* LDO1 ~ 18, 21 all */
74
75static const struct voltage_map_desc buck1245_voltage_map_desc = {
76 .min = 650, .max = 2225, .step = 25, .n_bits = 6,
77}; /* Buck1, 2, 4, 5 */
78
79static const struct voltage_map_desc buck37_voltage_map_desc = {
80 .min = 750, .max = 3900, .step = 50, .n_bits = 6,
81}; /* Buck3, 7 */
82
83/* current map in mA */
84static const struct voltage_map_desc charger_current_map_desc = {
85 .min = 200, .max = 950, .step = 50, .n_bits = 4,
86};
87
88static const struct voltage_map_desc topoff_current_map_desc = {
89 .min = 50, .max = 200, .step = 10, .n_bits = 4,
90};
91
92static const struct voltage_map_desc *reg_voltage_map[] = {
93 [MAX8997_LDO1] = &ldo_voltage_map_desc,
94 [MAX8997_LDO2] = &ldo_voltage_map_desc,
95 [MAX8997_LDO3] = &ldo_voltage_map_desc,
96 [MAX8997_LDO4] = &ldo_voltage_map_desc,
97 [MAX8997_LDO5] = &ldo_voltage_map_desc,
98 [MAX8997_LDO6] = &ldo_voltage_map_desc,
99 [MAX8997_LDO7] = &ldo_voltage_map_desc,
100 [MAX8997_LDO8] = &ldo_voltage_map_desc,
101 [MAX8997_LDO9] = &ldo_voltage_map_desc,
102 [MAX8997_LDO10] = &ldo_voltage_map_desc,
103 [MAX8997_LDO11] = &ldo_voltage_map_desc,
104 [MAX8997_LDO12] = &ldo_voltage_map_desc,
105 [MAX8997_LDO13] = &ldo_voltage_map_desc,
106 [MAX8997_LDO14] = &ldo_voltage_map_desc,
107 [MAX8997_LDO15] = &ldo_voltage_map_desc,
108 [MAX8997_LDO16] = &ldo_voltage_map_desc,
109 [MAX8997_LDO17] = &ldo_voltage_map_desc,
110 [MAX8997_LDO18] = &ldo_voltage_map_desc,
111 [MAX8997_LDO21] = &ldo_voltage_map_desc,
112 [MAX8997_BUCK1] = &buck1245_voltage_map_desc,
113 [MAX8997_BUCK2] = &buck1245_voltage_map_desc,
114 [MAX8997_BUCK3] = &buck37_voltage_map_desc,
115 [MAX8997_BUCK4] = &buck1245_voltage_map_desc,
116 [MAX8997_BUCK5] = &buck1245_voltage_map_desc,
117 [MAX8997_BUCK6] = NULL,
118 [MAX8997_BUCK7] = &buck37_voltage_map_desc,
119 [MAX8997_EN32KHZ_AP] = NULL,
120 [MAX8997_EN32KHZ_CP] = NULL,
121 [MAX8997_ENVICHG] = NULL,
122 [MAX8997_ESAFEOUT1] = NULL,
123 [MAX8997_ESAFEOUT2] = NULL,
124 [MAX8997_CHARGER_CV] = NULL,
125 [MAX8997_CHARGER] = &charger_current_map_desc,
126 [MAX8997_CHARGER_TOPOFF] = &topoff_current_map_desc,
127};
128
129static inline int max8997_get_rid(struct regulator_dev *rdev)
130{
131 return rdev_get_id(rdev);
132}
133
134static int max8997_list_voltage_safeout(struct regulator_dev *rdev,
135 unsigned int selector)
136{
137 int rid = max8997_get_rid(rdev);
138
139 if (rid == MAX8997_ESAFEOUT1 || rid == MAX8997_ESAFEOUT2) {
140 switch (selector) {
141 case 0:
142 return 4850000;
143 case 1:
144 return 4900000;
145 case 2:
146 return 4950000;
147 case 3:
148 return 3300000;
149 default:
150 return -EINVAL;
151 }
152 }
153
154 return -EINVAL;
155}
156
157static int max8997_list_voltage_charger_cv(struct regulator_dev *rdev,
158 unsigned int selector)
159{
160 int rid = max8997_get_rid(rdev);
161
162 if (rid != MAX8997_CHARGER_CV)
163 goto err;
164
165 switch (selector) {
166 case 0x00:
167 return 4200000;
168 case 0x01 ... 0x0E:
169 return 4000000 + 20000 * (selector - 0x01);
170 case 0x0F:
171 return 4350000;
172 default:
173 return -EINVAL;
174 }
175err:
176 return -EINVAL;
177}
178
179static int max8997_list_voltage(struct regulator_dev *rdev,
180 unsigned int selector)
181{
182 const struct voltage_map_desc *desc;
183 int rid = max8997_get_rid(rdev);
184 int val;
185
186 if (rid >= ARRAY_SIZE(reg_voltage_map) ||
187 rid < 0)
188 return -EINVAL;
189
190 desc = reg_voltage_map[rid];
191 if (desc == NULL)
192 return -EINVAL;
193
194 val = desc->min + desc->step * selector;
195 if (val > desc->max)
196 return -EINVAL;
197
198 return val * 1000;
199}
200
201static int max8997_get_enable_register(struct regulator_dev *rdev,
202 int *reg, int *mask, int *pattern)
203{
204 int rid = max8997_get_rid(rdev);
205
206 switch (rid) {
207 case MAX8997_LDO1 ... MAX8997_LDO21:
208 *reg = MAX8997_REG_LDO1CTRL + (rid - MAX8997_LDO1);
209 *mask = 0xC0;
210 *pattern = 0xC0;
211 break;
212 case MAX8997_BUCK1:
213 *reg = MAX8997_REG_BUCK1CTRL;
214 *mask = 0x01;
215 *pattern = 0x01;
216 break;
217 case MAX8997_BUCK2:
218 *reg = MAX8997_REG_BUCK2CTRL;
219 *mask = 0x01;
220 *pattern = 0x01;
221 break;
222 case MAX8997_BUCK3:
223 *reg = MAX8997_REG_BUCK3CTRL;
224 *mask = 0x01;
225 *pattern = 0x01;
226 break;
227 case MAX8997_BUCK4:
228 *reg = MAX8997_REG_BUCK4CTRL;
229 *mask = 0x01;
230 *pattern = 0x01;
231 break;
232 case MAX8997_BUCK5:
233 *reg = MAX8997_REG_BUCK5CTRL;
234 *mask = 0x01;
235 *pattern = 0x01;
236 break;
237 case MAX8997_BUCK6:
238 *reg = MAX8997_REG_BUCK6CTRL;
239 *mask = 0x01;
240 *pattern = 0x01;
241 break;
242 case MAX8997_BUCK7:
243 *reg = MAX8997_REG_BUCK7CTRL;
244 *mask = 0x01;
245 *pattern = 0x01;
246 break;
247 case MAX8997_EN32KHZ_AP ... MAX8997_EN32KHZ_CP:
248 *reg = MAX8997_REG_MAINCON1;
249 *mask = 0x01 << (rid - MAX8997_EN32KHZ_AP);
250 *pattern = 0x01 << (rid - MAX8997_EN32KHZ_AP);
251 break;
252 case MAX8997_ENVICHG:
253 *reg = MAX8997_REG_MBCCTRL1;
254 *mask = 0x80;
255 *pattern = 0x80;
256 break;
257 case MAX8997_ESAFEOUT1 ... MAX8997_ESAFEOUT2:
258 *reg = MAX8997_REG_SAFEOUTCTRL;
259 *mask = 0x40 << (rid - MAX8997_ESAFEOUT1);
260 *pattern = 0x40 << (rid - MAX8997_ESAFEOUT1);
261 break;
262 case MAX8997_CHARGER:
263 *reg = MAX8997_REG_MBCCTRL2;
264 *mask = 0x40;
265 *pattern = 0x40;
266 break;
267 default:
268 /* Not controllable or not exists */
269 return -EINVAL;
270 break;
271 }
272
273 return 0;
274}
275
276static int max8997_reg_is_enabled(struct regulator_dev *rdev)
277{
278 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
279 struct i2c_client *i2c = max8997->iodev->i2c;
280 int ret, reg, mask, pattern;
281 u8 val;
282
283 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
284 if (ret == -EINVAL)
285 return 1; /* "not controllable" */
286 else if (ret)
287 return ret;
288
289 ret = max8997_read_reg(i2c, reg, &val);
290 if (ret)
291 return ret;
292
293 return (val & mask) == pattern;
294}
295
296static int max8997_reg_enable(struct regulator_dev *rdev)
297{
298 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
299 struct i2c_client *i2c = max8997->iodev->i2c;
300 int ret, reg, mask, pattern;
301
302 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
303 if (ret)
304 return ret;
305
306 return max8997_update_reg(i2c, reg, pattern, mask);
307}
308
309static int max8997_reg_disable(struct regulator_dev *rdev)
310{
311 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
312 struct i2c_client *i2c = max8997->iodev->i2c;
313 int ret, reg, mask, pattern;
314
315 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
316 if (ret)
317 return ret;
318
319 return max8997_update_reg(i2c, reg, ~pattern, mask);
320}
321
322static int max8997_get_voltage_register(struct regulator_dev *rdev,
323 int *_reg, int *_shift, int *_mask)
324{
325 int rid = max8997_get_rid(rdev);
326 int reg, shift = 0, mask = 0x3f;
327
328 switch (rid) {
329 case MAX8997_LDO1 ... MAX8997_LDO21:
330 reg = MAX8997_REG_LDO1CTRL + (rid - MAX8997_LDO1);
331 break;
332 case MAX8997_BUCK1:
333 reg = MAX8997_REG_BUCK1DVS1;
334 break;
335 case MAX8997_BUCK2:
336 reg = MAX8997_REG_BUCK2DVS1;
337 break;
338 case MAX8997_BUCK3:
339 reg = MAX8997_REG_BUCK3DVS;
340 break;
341 case MAX8997_BUCK4:
342 reg = MAX8997_REG_BUCK4DVS;
343 break;
344 case MAX8997_BUCK5:
345 reg = MAX8997_REG_BUCK5DVS1;
346 break;
347 case MAX8997_BUCK7:
348 reg = MAX8997_REG_BUCK7DVS;
349 break;
350 case MAX8997_ESAFEOUT1 ... MAX8997_ESAFEOUT2:
351 reg = MAX8997_REG_SAFEOUTCTRL;
352 shift = (rid == MAX8997_ESAFEOUT2) ? 2 : 0;
353 mask = 0x3;
354 break;
355 case MAX8997_CHARGER_CV:
356 reg = MAX8997_REG_MBCCTRL3;
357 shift = 0;
358 mask = 0xf;
359 break;
360 case MAX8997_CHARGER:
361 reg = MAX8997_REG_MBCCTRL4;
362 shift = 0;
363 mask = 0xf;
364 break;
365 case MAX8997_CHARGER_TOPOFF:
366 reg = MAX8997_REG_MBCCTRL5;
367 shift = 0;
368 mask = 0xf;
369 break;
370 default:
371 return -EINVAL;
372 }
373
374 *_reg = reg;
375 *_shift = shift;
376 *_mask = mask;
377
378 return 0;
379}
380
381static int max8997_get_voltage(struct regulator_dev *rdev)
382{
383 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
384 struct max8997_platform_data *pdata =
385 dev_get_platdata(max8997->iodev->dev);
386 struct i2c_client *i2c = max8997->iodev->i2c;
387 int reg, shift, mask, ret;
388 int rid = max8997_get_rid(rdev);
389 u8 val;
390
391 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
392 if (ret)
393 return ret;
394
395 if ((rid == MAX8997_BUCK1 && pdata->buck1_gpiodvs) ||
396 (rid == MAX8997_BUCK2 && pdata->buck2_gpiodvs) ||
397 (rid == MAX8997_BUCK5 && pdata->buck5_gpiodvs))
398 reg += max8997->buck125_gpioindex;
399
400 ret = max8997_read_reg(i2c, reg, &val);
401 if (ret)
402 return ret;
403
404 val >>= shift;
405 val &= mask;
406
407 if (rdev->desc && rdev->desc->ops && rdev->desc->ops->list_voltage)
408 return rdev->desc->ops->list_voltage(rdev, val);
409
410 /*
411 * max8997_list_voltage returns value for any rdev with voltage_map,
412 * which works for "CHARGER" and "CHARGER TOPOFF" that do not have
413 * list_voltage ops (they are current regulators).
414 */
415 return max8997_list_voltage(rdev, val);
416}
417
418static inline int max8997_get_voltage_proper_val(
419 const struct voltage_map_desc *desc,
420 int min_vol, int max_vol)
421{
422 int i = 0;
423
424 if (desc == NULL)
425 return -EINVAL;
426
427 if (max_vol < desc->min || min_vol > desc->max)
428 return -EINVAL;
429
430 while (desc->min + desc->step * i < min_vol &&
431 desc->min + desc->step * i < desc->max)
432 i++;
433
434 if (desc->min + desc->step * i > max_vol)
435 return -EINVAL;
436
437 if (i >= (1 << desc->n_bits))
438 return -EINVAL;
439
440 return i;
441}
442
443static int max8997_set_voltage_charger_cv(struct regulator_dev *rdev,
444 int min_uV, int max_uV, unsigned *selector)
445{
446 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
447 struct i2c_client *i2c = max8997->iodev->i2c;
448 int rid = max8997_get_rid(rdev);
449 int lb, ub;
450 int reg, shift = 0, mask, ret = 0;
451 u8 val = 0x0;
452
453 if (rid != MAX8997_CHARGER_CV)
454 return -EINVAL;
455
456 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
457 if (ret)
458 return ret;
459
460 if (max_uV < 4000000 || min_uV > 4350000)
461 return -EINVAL;
462
463 if (min_uV <= 4000000) {
464 if (max_uV >= 4000000)
465 return -EINVAL;
466 else
467 val = 0x1;
468 } else if (min_uV <= 4200000 && max_uV >= 4200000)
469 val = 0x0;
470 else {
471 lb = (min_uV - 4000001) / 20000 + 2;
472 ub = (max_uV - 4000000) / 20000 + 1;
473
474 if (lb > ub)
475 return -EINVAL;
476
477 if (lb < 0xf)
478 val = lb;
479 else {
480 if (ub >= 0xf)
481 val = 0xf;
482 else
483 return -EINVAL;
484 }
485 }
486
487 *selector = val;
488
489 ret = max8997_update_reg(i2c, reg, val << shift, mask);
490
491 return ret;
492}
493
494/*
495 * For LDO1 ~ LDO21, BUCK1~5, BUCK7, CHARGER, CHARGER_TOPOFF
496 * BUCK1, 2, and 5 are available if they are not controlled by gpio
497 */
498static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev,
499 int min_uV, int max_uV, unsigned *selector)
500{
501 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
502 struct i2c_client *i2c = max8997->iodev->i2c;
503 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
504 const struct voltage_map_desc *desc;
505 int rid = max8997_get_rid(rdev);
506 int reg, shift = 0, mask, ret;
507 int i;
508 u8 org;
509
510 switch (rid) {
511 case MAX8997_LDO1 ... MAX8997_LDO21:
512 break;
513 case MAX8997_BUCK1 ... MAX8997_BUCK5:
514 break;
515 case MAX8997_BUCK6:
516 return -EINVAL;
517 case MAX8997_BUCK7:
518 break;
519 case MAX8997_CHARGER:
520 break;
521 case MAX8997_CHARGER_TOPOFF:
522 break;
523 default:
524 return -EINVAL;
525 }
526
527 desc = reg_voltage_map[rid];
528
529 i = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
530 if (i < 0)
531 return i;
532
533 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
534 if (ret)
535 return ret;
536
537 max8997_read_reg(i2c, reg, &org);
538 org = (org & mask) >> shift;
539
540 ret = max8997_update_reg(i2c, reg, i << shift, mask << shift);
541 *selector = i;
542
543 if (rid == MAX8997_BUCK1 || rid == MAX8997_BUCK2 ||
544 rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) {
545 /* If the voltage is increasing */
546 if (org < i)
547 udelay(desc->step * (i - org) / max8997->ramp_delay);
548 }
549
550 return ret;
551}
552
553/*
554 * Assess the damage on the voltage setting of BUCK1,2,5 by the change.
555 *
556 * When GPIO-DVS mode is used for multiple bucks, changing the voltage value
557 * of one of the bucks may affect that of another buck, which is the side
558 * effect of the change (set_voltage). This function examines the GPIO-DVS
559 * configurations and checks whether such side-effect exists.
560 */
561static int max8997_assess_side_effect(struct regulator_dev *rdev,
562 u8 new_val, int *best)
563{
564 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
565 struct max8997_platform_data *pdata =
566 dev_get_platdata(max8997->iodev->dev);
567 int rid = max8997_get_rid(rdev);
568 u8 *buckx_val[3];
569 bool buckx_gpiodvs[3];
570 int side_effect[8];
571 int min_side_effect = INT_MAX;
572 int i;
573
574 *best = -1;
575
576 switch (rid) {
577 case MAX8997_BUCK1:
578 rid = 0;
579 break;
580 case MAX8997_BUCK2:
581 rid = 1;
582 break;
583 case MAX8997_BUCK5:
584 rid = 2;
585 break;
586 default:
587 return -EINVAL;
588 }
589
590 buckx_val[0] = max8997->buck1_vol;
591 buckx_val[1] = max8997->buck2_vol;
592 buckx_val[2] = max8997->buck5_vol;
593 buckx_gpiodvs[0] = pdata->buck1_gpiodvs;
594 buckx_gpiodvs[1] = pdata->buck2_gpiodvs;
595 buckx_gpiodvs[2] = pdata->buck5_gpiodvs;
596
597 for (i = 0; i < 8; i++) {
598 int others;
599
600 if (new_val != (buckx_val[rid])[i]) {
601 side_effect[i] = -1;
602 continue;
603 }
604
605 side_effect[i] = 0;
606 for (others = 0; others < 3; others++) {
607 int diff;
608
609 if (others == rid)
610 continue;
611 if (buckx_gpiodvs[others] == false)
612 continue; /* Not affected */
613 diff = (buckx_val[others])[i] -
614 (buckx_val[others])[max8997->buck125_gpioindex];
615 if (diff > 0)
616 side_effect[i] += diff;
617 else if (diff < 0)
618 side_effect[i] -= diff;
619 }
620 if (side_effect[i] == 0) {
621 *best = i;
622 return 0; /* NO SIDE EFFECT! Use This! */
623 }
624 if (side_effect[i] < min_side_effect) {
625 min_side_effect = side_effect[i];
626 *best = i;
627 }
628 }
629
630 if (*best == -1)
631 return -EINVAL;
632
633 return side_effect[*best];
634}
635
636/*
637 * For Buck 1 ~ 5 and 7. If it is not controlled by GPIO, this calls
638 * max8997_set_voltage_ldobuck to do the job.
639 */
640static int max8997_set_voltage_buck(struct regulator_dev *rdev,
641 int min_uV, int max_uV, unsigned *selector)
642{
643 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
644 struct max8997_platform_data *pdata =
645 dev_get_platdata(max8997->iodev->dev);
646 int rid = max8997_get_rid(rdev);
647 const struct voltage_map_desc *desc;
648 int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg;
649 bool gpio_dvs_mode = false;
650 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
651
652 if (rid < MAX8997_BUCK1 || rid > MAX8997_BUCK7)
653 return -EINVAL;
654
655 switch (rid) {
656 case MAX8997_BUCK1:
657 if (pdata->buck1_gpiodvs)
658 gpio_dvs_mode = true;
659 break;
660 case MAX8997_BUCK2:
661 if (pdata->buck2_gpiodvs)
662 gpio_dvs_mode = true;
663 break;
664 case MAX8997_BUCK5:
665 if (pdata->buck5_gpiodvs)
666 gpio_dvs_mode = true;
667 break;
668 }
669
670 if (!gpio_dvs_mode)
671 return max8997_set_voltage_ldobuck(rdev, min_uV, max_uV,
672 selector);
673
674 desc = reg_voltage_map[rid];
675 new_val = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
676 if (new_val < 0)
677 return new_val;
678
679 tmp_dmg = INT_MAX;
680 tmp_idx = -1;
681 tmp_val = -1;
682 do {
683 damage = max8997_assess_side_effect(rdev, new_val, &new_idx);
684 if (damage == 0)
685 goto out;
686
687 if (tmp_dmg > damage) {
688 tmp_idx = new_idx;
689 tmp_val = new_val;
690 tmp_dmg = damage;
691 }
692
693 new_val++;
694 } while (desc->min + desc->step + new_val <= desc->max);
695
696 new_idx = tmp_idx;
697 new_val = tmp_val;
698
699 if (pdata->ignore_gpiodvs_side_effect == false)
700 return -EINVAL;
701
702 dev_warn(&rdev->dev, "MAX8997 GPIO-DVS Side Effect Warning: GPIO SET:"
703 " %d -> %d\n", max8997->buck125_gpioindex, tmp_idx);
704
705out:
706 if (new_idx < 0 || new_val < 0)
707 return -EINVAL;
708
709 max8997->buck125_gpioindex = new_idx;
710 max8997_set_gpio(max8997);
711 *selector = new_val;
712
713 return 0;
714}
715
716static const int safeoutvolt[] = {
717 3300000,
718 4850000,
719 4900000,
720 4950000,
721};
722
723/* For SAFEOUT1 and SAFEOUT2 */
724static int max8997_set_voltage_safeout(struct regulator_dev *rdev,
725 int min_uV, int max_uV, unsigned *selector)
726{
727 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
728 struct i2c_client *i2c = max8997->iodev->i2c;
729 int rid = max8997_get_rid(rdev);
730 int reg, shift = 0, mask, ret;
731 int i = 0;
732 u8 val;
733
734 if (rid != MAX8997_ESAFEOUT1 && rid != MAX8997_ESAFEOUT2)
735 return -EINVAL;
736
737 for (i = 0; i < ARRAY_SIZE(safeoutvolt); i++) {
738 if (min_uV <= safeoutvolt[i] &&
739 max_uV >= safeoutvolt[i])
740 break;
741 }
742
743 if (i >= ARRAY_SIZE(safeoutvolt))
744 return -EINVAL;
745
746 if (i == 0)
747 val = 0x3;
748 else
749 val = i - 1;
750
751 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
752 if (ret)
753 return ret;
754
755 ret = max8997_update_reg(i2c, reg, val << shift, mask << shift);
756 *selector = val;
757
758 return ret;
759}
760
761static int max8997_reg_enable_suspend(struct regulator_dev *rdev)
762{
763 return 0;
764}
765
766static int max8997_reg_disable_suspend(struct regulator_dev *rdev)
767{
768 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
769 struct i2c_client *i2c = max8997->iodev->i2c;
770 int ret, reg, mask, pattern;
771 int rid = max8997_get_rid(rdev);
772
773 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
774 if (ret)
775 return ret;
776
777 max8997_read_reg(i2c, reg, &max8997->saved_states[rid]);
778
779 if (rid == MAX8997_LDO1 ||
780 rid == MAX8997_LDO10 ||
781 rid == MAX8997_LDO21) {
782 dev_dbg(&rdev->dev, "Conditional Power-Off for %s\n",
783 rdev->desc->name);
784 return max8997_update_reg(i2c, reg, 0x40, mask);
785 }
786
787 dev_dbg(&rdev->dev, "Full Power-Off for %s (%xh -> %xh)\n",
788 rdev->desc->name, max8997->saved_states[rid] & mask,
789 (~pattern) & mask);
790 return max8997_update_reg(i2c, reg, ~pattern, mask);
791}
792
793static struct regulator_ops max8997_ldo_ops = {
794 .list_voltage = max8997_list_voltage,
795 .is_enabled = max8997_reg_is_enabled,
796 .enable = max8997_reg_enable,
797 .disable = max8997_reg_disable,
798 .get_voltage = max8997_get_voltage,
799 .set_voltage = max8997_set_voltage_ldobuck,
800 .set_suspend_enable = max8997_reg_enable_suspend,
801 .set_suspend_disable = max8997_reg_disable_suspend,
802};
803
804static struct regulator_ops max8997_buck_ops = {
805 .list_voltage = max8997_list_voltage,
806 .is_enabled = max8997_reg_is_enabled,
807 .enable = max8997_reg_enable,
808 .disable = max8997_reg_disable,
809 .get_voltage = max8997_get_voltage,
810 .set_voltage = max8997_set_voltage_buck,
811 .set_suspend_enable = max8997_reg_enable_suspend,
812 .set_suspend_disable = max8997_reg_disable_suspend,
813};
814
815static struct regulator_ops max8997_fixedvolt_ops = {
816 .list_voltage = max8997_list_voltage,
817 .is_enabled = max8997_reg_is_enabled,
818 .enable = max8997_reg_enable,
819 .disable = max8997_reg_disable,
820 .set_suspend_enable = max8997_reg_enable_suspend,
821 .set_suspend_disable = max8997_reg_disable_suspend,
822};
823
824static struct regulator_ops max8997_safeout_ops = {
825 .list_voltage = max8997_list_voltage_safeout,
826 .is_enabled = max8997_reg_is_enabled,
827 .enable = max8997_reg_enable,
828 .disable = max8997_reg_disable,
829 .get_voltage = max8997_get_voltage,
830 .set_voltage = max8997_set_voltage_safeout,
831 .set_suspend_enable = max8997_reg_enable_suspend,
832 .set_suspend_disable = max8997_reg_disable_suspend,
833};
834
835static struct regulator_ops max8997_fixedstate_ops = {
836 .list_voltage = max8997_list_voltage_charger_cv,
837 .get_voltage = max8997_get_voltage,
838 .set_voltage = max8997_set_voltage_charger_cv,
839};
840
841static int max8997_set_voltage_ldobuck_wrap(struct regulator_dev *rdev,
842 int min_uV, int max_uV)
843{
844 unsigned dummy;
845
846 return max8997_set_voltage_ldobuck(rdev, min_uV, max_uV, &dummy);
847}
848
849
850static struct regulator_ops max8997_charger_ops = {
851 .is_enabled = max8997_reg_is_enabled,
852 .enable = max8997_reg_enable,
853 .disable = max8997_reg_disable,
854 .get_current_limit = max8997_get_voltage,
855 .set_current_limit = max8997_set_voltage_ldobuck_wrap,
856};
857
858static struct regulator_ops max8997_charger_fixedstate_ops = {
859 .is_enabled = max8997_reg_is_enabled,
860 .get_current_limit = max8997_get_voltage,
861 .set_current_limit = max8997_set_voltage_ldobuck_wrap,
862};
863
864#define regulator_desc_ldo(num) { \
865 .name = "LDO"#num, \
866 .id = MAX8997_LDO##num, \
867 .ops = &max8997_ldo_ops, \
868 .type = REGULATOR_VOLTAGE, \
869 .owner = THIS_MODULE, \
870}
871#define regulator_desc_buck(num) { \
872 .name = "BUCK"#num, \
873 .id = MAX8997_BUCK##num, \
874 .ops = &max8997_buck_ops, \
875 .type = REGULATOR_VOLTAGE, \
876 .owner = THIS_MODULE, \
877}
878
879static struct regulator_desc regulators[] = {
880 regulator_desc_ldo(1),
881 regulator_desc_ldo(2),
882 regulator_desc_ldo(3),
883 regulator_desc_ldo(4),
884 regulator_desc_ldo(5),
885 regulator_desc_ldo(6),
886 regulator_desc_ldo(7),
887 regulator_desc_ldo(8),
888 regulator_desc_ldo(9),
889 regulator_desc_ldo(10),
890 regulator_desc_ldo(11),
891 regulator_desc_ldo(12),
892 regulator_desc_ldo(13),
893 regulator_desc_ldo(14),
894 regulator_desc_ldo(15),
895 regulator_desc_ldo(16),
896 regulator_desc_ldo(17),
897 regulator_desc_ldo(18),
898 regulator_desc_ldo(21),
899 regulator_desc_buck(1),
900 regulator_desc_buck(2),
901 regulator_desc_buck(3),
902 regulator_desc_buck(4),
903 regulator_desc_buck(5),
904 {
905 .name = "BUCK6",
906 .id = MAX8997_BUCK6,
907 .ops = &max8997_fixedvolt_ops,
908 .type = REGULATOR_VOLTAGE,
909 .owner = THIS_MODULE,
910 },
911 regulator_desc_buck(7),
912 {
913 .name = "EN32KHz AP",
914 .id = MAX8997_EN32KHZ_AP,
915 .ops = &max8997_fixedvolt_ops,
916 .type = REGULATOR_VOLTAGE,
917 .owner = THIS_MODULE,
918 }, {
919 .name = "EN32KHz CP",
920 .id = MAX8997_EN32KHZ_CP,
921 .ops = &max8997_fixedvolt_ops,
922 .type = REGULATOR_VOLTAGE,
923 .owner = THIS_MODULE,
924 }, {
925 .name = "ENVICHG",
926 .id = MAX8997_ENVICHG,
927 .ops = &max8997_fixedvolt_ops,
928 .type = REGULATOR_VOLTAGE,
929 .owner = THIS_MODULE,
930 }, {
931 .name = "ESAFEOUT1",
932 .id = MAX8997_ESAFEOUT1,
933 .ops = &max8997_safeout_ops,
934 .type = REGULATOR_VOLTAGE,
935 .owner = THIS_MODULE,
936 }, {
937 .name = "ESAFEOUT2",
938 .id = MAX8997_ESAFEOUT2,
939 .ops = &max8997_safeout_ops,
940 .type = REGULATOR_VOLTAGE,
941 .owner = THIS_MODULE,
942 }, {
943 .name = "CHARGER CV",
944 .id = MAX8997_CHARGER_CV,
945 .ops = &max8997_fixedstate_ops,
946 .type = REGULATOR_VOLTAGE,
947 .owner = THIS_MODULE,
948 }, {
949 .name = "CHARGER",
950 .id = MAX8997_CHARGER,
951 .ops = &max8997_charger_ops,
952 .type = REGULATOR_CURRENT,
953 .owner = THIS_MODULE,
954 }, {
955 .name = "CHARGER TOPOFF",
956 .id = MAX8997_CHARGER_TOPOFF,
957 .ops = &max8997_charger_fixedstate_ops,
958 .type = REGULATOR_CURRENT,
959 .owner = THIS_MODULE,
960 },
961};
962
963static __devinit int max8997_pmic_probe(struct platform_device *pdev)
964{
965 struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
966 struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
967 struct regulator_dev **rdev;
968 struct max8997_data *max8997;
969 struct i2c_client *i2c;
970 int i, ret, size;
971 u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0;
972
973 if (!pdata) {
974 dev_err(pdev->dev.parent, "No platform init data supplied.\n");
975 return -ENODEV;
976 }
977
978 max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL);
979 if (!max8997)
980 return -ENOMEM;
981
982 size = sizeof(struct regulator_dev *) * pdata->num_regulators;
983 max8997->rdev = kzalloc(size, GFP_KERNEL);
984 if (!max8997->rdev) {
985 kfree(max8997);
986 return -ENOMEM;
987 }
988
989 rdev = max8997->rdev;
990 max8997->dev = &pdev->dev;
991 max8997->iodev = iodev;
992 max8997->num_regulators = pdata->num_regulators;
993 platform_set_drvdata(pdev, max8997);
994 i2c = max8997->iodev->i2c;
995
996 max8997->buck125_gpioindex = pdata->buck125_default_idx;
997
998 for (i = 0; i < 8; i++) {
999 max8997->buck1_vol[i] = ret =
1000 max8997_get_voltage_proper_val(
1001 &buck1245_voltage_map_desc,
1002 pdata->buck1_voltage[i] / 1000,
1003 pdata->buck1_voltage[i] / 1000 +
1004 buck1245_voltage_map_desc.step);
1005 if (ret < 0)
1006 goto err_alloc;
1007
1008 max8997->buck2_vol[i] = ret =
1009 max8997_get_voltage_proper_val(
1010 &buck1245_voltage_map_desc,
1011 pdata->buck2_voltage[i] / 1000,
1012 pdata->buck2_voltage[i] / 1000 +
1013 buck1245_voltage_map_desc.step);
1014 if (ret < 0)
1015 goto err_alloc;
1016
1017 max8997->buck5_vol[i] = ret =
1018 max8997_get_voltage_proper_val(
1019 &buck1245_voltage_map_desc,
1020 pdata->buck5_voltage[i] / 1000,
1021 pdata->buck5_voltage[i] / 1000 +
1022 buck1245_voltage_map_desc.step);
1023 if (ret < 0)
1024 goto err_alloc;
1025
1026 if (max_buck1 < max8997->buck1_vol[i])
1027 max_buck1 = max8997->buck1_vol[i];
1028 if (max_buck2 < max8997->buck2_vol[i])
1029 max_buck2 = max8997->buck2_vol[i];
1030 if (max_buck5 < max8997->buck5_vol[i])
1031 max_buck5 = max8997->buck5_vol[i];
1032 }
1033
1034 /* For the safety, set max voltage before setting up */
1035 for (i = 0; i < 8; i++) {
1036 max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1),
1037 max_buck1, 0x3f);
1038 max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
1039 max_buck2, 0x3f);
1040 max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
1041 max_buck5, 0x3f);
1042 }
1043
1044 /*
1045 * If buck 1, 2, and 5 do not care DVS GPIO settings, ignore them.
1046 * If at least one of them cares, set gpios.
1047 */
1048 if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
1049 pdata->buck5_gpiodvs) {
1050 bool gpio1set = false, gpio2set = false;
1051
1052 if (!gpio_is_valid(pdata->buck125_gpios[0]) ||
1053 !gpio_is_valid(pdata->buck125_gpios[1]) ||
1054 !gpio_is_valid(pdata->buck125_gpios[2])) {
1055 dev_err(&pdev->dev, "GPIO NOT VALID\n");
1056 ret = -EINVAL;
1057 goto err_alloc;
1058 }
1059
1060 ret = gpio_request(pdata->buck125_gpios[0],
1061 "MAX8997 SET1");
1062 if (ret == -EBUSY)
1063 dev_warn(&pdev->dev, "Duplicated gpio request"
1064 " on SET1\n");
1065 else if (ret)
1066 goto err_alloc;
1067 else
1068 gpio1set = true;
1069
1070 ret = gpio_request(pdata->buck125_gpios[1],
1071 "MAX8997 SET2");
1072 if (ret == -EBUSY)
1073 dev_warn(&pdev->dev, "Duplicated gpio request"
1074 " on SET2\n");
1075 else if (ret) {
1076 if (gpio1set)
1077 gpio_free(pdata->buck125_gpios[0]);
1078 goto err_alloc;
1079 } else
1080 gpio2set = true;
1081
1082 ret = gpio_request(pdata->buck125_gpios[2],
1083 "MAX8997 SET3");
1084 if (ret == -EBUSY)
1085 dev_warn(&pdev->dev, "Duplicated gpio request"
1086 " on SET3\n");
1087 else if (ret) {
1088 if (gpio1set)
1089 gpio_free(pdata->buck125_gpios[0]);
1090 if (gpio2set)
1091 gpio_free(pdata->buck125_gpios[1]);
1092 goto err_alloc;
1093 }
1094
1095 gpio_direction_output(pdata->buck125_gpios[0],
1096 (max8997->buck125_gpioindex >> 2)
1097 & 0x1); /* SET1 */
1098 gpio_direction_output(pdata->buck125_gpios[1],
1099 (max8997->buck125_gpioindex >> 1)
1100 & 0x1); /* SET2 */
1101 gpio_direction_output(pdata->buck125_gpios[2],
1102 (max8997->buck125_gpioindex >> 0)
1103 & 0x1); /* SET3 */
1104 ret = 0;
1105 }
1106
1107 /* DVS-GPIO disabled */
1108 max8997_update_reg(i2c, MAX8997_REG_BUCK1CTRL, (pdata->buck1_gpiodvs) ?
1109 (1 << 1) : (0 << 1), 1 << 1);
1110 max8997_update_reg(i2c, MAX8997_REG_BUCK2CTRL, (pdata->buck2_gpiodvs) ?
1111 (1 << 1) : (0 << 1), 1 << 1);
1112 max8997_update_reg(i2c, MAX8997_REG_BUCK5CTRL, (pdata->buck5_gpiodvs) ?
1113 (1 << 1) : (0 << 1), 1 << 1);
1114
1115 /* Initialize all the DVS related BUCK registers */
1116 for (i = 0; i < 8; i++) {
1117 max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1),
1118 max8997->buck1_vol[i],
1119 0x3f);
1120 max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
1121 max8997->buck2_vol[i],
1122 0x3f);
1123 max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
1124 max8997->buck5_vol[i],
1125 0x3f);
1126 }
1127
1128 for (i = 0; i < pdata->num_regulators; i++) {
1129 const struct voltage_map_desc *desc;
1130 int id = pdata->regulators[i].id;
1131
1132 desc = reg_voltage_map[id];
1133 if (desc)
1134 regulators[id].n_voltages =
1135 (desc->max - desc->min) / desc->step + 1;
1136 else if (id == MAX8997_ESAFEOUT1 || id == MAX8997_ESAFEOUT2)
1137 regulators[id].n_voltages = 4;
1138 else if (id == MAX8997_CHARGER_CV)
1139 regulators[id].n_voltages = 16;
1140
1141 rdev[i] = regulator_register(&regulators[id], max8997->dev,
1142 pdata->regulators[i].initdata, max8997);
1143 if (IS_ERR(rdev[i])) {
1144 ret = PTR_ERR(rdev[i]);
1145 dev_err(max8997->dev, "regulator init failed for %d\n",
1146 id);
1147 rdev[i] = NULL;
1148 goto err;
1149 }
1150 }
1151
1152 /* Misc Settings */
1153 max8997->ramp_delay = 10; /* set 10mV/us, which is the default */
1154 max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9);
1155
1156 return 0;
1157err:
1158 for (i = 0; i < max8997->num_regulators; i++)
1159 if (rdev[i])
1160 regulator_unregister(rdev[i]);
1161err_alloc:
1162 kfree(max8997->rdev);
1163 kfree(max8997);
1164
1165 return ret;
1166}
1167
1168static int __devexit max8997_pmic_remove(struct platform_device *pdev)
1169{
1170 struct max8997_data *max8997 = platform_get_drvdata(pdev);
1171 struct regulator_dev **rdev = max8997->rdev;
1172 int i;
1173
1174 for (i = 0; i < max8997->num_regulators; i++)
1175 if (rdev[i])
1176 regulator_unregister(rdev[i]);
1177
1178 kfree(max8997->rdev);
1179 kfree(max8997);
1180
1181 return 0;
1182}
1183
1184static const struct platform_device_id max8997_pmic_id[] = {
1185 { "max8997-pmic", 0},
1186 { },
1187};
1188
1189static struct platform_driver max8997_pmic_driver = {
1190 .driver = {
1191 .name = "max8997-pmic",
1192 .owner = THIS_MODULE,
1193 },
1194 .probe = max8997_pmic_probe,
1195 .remove = __devexit_p(max8997_pmic_remove),
1196 .id_table = max8997_pmic_id,
1197};
1198
1199static int __init max8997_pmic_init(void)
1200{
1201 return platform_driver_register(&max8997_pmic_driver);
1202}
1203subsys_initcall(max8997_pmic_init);
1204
1205static void __exit max8997_pmic_cleanup(void)
1206{
1207 platform_driver_unregister(&max8997_pmic_driver);
1208}
1209module_exit(max8997_pmic_cleanup);
1210
1211MODULE_DESCRIPTION("MAXIM 8997/8966 Regulator Driver");
1212MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
1213MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index 3e5d0c3b4e53..23249cb0a8bd 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -15,6 +15,7 @@
15#include <linux/regulator/driver.h> 15#include <linux/regulator/driver.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/mfd/core.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/err.h> 21#include <linux/err.h>
@@ -336,8 +337,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
336{ 337{
337 struct mc13xxx_regulator_priv *priv; 338 struct mc13xxx_regulator_priv *priv;
338 struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); 339 struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
339 struct mc13783_regulator_platform_data *pdata = 340 struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev);
340 dev_get_platdata(&pdev->dev);
341 struct mc13783_regulator_init_data *init_data; 341 struct mc13783_regulator_init_data *init_data;
342 int i, ret; 342 int i, ret;
343 343
@@ -381,8 +381,7 @@ err:
381static int __devexit mc13783_regulator_remove(struct platform_device *pdev) 381static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
382{ 382{
383 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 383 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
384 struct mc13783_regulator_platform_data *pdata = 384 struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev);
385 dev_get_platdata(&pdev->dev);
386 int i; 385 int i;
387 386
388 platform_set_drvdata(pdev, NULL); 387 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c
index 1b8f7398a4a8..6f15168e5ed4 100644
--- a/drivers/regulator/mc13892-regulator.c
+++ b/drivers/regulator/mc13892-regulator.c
@@ -15,6 +15,7 @@
15#include <linux/regulator/driver.h> 15#include <linux/regulator/driver.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/mfd/core.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/err.h> 21#include <linux/err.h>
@@ -520,8 +521,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
520{ 521{
521 struct mc13xxx_regulator_priv *priv; 522 struct mc13xxx_regulator_priv *priv;
522 struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); 523 struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
523 struct mc13xxx_regulator_platform_data *pdata = 524 struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev);
524 dev_get_platdata(&pdev->dev);
525 struct mc13xxx_regulator_init_data *init_data; 525 struct mc13xxx_regulator_init_data *init_data;
526 int i, ret; 526 int i, ret;
527 u32 val; 527 u32 val;
@@ -595,8 +595,7 @@ err_free:
595static int __devexit mc13892_regulator_remove(struct platform_device *pdev) 595static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
596{ 596{
597 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 597 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
598 struct mc13xxx_regulator_platform_data *pdata = 598 struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev);
599 dev_get_platdata(&pdev->dev);
600 int i; 599 int i;
601 600
602 platform_set_drvdata(pdev, NULL); 601 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
new file mode 100644
index 000000000000..1661499feda4
--- /dev/null
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -0,0 +1,196 @@
1/*
2 * Driver for TPS61050/61052 boost converters, typically used for white LEDs
3 * or audio amplifiers.
4 *
5 * Copyright (C) 2011 ST-Ericsson SA
6 * Written on behalf of Linaro for ST-Ericsson
7 *
8 * Author: Linus Walleij <linus.walleij@linaro.org>
9 *
10 * License terms: GNU General Public License (GPL) version 2
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/err.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <linux/regulator/driver.h>
20#include <linux/mfd/core.h>
21#include <linux/mfd/tps6105x.h>
22
23static const int tps6105x_voltages[] = {
24 4500000,
25 5000000,
26 5250000,
27 5000000, /* There is an additional 5V */
28};
29
30static int tps6105x_regulator_enable(struct regulator_dev *rdev)
31{
32 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
33 int ret;
34
35 /* Activate voltage mode */
36 ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
37 TPS6105X_REG0_MODE_MASK,
38 TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);
39 if (ret)
40 return ret;
41
42 return 0;
43}
44
45static int tps6105x_regulator_disable(struct regulator_dev *rdev)
46{
47 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
48 int ret;
49
50 /* Set into shutdown mode */
51 ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
52 TPS6105X_REG0_MODE_MASK,
53 TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);
54 if (ret)
55 return ret;
56
57 return 0;
58}
59
60static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev)
61{
62 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
63 u8 regval;
64 int ret;
65
66 ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
67 if (ret)
68 return ret;
69 regval &= TPS6105X_REG0_MODE_MASK;
70 regval >>= TPS6105X_REG0_MODE_SHIFT;
71
72 if (regval == TPS6105X_REG0_MODE_VOLTAGE)
73 return 1;
74
75 return 0;
76}
77
78static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev)
79{
80 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
81 u8 regval;
82 int ret;
83
84 ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
85 if (ret)
86 return ret;
87
88 regval &= TPS6105X_REG0_VOLTAGE_MASK;
89 regval >>= TPS6105X_REG0_VOLTAGE_SHIFT;
90 return (int) regval;
91}
92
93static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev,
94 unsigned selector)
95{
96 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
97 int ret;
98
99 ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
100 TPS6105X_REG0_VOLTAGE_MASK,
101 selector << TPS6105X_REG0_VOLTAGE_SHIFT);
102 if (ret)
103 return ret;
104
105 return 0;
106}
107
108static int tps6105x_regulator_list_voltage(struct regulator_dev *rdev,
109 unsigned selector)
110{
111 if (selector >= ARRAY_SIZE(tps6105x_voltages))
112 return -EINVAL;
113
114 return tps6105x_voltages[selector];
115}
116
117static struct regulator_ops tps6105x_regulator_ops = {
118 .enable = tps6105x_regulator_enable,
119 .disable = tps6105x_regulator_disable,
120 .is_enabled = tps6105x_regulator_is_enabled,
121 .get_voltage_sel = tps6105x_regulator_get_voltage_sel,
122 .set_voltage_sel = tps6105x_regulator_set_voltage_sel,
123 .list_voltage = tps6105x_regulator_list_voltage,
124};
125
126static struct regulator_desc tps6105x_regulator_desc = {
127 .name = "tps6105x-boost",
128 .ops = &tps6105x_regulator_ops,
129 .type = REGULATOR_VOLTAGE,
130 .id = 0,
131 .owner = THIS_MODULE,
132 .n_voltages = ARRAY_SIZE(tps6105x_voltages),
133};
134
135/*
136 * Registers the chip as a voltage regulator
137 */
138static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
139{
140 struct tps6105x *tps6105x = mfd_get_data(pdev);
141 struct tps6105x_platform_data *pdata = tps6105x->pdata;
142 int ret;
143
144 /* This instance is not set for regulator mode so bail out */
145 if (pdata->mode != TPS6105X_MODE_VOLTAGE) {
146 dev_info(&pdev->dev,
147 "chip not in voltage mode mode, exit probe \n");
148 return 0;
149 }
150
151 /* Register regulator with framework */
152 tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
153 &tps6105x->client->dev,
154 pdata->regulator_data, tps6105x);
155 if (IS_ERR(tps6105x->regulator)) {
156 ret = PTR_ERR(tps6105x->regulator);
157 dev_err(&tps6105x->client->dev,
158 "failed to register regulator\n");
159 return ret;
160 }
161
162 return 0;
163}
164
165static int __devexit tps6105x_regulator_remove(struct platform_device *pdev)
166{
167 struct tps6105x *tps6105x = platform_get_drvdata(pdev);
168 regulator_unregister(tps6105x->regulator);
169 return 0;
170}
171
172static struct platform_driver tps6105x_regulator_driver = {
173 .driver = {
174 .name = "tps6105x-regulator",
175 .owner = THIS_MODULE,
176 },
177 .probe = tps6105x_regulator_probe,
178 .remove = __devexit_p(tps6105x_regulator_remove),
179};
180
181static __init int tps6105x_regulator_init(void)
182{
183 return platform_driver_register(&tps6105x_regulator_driver);
184}
185subsys_initcall(tps6105x_regulator_init);
186
187static __exit void tps6105x_regulator_exit(void)
188{
189 platform_driver_unregister(&tps6105x_regulator_driver);
190}
191module_exit(tps6105x_regulator_exit);
192
193MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
194MODULE_DESCRIPTION("TPS6105x regulator driver");
195MODULE_LICENSE("GPL v2");
196MODULE_ALIAS("platform:tps6105x-regulator");
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index bd332cf1cc3f..6a292852a358 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -475,6 +475,13 @@ static struct regulator_ops twlfixed_ops = {
475 .get_status = twlreg_get_status, 475 .get_status = twlreg_get_status,
476}; 476};
477 477
478static struct regulator_ops twl6030_fixed_resource = {
479 .enable = twlreg_enable,
480 .disable = twlreg_disable,
481 .is_enabled = twlreg_is_enabled,
482 .get_status = twlreg_get_status,
483};
484
478/*----------------------------------------------------------------------*/ 485/*----------------------------------------------------------------------*/
479 486
480#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ 487#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
@@ -538,6 +545,20 @@ static struct regulator_ops twlfixed_ops = {
538 }, \ 545 }, \
539 } 546 }
540 547
548#define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay, remap_conf) { \
549 .base = offset, \
550 .id = num, \
551 .delay = turnon_delay, \
552 .remap = remap_conf, \
553 .desc = { \
554 .name = #label, \
555 .id = TWL6030_REG_##label, \
556 .ops = &twl6030_fixed_resource, \
557 .type = REGULATOR_VOLTAGE, \
558 .owner = THIS_MODULE, \
559 }, \
560 }
561
541/* 562/*
542 * We list regulators here if systems need some level of 563 * We list regulators here if systems need some level of
543 * software control over them after boot. 564 * software control over them after boot.
@@ -577,7 +598,8 @@ static struct twlreg_info twl_regs[] = {
577 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), 598 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21),
578 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), 599 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21),
579 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), 600 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21),
580 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21) 601 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21),
602 TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0, 0x21),
581}; 603};
582 604
583static int __devinit twlreg_probe(struct platform_device *pdev) 605static int __devinit twlreg_probe(struct platform_device *pdev)
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 794bfd962266..4d2df2f76ea0 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1917,7 +1917,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
1917 return; 1917 return;
1918 } 1918 }
1919 /* Now we try to fetch requests from the request queue */ 1919 /* Now we try to fetch requests from the request queue */
1920 while (!blk_queue_plugged(queue) && (req = blk_peek_request(queue))) { 1920 while ((req = blk_peek_request(queue))) {
1921 if (basedev->features & DASD_FEATURE_READONLY && 1921 if (basedev->features & DASD_FEATURE_READONLY &&
1922 rq_data_dir(req) == WRITE) { 1922 rq_data_dir(req) == WRITE) {
1923 DBF_DEV_EVENT(DBF_ERR, basedev, 1923 DBF_DEV_EVENT(DBF_ERR, basedev,
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 55d2d0f4eabc..83cea9a55e2f 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -48,14 +48,14 @@
48static DEFINE_MUTEX(tape_block_mutex); 48static DEFINE_MUTEX(tape_block_mutex);
49static int tapeblock_open(struct block_device *, fmode_t); 49static int tapeblock_open(struct block_device *, fmode_t);
50static int tapeblock_release(struct gendisk *, fmode_t); 50static int tapeblock_release(struct gendisk *, fmode_t);
51static int tapeblock_medium_changed(struct gendisk *); 51static unsigned int tapeblock_check_events(struct gendisk *, unsigned int);
52static int tapeblock_revalidate_disk(struct gendisk *); 52static int tapeblock_revalidate_disk(struct gendisk *);
53 53
54static const struct block_device_operations tapeblock_fops = { 54static const struct block_device_operations tapeblock_fops = {
55 .owner = THIS_MODULE, 55 .owner = THIS_MODULE,
56 .open = tapeblock_open, 56 .open = tapeblock_open,
57 .release = tapeblock_release, 57 .release = tapeblock_release,
58 .media_changed = tapeblock_medium_changed, 58 .check_events = tapeblock_check_events,
59 .revalidate_disk = tapeblock_revalidate_disk, 59 .revalidate_disk = tapeblock_revalidate_disk,
60}; 60};
61 61
@@ -161,7 +161,6 @@ tapeblock_requeue(struct work_struct *work) {
161 161
162 spin_lock_irq(&device->blk_data.request_queue_lock); 162 spin_lock_irq(&device->blk_data.request_queue_lock);
163 while ( 163 while (
164 !blk_queue_plugged(queue) &&
165 blk_peek_request(queue) && 164 blk_peek_request(queue) &&
166 nr_queued < TAPEBLOCK_MIN_REQUEUE 165 nr_queued < TAPEBLOCK_MIN_REQUEUE
167 ) { 166 ) {
@@ -237,6 +236,7 @@ tapeblock_setup_device(struct tape_device * device)
237 disk->major = tapeblock_major; 236 disk->major = tapeblock_major;
238 disk->first_minor = device->first_minor; 237 disk->first_minor = device->first_minor;
239 disk->fops = &tapeblock_fops; 238 disk->fops = &tapeblock_fops;
239 disk->events = DISK_EVENT_MEDIA_CHANGE;
240 disk->private_data = tape_get_device(device); 240 disk->private_data = tape_get_device(device);
241 disk->queue = blkdat->request_queue; 241 disk->queue = blkdat->request_queue;
242 set_capacity(disk, 0); 242 set_capacity(disk, 0);
@@ -340,8 +340,8 @@ tapeblock_revalidate_disk(struct gendisk *disk)
340 return 0; 340 return 0;
341} 341}
342 342
343static int 343static unsigned int
344tapeblock_medium_changed(struct gendisk *disk) 344tapeblock_check_events(struct gendisk *disk, unsigned int clearing)
345{ 345{
346 struct tape_device *device; 346 struct tape_device *device;
347 347
@@ -349,7 +349,7 @@ tapeblock_medium_changed(struct gendisk *disk)
349 DBF_LH(6, "tapeblock_medium_changed(%p) = %d\n", 349 DBF_LH(6, "tapeblock_medium_changed(%p) = %d\n",
350 device, device->blk_data.medium_changed); 350 device, device->blk_data.medium_changed);
351 351
352 return device->blk_data.medium_changed; 352 return device->blk_data.medium_changed ? DISK_EVENT_MEDIA_CHANGE : 0;
353} 353}
354 354
355/* 355/*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 2d63c8ad1442..6d5c7ff43f5b 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -67,6 +67,13 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = {
67 67
68struct kmem_cache *scsi_sdb_cache; 68struct kmem_cache *scsi_sdb_cache;
69 69
70/*
71 * When to reinvoke queueing after a resource shortage. It's 3 msecs to
72 * not change behaviour from the previous unplug mechanism, experimentation
73 * may prove this needs changing.
74 */
75#define SCSI_QUEUE_DELAY 3
76
70static void scsi_run_queue(struct request_queue *q); 77static void scsi_run_queue(struct request_queue *q);
71 78
72/* 79/*
@@ -149,14 +156,7 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
149 /* 156 /*
150 * Requeue this command. It will go before all other commands 157 * Requeue this command. It will go before all other commands
151 * that are already in the queue. 158 * that are already in the queue.
152 * 159 */
153 * NOTE: there is magic here about the way the queue is plugged if
154 * we have no outstanding commands.
155 *
156 * Although we *don't* plug the queue, we call the request
157 * function. The SCSI request function detects the blocked condition
158 * and plugs the queue appropriately.
159 */
160 spin_lock_irqsave(q->queue_lock, flags); 160 spin_lock_irqsave(q->queue_lock, flags);
161 blk_requeue_request(q, cmd->request); 161 blk_requeue_request(q, cmd->request);
162 spin_unlock_irqrestore(q->queue_lock, flags); 162 spin_unlock_irqrestore(q->queue_lock, flags);
@@ -1226,11 +1226,11 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret)
1226 case BLKPREP_DEFER: 1226 case BLKPREP_DEFER:
1227 /* 1227 /*
1228 * If we defer, the blk_peek_request() returns NULL, but the 1228 * If we defer, the blk_peek_request() returns NULL, but the
1229 * queue must be restarted, so we plug here if no returning 1229 * queue must be restarted, so we schedule a callback to happen
1230 * command will automatically do that. 1230 * shortly.
1231 */ 1231 */
1232 if (sdev->device_busy == 0) 1232 if (sdev->device_busy == 0)
1233 blk_plug_device(q); 1233 blk_delay_queue(q, SCSI_QUEUE_DELAY);
1234 break; 1234 break;
1235 default: 1235 default:
1236 req->cmd_flags |= REQ_DONTPREP; 1236 req->cmd_flags |= REQ_DONTPREP;
@@ -1269,7 +1269,7 @@ static inline int scsi_dev_queue_ready(struct request_queue *q,
1269 sdev_printk(KERN_INFO, sdev, 1269 sdev_printk(KERN_INFO, sdev,
1270 "unblocking device at zero depth\n")); 1270 "unblocking device at zero depth\n"));
1271 } else { 1271 } else {
1272 blk_plug_device(q); 1272 blk_delay_queue(q, SCSI_QUEUE_DELAY);
1273 return 0; 1273 return 0;
1274 } 1274 }
1275 } 1275 }
@@ -1499,7 +1499,7 @@ static void scsi_request_fn(struct request_queue *q)
1499 * the host is no longer able to accept any more requests. 1499 * the host is no longer able to accept any more requests.
1500 */ 1500 */
1501 shost = sdev->host; 1501 shost = sdev->host;
1502 while (!blk_queue_plugged(q)) { 1502 for (;;) {
1503 int rtn; 1503 int rtn;
1504 /* 1504 /*
1505 * get next queueable request. We do this early to make sure 1505 * get next queueable request. We do this early to make sure
@@ -1578,15 +1578,8 @@ static void scsi_request_fn(struct request_queue *q)
1578 */ 1578 */
1579 rtn = scsi_dispatch_cmd(cmd); 1579 rtn = scsi_dispatch_cmd(cmd);
1580 spin_lock_irq(q->queue_lock); 1580 spin_lock_irq(q->queue_lock);
1581 if(rtn) { 1581 if (rtn)
1582 /* we're refusing the command; because of 1582 goto out_delay;
1583 * the way locks get dropped, we need to
1584 * check here if plugging is required */
1585 if(sdev->device_busy == 0)
1586 blk_plug_device(q);
1587
1588 break;
1589 }
1590 } 1583 }
1591 1584
1592 goto out; 1585 goto out;
@@ -1605,9 +1598,10 @@ static void scsi_request_fn(struct request_queue *q)
1605 spin_lock_irq(q->queue_lock); 1598 spin_lock_irq(q->queue_lock);
1606 blk_requeue_request(q, req); 1599 blk_requeue_request(q, req);
1607 sdev->device_busy--; 1600 sdev->device_busy--;
1608 if(sdev->device_busy == 0) 1601out_delay:
1609 blk_plug_device(q); 1602 if (sdev->device_busy == 0)
1610 out: 1603 blk_delay_queue(q, SCSI_QUEUE_DELAY);
1604out:
1611 /* must be careful here...if we trigger the ->remove() function 1605 /* must be careful here...if we trigger the ->remove() function
1612 * we cannot be holding the q lock */ 1606 * we cannot be holding the q lock */
1613 spin_unlock_irq(q->queue_lock); 1607 spin_unlock_irq(q->queue_lock);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 5c3ccfc6b622..2941d2d92c94 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3913,7 +3913,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3913 if (!get_device(dev)) 3913 if (!get_device(dev))
3914 return; 3914 return;
3915 3915
3916 while (!blk_queue_plugged(q)) { 3916 while (1) {
3917 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) && 3917 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
3918 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)) 3918 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
3919 break; 3919 break;
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 927e99cb7225..c6fcf76cade5 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -173,11 +173,7 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
173 int ret; 173 int ret;
174 int (*handler)(struct Scsi_Host *, struct sas_rphy *, struct request *); 174 int (*handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);
175 175
176 while (!blk_queue_plugged(q)) { 176 while ((req = blk_fetch_request(q)) != NULL) {
177 req = blk_fetch_request(q);
178 if (!req)
179 break;
180
181 spin_unlock_irq(q->queue_lock); 177 spin_unlock_irq(q->queue_lock);
182 178
183 handler = to_sas_internal(shost->transportt)->f->smp_handler; 179 handler = to_sas_internal(shost->transportt)->f->smp_handler;
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c
index 5f63c3b83828..4f64183b27fa 100644
--- a/drivers/sh/clk/core.c
+++ b/drivers/sh/clk/core.c
@@ -21,7 +21,7 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/sysdev.h> 24#include <linux/syscore_ops.h>
25#include <linux/seq_file.h> 25#include <linux/seq_file.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/io.h> 27#include <linux/io.h>
@@ -630,68 +630,36 @@ long clk_round_parent(struct clk *clk, unsigned long target,
630EXPORT_SYMBOL_GPL(clk_round_parent); 630EXPORT_SYMBOL_GPL(clk_round_parent);
631 631
632#ifdef CONFIG_PM 632#ifdef CONFIG_PM
633static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) 633static void clks_core_resume(void)
634{ 634{
635 static pm_message_t prev_state;
636 struct clk *clkp; 635 struct clk *clkp;
637 636
638 switch (state.event) { 637 list_for_each_entry(clkp, &clock_list, node) {
639 case PM_EVENT_ON: 638 if (likely(clkp->ops)) {
640 /* Resumeing from hibernation */ 639 unsigned long rate = clkp->rate;
641 if (prev_state.event != PM_EVENT_FREEZE) 640
642 break; 641 if (likely(clkp->ops->set_parent))
643 642 clkp->ops->set_parent(clkp,
644 list_for_each_entry(clkp, &clock_list, node) { 643 clkp->parent);
645 if (likely(clkp->ops)) { 644 if (likely(clkp->ops->set_rate))
646 unsigned long rate = clkp->rate; 645 clkp->ops->set_rate(clkp, rate);
647 646 else if (likely(clkp->ops->recalc))
648 if (likely(clkp->ops->set_parent)) 647 clkp->rate = clkp->ops->recalc(clkp);
649 clkp->ops->set_parent(clkp,
650 clkp->parent);
651 if (likely(clkp->ops->set_rate))
652 clkp->ops->set_rate(clkp, rate);
653 else if (likely(clkp->ops->recalc))
654 clkp->rate = clkp->ops->recalc(clkp);
655 }
656 } 648 }
657 break;
658 case PM_EVENT_FREEZE:
659 break;
660 case PM_EVENT_SUSPEND:
661 break;
662 } 649 }
663
664 prev_state = state;
665 return 0;
666}
667
668static int clks_sysdev_resume(struct sys_device *dev)
669{
670 return clks_sysdev_suspend(dev, PMSG_ON);
671} 650}
672 651
673static struct sysdev_class clks_sysdev_class = { 652static struct syscore_ops clks_syscore_ops = {
674 .name = "clks", 653 .resume = clks_core_resume,
675};
676
677static struct sysdev_driver clks_sysdev_driver = {
678 .suspend = clks_sysdev_suspend,
679 .resume = clks_sysdev_resume,
680};
681
682static struct sys_device clks_sysdev_dev = {
683 .cls = &clks_sysdev_class,
684}; 654};
685 655
686static int __init clk_sysdev_init(void) 656static int __init clk_syscore_init(void)
687{ 657{
688 sysdev_class_register(&clks_sysdev_class); 658 register_syscore_ops(&clks_syscore_ops);
689 sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
690 sysdev_register(&clks_sysdev_dev);
691 659
692 return 0; 660 return 0;
693} 661}
694subsys_initcall(clk_sysdev_init); 662subsys_initcall(clk_syscore_init);
695#endif 663#endif
696 664
697/* 665/*
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index 9739431092d1..5833afbf08d7 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -25,6 +25,7 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/sh_intc.h> 26#include <linux/sh_intc.h>
27#include <linux/sysdev.h> 27#include <linux/sysdev.h>
28#include <linux/syscore_ops.h>
28#include <linux/list.h> 29#include <linux/list.h>
29#include <linux/spinlock.h> 30#include <linux/spinlock.h>
30#include <linux/radix-tree.h> 31#include <linux/radix-tree.h>
@@ -376,91 +377,89 @@ err0:
376 return -ENOMEM; 377 return -ENOMEM;
377} 378}
378 379
379static ssize_t 380static int intc_suspend(void)
380show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf)
381{ 381{
382 struct intc_desc_int *d; 382 struct intc_desc_int *d;
383 383
384 d = container_of(dev, struct intc_desc_int, sysdev); 384 list_for_each_entry(d, &intc_list, list) {
385 int irq;
385 386
386 return sprintf(buf, "%s\n", d->chip.name); 387 /* enable wakeup irqs belonging to this intc controller */
387} 388 for_each_active_irq(irq) {
389 struct irq_data *data;
390 struct irq_desc *desc;
391 struct irq_chip *chip;
388 392
389static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL); 393 data = irq_get_irq_data(irq);
394 chip = irq_data_get_irq_chip(data);
395 if (chip != &d->chip)
396 continue;
397 desc = irq_to_desc(irq);
398 if ((desc->status & IRQ_WAKEUP))
399 chip->irq_enable(data);
400 }
401 }
402
403 return 0;
404}
390 405
391static int intc_suspend(struct sys_device *dev, pm_message_t state) 406static void intc_resume(void)
392{ 407{
393 struct intc_desc_int *d; 408 struct intc_desc_int *d;
394 struct irq_data *data;
395 struct irq_desc *desc;
396 struct irq_chip *chip;
397 int irq;
398
399 /* get intc controller associated with this sysdev */
400 d = container_of(dev, struct intc_desc_int, sysdev);
401 409
402 switch (state.event) { 410 list_for_each_entry(d, &intc_list, list) {
403 case PM_EVENT_ON: 411 int irq;
404 if (d->state.event != PM_EVENT_FREEZE)
405 break;
406 412
407 for_each_active_irq(irq) { 413 for_each_active_irq(irq) {
408 desc = irq_to_desc(irq); 414 struct irq_data *data;
415 struct irq_desc *desc;
416 struct irq_chip *chip;
417
409 data = irq_get_irq_data(irq); 418 data = irq_get_irq_data(irq);
410 chip = irq_data_get_irq_chip(data); 419 chip = irq_data_get_irq_chip(data);
411
412 /* 420 /*
413 * This will catch the redirect and VIRQ cases 421 * This will catch the redirect and VIRQ cases
414 * due to the dummy_irq_chip being inserted. 422 * due to the dummy_irq_chip being inserted.
415 */ 423 */
416 if (chip != &d->chip) 424 if (chip != &d->chip)
417 continue; 425 continue;
426 desc = irq_to_desc(irq);
418 if (desc->status & IRQ_DISABLED) 427 if (desc->status & IRQ_DISABLED)
419 chip->irq_disable(data); 428 chip->irq_disable(data);
420 else 429 else
421 chip->irq_enable(data); 430 chip->irq_enable(data);
422 } 431 }
423 break;
424 case PM_EVENT_FREEZE:
425 /* nothing has to be done */
426 break;
427 case PM_EVENT_SUSPEND:
428 /* enable wakeup irqs belonging to this intc controller */
429 for_each_active_irq(irq) {
430 desc = irq_to_desc(irq);
431 data = irq_get_irq_data(irq);
432 chip = irq_data_get_irq_chip(data);
433
434 if (chip != &d->chip)
435 continue;
436 if ((desc->status & IRQ_WAKEUP))
437 chip->irq_enable(data);
438 }
439 break;
440 } 432 }
441
442 d->state = state;
443
444 return 0;
445} 433}
446 434
447static int intc_resume(struct sys_device *dev) 435struct syscore_ops intc_syscore_ops = {
448{ 436 .suspend = intc_suspend,
449 return intc_suspend(dev, PMSG_ON); 437 .resume = intc_resume,
450} 438};
451 439
452struct sysdev_class intc_sysdev_class = { 440struct sysdev_class intc_sysdev_class = {
453 .name = "intc", 441 .name = "intc",
454 .suspend = intc_suspend,
455 .resume = intc_resume,
456}; 442};
457 443
458/* register this intc as sysdev to allow suspend/resume */ 444static ssize_t
445show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf)
446{
447 struct intc_desc_int *d;
448
449 d = container_of(dev, struct intc_desc_int, sysdev);
450
451 return sprintf(buf, "%s\n", d->chip.name);
452}
453
454static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
455
459static int __init register_intc_sysdevs(void) 456static int __init register_intc_sysdevs(void)
460{ 457{
461 struct intc_desc_int *d; 458 struct intc_desc_int *d;
462 int error; 459 int error;
463 460
461 register_syscore_ops(&intc_syscore_ops);
462
464 error = sysdev_class_register(&intc_sysdev_class); 463 error = sysdev_class_register(&intc_sysdev_class);
465 if (!error) { 464 if (!error) {
466 list_for_each_entry(d, &intc_list, list) { 465 list_for_each_entry(d, &intc_list, list) {
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
index 0cf8260971d4..df36a421e675 100644
--- a/drivers/sh/intc/internals.h
+++ b/drivers/sh/intc/internals.h
@@ -53,7 +53,6 @@ struct intc_desc_int {
53 struct list_head list; 53 struct list_head list;
54 struct sys_device sysdev; 54 struct sys_device sysdev;
55 struct radix_tree_root tree; 55 struct radix_tree_root tree;
56 pm_message_t state;
57 raw_spinlock_t lock; 56 raw_spinlock_t lock;
58 unsigned int index; 57 unsigned int index;
59 unsigned long *reg; 58 unsigned long *reg;
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 5c2b092a915e..5a4e0afb9ad6 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -324,6 +324,7 @@ struct vendor_data {
324 bool unidir; 324 bool unidir;
325 bool extended_cr; 325 bool extended_cr;
326 bool pl023; 326 bool pl023;
327 bool loopback;
327}; 328};
328 329
329/** 330/**
@@ -1983,7 +1984,7 @@ static int pl022_setup(struct spi_device *spi)
1983 1984
1984 SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8); 1985 SSP_WRITE_BITS(chip->cr0, clk_freq.scr, SSP_CR0_MASK_SCR, 8);
1985 /* Loopback is available on all versions except PL023 */ 1986 /* Loopback is available on all versions except PL023 */
1986 if (!pl022->vendor->pl023) { 1987 if (pl022->vendor->loopback) {
1987 if (spi->mode & SPI_LOOP) 1988 if (spi->mode & SPI_LOOP)
1988 tmp = LOOPBACK_ENABLED; 1989 tmp = LOOPBACK_ENABLED;
1989 else 1990 else
@@ -2233,6 +2234,7 @@ static struct vendor_data vendor_arm = {
2233 .unidir = false, 2234 .unidir = false,
2234 .extended_cr = false, 2235 .extended_cr = false,
2235 .pl023 = false, 2236 .pl023 = false,
2237 .loopback = true,
2236}; 2238};
2237 2239
2238 2240
@@ -2242,6 +2244,7 @@ static struct vendor_data vendor_st = {
2242 .unidir = false, 2244 .unidir = false,
2243 .extended_cr = true, 2245 .extended_cr = true,
2244 .pl023 = false, 2246 .pl023 = false,
2247 .loopback = true,
2245}; 2248};
2246 2249
2247static struct vendor_data vendor_st_pl023 = { 2250static struct vendor_data vendor_st_pl023 = {
@@ -2250,6 +2253,16 @@ static struct vendor_data vendor_st_pl023 = {
2250 .unidir = false, 2253 .unidir = false,
2251 .extended_cr = true, 2254 .extended_cr = true,
2252 .pl023 = true, 2255 .pl023 = true,
2256 .loopback = false,
2257};
2258
2259static struct vendor_data vendor_db5500_pl023 = {
2260 .fifodepth = 32,
2261 .max_bpw = 32,
2262 .unidir = false,
2263 .extended_cr = true,
2264 .pl023 = true,
2265 .loopback = true,
2253}; 2266};
2254 2267
2255static struct amba_id pl022_ids[] = { 2268static struct amba_id pl022_ids[] = {
@@ -2283,6 +2296,11 @@ static struct amba_id pl022_ids[] = {
2283 .mask = 0xffffffff, 2296 .mask = 0xffffffff,
2284 .data = &vendor_st_pl023, 2297 .data = &vendor_st_pl023,
2285 }, 2298 },
2299 {
2300 .id = 0x10080023,
2301 .mask = 0xffffffff,
2302 .data = &vendor_db5500_pl023,
2303 },
2286 { 0, 0 }, 2304 { 0, 0 },
2287}; 2305};
2288 2306
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 3a5ed06d3d2f..6f86ba0175ac 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -517,7 +517,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
517 dev_vdbg(&spi->dev, "read-%d %02x\n", 517 dev_vdbg(&spi->dev, "read-%d %02x\n",
518 word_len, *(rx - 1)); 518 word_len, *(rx - 1));
519 } 519 }
520 } while (c > (word_len>>3)); 520 } while (c);
521 } else if (word_len <= 16) { 521 } else if (word_len <= 16) {
522 u16 *rx; 522 u16 *rx;
523 const u16 *tx; 523 const u16 *tx;
@@ -564,7 +564,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
564 dev_vdbg(&spi->dev, "read-%d %04x\n", 564 dev_vdbg(&spi->dev, "read-%d %04x\n",
565 word_len, *(rx - 1)); 565 word_len, *(rx - 1));
566 } 566 }
567 } while (c > (word_len>>3)); 567 } while (c >= 2);
568 } else if (word_len <= 32) { 568 } else if (word_len <= 32) {
569 u32 *rx; 569 u32 *rx;
570 const u32 *tx; 570 const u32 *tx;
@@ -611,7 +611,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
611 dev_vdbg(&spi->dev, "read-%d %08x\n", 611 dev_vdbg(&spi->dev, "read-%d %08x\n",
612 word_len, *(rx - 1)); 612 word_len, *(rx - 1));
613 } 613 }
614 } while (c > (word_len>>3)); 614 } while (c >= 4);
615 } 615 }
616 616
617 /* for TX_ONLY mode, be sure all words have shifted out */ 617 /* for TX_ONLY mode, be sure all words have shifted out */
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index 4d2c75df886c..c69c6f2c2c5c 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -18,6 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/mfd/core.h>
21#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
22#include <linux/spi/spi_bitbang.h> 23#include <linux/spi/spi_bitbang.h>
23#include <linux/spi/xilinx_spi.h> 24#include <linux/spi/xilinx_spi.h>
@@ -470,7 +471,7 @@ static int __devinit xilinx_spi_probe(struct platform_device *dev)
470 struct spi_master *master; 471 struct spi_master *master;
471 u8 i; 472 u8 i;
472 473
473 pdata = dev->dev.platform_data; 474 pdata = mfd_get_data(dev);
474 if (pdata) { 475 if (pdata) {
475 num_cs = pdata->num_chipselect; 476 num_cs = pdata->num_chipselect;
476 little_endian = pdata->little_endian; 477 little_endian = pdata->little_endian;
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ccaa2009414b..18b43fcb4171 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -55,11 +55,7 @@ source "drivers/staging/cx25821/Kconfig"
55 55
56source "drivers/staging/tm6000/Kconfig" 56source "drivers/staging/tm6000/Kconfig"
57 57
58source "drivers/staging/dabusb/Kconfig" 58source "drivers/staging/cxd2099/Kconfig"
59
60source "drivers/staging/se401/Kconfig"
61
62source "drivers/staging/usbvideo/Kconfig"
63 59
64source "drivers/staging/usbip/Kconfig" 60source "drivers/staging/usbip/Kconfig"
65 61
@@ -183,5 +179,7 @@ source "drivers/staging/ste_rmi4/Kconfig"
183 179
184source "drivers/staging/gma500/Kconfig" 180source "drivers/staging/gma500/Kconfig"
185 181
182source "drivers/staging/altera-stapl/Kconfig"
183
186endif # !STAGING_EXCLUDE_BUILD 184endif # !STAGING_EXCLUDE_BUILD
187endif # STAGING 185endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 3b223cbf86b4..cfd13cd55efb 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -10,9 +10,7 @@ obj-$(CONFIG_SLICOSS) += slicoss/
10obj-$(CONFIG_VIDEO_GO7007) += go7007/ 10obj-$(CONFIG_VIDEO_GO7007) += go7007/
11obj-$(CONFIG_VIDEO_CX25821) += cx25821/ 11obj-$(CONFIG_VIDEO_CX25821) += cx25821/
12obj-$(CONFIG_VIDEO_TM6000) += tm6000/ 12obj-$(CONFIG_VIDEO_TM6000) += tm6000/
13obj-$(CONFIG_USB_DABUSB) += dabusb/ 13obj-$(CONFIG_DVB_CXD2099) += cxd2099/
14obj-$(CONFIG_USB_VICAM) += usbvideo/
15obj-$(CONFIG_USB_SE401) += se401/
16obj-$(CONFIG_LIRC_STAGING) += lirc/ 14obj-$(CONFIG_LIRC_STAGING) += lirc/
17obj-$(CONFIG_USB_IP_COMMON) += usbip/ 15obj-$(CONFIG_USB_IP_COMMON) += usbip/
18obj-$(CONFIG_W35UND) += winbond/ 16obj-$(CONFIG_W35UND) += winbond/
@@ -70,6 +68,7 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/
70obj-$(CONFIG_FT1000) += ft1000/ 68obj-$(CONFIG_FT1000) += ft1000/
71obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ 69obj-$(CONFIG_SND_INTEL_SST) += intel_sst/
72obj-$(CONFIG_SPEAKUP) += speakup/ 70obj-$(CONFIG_SPEAKUP) += speakup/
71obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
73obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ 72obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
74obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ 73obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
75obj-$(CONFIG_DRM_PSB) += gma500/ 74obj-$(CONFIG_DRM_PSB) += gma500/
diff --git a/drivers/staging/altera-stapl/Kconfig b/drivers/staging/altera-stapl/Kconfig
new file mode 100644
index 000000000000..7f01d8e93992
--- /dev/null
+++ b/drivers/staging/altera-stapl/Kconfig
@@ -0,0 +1,8 @@
1comment "Altera FPGA firmware download module"
2
3config ALTERA_STAPL
4 tristate "Altera FPGA firmware download module"
5 depends on I2C
6 default n
7 help
8 An Altera FPGA module. Say Y when you want to support this tool.
diff --git a/drivers/staging/altera-stapl/Makefile b/drivers/staging/altera-stapl/Makefile
new file mode 100644
index 000000000000..055f61ee781a
--- /dev/null
+++ b/drivers/staging/altera-stapl/Makefile
@@ -0,0 +1,3 @@
1altera-stapl-objs = altera-lpt.o altera-jtag.o altera-comp.o altera.o
2
3obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o
diff --git a/drivers/staging/altera-stapl/altera-comp.c b/drivers/staging/altera-stapl/altera-comp.c
new file mode 100644
index 000000000000..49b103bedaaf
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-comp.c
@@ -0,0 +1,142 @@
1/*
2 * altera-comp.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include "altera-exprt.h"
28
29#define SHORT_BITS 16
30#define CHAR_BITS 8
31#define DATA_BLOB_LENGTH 3
32#define MATCH_DATA_LENGTH 8192
33#define ALTERA_REQUEST_SIZE 1024
34#define ALTERA_BUFFER_SIZE (MATCH_DATA_LENGTH + ALTERA_REQUEST_SIZE)
35
36static u32 altera_bits_req(u32 n)
37{
38 u32 result = SHORT_BITS;
39
40 if (n == 0)
41 result = 1;
42 else {
43 /* Look for the highest non-zero bit position */
44 while ((n & (1 << (SHORT_BITS - 1))) == 0) {
45 n <<= 1;
46 --result;
47 }
48 }
49
50 return result;
51}
52
53static u32 altera_read_packed(u8 *buffer, u32 bits, u32 *bits_avail,
54 u32 *in_index)
55{
56 u32 result = 0;
57 u32 shift = 0;
58 u32 databyte = 0;
59
60 while (bits > 0) {
61 databyte = buffer[*in_index];
62 result |= (((databyte >> (CHAR_BITS - *bits_avail))
63 & (0xff >> (CHAR_BITS - *bits_avail))) << shift);
64
65 if (bits <= *bits_avail) {
66 result &= (0xffff >> (SHORT_BITS - (bits + shift)));
67 *bits_avail -= bits;
68 bits = 0;
69 } else {
70 ++(*in_index);
71 shift += *bits_avail;
72 bits -= *bits_avail;
73 *bits_avail = CHAR_BITS;
74 }
75 }
76
77 return result;
78}
79
80u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version)
81{
82 u32 i, j, data_length = 0L;
83 u32 offset, length;
84 u32 match_data_length = MATCH_DATA_LENGTH;
85 u32 bits_avail = CHAR_BITS;
86 u32 in_index = 0L;
87
88 if (version > 0)
89 --match_data_length;
90
91 for (i = 0; i < out_length; ++i)
92 out[i] = 0;
93
94 /* Read number of bytes in data. */
95 for (i = 0; i < sizeof(in_length); ++i) {
96 data_length = data_length | (
97 altera_read_packed(in,
98 CHAR_BITS,
99 &bits_avail,
100 &in_index) << (i * CHAR_BITS));
101 }
102
103 if (data_length > out_length) {
104 data_length = 0L;
105 return data_length;
106 }
107
108 i = 0;
109 while (i < data_length) {
110 /* A 0 bit indicates literal data. */
111 if (altera_read_packed(in, 1, &bits_avail,
112 &in_index) == 0) {
113 for (j = 0; j < DATA_BLOB_LENGTH; ++j) {
114 if (i < data_length) {
115 out[i] = (u8)altera_read_packed(in,
116 CHAR_BITS,
117 &bits_avail,
118 &in_index);
119 i++;
120 }
121 }
122 } else {
123 /* A 1 bit indicates offset/length to follow. */
124 offset = altera_read_packed(in, altera_bits_req((s16)
125 (i > match_data_length ?
126 match_data_length : i)),
127 &bits_avail,
128 &in_index);
129 length = altera_read_packed(in, CHAR_BITS,
130 &bits_avail,
131 &in_index);
132 for (j = 0; j < length; ++j) {
133 if (i < data_length) {
134 out[i] = out[i - offset];
135 i++;
136 }
137 }
138 }
139 }
140
141 return data_length;
142}
diff --git a/drivers/staging/altera-stapl/altera-exprt.h b/drivers/staging/altera-stapl/altera-exprt.h
new file mode 100644
index 000000000000..39c38d84a670
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-exprt.h
@@ -0,0 +1,33 @@
1/*
2 * altera-exprt.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef ALTERA_EXPRT_H
27#define ALTERA_EXPRT_H
28
29
30u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version);
31int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo);
32
33#endif /* ALTERA_EXPRT_H */
diff --git a/drivers/staging/altera-stapl/altera-jtag.c b/drivers/staging/altera-stapl/altera-jtag.c
new file mode 100644
index 000000000000..6b633b179a7e
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-jtag.c
@@ -0,0 +1,1020 @@
1/*
2 * altera-jtag.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/firmware.h>
27#include <linux/slab.h>
28#include <staging/altera.h>
29#include "altera-exprt.h"
30#include "altera-jtag.h"
31
32#define alt_jtag_io(a, b, c)\
33 astate->config->jtag_io(astate->config->dev, a, b, c);
34
35#define alt_malloc(a) kzalloc(a, GFP_KERNEL);
36
37/*
38 * This structure shows, for each JTAG state, which state is reached after
39 * a single TCK clock cycle with TMS high or TMS low, respectively. This
40 * describes all possible state transitions in the JTAG state machine.
41 */
42struct altera_jtag_machine {
43 enum altera_jtag_state tms_high;
44 enum altera_jtag_state tms_low;
45};
46
47static const struct altera_jtag_machine altera_transitions[] = {
48 /* RESET */ { RESET, IDLE },
49 /* IDLE */ { DRSELECT, IDLE },
50 /* DRSELECT */ { IRSELECT, DRCAPTURE },
51 /* DRCAPTURE */ { DREXIT1, DRSHIFT },
52 /* DRSHIFT */ { DREXIT1, DRSHIFT },
53 /* DREXIT1 */ { DRUPDATE, DRPAUSE },
54 /* DRPAUSE */ { DREXIT2, DRPAUSE },
55 /* DREXIT2 */ { DRUPDATE, DRSHIFT },
56 /* DRUPDATE */ { DRSELECT, IDLE },
57 /* IRSELECT */ { RESET, IRCAPTURE },
58 /* IRCAPTURE */ { IREXIT1, IRSHIFT },
59 /* IRSHIFT */ { IREXIT1, IRSHIFT },
60 /* IREXIT1 */ { IRUPDATE, IRPAUSE },
61 /* IRPAUSE */ { IREXIT2, IRPAUSE },
62 /* IREXIT2 */ { IRUPDATE, IRSHIFT },
63 /* IRUPDATE */ { DRSELECT, IDLE }
64};
65
66/*
67 * This table contains the TMS value to be used to take the NEXT STEP on
68 * the path to the desired state. The array index is the current state,
69 * and the bit position is the desired endstate. To find out which state
70 * is used as the intermediate state, look up the TMS value in the
71 * altera_transitions[] table.
72 */
73static const u16 altera_jtag_path_map[16] = {
74 /* RST RTI SDRS CDR SDR E1DR PDR E2DR */
75 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
76 /* UDR SIRS CIR SIR E1IR PIR E2IR UIR */
77 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
78};
79
80/* Flag bits for alt_jtag_io() function */
81#define TMS_HIGH 1
82#define TMS_LOW 0
83#define TDI_HIGH 1
84#define TDI_LOW 0
85#define READ_TDO 1
86#define IGNORE_TDO 0
87
88int altera_jinit(struct altera_state *astate)
89{
90 struct altera_jtag *js = &astate->js;
91
92 /* initial JTAG state is unknown */
93 js->jtag_state = ILLEGAL_JTAG_STATE;
94
95 /* initialize to default state */
96 js->drstop_state = IDLE;
97 js->irstop_state = IDLE;
98 js->dr_pre = 0;
99 js->dr_post = 0;
100 js->ir_pre = 0;
101 js->ir_post = 0;
102 js->dr_length = 0;
103 js->ir_length = 0;
104
105 js->dr_pre_data = NULL;
106 js->dr_post_data = NULL;
107 js->ir_pre_data = NULL;
108 js->ir_post_data = NULL;
109 js->dr_buffer = NULL;
110 js->ir_buffer = NULL;
111
112 return 0;
113}
114
115int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
116{
117 js->drstop_state = state;
118
119 return 0;
120}
121
122int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
123{
124 js->irstop_state = state;
125
126 return 0;
127}
128
129int altera_set_dr_pre(struct altera_jtag *js,
130 u32 count, u32 start_index,
131 u8 *preamble_data)
132{
133 int status = 0;
134 u32 i;
135 u32 j;
136
137 if (count > js->dr_pre) {
138 kfree(js->dr_pre_data);
139 js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
140 if (js->dr_pre_data == NULL)
141 status = -ENOMEM;
142 else
143 js->dr_pre = count;
144 } else
145 js->dr_pre = count;
146
147 if (status == 0) {
148 for (i = 0; i < count; ++i) {
149 j = i + start_index;
150
151 if (preamble_data == NULL)
152 js->dr_pre_data[i >> 3] |= (1 << (i & 7));
153 else {
154 if (preamble_data[j >> 3] & (1 << (j & 7)))
155 js->dr_pre_data[i >> 3] |=
156 (1 << (i & 7));
157 else
158 js->dr_pre_data[i >> 3] &=
159 ~(u32)(1 << (i & 7));
160
161 }
162 }
163 }
164
165 return status;
166}
167
168int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
169 u8 *preamble_data)
170{
171 int status = 0;
172 u32 i;
173 u32 j;
174
175 if (count > js->ir_pre) {
176 kfree(js->ir_pre_data);
177 js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
178 if (js->ir_pre_data == NULL)
179 status = -ENOMEM;
180 else
181 js->ir_pre = count;
182
183 } else
184 js->ir_pre = count;
185
186 if (status == 0) {
187 for (i = 0; i < count; ++i) {
188 j = i + start_index;
189 if (preamble_data == NULL)
190 js->ir_pre_data[i >> 3] |= (1 << (i & 7));
191 else {
192 if (preamble_data[j >> 3] & (1 << (j & 7)))
193 js->ir_pre_data[i >> 3] |=
194 (1 << (i & 7));
195 else
196 js->ir_pre_data[i >> 3] &=
197 ~(u32)(1 << (i & 7));
198
199 }
200 }
201 }
202
203 return status;
204}
205
206int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
207 u8 *postamble_data)
208{
209 int status = 0;
210 u32 i;
211 u32 j;
212
213 if (count > js->dr_post) {
214 kfree(js->dr_post_data);
215 js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
216
217 if (js->dr_post_data == NULL)
218 status = -ENOMEM;
219 else
220 js->dr_post = count;
221
222 } else
223 js->dr_post = count;
224
225 if (status == 0) {
226 for (i = 0; i < count; ++i) {
227 j = i + start_index;
228
229 if (postamble_data == NULL)
230 js->dr_post_data[i >> 3] |= (1 << (i & 7));
231 else {
232 if (postamble_data[j >> 3] & (1 << (j & 7)))
233 js->dr_post_data[i >> 3] |=
234 (1 << (i & 7));
235 else
236 js->dr_post_data[i >> 3] &=
237 ~(u32)(1 << (i & 7));
238
239 }
240 }
241 }
242
243 return status;
244}
245
246int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
247 u8 *postamble_data)
248{
249 int status = 0;
250 u32 i;
251 u32 j;
252
253 if (count > js->ir_post) {
254 kfree(js->ir_post_data);
255 js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
256 if (js->ir_post_data == NULL)
257 status = -ENOMEM;
258 else
259 js->ir_post = count;
260
261 } else
262 js->ir_post = count;
263
264 if (status != 0)
265 return status;
266
267 for (i = 0; i < count; ++i) {
268 j = i + start_index;
269
270 if (postamble_data == NULL)
271 js->ir_post_data[i >> 3] |= (1 << (i & 7));
272 else {
273 if (postamble_data[j >> 3] & (1 << (j & 7)))
274 js->ir_post_data[i >> 3] |= (1 << (i & 7));
275 else
276 js->ir_post_data[i >> 3] &=
277 ~(u32)(1 << (i & 7));
278
279 }
280 }
281
282 return status;
283}
284
285static void altera_jreset_idle(struct altera_state *astate)
286{
287 struct altera_jtag *js = &astate->js;
288 int i;
289 /* Go to Test Logic Reset (no matter what the starting state may be) */
290 for (i = 0; i < 5; ++i)
291 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
292
293 /* Now step to Run Test / Idle */
294 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
295 js->jtag_state = IDLE;
296}
297
298int altera_goto_jstate(struct altera_state *astate,
299 enum altera_jtag_state state)
300{
301 struct altera_jtag *js = &astate->js;
302 int tms;
303 int count = 0;
304 int status = 0;
305
306 if (js->jtag_state == ILLEGAL_JTAG_STATE)
307 /* initialize JTAG chain to known state */
308 altera_jreset_idle(astate);
309
310 if (js->jtag_state == state) {
311 /*
312 * We are already in the desired state.
313 * If it is a stable state, loop here.
314 * Otherwise do nothing (no clock cycles).
315 */
316 if ((state == IDLE) || (state == DRSHIFT) ||
317 (state == DRPAUSE) || (state == IRSHIFT) ||
318 (state == IRPAUSE)) {
319 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
320 } else if (state == RESET)
321 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
322
323 } else {
324 while ((js->jtag_state != state) && (count < 9)) {
325 /* Get TMS value to take a step toward desired state */
326 tms = (altera_jtag_path_map[js->jtag_state] &
327 (1 << state))
328 ? TMS_HIGH : TMS_LOW;
329
330 /* Take a step */
331 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
332
333 if (tms)
334 js->jtag_state =
335 altera_transitions[js->jtag_state].tms_high;
336 else
337 js->jtag_state =
338 altera_transitions[js->jtag_state].tms_low;
339
340 ++count;
341 }
342 }
343
344 if (js->jtag_state != state)
345 status = -EREMOTEIO;
346
347 return status;
348}
349
350int altera_wait_cycles(struct altera_state *astate,
351 s32 cycles,
352 enum altera_jtag_state wait_state)
353{
354 struct altera_jtag *js = &astate->js;
355 int tms;
356 s32 count;
357 int status = 0;
358
359 if (js->jtag_state != wait_state)
360 status = altera_goto_jstate(astate, wait_state);
361
362 if (status == 0) {
363 /*
364 * Set TMS high to loop in RESET state
365 * Set TMS low to loop in any other stable state
366 */
367 tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
368
369 for (count = 0L; count < cycles; count++)
370 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
371
372 }
373
374 return status;
375}
376
377int altera_wait_msecs(struct altera_state *astate,
378 s32 microseconds, enum altera_jtag_state wait_state)
379/*
380 * Causes JTAG hardware to sit in the specified stable
381 * state for the specified duration of real time. If
382 * no JTAG operations have been performed yet, then only
383 * a delay is performed. This permits the WAIT USECS
384 * statement to be used in VECTOR programs without causing
385 * any JTAG operations.
386 * Returns 0 for success, else appropriate error code.
387 */
388{
389 struct altera_jtag *js = &astate->js;
390 int status = 0;
391
392 if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
393 (js->jtag_state != wait_state))
394 status = altera_goto_jstate(astate, wait_state);
395
396 if (status == 0)
397 /* Wait for specified time interval */
398 udelay(microseconds);
399
400 return status;
401}
402
403static void altera_concatenate_data(u8 *buffer,
404 u8 *preamble_data,
405 u32 preamble_count,
406 u8 *target_data,
407 u32 start_index,
408 u32 target_count,
409 u8 *postamble_data,
410 u32 postamble_count)
411/*
412 * Copies preamble data, target data, and postamble data
413 * into one buffer for IR or DR scans.
414 */
415{
416 u32 i, j, k;
417
418 for (i = 0L; i < preamble_count; ++i) {
419 if (preamble_data[i >> 3L] & (1L << (i & 7L)))
420 buffer[i >> 3L] |= (1L << (i & 7L));
421 else
422 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
423
424 }
425
426 j = start_index;
427 k = preamble_count + target_count;
428 for (; i < k; ++i, ++j) {
429 if (target_data[j >> 3L] & (1L << (j & 7L)))
430 buffer[i >> 3L] |= (1L << (i & 7L));
431 else
432 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
433
434 }
435
436 j = 0L;
437 k = preamble_count + target_count + postamble_count;
438 for (; i < k; ++i, ++j) {
439 if (postamble_data[j >> 3L] & (1L << (j & 7L)))
440 buffer[i >> 3L] |= (1L << (i & 7L));
441 else
442 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
443
444 }
445}
446
447static int alt_jtag_drscan(struct altera_state *astate,
448 int start_state,
449 int count,
450 u8 *tdi,
451 u8 *tdo)
452{
453 int i = 0;
454 int tdo_bit = 0;
455 int status = 1;
456
457 /* First go to DRSHIFT state */
458 switch (start_state) {
459 case 0: /* IDLE */
460 alt_jtag_io(1, 0, 0); /* DRSELECT */
461 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
462 alt_jtag_io(0, 0, 0); /* DRSHIFT */
463 break;
464
465 case 1: /* DRPAUSE */
466 alt_jtag_io(1, 0, 0); /* DREXIT2 */
467 alt_jtag_io(1, 0, 0); /* DRUPDATE */
468 alt_jtag_io(1, 0, 0); /* DRSELECT */
469 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
470 alt_jtag_io(0, 0, 0); /* DRSHIFT */
471 break;
472
473 case 2: /* IRPAUSE */
474 alt_jtag_io(1, 0, 0); /* IREXIT2 */
475 alt_jtag_io(1, 0, 0); /* IRUPDATE */
476 alt_jtag_io(1, 0, 0); /* DRSELECT */
477 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
478 alt_jtag_io(0, 0, 0); /* DRSHIFT */
479 break;
480
481 default:
482 status = 0;
483 }
484
485 if (status) {
486 /* loop in the SHIFT-DR state */
487 for (i = 0; i < count; i++) {
488 tdo_bit = alt_jtag_io(
489 (i == count - 1),
490 tdi[i >> 3] & (1 << (i & 7)),
491 (tdo != NULL));
492
493 if (tdo != NULL) {
494 if (tdo_bit)
495 tdo[i >> 3] |= (1 << (i & 7));
496 else
497 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
498
499 }
500 }
501
502 alt_jtag_io(0, 0, 0); /* DRPAUSE */
503 }
504
505 return status;
506}
507
508static int alt_jtag_irscan(struct altera_state *astate,
509 int start_state,
510 int count,
511 u8 *tdi,
512 u8 *tdo)
513{
514 int i = 0;
515 int tdo_bit = 0;
516 int status = 1;
517
518 /* First go to IRSHIFT state */
519 switch (start_state) {
520 case 0: /* IDLE */
521 alt_jtag_io(1, 0, 0); /* DRSELECT */
522 alt_jtag_io(1, 0, 0); /* IRSELECT */
523 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
524 alt_jtag_io(0, 0, 0); /* IRSHIFT */
525 break;
526
527 case 1: /* DRPAUSE */
528 alt_jtag_io(1, 0, 0); /* DREXIT2 */
529 alt_jtag_io(1, 0, 0); /* DRUPDATE */
530 alt_jtag_io(1, 0, 0); /* DRSELECT */
531 alt_jtag_io(1, 0, 0); /* IRSELECT */
532 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
533 alt_jtag_io(0, 0, 0); /* IRSHIFT */
534 break;
535
536 case 2: /* IRPAUSE */
537 alt_jtag_io(1, 0, 0); /* IREXIT2 */
538 alt_jtag_io(1, 0, 0); /* IRUPDATE */
539 alt_jtag_io(1, 0, 0); /* DRSELECT */
540 alt_jtag_io(1, 0, 0); /* IRSELECT */
541 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
542 alt_jtag_io(0, 0, 0); /* IRSHIFT */
543 break;
544
545 default:
546 status = 0;
547 }
548
549 if (status) {
550 /* loop in the SHIFT-IR state */
551 for (i = 0; i < count; i++) {
552 tdo_bit = alt_jtag_io(
553 (i == count - 1),
554 tdi[i >> 3] & (1 << (i & 7)),
555 (tdo != NULL));
556 if (tdo != NULL) {
557 if (tdo_bit)
558 tdo[i >> 3] |= (1 << (i & 7));
559 else
560 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
561
562 }
563 }
564
565 alt_jtag_io(0, 0, 0); /* IRPAUSE */
566 }
567
568 return status;
569}
570
571static void altera_extract_target_data(u8 *buffer,
572 u8 *target_data,
573 u32 start_index,
574 u32 preamble_count,
575 u32 target_count)
576/*
577 * Copies target data from scan buffer, filtering out
578 * preamble and postamble data.
579 */
580{
581 u32 i;
582 u32 j;
583 u32 k;
584
585 j = preamble_count;
586 k = start_index + target_count;
587 for (i = start_index; i < k; ++i, ++j) {
588 if (buffer[j >> 3] & (1 << (j & 7)))
589 target_data[i >> 3] |= (1 << (i & 7));
590 else
591 target_data[i >> 3] &= ~(u32)(1 << (i & 7));
592
593 }
594}
595
596int altera_irscan(struct altera_state *astate,
597 u32 count,
598 u8 *tdi_data,
599 u32 start_index)
600/* Shifts data into instruction register */
601{
602 struct altera_jtag *js = &astate->js;
603 int start_code = 0;
604 u32 alloc_chars = 0;
605 u32 shift_count = js->ir_pre + count + js->ir_post;
606 int status = 0;
607 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
608
609 switch (js->jtag_state) {
610 case ILLEGAL_JTAG_STATE:
611 case RESET:
612 case IDLE:
613 start_code = 0;
614 start_state = IDLE;
615 break;
616
617 case DRSELECT:
618 case DRCAPTURE:
619 case DRSHIFT:
620 case DREXIT1:
621 case DRPAUSE:
622 case DREXIT2:
623 case DRUPDATE:
624 start_code = 1;
625 start_state = DRPAUSE;
626 break;
627
628 case IRSELECT:
629 case IRCAPTURE:
630 case IRSHIFT:
631 case IREXIT1:
632 case IRPAUSE:
633 case IREXIT2:
634 case IRUPDATE:
635 start_code = 2;
636 start_state = IRPAUSE;
637 break;
638
639 default:
640 status = -EREMOTEIO;
641 break;
642 }
643
644 if (status == 0)
645 if (js->jtag_state != start_state)
646 status = altera_goto_jstate(astate, start_state);
647
648 if (status == 0) {
649 if (shift_count > js->ir_length) {
650 alloc_chars = (shift_count + 7) >> 3;
651 kfree(js->ir_buffer);
652 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
653 if (js->ir_buffer == NULL)
654 status = -ENOMEM;
655 else
656 js->ir_length = alloc_chars * 8;
657
658 }
659 }
660
661 if (status == 0) {
662 /*
663 * Copy preamble data, IR data,
664 * and postamble data into a buffer
665 */
666 altera_concatenate_data(js->ir_buffer,
667 js->ir_pre_data,
668 js->ir_pre,
669 tdi_data,
670 start_index,
671 count,
672 js->ir_post_data,
673 js->ir_post);
674 /* Do the IRSCAN */
675 alt_jtag_irscan(astate,
676 start_code,
677 shift_count,
678 js->ir_buffer,
679 NULL);
680
681 /* alt_jtag_irscan() always ends in IRPAUSE state */
682 js->jtag_state = IRPAUSE;
683 }
684
685 if (status == 0)
686 if (js->irstop_state != IRPAUSE)
687 status = altera_goto_jstate(astate, js->irstop_state);
688
689
690 return status;
691}
692
693int altera_swap_ir(struct altera_state *astate,
694 u32 count,
695 u8 *in_data,
696 u32 in_index,
697 u8 *out_data,
698 u32 out_index)
699/* Shifts data into instruction register, capturing output data */
700{
701 struct altera_jtag *js = &astate->js;
702 int start_code = 0;
703 u32 alloc_chars = 0;
704 u32 shift_count = js->ir_pre + count + js->ir_post;
705 int status = 0;
706 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
707
708 switch (js->jtag_state) {
709 case ILLEGAL_JTAG_STATE:
710 case RESET:
711 case IDLE:
712 start_code = 0;
713 start_state = IDLE;
714 break;
715
716 case DRSELECT:
717 case DRCAPTURE:
718 case DRSHIFT:
719 case DREXIT1:
720 case DRPAUSE:
721 case DREXIT2:
722 case DRUPDATE:
723 start_code = 1;
724 start_state = DRPAUSE;
725 break;
726
727 case IRSELECT:
728 case IRCAPTURE:
729 case IRSHIFT:
730 case IREXIT1:
731 case IRPAUSE:
732 case IREXIT2:
733 case IRUPDATE:
734 start_code = 2;
735 start_state = IRPAUSE;
736 break;
737
738 default:
739 status = -EREMOTEIO;
740 break;
741 }
742
743 if (status == 0)
744 if (js->jtag_state != start_state)
745 status = altera_goto_jstate(astate, start_state);
746
747 if (status == 0) {
748 if (shift_count > js->ir_length) {
749 alloc_chars = (shift_count + 7) >> 3;
750 kfree(js->ir_buffer);
751 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
752 if (js->ir_buffer == NULL)
753 status = -ENOMEM;
754 else
755 js->ir_length = alloc_chars * 8;
756
757 }
758 }
759
760 if (status == 0) {
761 /*
762 * Copy preamble data, IR data,
763 * and postamble data into a buffer
764 */
765 altera_concatenate_data(js->ir_buffer,
766 js->ir_pre_data,
767 js->ir_pre,
768 in_data,
769 in_index,
770 count,
771 js->ir_post_data,
772 js->ir_post);
773
774 /* Do the IRSCAN */
775 alt_jtag_irscan(astate,
776 start_code,
777 shift_count,
778 js->ir_buffer,
779 js->ir_buffer);
780
781 /* alt_jtag_irscan() always ends in IRPAUSE state */
782 js->jtag_state = IRPAUSE;
783 }
784
785 if (status == 0)
786 if (js->irstop_state != IRPAUSE)
787 status = altera_goto_jstate(astate, js->irstop_state);
788
789
790 if (status == 0)
791 /* Now extract the returned data from the buffer */
792 altera_extract_target_data(js->ir_buffer,
793 out_data, out_index,
794 js->ir_pre, count);
795
796 return status;
797}
798
799int altera_drscan(struct altera_state *astate,
800 u32 count,
801 u8 *tdi_data,
802 u32 start_index)
803/* Shifts data into data register (ignoring output data) */
804{
805 struct altera_jtag *js = &astate->js;
806 int start_code = 0;
807 u32 alloc_chars = 0;
808 u32 shift_count = js->dr_pre + count + js->dr_post;
809 int status = 0;
810 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
811
812 switch (js->jtag_state) {
813 case ILLEGAL_JTAG_STATE:
814 case RESET:
815 case IDLE:
816 start_code = 0;
817 start_state = IDLE;
818 break;
819
820 case DRSELECT:
821 case DRCAPTURE:
822 case DRSHIFT:
823 case DREXIT1:
824 case DRPAUSE:
825 case DREXIT2:
826 case DRUPDATE:
827 start_code = 1;
828 start_state = DRPAUSE;
829 break;
830
831 case IRSELECT:
832 case IRCAPTURE:
833 case IRSHIFT:
834 case IREXIT1:
835 case IRPAUSE:
836 case IREXIT2:
837 case IRUPDATE:
838 start_code = 2;
839 start_state = IRPAUSE;
840 break;
841
842 default:
843 status = -EREMOTEIO;
844 break;
845 }
846
847 if (status == 0)
848 if (js->jtag_state != start_state)
849 status = altera_goto_jstate(astate, start_state);
850
851 if (status == 0) {
852 if (shift_count > js->dr_length) {
853 alloc_chars = (shift_count + 7) >> 3;
854 kfree(js->dr_buffer);
855 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
856 if (js->dr_buffer == NULL)
857 status = -ENOMEM;
858 else
859 js->dr_length = alloc_chars * 8;
860
861 }
862 }
863
864 if (status == 0) {
865 /*
866 * Copy preamble data, DR data,
867 * and postamble data into a buffer
868 */
869 altera_concatenate_data(js->dr_buffer,
870 js->dr_pre_data,
871 js->dr_pre,
872 tdi_data,
873 start_index,
874 count,
875 js->dr_post_data,
876 js->dr_post);
877 /* Do the DRSCAN */
878 alt_jtag_drscan(astate, start_code, shift_count,
879 js->dr_buffer, NULL);
880 /* alt_jtag_drscan() always ends in DRPAUSE state */
881 js->jtag_state = DRPAUSE;
882 }
883
884 if (status == 0)
885 if (js->drstop_state != DRPAUSE)
886 status = altera_goto_jstate(astate, js->drstop_state);
887
888 return status;
889}
890
891int altera_swap_dr(struct altera_state *astate, u32 count,
892 u8 *in_data, u32 in_index,
893 u8 *out_data, u32 out_index)
894/* Shifts data into data register, capturing output data */
895{
896 struct altera_jtag *js = &astate->js;
897 int start_code = 0;
898 u32 alloc_chars = 0;
899 u32 shift_count = js->dr_pre + count + js->dr_post;
900 int status = 0;
901 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
902
903 switch (js->jtag_state) {
904 case ILLEGAL_JTAG_STATE:
905 case RESET:
906 case IDLE:
907 start_code = 0;
908 start_state = IDLE;
909 break;
910
911 case DRSELECT:
912 case DRCAPTURE:
913 case DRSHIFT:
914 case DREXIT1:
915 case DRPAUSE:
916 case DREXIT2:
917 case DRUPDATE:
918 start_code = 1;
919 start_state = DRPAUSE;
920 break;
921
922 case IRSELECT:
923 case IRCAPTURE:
924 case IRSHIFT:
925 case IREXIT1:
926 case IRPAUSE:
927 case IREXIT2:
928 case IRUPDATE:
929 start_code = 2;
930 start_state = IRPAUSE;
931 break;
932
933 default:
934 status = -EREMOTEIO;
935 break;
936 }
937
938 if (status == 0)
939 if (js->jtag_state != start_state)
940 status = altera_goto_jstate(astate, start_state);
941
942 if (status == 0) {
943 if (shift_count > js->dr_length) {
944 alloc_chars = (shift_count + 7) >> 3;
945 kfree(js->dr_buffer);
946 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
947
948 if (js->dr_buffer == NULL)
949 status = -ENOMEM;
950 else
951 js->dr_length = alloc_chars * 8;
952
953 }
954 }
955
956 if (status == 0) {
957 /*
958 * Copy preamble data, DR data,
959 * and postamble data into a buffer
960 */
961 altera_concatenate_data(js->dr_buffer,
962 js->dr_pre_data,
963 js->dr_pre,
964 in_data,
965 in_index,
966 count,
967 js->dr_post_data,
968 js->dr_post);
969
970 /* Do the DRSCAN */
971 alt_jtag_drscan(astate,
972 start_code,
973 shift_count,
974 js->dr_buffer,
975 js->dr_buffer);
976
977 /* alt_jtag_drscan() always ends in DRPAUSE state */
978 js->jtag_state = DRPAUSE;
979 }
980
981 if (status == 0)
982 if (js->drstop_state != DRPAUSE)
983 status = altera_goto_jstate(astate, js->drstop_state);
984
985 if (status == 0)
986 /* Now extract the returned data from the buffer */
987 altera_extract_target_data(js->dr_buffer,
988 out_data,
989 out_index,
990 js->dr_pre,
991 count);
992
993 return status;
994}
995
996void altera_free_buffers(struct altera_state *astate)
997{
998 struct altera_jtag *js = &astate->js;
999 /* If the JTAG interface was used, reset it to TLR */
1000 if (js->jtag_state != ILLEGAL_JTAG_STATE)
1001 altera_jreset_idle(astate);
1002
1003 kfree(js->dr_pre_data);
1004 js->dr_pre_data = NULL;
1005
1006 kfree(js->dr_post_data);
1007 js->dr_post_data = NULL;
1008
1009 kfree(js->dr_buffer);
1010 js->dr_buffer = NULL;
1011
1012 kfree(js->ir_pre_data);
1013 js->ir_pre_data = NULL;
1014
1015 kfree(js->ir_post_data);
1016 js->ir_post_data = NULL;
1017
1018 kfree(js->ir_buffer);
1019 js->ir_buffer = NULL;
1020}
diff --git a/drivers/staging/altera-stapl/altera-jtag.h b/drivers/staging/altera-stapl/altera-jtag.h
new file mode 100644
index 000000000000..2f97e36a2fbc
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-jtag.h
@@ -0,0 +1,113 @@
1/*
2 * altera-jtag.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef ALTERA_JTAG_H
27#define ALTERA_JTAG_H
28
29/* Function Prototypes */
30enum altera_jtag_state {
31 ILLEGAL_JTAG_STATE = -1,
32 RESET = 0,
33 IDLE = 1,
34 DRSELECT = 2,
35 DRCAPTURE = 3,
36 DRSHIFT = 4,
37 DREXIT1 = 5,
38 DRPAUSE = 6,
39 DREXIT2 = 7,
40 DRUPDATE = 8,
41 IRSELECT = 9,
42 IRCAPTURE = 10,
43 IRSHIFT = 11,
44 IREXIT1 = 12,
45 IRPAUSE = 13,
46 IREXIT2 = 14,
47 IRUPDATE = 15
48
49};
50
51struct altera_jtag {
52 /* Global variable to store the current JTAG state */
53 enum altera_jtag_state jtag_state;
54
55 /* Store current stop-state for DR and IR scan commands */
56 enum altera_jtag_state drstop_state;
57 enum altera_jtag_state irstop_state;
58
59 /* Store current padding values */
60 u32 dr_pre;
61 u32 dr_post;
62 u32 ir_pre;
63 u32 ir_post;
64 u32 dr_length;
65 u32 ir_length;
66 u8 *dr_pre_data;
67 u8 *dr_post_data;
68 u8 *ir_pre_data;
69 u8 *ir_post_data;
70 u8 *dr_buffer;
71 u8 *ir_buffer;
72};
73
74#define ALTERA_STACK_SIZE 128
75#define ALTERA_MESSAGE_LENGTH 1024
76
77struct altera_state {
78 struct altera_config *config;
79 struct altera_jtag js;
80 char msg_buff[ALTERA_MESSAGE_LENGTH + 1];
81 long stack[ALTERA_STACK_SIZE];
82};
83
84int altera_jinit(struct altera_state *astate);
85int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state);
86int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state);
87int altera_set_dr_pre(struct altera_jtag *js, u32 count, u32 start_index,
88 u8 *preamble_data);
89int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
90 u8 *preamble_data);
91int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
92 u8 *postamble_data);
93int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
94 u8 *postamble_data);
95int altera_goto_jstate(struct altera_state *astate,
96 enum altera_jtag_state state);
97int altera_wait_cycles(struct altera_state *astate, s32 cycles,
98 enum altera_jtag_state wait_state);
99int altera_wait_msecs(struct altera_state *astate, s32 microseconds,
100 enum altera_jtag_state wait_state);
101int altera_irscan(struct altera_state *astate, u32 count,
102 u8 *tdi_data, u32 start_index);
103int altera_swap_ir(struct altera_state *astate,
104 u32 count, u8 *in_data,
105 u32 in_index, u8 *out_data,
106 u32 out_index);
107int altera_drscan(struct altera_state *astate, u32 count,
108 u8 *tdi_data, u32 start_index);
109int altera_swap_dr(struct altera_state *astate, u32 count,
110 u8 *in_data, u32 in_index,
111 u8 *out_data, u32 out_index);
112void altera_free_buffers(struct altera_state *astate);
113#endif /* ALTERA_JTAG_H */
diff --git a/drivers/staging/altera-stapl/altera-lpt.c b/drivers/staging/altera-stapl/altera-lpt.c
new file mode 100644
index 000000000000..91456a03612d
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-lpt.c
@@ -0,0 +1,70 @@
1/*
2 * altera-lpt.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Abylay Ospan <aospan@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/io.h>
27#include <linux/kernel.h>
28#include "altera-exprt.h"
29
30static int lpt_hardware_initialized;
31
32static void byteblaster_write(int port, int data)
33{
34 outb((u8)data, (u16)(port + 0x378));
35};
36
37static int byteblaster_read(int port)
38{
39 int data = 0;
40 data = inb((u16)(port + 0x378));
41 return data & 0xff;
42};
43
44int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo)
45{
46 int data = 0;
47 int tdo = 0;
48 int initial_lpt_ctrl = 0;
49
50 if (!lpt_hardware_initialized) {
51 initial_lpt_ctrl = byteblaster_read(2);
52 byteblaster_write(2, (initial_lpt_ctrl | 0x02) & 0xdf);
53 lpt_hardware_initialized = 1;
54 }
55
56 data = ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0));
57
58 byteblaster_write(0, data);
59
60 if (read_tdo) {
61 tdo = byteblaster_read(1);
62 tdo = ((tdo & 0x80) ? 0 : 1);
63 }
64
65 byteblaster_write(0, data | 0x01);
66
67 byteblaster_write(0, data);
68
69 return tdo;
70}
diff --git a/drivers/staging/altera-stapl/altera.c b/drivers/staging/altera-stapl/altera.c
new file mode 100644
index 000000000000..05aad351b120
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera.c
@@ -0,0 +1,2527 @@
1/*
2 * altera.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <asm/unaligned.h>
27#include <linux/ctype.h>
28#include <linux/string.h>
29#include <linux/firmware.h>
30#include <linux/slab.h>
31#include <staging/altera.h>
32#include "altera-exprt.h"
33#include "altera-jtag.h"
34
35static int debug = 1;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debugging information");
38
39MODULE_DESCRIPTION("altera FPGA kernel module");
40MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");
41MODULE_LICENSE("GPL");
42
43#define dprintk(args...) \
44 if (debug) { \
45 printk(KERN_DEBUG args); \
46 }
47
48enum altera_fpga_opcode {
49 OP_NOP = 0,
50 OP_DUP,
51 OP_SWP,
52 OP_ADD,
53 OP_SUB,
54 OP_MULT,
55 OP_DIV,
56 OP_MOD,
57 OP_SHL,
58 OP_SHR,
59 OP_NOT,
60 OP_AND,
61 OP_OR,
62 OP_XOR,
63 OP_INV,
64 OP_GT,
65 OP_LT,
66 OP_RET,
67 OP_CMPS,
68 OP_PINT,
69 OP_PRNT,
70 OP_DSS,
71 OP_DSSC,
72 OP_ISS,
73 OP_ISSC,
74 OP_DPR = 0x1c,
75 OP_DPRL,
76 OP_DPO,
77 OP_DPOL,
78 OP_IPR,
79 OP_IPRL,
80 OP_IPO,
81 OP_IPOL,
82 OP_PCHR,
83 OP_EXIT,
84 OP_EQU,
85 OP_POPT,
86 OP_ABS = 0x2c,
87 OP_BCH0,
88 OP_PSH0 = 0x2f,
89 OP_PSHL = 0x40,
90 OP_PSHV,
91 OP_JMP,
92 OP_CALL,
93 OP_NEXT,
94 OP_PSTR,
95 OP_SINT = 0x47,
96 OP_ST,
97 OP_ISTP,
98 OP_DSTP,
99 OP_SWPN,
100 OP_DUPN,
101 OP_POPV,
102 OP_POPE,
103 OP_POPA,
104 OP_JMPZ,
105 OP_DS,
106 OP_IS,
107 OP_DPRA,
108 OP_DPOA,
109 OP_IPRA,
110 OP_IPOA,
111 OP_EXPT,
112 OP_PSHE,
113 OP_PSHA,
114 OP_DYNA,
115 OP_EXPV = 0x5c,
116 OP_COPY = 0x80,
117 OP_REVA,
118 OP_DSC,
119 OP_ISC,
120 OP_WAIT,
121 OP_VS,
122 OP_CMPA = 0xc0,
123 OP_VSC,
124};
125
126struct altera_procinfo {
127 char *name;
128 u8 attrs;
129 struct altera_procinfo *next;
130};
131
132/* This function checks if enough parameters are available on the stack. */
133static int altera_check_stack(int stack_ptr, int count, int *status)
134{
135 if (stack_ptr < count) {
136 *status = -EOVERFLOW;
137 return 0;
138 }
139
140 return 1;
141}
142
143static void altera_export_int(char *key, s32 value)
144{
145 dprintk("Export: key = \"%s\", value = %d\n", key, value);
146}
147
148#define HEX_LINE_CHARS 72
149#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
150
151static void altera_export_bool_array(char *key, u8 *data, s32 count)
152{
153 char string[HEX_LINE_CHARS + 1];
154 s32 i, offset;
155 u32 size, line, lines, linebits, value, j, k;
156
157 if (count > HEX_LINE_BITS) {
158 dprintk("Export: key = \"%s\", %d bits, value = HEX\n",
159 key, count);
160 lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;
161
162 for (line = 0; line < lines; ++line) {
163 if (line < (lines - 1)) {
164 linebits = HEX_LINE_BITS;
165 size = HEX_LINE_CHARS;
166 offset = count - ((line + 1) * HEX_LINE_BITS);
167 } else {
168 linebits =
169 count - ((lines - 1) * HEX_LINE_BITS);
170 size = (linebits + 3) / 4;
171 offset = 0L;
172 }
173
174 string[size] = '\0';
175 j = size - 1;
176 value = 0;
177
178 for (k = 0; k < linebits; ++k) {
179 i = k + offset;
180 if (data[i >> 3] & (1 << (i & 7)))
181 value |= (1 << (i & 3));
182 if ((i & 3) == 3) {
183 sprintf(&string[j], "%1x", value);
184 value = 0;
185 --j;
186 }
187 }
188 if ((k & 3) > 0)
189 sprintf(&string[j], "%1x", value);
190
191 dprintk("%s\n", string);
192 }
193
194 } else {
195 size = (count + 3) / 4;
196 string[size] = '\0';
197 j = size - 1;
198 value = 0;
199
200 for (i = 0; i < count; ++i) {
201 if (data[i >> 3] & (1 << (i & 7)))
202 value |= (1 << (i & 3));
203 if ((i & 3) == 3) {
204 sprintf(&string[j], "%1x", value);
205 value = 0;
206 --j;
207 }
208 }
209 if ((i & 3) > 0)
210 sprintf(&string[j], "%1x", value);
211
212 dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n",
213 key, count, string);
214 }
215}
216
217static int altera_execute(struct altera_state *astate,
218 u8 *p,
219 s32 program_size,
220 s32 *error_address,
221 int *exit_code,
222 int *format_version)
223{
224 struct altera_config *aconf = astate->config;
225 char *msg_buff = astate->msg_buff;
226 long *stack = astate->stack;
227 int status = 0;
228 u32 first_word = 0L;
229 u32 action_table = 0L;
230 u32 proc_table = 0L;
231 u32 str_table = 0L;
232 u32 sym_table = 0L;
233 u32 data_sect = 0L;
234 u32 code_sect = 0L;
235 u32 debug_sect = 0L;
236 u32 action_count = 0L;
237 u32 proc_count = 0L;
238 u32 sym_count = 0L;
239 long *vars = NULL;
240 s32 *var_size = NULL;
241 char *attrs = NULL;
242 u8 *proc_attributes = NULL;
243 u32 pc;
244 u32 opcode_address;
245 u32 args[3];
246 u32 opcode;
247 u32 name_id;
248 u8 charbuf[4];
249 long long_tmp;
250 u32 variable_id;
251 u8 *charptr_tmp;
252 u8 *charptr_tmp2;
253 long *longptr_tmp;
254 int version = 0;
255 int delta = 0;
256 int stack_ptr = 0;
257 u32 arg_count;
258 int done = 0;
259 int bad_opcode = 0;
260 u32 count;
261 u32 index;
262 u32 index2;
263 s32 long_count;
264 s32 long_idx;
265 s32 long_idx2;
266 u32 i;
267 u32 j;
268 u32 uncomp_size;
269 u32 offset;
270 u32 value;
271 int current_proc = 0;
272 int reverse;
273
274 char *name;
275
276 dprintk("%s\n", __func__);
277
278 /* Read header information */
279 if (program_size > 52L) {
280 first_word = get_unaligned_be32(&p[0]);
281 version = (first_word & 1L);
282 *format_version = version + 1;
283 delta = version * 8;
284
285 action_table = get_unaligned_be32(&p[4]);
286 proc_table = get_unaligned_be32(&p[8]);
287 str_table = get_unaligned_be32(&p[4 + delta]);
288 sym_table = get_unaligned_be32(&p[16 + delta]);
289 data_sect = get_unaligned_be32(&p[20 + delta]);
290 code_sect = get_unaligned_be32(&p[24 + delta]);
291 debug_sect = get_unaligned_be32(&p[28 + delta]);
292 action_count = get_unaligned_be32(&p[40 + delta]);
293 proc_count = get_unaligned_be32(&p[44 + delta]);
294 sym_count = get_unaligned_be32(&p[48 + (2 * delta)]);
295 }
296
297 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {
298 done = 1;
299 status = -EIO;
300 goto exit_done;
301 }
302
303 if (sym_count <= 0)
304 goto exit_done;
305
306 vars = kzalloc(sym_count * sizeof(long), GFP_KERNEL);
307
308 if (vars == NULL)
309 status = -ENOMEM;
310
311 if (status == 0) {
312 var_size = kzalloc(sym_count * sizeof(s32), GFP_KERNEL);
313
314 if (var_size == NULL)
315 status = -ENOMEM;
316 }
317
318 if (status == 0) {
319 attrs = kzalloc(sym_count, GFP_KERNEL);
320
321 if (attrs == NULL)
322 status = -ENOMEM;
323 }
324
325 if ((status == 0) && (version > 0)) {
326 proc_attributes = kzalloc(proc_count, GFP_KERNEL);
327
328 if (proc_attributes == NULL)
329 status = -ENOMEM;
330 }
331
332 if (status != 0)
333 goto exit_done;
334
335 delta = version * 2;
336
337 for (i = 0; i < sym_count; ++i) {
338 offset = (sym_table + ((11 + delta) * i));
339
340 value = get_unaligned_be32(&p[offset + 3 + delta]);
341
342 attrs[i] = p[offset];
343
344 /*
345 * use bit 7 of attribute byte to indicate that
346 * this buffer was dynamically allocated
347 * and should be freed later
348 */
349 attrs[i] &= 0x7f;
350
351 var_size[i] = get_unaligned_be32(&p[offset + 7 + delta]);
352
353 /*
354 * Attribute bits:
355 * bit 0: 0 = read-only, 1 = read-write
356 * bit 1: 0 = not compressed, 1 = compressed
357 * bit 2: 0 = not initialized, 1 = initialized
358 * bit 3: 0 = scalar, 1 = array
359 * bit 4: 0 = Boolean, 1 = integer
360 * bit 5: 0 = declared variable,
361 * 1 = compiler created temporary variable
362 */
363
364 if ((attrs[i] & 0x0c) == 0x04)
365 /* initialized scalar variable */
366 vars[i] = value;
367 else if ((attrs[i] & 0x1e) == 0x0e) {
368 /* initialized compressed Boolean array */
369 uncomp_size = get_unaligned_le32(&p[data_sect + value]);
370
371 /* allocate a buffer for the uncompressed data */
372 vars[i] = (long)kzalloc(uncomp_size, GFP_KERNEL);
373 if (vars[i] == 0L)
374 status = -ENOMEM;
375 else {
376 /* set flag so buffer will be freed later */
377 attrs[i] |= 0x80;
378
379 /* uncompress the data */
380 if (altera_shrink(&p[data_sect + value],
381 var_size[i],
382 (u8 *)vars[i],
383 uncomp_size,
384 version) != uncomp_size)
385 /* decompression failed */
386 status = -EIO;
387 else
388 var_size[i] = uncomp_size * 8L;
389
390 }
391 } else if ((attrs[i] & 0x1e) == 0x0c) {
392 /* initialized Boolean array */
393 vars[i] = value + data_sect + (long)p;
394 } else if ((attrs[i] & 0x1c) == 0x1c) {
395 /* initialized integer array */
396 vars[i] = value + data_sect;
397 } else if ((attrs[i] & 0x0c) == 0x08) {
398 /* uninitialized array */
399
400 /* flag attrs so that memory is freed */
401 attrs[i] |= 0x80;
402
403 if (var_size[i] > 0) {
404 u32 size;
405
406 if (attrs[i] & 0x10)
407 /* integer array */
408 size = (var_size[i] * sizeof(s32));
409 else
410 /* Boolean array */
411 size = ((var_size[i] + 7L) / 8L);
412
413 vars[i] = (long)kzalloc(size, GFP_KERNEL);
414
415 if (vars[i] == 0) {
416 status = -ENOMEM;
417 } else {
418 /* zero out memory */
419 for (j = 0; j < size; ++j)
420 ((u8 *)(vars[i]))[j] = 0;
421
422 }
423 } else
424 vars[i] = 0;
425
426 } else
427 vars[i] = 0;
428
429 }
430
431exit_done:
432 if (status != 0)
433 done = 1;
434
435 altera_jinit(astate);
436
437 pc = code_sect;
438 msg_buff[0] = '\0';
439
440 /*
441 * For JBC version 2, we will execute the procedures corresponding to
442 * the selected ACTION
443 */
444 if (version > 0) {
445 if (aconf->action == NULL) {
446 status = -EINVAL;
447 done = 1;
448 } else {
449 int action_found = 0;
450 for (i = 0; (i < action_count) && !action_found; ++i) {
451 name_id = get_unaligned_be32(&p[action_table +
452 (12 * i)]);
453
454 name = &p[str_table + name_id];
455
456 if (strnicmp(aconf->action, name, strlen(name)) == 0) {
457 action_found = 1;
458 current_proc =
459 get_unaligned_be32(&p[action_table +
460 (12 * i) + 8]);
461 }
462 }
463
464 if (!action_found) {
465 status = -EINVAL;
466 done = 1;
467 }
468 }
469
470 if (status == 0) {
471 int first_time = 1;
472 i = current_proc;
473 while ((i != 0) || first_time) {
474 first_time = 0;
475 /* check procedure attribute byte */
476 proc_attributes[i] =
477 (p[proc_table +
478 (13 * i) + 8] &
479 0x03);
480
481 /*
482 * BIT0 - OPTIONAL
483 * BIT1 - RECOMMENDED
484 * BIT6 - FORCED OFF
485 * BIT7 - FORCED ON
486 */
487
488 i = get_unaligned_be32(&p[proc_table +
489 (13 * i) + 4]);
490 }
491
492 /*
493 * Set current_proc to the first procedure
494 * to be executed
495 */
496 i = current_proc;
497 while ((i != 0) &&
498 ((proc_attributes[i] == 1) ||
499 ((proc_attributes[i] & 0xc0) == 0x40))) {
500 i = get_unaligned_be32(&p[proc_table +
501 (13 * i) + 4]);
502 }
503
504 if ((i != 0) || ((i == 0) && (current_proc == 0) &&
505 ((proc_attributes[0] != 1) &&
506 ((proc_attributes[0] & 0xc0) != 0x40)))) {
507 current_proc = i;
508 pc = code_sect +
509 get_unaligned_be32(&p[proc_table +
510 (13 * i) + 9]);
511 if ((pc < code_sect) || (pc >= debug_sect))
512 status = -ERANGE;
513 } else
514 /* there are no procedures to execute! */
515 done = 1;
516
517 }
518 }
519
520 msg_buff[0] = '\0';
521
522 while (!done) {
523 opcode = (p[pc] & 0xff);
524 opcode_address = pc;
525 ++pc;
526
527 if (debug > 1)
528 printk("opcode: %02x\n", opcode);
529
530 arg_count = (opcode >> 6) & 3;
531 for (i = 0; i < arg_count; ++i) {
532 args[i] = get_unaligned_be32(&p[pc]);
533 pc += 4;
534 }
535
536 switch (opcode) {
537 case OP_NOP:
538 break;
539 case OP_DUP:
540 if (altera_check_stack(stack_ptr, 1, &status)) {
541 stack[stack_ptr] = stack[stack_ptr - 1];
542 ++stack_ptr;
543 }
544 break;
545 case OP_SWP:
546 if (altera_check_stack(stack_ptr, 2, &status)) {
547 long_tmp = stack[stack_ptr - 2];
548 stack[stack_ptr - 2] = stack[stack_ptr - 1];
549 stack[stack_ptr - 1] = long_tmp;
550 }
551 break;
552 case OP_ADD:
553 if (altera_check_stack(stack_ptr, 2, &status)) {
554 --stack_ptr;
555 stack[stack_ptr - 1] += stack[stack_ptr];
556 }
557 break;
558 case OP_SUB:
559 if (altera_check_stack(stack_ptr, 2, &status)) {
560 --stack_ptr;
561 stack[stack_ptr - 1] -= stack[stack_ptr];
562 }
563 break;
564 case OP_MULT:
565 if (altera_check_stack(stack_ptr, 2, &status)) {
566 --stack_ptr;
567 stack[stack_ptr - 1] *= stack[stack_ptr];
568 }
569 break;
570 case OP_DIV:
571 if (altera_check_stack(stack_ptr, 2, &status)) {
572 --stack_ptr;
573 stack[stack_ptr - 1] /= stack[stack_ptr];
574 }
575 break;
576 case OP_MOD:
577 if (altera_check_stack(stack_ptr, 2, &status)) {
578 --stack_ptr;
579 stack[stack_ptr - 1] %= stack[stack_ptr];
580 }
581 break;
582 case OP_SHL:
583 if (altera_check_stack(stack_ptr, 2, &status)) {
584 --stack_ptr;
585 stack[stack_ptr - 1] <<= stack[stack_ptr];
586 }
587 break;
588 case OP_SHR:
589 if (altera_check_stack(stack_ptr, 2, &status)) {
590 --stack_ptr;
591 stack[stack_ptr - 1] >>= stack[stack_ptr];
592 }
593 break;
594 case OP_NOT:
595 if (altera_check_stack(stack_ptr, 1, &status))
596 stack[stack_ptr - 1] ^= (-1L);
597
598 break;
599 case OP_AND:
600 if (altera_check_stack(stack_ptr, 2, &status)) {
601 --stack_ptr;
602 stack[stack_ptr - 1] &= stack[stack_ptr];
603 }
604 break;
605 case OP_OR:
606 if (altera_check_stack(stack_ptr, 2, &status)) {
607 --stack_ptr;
608 stack[stack_ptr - 1] |= stack[stack_ptr];
609 }
610 break;
611 case OP_XOR:
612 if (altera_check_stack(stack_ptr, 2, &status)) {
613 --stack_ptr;
614 stack[stack_ptr - 1] ^= stack[stack_ptr];
615 }
616 break;
617 case OP_INV:
618 if (!altera_check_stack(stack_ptr, 1, &status))
619 break;
620 stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;
621 break;
622 case OP_GT:
623 if (!altera_check_stack(stack_ptr, 2, &status))
624 break;
625 --stack_ptr;
626 stack[stack_ptr - 1] =
627 (stack[stack_ptr - 1] > stack[stack_ptr]) ?
628 1L : 0L;
629
630 break;
631 case OP_LT:
632 if (!altera_check_stack(stack_ptr, 2, &status))
633 break;
634 --stack_ptr;
635 stack[stack_ptr - 1] =
636 (stack[stack_ptr - 1] < stack[stack_ptr]) ?
637 1L : 0L;
638
639 break;
640 case OP_RET:
641 if ((version > 0) && (stack_ptr == 0)) {
642 /*
643 * We completed one of the main procedures
644 * of an ACTION.
645 * Find the next procedure
646 * to be executed and jump to it.
647 * If there are no more procedures, then EXIT.
648 */
649 i = get_unaligned_be32(&p[proc_table +
650 (13 * current_proc) + 4]);
651 while ((i != 0) &&
652 ((proc_attributes[i] == 1) ||
653 ((proc_attributes[i] & 0xc0) == 0x40)))
654 i = get_unaligned_be32(&p[proc_table +
655 (13 * i) + 4]);
656
657 if (i == 0) {
658 /* no procedures to execute! */
659 done = 1;
660 *exit_code = 0; /* success */
661 } else {
662 current_proc = i;
663 pc = code_sect + get_unaligned_be32(
664 &p[proc_table +
665 (13 * i) + 9]);
666 if ((pc < code_sect) ||
667 (pc >= debug_sect))
668 status = -ERANGE;
669 }
670
671 } else
672 if (altera_check_stack(stack_ptr, 1, &status)) {
673 pc = stack[--stack_ptr] + code_sect;
674 if ((pc <= code_sect) ||
675 (pc >= debug_sect))
676 status = -ERANGE;
677
678 }
679
680 break;
681 case OP_CMPS:
682 /*
683 * Array short compare
684 * ...stack 0 is source 1 value
685 * ...stack 1 is source 2 value
686 * ...stack 2 is mask value
687 * ...stack 3 is count
688 */
689 if (altera_check_stack(stack_ptr, 4, &status)) {
690 s32 a = stack[--stack_ptr];
691 s32 b = stack[--stack_ptr];
692 long_tmp = stack[--stack_ptr];
693 count = stack[stack_ptr - 1];
694
695 if ((count < 1) || (count > 32))
696 status = -ERANGE;
697 else {
698 long_tmp &= ((-1L) >> (32 - count));
699
700 stack[stack_ptr - 1] =
701 ((a & long_tmp) == (b & long_tmp))
702 ? 1L : 0L;
703 }
704 }
705 break;
706 case OP_PINT:
707 /*
708 * PRINT add integer
709 * ...stack 0 is integer value
710 */
711 if (!altera_check_stack(stack_ptr, 1, &status))
712 break;
713 sprintf(&msg_buff[strlen(msg_buff)],
714 "%ld", stack[--stack_ptr]);
715 break;
716 case OP_PRNT:
717 /* PRINT finish */
718 if (debug)
719 printk(msg_buff, "\n");
720
721 msg_buff[0] = '\0';
722 break;
723 case OP_DSS:
724 /*
725 * DRSCAN short
726 * ...stack 0 is scan data
727 * ...stack 1 is count
728 */
729 if (!altera_check_stack(stack_ptr, 2, &status))
730 break;
731 long_tmp = stack[--stack_ptr];
732 count = stack[--stack_ptr];
733 put_unaligned_le32(long_tmp, &charbuf[0]);
734 status = altera_drscan(astate, count, charbuf, 0);
735 break;
736 case OP_DSSC:
737 /*
738 * DRSCAN short with capture
739 * ...stack 0 is scan data
740 * ...stack 1 is count
741 */
742 if (!altera_check_stack(stack_ptr, 2, &status))
743 break;
744 long_tmp = stack[--stack_ptr];
745 count = stack[stack_ptr - 1];
746 put_unaligned_le32(long_tmp, &charbuf[0]);
747 status = altera_swap_dr(astate, count, charbuf,
748 0, charbuf, 0);
749 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
750 break;
751 case OP_ISS:
752 /*
753 * IRSCAN short
754 * ...stack 0 is scan data
755 * ...stack 1 is count
756 */
757 if (!altera_check_stack(stack_ptr, 2, &status))
758 break;
759 long_tmp = stack[--stack_ptr];
760 count = stack[--stack_ptr];
761 put_unaligned_le32(long_tmp, &charbuf[0]);
762 status = altera_irscan(astate, count, charbuf, 0);
763 break;
764 case OP_ISSC:
765 /*
766 * IRSCAN short with capture
767 * ...stack 0 is scan data
768 * ...stack 1 is count
769 */
770 if (!altera_check_stack(stack_ptr, 2, &status))
771 break;
772 long_tmp = stack[--stack_ptr];
773 count = stack[stack_ptr - 1];
774 put_unaligned_le32(long_tmp, &charbuf[0]);
775 status = altera_swap_ir(astate, count, charbuf,
776 0, charbuf, 0);
777 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
778 break;
779 case OP_DPR:
780 if (!altera_check_stack(stack_ptr, 1, &status))
781 break;
782 count = stack[--stack_ptr];
783 status = altera_set_dr_pre(&astate->js, count, 0, NULL);
784 break;
785 case OP_DPRL:
786 /*
787 * DRPRE with literal data
788 * ...stack 0 is count
789 * ...stack 1 is literal data
790 */
791 if (!altera_check_stack(stack_ptr, 2, &status))
792 break;
793 count = stack[--stack_ptr];
794 long_tmp = stack[--stack_ptr];
795 put_unaligned_le32(long_tmp, &charbuf[0]);
796 status = altera_set_dr_pre(&astate->js, count, 0,
797 charbuf);
798 break;
799 case OP_DPO:
800 /*
801 * DRPOST
802 * ...stack 0 is count
803 */
804 if (altera_check_stack(stack_ptr, 1, &status)) {
805 count = stack[--stack_ptr];
806 status = altera_set_dr_post(&astate->js, count,
807 0, NULL);
808 }
809 break;
810 case OP_DPOL:
811 /*
812 * DRPOST with literal data
813 * ...stack 0 is count
814 * ...stack 1 is literal data
815 */
816 if (!altera_check_stack(stack_ptr, 2, &status))
817 break;
818 count = stack[--stack_ptr];
819 long_tmp = stack[--stack_ptr];
820 put_unaligned_le32(long_tmp, &charbuf[0]);
821 status = altera_set_dr_post(&astate->js, count, 0,
822 charbuf);
823 break;
824 case OP_IPR:
825 if (altera_check_stack(stack_ptr, 1, &status)) {
826 count = stack[--stack_ptr];
827 status = altera_set_ir_pre(&astate->js, count,
828 0, NULL);
829 }
830 break;
831 case OP_IPRL:
832 /*
833 * IRPRE with literal data
834 * ...stack 0 is count
835 * ...stack 1 is literal data
836 */
837 if (altera_check_stack(stack_ptr, 2, &status)) {
838 count = stack[--stack_ptr];
839 long_tmp = stack[--stack_ptr];
840 put_unaligned_le32(long_tmp, &charbuf[0]);
841 status = altera_set_ir_pre(&astate->js, count,
842 0, charbuf);
843 }
844 break;
845 case OP_IPO:
846 /*
847 * IRPOST
848 * ...stack 0 is count
849 */
850 if (altera_check_stack(stack_ptr, 1, &status)) {
851 count = stack[--stack_ptr];
852 status = altera_set_ir_post(&astate->js, count,
853 0, NULL);
854 }
855 break;
856 case OP_IPOL:
857 /*
858 * IRPOST with literal data
859 * ...stack 0 is count
860 * ...stack 1 is literal data
861 */
862 if (!altera_check_stack(stack_ptr, 2, &status))
863 break;
864 count = stack[--stack_ptr];
865 long_tmp = stack[--stack_ptr];
866 put_unaligned_le32(long_tmp, &charbuf[0]);
867 status = altera_set_ir_post(&astate->js, count, 0,
868 charbuf);
869 break;
870 case OP_PCHR:
871 if (altera_check_stack(stack_ptr, 1, &status)) {
872 u8 ch;
873 count = strlen(msg_buff);
874 ch = (char) stack[--stack_ptr];
875 if ((ch < 1) || (ch > 127)) {
876 /*
877 * character code out of range
878 * instead of flagging an error,
879 * force the value to 127
880 */
881 ch = 127;
882 }
883 msg_buff[count] = ch;
884 msg_buff[count + 1] = '\0';
885 }
886 break;
887 case OP_EXIT:
888 if (altera_check_stack(stack_ptr, 1, &status))
889 *exit_code = stack[--stack_ptr];
890
891 done = 1;
892 break;
893 case OP_EQU:
894 if (!altera_check_stack(stack_ptr, 2, &status))
895 break;
896 --stack_ptr;
897 stack[stack_ptr - 1] =
898 (stack[stack_ptr - 1] == stack[stack_ptr]) ?
899 1L : 0L;
900 break;
901 case OP_POPT:
902 if (altera_check_stack(stack_ptr, 1, &status))
903 --stack_ptr;
904
905 break;
906 case OP_ABS:
907 if (!altera_check_stack(stack_ptr, 1, &status))
908 break;
909 if (stack[stack_ptr - 1] < 0)
910 stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
911
912 break;
913 case OP_BCH0:
914 /*
915 * Batch operation 0
916 * SWP
917 * SWPN 7
918 * SWP
919 * SWPN 6
920 * DUPN 8
921 * SWPN 2
922 * SWP
923 * DUPN 6
924 * DUPN 6
925 */
926
927 /* SWP */
928 if (altera_check_stack(stack_ptr, 2, &status)) {
929 long_tmp = stack[stack_ptr - 2];
930 stack[stack_ptr - 2] = stack[stack_ptr - 1];
931 stack[stack_ptr - 1] = long_tmp;
932 }
933
934 /* SWPN 7 */
935 index = 7 + 1;
936 if (altera_check_stack(stack_ptr, index, &status)) {
937 long_tmp = stack[stack_ptr - index];
938 stack[stack_ptr - index] = stack[stack_ptr - 1];
939 stack[stack_ptr - 1] = long_tmp;
940 }
941
942 /* SWP */
943 if (altera_check_stack(stack_ptr, 2, &status)) {
944 long_tmp = stack[stack_ptr - 2];
945 stack[stack_ptr - 2] = stack[stack_ptr - 1];
946 stack[stack_ptr - 1] = long_tmp;
947 }
948
949 /* SWPN 6 */
950 index = 6 + 1;
951 if (altera_check_stack(stack_ptr, index, &status)) {
952 long_tmp = stack[stack_ptr - index];
953 stack[stack_ptr - index] = stack[stack_ptr - 1];
954 stack[stack_ptr - 1] = long_tmp;
955 }
956
957 /* DUPN 8 */
958 index = 8 + 1;
959 if (altera_check_stack(stack_ptr, index, &status)) {
960 stack[stack_ptr] = stack[stack_ptr - index];
961 ++stack_ptr;
962 }
963
964 /* SWPN 2 */
965 index = 2 + 1;
966 if (altera_check_stack(stack_ptr, index, &status)) {
967 long_tmp = stack[stack_ptr - index];
968 stack[stack_ptr - index] = stack[stack_ptr - 1];
969 stack[stack_ptr - 1] = long_tmp;
970 }
971
972 /* SWP */
973 if (altera_check_stack(stack_ptr, 2, &status)) {
974 long_tmp = stack[stack_ptr - 2];
975 stack[stack_ptr - 2] = stack[stack_ptr - 1];
976 stack[stack_ptr - 1] = long_tmp;
977 }
978
979 /* DUPN 6 */
980 index = 6 + 1;
981 if (altera_check_stack(stack_ptr, index, &status)) {
982 stack[stack_ptr] = stack[stack_ptr - index];
983 ++stack_ptr;
984 }
985
986 /* DUPN 6 */
987 index = 6 + 1;
988 if (altera_check_stack(stack_ptr, index, &status)) {
989 stack[stack_ptr] = stack[stack_ptr - index];
990 ++stack_ptr;
991 }
992 break;
993 case OP_PSH0:
994 stack[stack_ptr++] = 0;
995 break;
996 case OP_PSHL:
997 stack[stack_ptr++] = (s32) args[0];
998 break;
999 case OP_PSHV:
1000 stack[stack_ptr++] = vars[args[0]];
1001 break;
1002 case OP_JMP:
1003 pc = args[0] + code_sect;
1004 if ((pc < code_sect) || (pc >= debug_sect))
1005 status = -ERANGE;
1006 break;
1007 case OP_CALL:
1008 stack[stack_ptr++] = pc;
1009 pc = args[0] + code_sect;
1010 if ((pc < code_sect) || (pc >= debug_sect))
1011 status = -ERANGE;
1012 break;
1013 case OP_NEXT:
1014 /*
1015 * Process FOR / NEXT loop
1016 * ...argument 0 is variable ID
1017 * ...stack 0 is step value
1018 * ...stack 1 is end value
1019 * ...stack 2 is top address
1020 */
1021 if (altera_check_stack(stack_ptr, 3, &status)) {
1022 s32 step = stack[stack_ptr - 1];
1023 s32 end = stack[stack_ptr - 2];
1024 s32 top = stack[stack_ptr - 3];
1025 s32 iterator = vars[args[0]];
1026 int break_out = 0;
1027
1028 if (step < 0) {
1029 if (iterator <= end)
1030 break_out = 1;
1031 } else if (iterator >= end)
1032 break_out = 1;
1033
1034 if (break_out) {
1035 stack_ptr -= 3;
1036 } else {
1037 vars[args[0]] = iterator + step;
1038 pc = top + code_sect;
1039 if ((pc < code_sect) ||
1040 (pc >= debug_sect))
1041 status = -ERANGE;
1042 }
1043 }
1044 break;
1045 case OP_PSTR:
1046 /*
1047 * PRINT add string
1048 * ...argument 0 is string ID
1049 */
1050 count = strlen(msg_buff);
1051 strlcpy(&msg_buff[count],
1052 &p[str_table + args[0]],
1053 ALTERA_MESSAGE_LENGTH - count);
1054 break;
1055 case OP_SINT:
1056 /*
1057 * STATE intermediate state
1058 * ...argument 0 is state code
1059 */
1060 status = altera_goto_jstate(astate, args[0]);
1061 break;
1062 case OP_ST:
1063 /*
1064 * STATE final state
1065 * ...argument 0 is state code
1066 */
1067 status = altera_goto_jstate(astate, args[0]);
1068 break;
1069 case OP_ISTP:
1070 /*
1071 * IRSTOP state
1072 * ...argument 0 is state code
1073 */
1074 status = altera_set_irstop(&astate->js, args[0]);
1075 break;
1076 case OP_DSTP:
1077 /*
1078 * DRSTOP state
1079 * ...argument 0 is state code
1080 */
1081 status = altera_set_drstop(&astate->js, args[0]);
1082 break;
1083
1084 case OP_SWPN:
1085 /*
1086 * Exchange top with Nth stack value
1087 * ...argument 0 is 0-based stack entry
1088 * to swap with top element
1089 */
1090 index = (args[0]) + 1;
1091 if (altera_check_stack(stack_ptr, index, &status)) {
1092 long_tmp = stack[stack_ptr - index];
1093 stack[stack_ptr - index] = stack[stack_ptr - 1];
1094 stack[stack_ptr - 1] = long_tmp;
1095 }
1096 break;
1097 case OP_DUPN:
1098 /*
1099 * Duplicate Nth stack value
1100 * ...argument 0 is 0-based stack entry to duplicate
1101 */
1102 index = (args[0]) + 1;
1103 if (altera_check_stack(stack_ptr, index, &status)) {
1104 stack[stack_ptr] = stack[stack_ptr - index];
1105 ++stack_ptr;
1106 }
1107 break;
1108 case OP_POPV:
1109 /*
1110 * Pop stack into scalar variable
1111 * ...argument 0 is variable ID
1112 * ...stack 0 is value
1113 */
1114 if (altera_check_stack(stack_ptr, 1, &status))
1115 vars[args[0]] = stack[--stack_ptr];
1116
1117 break;
1118 case OP_POPE:
1119 /*
1120 * Pop stack into integer array element
1121 * ...argument 0 is variable ID
1122 * ...stack 0 is array index
1123 * ...stack 1 is value
1124 */
1125 if (!altera_check_stack(stack_ptr, 2, &status))
1126 break;
1127 variable_id = args[0];
1128
1129 /*
1130 * If variable is read-only,
1131 * convert to writable array
1132 */
1133 if ((version > 0) &&
1134 ((attrs[variable_id] & 0x9c) == 0x1c)) {
1135 /* Allocate a writable buffer for this array */
1136 count = var_size[variable_id];
1137 long_tmp = vars[variable_id];
1138 longptr_tmp = kzalloc(count * sizeof(long),
1139 GFP_KERNEL);
1140 vars[variable_id] = (long)longptr_tmp;
1141
1142 if (vars[variable_id] == 0) {
1143 status = -ENOMEM;
1144 break;
1145 }
1146
1147 /* copy previous contents into buffer */
1148 for (i = 0; i < count; ++i) {
1149 longptr_tmp[i] =
1150 get_unaligned_be32(&p[long_tmp]);
1151 long_tmp += sizeof(long);
1152 }
1153
1154 /*
1155 * set bit 7 - buffer was
1156 * dynamically allocated
1157 */
1158 attrs[variable_id] |= 0x80;
1159
1160 /* clear bit 2 - variable is writable */
1161 attrs[variable_id] &= ~0x04;
1162 attrs[variable_id] |= 0x01;
1163
1164 }
1165
1166 /* check that variable is a writable integer array */
1167 if ((attrs[variable_id] & 0x1c) != 0x18)
1168 status = -ERANGE;
1169 else {
1170 longptr_tmp = (long *)vars[variable_id];
1171
1172 /* pop the array index */
1173 index = stack[--stack_ptr];
1174
1175 /* pop the value and store it into the array */
1176 longptr_tmp[index] = stack[--stack_ptr];
1177 }
1178
1179 break;
1180 case OP_POPA:
1181 /*
1182 * Pop stack into Boolean array
1183 * ...argument 0 is variable ID
1184 * ...stack 0 is count
1185 * ...stack 1 is array index
1186 * ...stack 2 is value
1187 */
1188 if (!altera_check_stack(stack_ptr, 3, &status))
1189 break;
1190 variable_id = args[0];
1191
1192 /*
1193 * If variable is read-only,
1194 * convert to writable array
1195 */
1196 if ((version > 0) &&
1197 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1198 /* Allocate a writable buffer for this array */
1199 long_tmp =
1200 (var_size[variable_id] + 7L) >> 3L;
1201 charptr_tmp2 = (u8 *)vars[variable_id];
1202 charptr_tmp =
1203 kzalloc(long_tmp, GFP_KERNEL);
1204 vars[variable_id] = (long)charptr_tmp;
1205
1206 if (vars[variable_id] == 0) {
1207 status = -ENOMEM;
1208 break;
1209 }
1210
1211 /* zero the buffer */
1212 for (long_idx = 0L;
1213 long_idx < long_tmp;
1214 ++long_idx) {
1215 charptr_tmp[long_idx] = 0;
1216 }
1217
1218 /* copy previous contents into buffer */
1219 for (long_idx = 0L;
1220 long_idx < var_size[variable_id];
1221 ++long_idx) {
1222 long_idx2 = long_idx;
1223
1224 if (charptr_tmp2[long_idx2 >> 3] &
1225 (1 << (long_idx2 & 7))) {
1226 charptr_tmp[long_idx >> 3] |=
1227 (1 << (long_idx & 7));
1228 }
1229 }
1230
1231 /*
1232 * set bit 7 - buffer was
1233 * dynamically allocated
1234 */
1235 attrs[variable_id] |= 0x80;
1236
1237 /* clear bit 2 - variable is writable */
1238 attrs[variable_id] &= ~0x04;
1239 attrs[variable_id] |= 0x01;
1240
1241 }
1242
1243 /*
1244 * check that variable is
1245 * a writable Boolean array
1246 */
1247 if ((attrs[variable_id] & 0x1c) != 0x08) {
1248 status = -ERANGE;
1249 break;
1250 }
1251
1252 charptr_tmp = (u8 *)vars[variable_id];
1253
1254 /* pop the count (number of bits to copy) */
1255 long_count = stack[--stack_ptr];
1256
1257 /* pop the array index */
1258 long_idx = stack[--stack_ptr];
1259
1260 reverse = 0;
1261
1262 if (version > 0) {
1263 /*
1264 * stack 0 = array right index
1265 * stack 1 = array left index
1266 */
1267
1268 if (long_idx > long_count) {
1269 reverse = 1;
1270 long_tmp = long_count;
1271 long_count = 1 + long_idx -
1272 long_count;
1273 long_idx = long_tmp;
1274
1275 /* reverse POPA is not supported */
1276 status = -ERANGE;
1277 break;
1278 } else
1279 long_count = 1 + long_count -
1280 long_idx;
1281
1282 }
1283
1284 /* pop the data */
1285 long_tmp = stack[--stack_ptr];
1286
1287 if (long_count < 1) {
1288 status = -ERANGE;
1289 break;
1290 }
1291
1292 for (i = 0; i < long_count; ++i) {
1293 if (long_tmp & (1L << (s32) i))
1294 charptr_tmp[long_idx >> 3L] |=
1295 (1L << (long_idx & 7L));
1296 else
1297 charptr_tmp[long_idx >> 3L] &=
1298 ~(1L << (long_idx & 7L));
1299
1300 ++long_idx;
1301 }
1302
1303 break;
1304 case OP_JMPZ:
1305 /*
1306 * Pop stack and branch if zero
1307 * ...argument 0 is address
1308 * ...stack 0 is condition value
1309 */
1310 if (altera_check_stack(stack_ptr, 1, &status)) {
1311 if (stack[--stack_ptr] == 0) {
1312 pc = args[0] + code_sect;
1313 if ((pc < code_sect) ||
1314 (pc >= debug_sect))
1315 status = -ERANGE;
1316 }
1317 }
1318 break;
1319 case OP_DS:
1320 case OP_IS:
1321 /*
1322 * DRSCAN
1323 * IRSCAN
1324 * ...argument 0 is scan data variable ID
1325 * ...stack 0 is array index
1326 * ...stack 1 is count
1327 */
1328 if (!altera_check_stack(stack_ptr, 2, &status))
1329 break;
1330 long_idx = stack[--stack_ptr];
1331 long_count = stack[--stack_ptr];
1332 reverse = 0;
1333 if (version > 0) {
1334 /*
1335 * stack 0 = array right index
1336 * stack 1 = array left index
1337 * stack 2 = count
1338 */
1339 long_tmp = long_count;
1340 long_count = stack[--stack_ptr];
1341
1342 if (long_idx > long_tmp) {
1343 reverse = 1;
1344 long_idx = long_tmp;
1345 }
1346 }
1347
1348 charptr_tmp = (u8 *)vars[args[0]];
1349
1350 if (reverse) {
1351 /*
1352 * allocate a buffer
1353 * and reverse the data order
1354 */
1355 charptr_tmp2 = charptr_tmp;
1356 charptr_tmp = kzalloc((long_count >> 3) + 1,
1357 GFP_KERNEL);
1358 if (charptr_tmp == NULL) {
1359 status = -ENOMEM;
1360 break;
1361 }
1362
1363 long_tmp = long_idx + long_count - 1;
1364 long_idx2 = 0;
1365 while (long_idx2 < long_count) {
1366 if (charptr_tmp2[long_tmp >> 3] &
1367 (1 << (long_tmp & 7)))
1368 charptr_tmp[long_idx2 >> 3] |=
1369 (1 << (long_idx2 & 7));
1370 else
1371 charptr_tmp[long_idx2 >> 3] &=
1372 ~(1 << (long_idx2 & 7));
1373
1374 --long_tmp;
1375 ++long_idx2;
1376 }
1377 }
1378
1379 if (opcode == 0x51) /* DS */
1380 status = altera_drscan(astate, long_count,
1381 charptr_tmp, long_idx);
1382 else /* IS */
1383 status = altera_irscan(astate, long_count,
1384 charptr_tmp, long_idx);
1385
1386 if (reverse)
1387 kfree(charptr_tmp);
1388
1389 break;
1390 case OP_DPRA:
1391 /*
1392 * DRPRE with array data
1393 * ...argument 0 is variable ID
1394 * ...stack 0 is array index
1395 * ...stack 1 is count
1396 */
1397 if (!altera_check_stack(stack_ptr, 2, &status))
1398 break;
1399 index = stack[--stack_ptr];
1400 count = stack[--stack_ptr];
1401
1402 if (version > 0)
1403 /*
1404 * stack 0 = array right index
1405 * stack 1 = array left index
1406 */
1407 count = 1 + count - index;
1408
1409 charptr_tmp = (u8 *)vars[args[0]];
1410 status = altera_set_dr_pre(&astate->js, count, index,
1411 charptr_tmp);
1412 break;
1413 case OP_DPOA:
1414 /*
1415 * DRPOST with array data
1416 * ...argument 0 is variable ID
1417 * ...stack 0 is array index
1418 * ...stack 1 is count
1419 */
1420 if (!altera_check_stack(stack_ptr, 2, &status))
1421 break;
1422 index = stack[--stack_ptr];
1423 count = stack[--stack_ptr];
1424
1425 if (version > 0)
1426 /*
1427 * stack 0 = array right index
1428 * stack 1 = array left index
1429 */
1430 count = 1 + count - index;
1431
1432 charptr_tmp = (u8 *)vars[args[0]];
1433 status = altera_set_dr_post(&astate->js, count, index,
1434 charptr_tmp);
1435 break;
1436 case OP_IPRA:
1437 /*
1438 * IRPRE with array data
1439 * ...argument 0 is variable ID
1440 * ...stack 0 is array index
1441 * ...stack 1 is count
1442 */
1443 if (!altera_check_stack(stack_ptr, 2, &status))
1444 break;
1445 index = stack[--stack_ptr];
1446 count = stack[--stack_ptr];
1447
1448 if (version > 0)
1449 /*
1450 * stack 0 = array right index
1451 * stack 1 = array left index
1452 */
1453 count = 1 + count - index;
1454
1455 charptr_tmp = (u8 *)vars[args[0]];
1456 status = altera_set_ir_pre(&astate->js, count, index,
1457 charptr_tmp);
1458
1459 break;
1460 case OP_IPOA:
1461 /*
1462 * IRPOST with array data
1463 * ...argument 0 is variable ID
1464 * ...stack 0 is array index
1465 * ...stack 1 is count
1466 */
1467 if (!altera_check_stack(stack_ptr, 2, &status))
1468 break;
1469 index = stack[--stack_ptr];
1470 count = stack[--stack_ptr];
1471
1472 if (version > 0)
1473 /*
1474 * stack 0 = array right index
1475 * stack 1 = array left index
1476 */
1477 count = 1 + count - index;
1478
1479 charptr_tmp = (u8 *)vars[args[0]];
1480 status = altera_set_ir_post(&astate->js, count, index,
1481 charptr_tmp);
1482
1483 break;
1484 case OP_EXPT:
1485 /*
1486 * EXPORT
1487 * ...argument 0 is string ID
1488 * ...stack 0 is integer expression
1489 */
1490 if (altera_check_stack(stack_ptr, 1, &status)) {
1491 name = &p[str_table + args[0]];
1492 long_tmp = stack[--stack_ptr];
1493 altera_export_int(name, long_tmp);
1494 }
1495 break;
1496 case OP_PSHE:
1497 /*
1498 * Push integer array element
1499 * ...argument 0 is variable ID
1500 * ...stack 0 is array index
1501 */
1502 if (!altera_check_stack(stack_ptr, 1, &status))
1503 break;
1504 variable_id = args[0];
1505 index = stack[stack_ptr - 1];
1506
1507 /* check variable type */
1508 if ((attrs[variable_id] & 0x1f) == 0x19) {
1509 /* writable integer array */
1510 longptr_tmp = (long *)vars[variable_id];
1511 stack[stack_ptr - 1] = longptr_tmp[index];
1512 } else if ((attrs[variable_id] & 0x1f) == 0x1c) {
1513 /* read-only integer array */
1514 long_tmp = vars[variable_id] +
1515 (index * sizeof(long));
1516 stack[stack_ptr - 1] =
1517 get_unaligned_be32(&p[long_tmp]);
1518 } else
1519 status = -ERANGE;
1520
1521 break;
1522 case OP_PSHA:
1523 /*
1524 * Push Boolean array
1525 * ...argument 0 is variable ID
1526 * ...stack 0 is count
1527 * ...stack 1 is array index
1528 */
1529 if (!altera_check_stack(stack_ptr, 2, &status))
1530 break;
1531 variable_id = args[0];
1532
1533 /* check that variable is a Boolean array */
1534 if ((attrs[variable_id] & 0x18) != 0x08) {
1535 status = -ERANGE;
1536 break;
1537 }
1538
1539 charptr_tmp = (u8 *)vars[variable_id];
1540
1541 /* pop the count (number of bits to copy) */
1542 count = stack[--stack_ptr];
1543
1544 /* pop the array index */
1545 index = stack[stack_ptr - 1];
1546
1547 if (version > 0)
1548 /*
1549 * stack 0 = array right index
1550 * stack 1 = array left index
1551 */
1552 count = 1 + count - index;
1553
1554 if ((count < 1) || (count > 32)) {
1555 status = -ERANGE;
1556 break;
1557 }
1558
1559 long_tmp = 0L;
1560
1561 for (i = 0; i < count; ++i)
1562 if (charptr_tmp[(i + index) >> 3] &
1563 (1 << ((i + index) & 7)))
1564 long_tmp |= (1L << i);
1565
1566 stack[stack_ptr - 1] = long_tmp;
1567
1568 break;
1569 case OP_DYNA:
1570 /*
1571 * Dynamically change size of array
1572 * ...argument 0 is variable ID
1573 * ...stack 0 is new size
1574 */
1575 if (!altera_check_stack(stack_ptr, 1, &status))
1576 break;
1577 variable_id = args[0];
1578 long_tmp = stack[--stack_ptr];
1579
1580 if (long_tmp > var_size[variable_id]) {
1581 var_size[variable_id] = long_tmp;
1582
1583 if (attrs[variable_id] & 0x10)
1584 /* allocate integer array */
1585 long_tmp *= sizeof(long);
1586 else
1587 /* allocate Boolean array */
1588 long_tmp = (long_tmp + 7) >> 3;
1589
1590 /*
1591 * If the buffer was previously allocated,
1592 * free it
1593 */
1594 if (attrs[variable_id] & 0x80) {
1595 kfree((void *)vars[variable_id]);
1596 vars[variable_id] = 0;
1597 }
1598
1599 /*
1600 * Allocate a new buffer
1601 * of the requested size
1602 */
1603 vars[variable_id] = (long)
1604 kzalloc(long_tmp, GFP_KERNEL);
1605
1606 if (vars[variable_id] == 0) {
1607 status = -ENOMEM;
1608 break;
1609 }
1610
1611 /*
1612 * Set the attribute bit to indicate that
1613 * this buffer was dynamically allocated and
1614 * should be freed later
1615 */
1616 attrs[variable_id] |= 0x80;
1617
1618 /* zero out memory */
1619 count = ((var_size[variable_id] + 7L) /
1620 8L);
1621 charptr_tmp = (u8 *)(vars[variable_id]);
1622 for (index = 0; index < count; ++index)
1623 charptr_tmp[index] = 0;
1624
1625 }
1626
1627 break;
1628 case OP_EXPV:
1629 /*
1630 * Export Boolean array
1631 * ...argument 0 is string ID
1632 * ...stack 0 is variable ID
1633 * ...stack 1 is array right index
1634 * ...stack 2 is array left index
1635 */
1636 if (!altera_check_stack(stack_ptr, 3, &status))
1637 break;
1638 if (version == 0) {
1639 /* EXPV is not supported in JBC 1.0 */
1640 bad_opcode = 1;
1641 break;
1642 }
1643 name = &p[str_table + args[0]];
1644 variable_id = stack[--stack_ptr];
1645 long_idx = stack[--stack_ptr];/* right indx */
1646 long_idx2 = stack[--stack_ptr];/* left indx */
1647
1648 if (long_idx > long_idx2) {
1649 /* reverse indices not supported */
1650 status = -ERANGE;
1651 break;
1652 }
1653
1654 long_count = 1 + long_idx2 - long_idx;
1655
1656 charptr_tmp = (u8 *)vars[variable_id];
1657 charptr_tmp2 = NULL;
1658
1659 if ((long_idx & 7L) != 0) {
1660 s32 k = long_idx;
1661 charptr_tmp2 =
1662 kzalloc(((long_count + 7L) / 8L),
1663 GFP_KERNEL);
1664 if (charptr_tmp2 == NULL) {
1665 status = -ENOMEM;
1666 break;
1667 }
1668
1669 for (i = 0; i < long_count; ++i) {
1670 if (charptr_tmp[k >> 3] &
1671 (1 << (k & 7)))
1672 charptr_tmp2[i >> 3] |=
1673 (1 << (i & 7));
1674 else
1675 charptr_tmp2[i >> 3] &=
1676 ~(1 << (i & 7));
1677
1678 ++k;
1679 }
1680 charptr_tmp = charptr_tmp2;
1681
1682 } else if (long_idx != 0)
1683 charptr_tmp = &charptr_tmp[long_idx >> 3];
1684
1685 altera_export_bool_array(name, charptr_tmp,
1686 long_count);
1687
1688 /* free allocated buffer */
1689 if ((long_idx & 7L) != 0)
1690 kfree(charptr_tmp2);
1691
1692 break;
1693 case OP_COPY: {
1694 /*
1695 * Array copy
1696 * ...argument 0 is dest ID
1697 * ...argument 1 is source ID
1698 * ...stack 0 is count
1699 * ...stack 1 is dest index
1700 * ...stack 2 is source index
1701 */
1702 s32 copy_count;
1703 s32 copy_index;
1704 s32 copy_index2;
1705 s32 destleft;
1706 s32 src_count;
1707 s32 dest_count;
1708 int src_reverse = 0;
1709 int dest_reverse = 0;
1710
1711 if (!altera_check_stack(stack_ptr, 3, &status))
1712 break;
1713
1714 copy_count = stack[--stack_ptr];
1715 copy_index = stack[--stack_ptr];
1716 copy_index2 = stack[--stack_ptr];
1717 reverse = 0;
1718
1719 if (version > 0) {
1720 /*
1721 * stack 0 = source right index
1722 * stack 1 = source left index
1723 * stack 2 = destination right index
1724 * stack 3 = destination left index
1725 */
1726 destleft = stack[--stack_ptr];
1727
1728 if (copy_count > copy_index) {
1729 src_reverse = 1;
1730 reverse = 1;
1731 src_count = 1 + copy_count - copy_index;
1732 /* copy_index = source start index */
1733 } else {
1734 src_count = 1 + copy_index - copy_count;
1735 /* source start index */
1736 copy_index = copy_count;
1737 }
1738
1739 if (copy_index2 > destleft) {
1740 dest_reverse = 1;
1741 reverse = !reverse;
1742 dest_count = 1 + copy_index2 - destleft;
1743 /* destination start index */
1744 copy_index2 = destleft;
1745 } else
1746 dest_count = 1 + destleft - copy_index2;
1747
1748 copy_count = (src_count < dest_count) ?
1749 src_count : dest_count;
1750
1751 if ((src_reverse || dest_reverse) &&
1752 (src_count != dest_count))
1753 /*
1754 * If either the source or destination
1755 * is reversed, we can't tolerate
1756 * a length mismatch, because we
1757 * "left justify" arrays when copying.
1758 * This won't work correctly
1759 * with reversed arrays.
1760 */
1761 status = -ERANGE;
1762
1763 }
1764
1765 count = copy_count;
1766 index = copy_index;
1767 index2 = copy_index2;
1768
1769 /*
1770 * If destination is a read-only array,
1771 * allocate a buffer and convert it to a writable array
1772 */
1773 variable_id = args[1];
1774 if ((version > 0) &&
1775 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1776 /* Allocate a writable buffer for this array */
1777 long_tmp =
1778 (var_size[variable_id] + 7L) >> 3L;
1779 charptr_tmp2 = (u8 *)vars[variable_id];
1780 charptr_tmp =
1781 kzalloc(long_tmp, GFP_KERNEL);
1782 vars[variable_id] = (long)charptr_tmp;
1783
1784 if (vars[variable_id] == 0) {
1785 status = -ENOMEM;
1786 break;
1787 }
1788
1789 /* zero the buffer */
1790 for (long_idx = 0L; long_idx < long_tmp;
1791 ++long_idx)
1792 charptr_tmp[long_idx] = 0;
1793
1794 /* copy previous contents into buffer */
1795 for (long_idx = 0L;
1796 long_idx < var_size[variable_id];
1797 ++long_idx) {
1798 long_idx2 = long_idx;
1799
1800 if (charptr_tmp2[long_idx2 >> 3] &
1801 (1 << (long_idx2 & 7)))
1802 charptr_tmp[long_idx >> 3] |=
1803 (1 << (long_idx & 7));
1804
1805 }
1806
1807 /*
1808 set bit 7 - buffer was dynamically allocated */
1809 attrs[variable_id] |= 0x80;
1810
1811 /* clear bit 2 - variable is writable */
1812 attrs[variable_id] &= ~0x04;
1813 attrs[variable_id] |= 0x01;
1814 }
1815
1816 charptr_tmp = (u8 *)vars[args[1]];
1817 charptr_tmp2 = (u8 *)vars[args[0]];
1818
1819 /* check if destination is a writable Boolean array */
1820 if ((attrs[args[1]] & 0x1c) != 0x08) {
1821 status = -ERANGE;
1822 break;
1823 }
1824
1825 if (count < 1) {
1826 status = -ERANGE;
1827 break;
1828 }
1829
1830 if (reverse)
1831 index2 += (count - 1);
1832
1833 for (i = 0; i < count; ++i) {
1834 if (charptr_tmp2[index >> 3] &
1835 (1 << (index & 7)))
1836 charptr_tmp[index2 >> 3] |=
1837 (1 << (index2 & 7));
1838 else
1839 charptr_tmp[index2 >> 3] &=
1840 ~(1 << (index2 & 7));
1841
1842 ++index;
1843 if (reverse)
1844 --index2;
1845 else
1846 ++index2;
1847 }
1848
1849 break;
1850 }
1851 case OP_DSC:
1852 case OP_ISC: {
1853 /*
1854 * DRSCAN with capture
1855 * IRSCAN with capture
1856 * ...argument 0 is scan data variable ID
1857 * ...argument 1 is capture variable ID
1858 * ...stack 0 is capture index
1859 * ...stack 1 is scan data index
1860 * ...stack 2 is count
1861 */
1862 s32 scan_right, scan_left;
1863 s32 capture_count = 0;
1864 s32 scan_count = 0;
1865 s32 capture_index;
1866 s32 scan_index;
1867
1868 if (!altera_check_stack(stack_ptr, 3, &status))
1869 break;
1870
1871 capture_index = stack[--stack_ptr];
1872 scan_index = stack[--stack_ptr];
1873
1874 if (version > 0) {
1875 /*
1876 * stack 0 = capture right index
1877 * stack 1 = capture left index
1878 * stack 2 = scan right index
1879 * stack 3 = scan left index
1880 * stack 4 = count
1881 */
1882 scan_right = stack[--stack_ptr];
1883 scan_left = stack[--stack_ptr];
1884 capture_count = 1 + scan_index - capture_index;
1885 scan_count = 1 + scan_left - scan_right;
1886 scan_index = scan_right;
1887 }
1888
1889 long_count = stack[--stack_ptr];
1890 /*
1891 * If capture array is read-only, allocate a buffer
1892 * and convert it to a writable array
1893 */
1894 variable_id = args[1];
1895 if ((version > 0) &&
1896 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1897 /* Allocate a writable buffer for this array */
1898 long_tmp =
1899 (var_size[variable_id] + 7L) >> 3L;
1900 charptr_tmp2 = (u8 *)vars[variable_id];
1901 charptr_tmp =
1902 kzalloc(long_tmp, GFP_KERNEL);
1903 vars[variable_id] = (long)charptr_tmp;
1904
1905 if (vars[variable_id] == 0) {
1906 status = -ENOMEM;
1907 break;
1908 }
1909
1910 /* zero the buffer */
1911 for (long_idx = 0L; long_idx < long_tmp;
1912 ++long_idx)
1913 charptr_tmp[long_idx] = 0;
1914
1915 /* copy previous contents into buffer */
1916 for (long_idx = 0L;
1917 long_idx < var_size[variable_id];
1918 ++long_idx) {
1919 long_idx2 = long_idx;
1920
1921 if (charptr_tmp2[long_idx2 >> 3] &
1922 (1 << (long_idx2 & 7)))
1923 charptr_tmp[long_idx >> 3] |=
1924 (1 << (long_idx & 7));
1925
1926 }
1927
1928 /*
1929 * set bit 7 - buffer was
1930 * dynamically allocated
1931 */
1932 attrs[variable_id] |= 0x80;
1933
1934 /* clear bit 2 - variable is writable */
1935 attrs[variable_id] &= ~0x04;
1936 attrs[variable_id] |= 0x01;
1937
1938 }
1939
1940 charptr_tmp = (u8 *)vars[args[0]];
1941 charptr_tmp2 = (u8 *)vars[args[1]];
1942
1943 if ((version > 0) &&
1944 ((long_count > capture_count) ||
1945 (long_count > scan_count))) {
1946 status = -ERANGE;
1947 break;
1948 }
1949
1950 /*
1951 * check that capture array
1952 * is a writable Boolean array
1953 */
1954 if ((attrs[args[1]] & 0x1c) != 0x08) {
1955 status = -ERANGE;
1956 break;
1957 }
1958
1959 if (status == 0) {
1960 if (opcode == 0x82) /* DSC */
1961 status = altera_swap_dr(astate,
1962 long_count,
1963 charptr_tmp,
1964 scan_index,
1965 charptr_tmp2,
1966 capture_index);
1967 else /* ISC */
1968 status = altera_swap_ir(astate,
1969 long_count,
1970 charptr_tmp,
1971 scan_index,
1972 charptr_tmp2,
1973 capture_index);
1974
1975 }
1976
1977 break;
1978 }
1979 case OP_WAIT:
1980 /*
1981 * WAIT
1982 * ...argument 0 is wait state
1983 * ...argument 1 is end state
1984 * ...stack 0 is cycles
1985 * ...stack 1 is microseconds
1986 */
1987 if (!altera_check_stack(stack_ptr, 2, &status))
1988 break;
1989 long_tmp = stack[--stack_ptr];
1990
1991 if (long_tmp != 0L)
1992 status = altera_wait_cycles(astate, long_tmp,
1993 args[0]);
1994
1995 long_tmp = stack[--stack_ptr];
1996
1997 if ((status == 0) && (long_tmp != 0L))
1998 status = altera_wait_msecs(astate,
1999 long_tmp,
2000 args[0]);
2001
2002 if ((status == 0) && (args[1] != args[0]))
2003 status = altera_goto_jstate(astate,
2004 args[1]);
2005
2006 if (version > 0) {
2007 --stack_ptr; /* throw away MAX cycles */
2008 --stack_ptr; /* throw away MAX microseconds */
2009 }
2010 break;
2011 case OP_CMPA: {
2012 /*
2013 * Array compare
2014 * ...argument 0 is source 1 ID
2015 * ...argument 1 is source 2 ID
2016 * ...argument 2 is mask ID
2017 * ...stack 0 is source 1 index
2018 * ...stack 1 is source 2 index
2019 * ...stack 2 is mask index
2020 * ...stack 3 is count
2021 */
2022 s32 a, b;
2023 u8 *source1 = (u8 *)vars[args[0]];
2024 u8 *source2 = (u8 *)vars[args[1]];
2025 u8 *mask = (u8 *)vars[args[2]];
2026 u32 index1;
2027 u32 index2;
2028 u32 mask_index;
2029
2030 if (!altera_check_stack(stack_ptr, 4, &status))
2031 break;
2032
2033 index1 = stack[--stack_ptr];
2034 index2 = stack[--stack_ptr];
2035 mask_index = stack[--stack_ptr];
2036 long_count = stack[--stack_ptr];
2037
2038 if (version > 0) {
2039 /*
2040 * stack 0 = source 1 right index
2041 * stack 1 = source 1 left index
2042 * stack 2 = source 2 right index
2043 * stack 3 = source 2 left index
2044 * stack 4 = mask right index
2045 * stack 5 = mask left index
2046 */
2047 s32 mask_right = stack[--stack_ptr];
2048 s32 mask_left = stack[--stack_ptr];
2049 /* source 1 count */
2050 a = 1 + index2 - index1;
2051 /* source 2 count */
2052 b = 1 + long_count - mask_index;
2053 a = (a < b) ? a : b;
2054 /* mask count */
2055 b = 1 + mask_left - mask_right;
2056 a = (a < b) ? a : b;
2057 /* source 2 start index */
2058 index2 = mask_index;
2059 /* mask start index */
2060 mask_index = mask_right;
2061 long_count = a;
2062 }
2063
2064 long_tmp = 1L;
2065
2066 if (long_count < 1)
2067 status = -ERANGE;
2068 else {
2069 count = long_count;
2070
2071 for (i = 0; i < count; ++i) {
2072 if (mask[mask_index >> 3] &
2073 (1 << (mask_index & 7))) {
2074 a = source1[index1 >> 3] &
2075 (1 << (index1 & 7))
2076 ? 1 : 0;
2077 b = source2[index2 >> 3] &
2078 (1 << (index2 & 7))
2079 ? 1 : 0;
2080
2081 if (a != b) /* failure */
2082 long_tmp = 0L;
2083 }
2084 ++index1;
2085 ++index2;
2086 ++mask_index;
2087 }
2088 }
2089
2090 stack[stack_ptr++] = long_tmp;
2091
2092 break;
2093 }
2094 default:
2095 /* Unrecognized opcode -- ERROR! */
2096 bad_opcode = 1;
2097 break;
2098 }
2099
2100 if (bad_opcode)
2101 status = -ENOSYS;
2102
2103 if ((stack_ptr < 0) || (stack_ptr >= ALTERA_STACK_SIZE))
2104 status = -EOVERFLOW;
2105
2106 if (status != 0) {
2107 done = 1;
2108 *error_address = (s32)(opcode_address - code_sect);
2109 }
2110 }
2111
2112 altera_free_buffers(astate);
2113
2114 /* Free all dynamically allocated arrays */
2115 if ((attrs != NULL) && (vars != NULL))
2116 for (i = 0; i < sym_count; ++i)
2117 if (attrs[i] & 0x80)
2118 kfree((void *)vars[i]);
2119
2120 kfree(vars);
2121 kfree(var_size);
2122 kfree(attrs);
2123 kfree(proc_attributes);
2124
2125 return status;
2126}
2127
2128static int altera_get_note(u8 *p, s32 program_size,
2129 s32 *offset, char *key, char *value, int length)
2130/*
2131 * Gets key and value of NOTE fields in the JBC file.
2132 * Can be called in two modes: if offset pointer is NULL,
2133 * then the function searches for note fields which match
2134 * the key string provided. If offset is not NULL, then
2135 * the function finds the next note field of any key,
2136 * starting at the offset specified by the offset pointer.
2137 * Returns 0 for success, else appropriate error code
2138 */
2139{
2140 int status = -ENODATA;
2141 u32 note_strings = 0L;
2142 u32 note_table = 0L;
2143 u32 note_count = 0L;
2144 u32 first_word = 0L;
2145 int version = 0;
2146 int delta = 0;
2147 char *key_ptr;
2148 char *value_ptr;
2149 int i;
2150
2151 /* Read header information */
2152 if (program_size > 52L) {
2153 first_word = get_unaligned_be32(&p[0]);
2154 version = (first_word & 1L);
2155 delta = version * 8;
2156
2157 note_strings = get_unaligned_be32(&p[8 + delta]);
2158 note_table = get_unaligned_be32(&p[12 + delta]);
2159 note_count = get_unaligned_be32(&p[44 + (2 * delta)]);
2160 }
2161
2162 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2163 return -EIO;
2164
2165 if (note_count <= 0L)
2166 return status;
2167
2168 if (offset == NULL) {
2169 /*
2170 * We will search for the first note with a specific key,
2171 * and return only the value
2172 */
2173 for (i = 0; (i < note_count) &&
2174 (status != 0); ++i) {
2175 key_ptr = &p[note_strings +
2176 get_unaligned_be32(
2177 &p[note_table + (8 * i)])];
2178 if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) &&
2179 (key != NULL)) {
2180 status = 0;
2181
2182 value_ptr = &p[note_strings +
2183 get_unaligned_be32(
2184 &p[note_table + (8 * i) + 4])];
2185
2186 if (value != NULL)
2187 strlcpy(value, value_ptr, length);
2188
2189 }
2190 }
2191 } else {
2192 /*
2193 * We will search for the next note, regardless of the key,
2194 * and return both the value and the key
2195 */
2196
2197 i = *offset;
2198
2199 if ((i >= 0) && (i < note_count)) {
2200 status = 0;
2201
2202 if (key != NULL)
2203 strlcpy(key, &p[note_strings +
2204 get_unaligned_be32(
2205 &p[note_table + (8 * i)])],
2206 length);
2207
2208 if (value != NULL)
2209 strlcpy(value, &p[note_strings +
2210 get_unaligned_be32(
2211 &p[note_table + (8 * i) + 4])],
2212 length);
2213
2214 *offset = i + 1;
2215 }
2216 }
2217
2218 return status;
2219}
2220
2221static int altera_check_crc(u8 *p, s32 program_size)
2222{
2223 int status = 0;
2224 u16 local_expected = 0,
2225 local_actual = 0,
2226 shift_reg = 0xffff;
2227 int bit, feedback;
2228 u8 databyte;
2229 u32 i;
2230 u32 crc_section = 0L;
2231 u32 first_word = 0L;
2232 int version = 0;
2233 int delta = 0;
2234
2235 if (program_size > 52L) {
2236 first_word = get_unaligned_be32(&p[0]);
2237 version = (first_word & 1L);
2238 delta = version * 8;
2239
2240 crc_section = get_unaligned_be32(&p[32 + delta]);
2241 }
2242
2243 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2244 status = -EIO;
2245
2246 if (crc_section >= program_size)
2247 status = -EIO;
2248
2249 if (status == 0) {
2250 local_expected = (u16)get_unaligned_be16(&p[crc_section]);
2251
2252 for (i = 0; i < crc_section; ++i) {
2253 databyte = p[i];
2254 for (bit = 0; bit < 8; bit++) {
2255 feedback = (databyte ^ shift_reg) & 0x01;
2256 shift_reg >>= 1;
2257 if (feedback)
2258 shift_reg ^= 0x8408;
2259
2260 databyte >>= 1;
2261 }
2262 }
2263
2264 local_actual = (u16)~shift_reg;
2265
2266 if (local_expected != local_actual)
2267 status = -EILSEQ;
2268
2269 }
2270
2271 if (debug || status) {
2272 switch (status) {
2273 case 0:
2274 printk(KERN_INFO "%s: CRC matched: %04x\n", __func__,
2275 local_actual);
2276 break;
2277 case -EILSEQ:
2278 printk(KERN_ERR "%s: CRC mismatch: expected %04x, "
2279 "actual %04x\n", __func__, local_expected,
2280 local_actual);
2281 break;
2282 case -ENODATA:
2283 printk(KERN_ERR "%s: expected CRC not found, "
2284 "actual CRC = %04x\n", __func__,
2285 local_actual);
2286 break;
2287 case -EIO:
2288 printk(KERN_ERR "%s: error: format isn't "
2289 "recognized.\n", __func__);
2290 break;
2291 default:
2292 printk(KERN_ERR "%s: CRC function returned error "
2293 "code %d\n", __func__, status);
2294 break;
2295 }
2296 }
2297
2298 return status;
2299}
2300
2301static int altera_get_file_info(u8 *p,
2302 s32 program_size,
2303 int *format_version,
2304 int *action_count,
2305 int *procedure_count)
2306{
2307 int status = -EIO;
2308 u32 first_word = 0;
2309 int version = 0;
2310
2311 if (program_size <= 52L)
2312 return status;
2313
2314 first_word = get_unaligned_be32(&p[0]);
2315
2316 if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) {
2317 status = 0;
2318
2319 version = (first_word & 1L);
2320 *format_version = version + 1;
2321
2322 if (version > 0) {
2323 *action_count = get_unaligned_be32(&p[48]);
2324 *procedure_count = get_unaligned_be32(&p[52]);
2325 }
2326 }
2327
2328 return status;
2329}
2330
2331static int altera_get_act_info(u8 *p,
2332 s32 program_size,
2333 int index,
2334 char **name,
2335 char **description,
2336 struct altera_procinfo **proc_list)
2337{
2338 int status = -EIO;
2339 struct altera_procinfo *procptr = NULL;
2340 struct altera_procinfo *tmpptr = NULL;
2341 u32 first_word = 0L;
2342 u32 action_table = 0L;
2343 u32 proc_table = 0L;
2344 u32 str_table = 0L;
2345 u32 note_strings = 0L;
2346 u32 action_count = 0L;
2347 u32 proc_count = 0L;
2348 u32 act_name_id = 0L;
2349 u32 act_desc_id = 0L;
2350 u32 act_proc_id = 0L;
2351 u32 act_proc_name = 0L;
2352 u8 act_proc_attribute = 0;
2353
2354 if (program_size <= 52L)
2355 return status;
2356 /* Read header information */
2357 first_word = get_unaligned_be32(&p[0]);
2358
2359 if (first_word != 0x4A414D01L)
2360 return status;
2361
2362 action_table = get_unaligned_be32(&p[4]);
2363 proc_table = get_unaligned_be32(&p[8]);
2364 str_table = get_unaligned_be32(&p[12]);
2365 note_strings = get_unaligned_be32(&p[16]);
2366 action_count = get_unaligned_be32(&p[48]);
2367 proc_count = get_unaligned_be32(&p[52]);
2368
2369 if (index >= action_count)
2370 return status;
2371
2372 act_name_id = get_unaligned_be32(&p[action_table + (12 * index)]);
2373 act_desc_id = get_unaligned_be32(&p[action_table + (12 * index) + 4]);
2374 act_proc_id = get_unaligned_be32(&p[action_table + (12 * index) + 8]);
2375
2376 *name = &p[str_table + act_name_id];
2377
2378 if (act_desc_id < (note_strings - str_table))
2379 *description = &p[str_table + act_desc_id];
2380
2381 do {
2382 act_proc_name = get_unaligned_be32(
2383 &p[proc_table + (13 * act_proc_id)]);
2384 act_proc_attribute =
2385 (p[proc_table + (13 * act_proc_id) + 8] & 0x03);
2386
2387 procptr = (struct altera_procinfo *)
2388 kzalloc(sizeof(struct altera_procinfo),
2389 GFP_KERNEL);
2390
2391 if (procptr == NULL)
2392 status = -ENOMEM;
2393 else {
2394 procptr->name = &p[str_table + act_proc_name];
2395 procptr->attrs = act_proc_attribute;
2396 procptr->next = NULL;
2397
2398 /* add record to end of linked list */
2399 if (*proc_list == NULL)
2400 *proc_list = procptr;
2401 else {
2402 tmpptr = *proc_list;
2403 while (tmpptr->next != NULL)
2404 tmpptr = tmpptr->next;
2405 tmpptr->next = procptr;
2406 }
2407 }
2408
2409 act_proc_id = get_unaligned_be32(
2410 &p[proc_table + (13 * act_proc_id) + 4]);
2411 } while ((act_proc_id != 0) && (act_proc_id < proc_count));
2412
2413 return status;
2414}
2415
2416int altera_init(struct altera_config *config, const struct firmware *fw)
2417{
2418 struct altera_state *astate = NULL;
2419 struct altera_procinfo *proc_list = NULL;
2420 struct altera_procinfo *procptr = NULL;
2421 char *key = NULL;
2422 char *value = NULL;
2423 char *action_name = NULL;
2424 char *description = NULL;
2425 int exec_result = 0;
2426 int exit_code = 0;
2427 int format_version = 0;
2428 int action_count = 0;
2429 int procedure_count = 0;
2430 int index = 0;
2431 s32 offset = 0L;
2432 s32 error_address = 0L;
2433
2434 key = kzalloc(33 * sizeof(char), GFP_KERNEL);
2435 if (!key)
2436 return -ENOMEM;
2437 value = kzalloc(257 * sizeof(char), GFP_KERNEL);
2438 if (!value)
2439 return -ENOMEM;
2440 astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL);
2441 if (!astate)
2442 return -ENOMEM;
2443
2444 astate->config = config;
2445 if (!astate->config->jtag_io) {
2446 dprintk(KERN_INFO "%s: using byteblaster!\n", __func__);
2447 astate->config->jtag_io = netup_jtag_io_lpt;
2448 }
2449
2450 altera_check_crc((u8 *)fw->data, fw->size);
2451
2452 if (debug) {
2453 altera_get_file_info((u8 *)fw->data, fw->size, &format_version,
2454 &action_count, &procedure_count);
2455 printk(KERN_INFO "%s: File format is %s ByteCode format\n",
2456 __func__, (format_version == 2) ? "Jam STAPL" :
2457 "pre-standardized Jam 1.1");
2458 while (altera_get_note((u8 *)fw->data, fw->size,
2459 &offset, key, value, 256) == 0)
2460 printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
2461 __func__, key, value);
2462 }
2463
2464 if (debug && (format_version == 2) && (action_count > 0)) {
2465 printk(KERN_INFO "%s: Actions available:\n", __func__);
2466 for (index = 0; index < action_count; ++index) {
2467 altera_get_act_info((u8 *)fw->data, fw->size,
2468 index, &action_name,
2469 &description,
2470 &proc_list);
2471
2472 if (description == NULL)
2473 printk(KERN_INFO "%s: %s\n",
2474 __func__,
2475 action_name);
2476 else
2477 printk(KERN_INFO "%s: %s \"%s\"\n",
2478 __func__,
2479 action_name,
2480 description);
2481
2482 procptr = proc_list;
2483 while (procptr != NULL) {
2484 if (procptr->attrs != 0)
2485 printk(KERN_INFO "%s: %s (%s)\n",
2486 __func__,
2487 procptr->name,
2488 (procptr->attrs == 1) ?
2489 "optional" : "recommended");
2490
2491 proc_list = procptr->next;
2492 kfree(procptr);
2493 procptr = proc_list;
2494 }
2495 }
2496
2497 printk(KERN_INFO "\n");
2498 }
2499
2500 exec_result = altera_execute(astate, (u8 *)fw->data, fw->size,
2501 &error_address, &exit_code, &format_version);
2502
2503 if (exit_code)
2504 exec_result = -EREMOTEIO;
2505
2506 if ((format_version == 2) && (exec_result == -EINVAL)) {
2507 if (astate->config->action == NULL)
2508 printk(KERN_ERR "%s: error: no action specified for "
2509 "Jam STAPL file.\nprogram terminated.\n",
2510 __func__);
2511 else
2512 printk(KERN_ERR "%s: error: action \"%s\""
2513 " is not supported "
2514 "for this Jam STAPL file.\n"
2515 "Program terminated.\n", __func__,
2516 astate->config->action);
2517
2518 } else if (exec_result)
2519 printk(KERN_ERR "%s: error %d\n", __func__, exec_result);
2520
2521 kfree(key);
2522 kfree(value);
2523 kfree(astate);
2524
2525 return 0;
2526}
2527EXPORT_SYMBOL(altera_init);
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
index b2656957aa8f..5f6b54213713 100644
--- a/drivers/staging/cx25821/Kconfig
+++ b/drivers/staging/cx25821/Kconfig
@@ -1,7 +1,6 @@
1config VIDEO_CX25821 1config VIDEO_CX25821
2 tristate "Conexant cx25821 support" 2 tristate "Conexant cx25821 support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C 3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C
4 depends on BKL # please fix
5 select I2C_ALGOBIT 4 select I2C_ALGOBIT
6 select VIDEO_BTCX 5 select VIDEO_BTCX
7 select VIDEO_TVEEPROM 6 select VIDEO_TVEEPROM
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index 160f6693aa33..ebdba7c65bc5 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -770,10 +770,12 @@ static int cx25821_alsa_init(void)
770 struct cx25821_dev *dev = NULL; 770 struct cx25821_dev *dev = NULL;
771 struct list_head *list; 771 struct list_head *list;
772 772
773 mutex_lock(&cx25821_devlist_mutex);
773 list_for_each(list, &cx25821_devlist) { 774 list_for_each(list, &cx25821_devlist) {
774 dev = list_entry(list, struct cx25821_dev, devlist); 775 dev = list_entry(list, struct cx25821_dev, devlist);
775 cx25821_audio_initdev(dev); 776 cx25821_audio_initdev(dev);
776 } 777 }
778 mutex_unlock(&cx25821_devlist_mutex);
777 779
778 if (dev == NULL) 780 if (dev == NULL)
779 pr_info("ERROR ALSA: no cx25821 cards found\n"); 781 pr_info("ERROR ALSA: no cx25821 cards found\n");
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index a216b620b718..523ac5e16c1b 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -33,9 +33,6 @@ MODULE_DESCRIPTION("Driver for Athena cards");
33MODULE_AUTHOR("Shu Lin - Hiep Huynh"); 33MODULE_AUTHOR("Shu Lin - Hiep Huynh");
34MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
35 35
36struct list_head cx25821_devlist;
37EXPORT_SYMBOL(cx25821_devlist);
38
39static unsigned int debug; 36static unsigned int debug;
40module_param(debug, int, 0644); 37module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "enable debug messages"); 38MODULE_PARM_DESC(debug, "enable debug messages");
@@ -46,8 +43,10 @@ MODULE_PARM_DESC(card, "card type");
46 43
47static unsigned int cx25821_devcount; 44static unsigned int cx25821_devcount;
48 45
49static DEFINE_MUTEX(devlist); 46DEFINE_MUTEX(cx25821_devlist_mutex);
47EXPORT_SYMBOL(cx25821_devlist_mutex);
50LIST_HEAD(cx25821_devlist); 48LIST_HEAD(cx25821_devlist);
49EXPORT_SYMBOL(cx25821_devlist);
51 50
52struct sram_channel cx25821_sram_channels[] = { 51struct sram_channel cx25821_sram_channels[] = {
53 [SRAM_CH00] = { 52 [SRAM_CH00] = {
@@ -911,9 +910,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
911 dev->nr = ++cx25821_devcount; 910 dev->nr = ++cx25821_devcount;
912 sprintf(dev->name, "cx25821[%d]", dev->nr); 911 sprintf(dev->name, "cx25821[%d]", dev->nr);
913 912
914 mutex_lock(&devlist); 913 mutex_lock(&cx25821_devlist_mutex);
915 list_add_tail(&dev->devlist, &cx25821_devlist); 914 list_add_tail(&dev->devlist, &cx25821_devlist);
916 mutex_unlock(&devlist); 915 mutex_unlock(&cx25821_devlist_mutex);
917 916
918 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown"); 917 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
919 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821"); 918 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
@@ -1465,9 +1464,9 @@ static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
1465 if (pci_dev->irq) 1464 if (pci_dev->irq)
1466 free_irq(pci_dev->irq, dev); 1465 free_irq(pci_dev->irq, dev);
1467 1466
1468 mutex_lock(&devlist); 1467 mutex_lock(&cx25821_devlist_mutex);
1469 list_del(&dev->devlist); 1468 list_del(&dev->devlist);
1470 mutex_unlock(&devlist); 1469 mutex_unlock(&cx25821_devlist_mutex);
1471 1470
1472 cx25821_dev_unregister(dev); 1471 cx25821_dev_unregister(dev);
1473 v4l2_device_unregister(v4l2_dev); 1472 v4l2_device_unregister(v4l2_dev);
@@ -1501,7 +1500,6 @@ static struct pci_driver cx25821_pci_driver = {
1501 1500
1502static int __init cx25821_init(void) 1501static int __init cx25821_init(void)
1503{ 1502{
1504 INIT_LIST_HEAD(&cx25821_devlist);
1505 pr_info("driver version %d.%d.%d loaded\n", 1503 pr_info("driver version %d.%d.%d loaded\n",
1506 (CX25821_VERSION_CODE >> 16) & 0xff, 1504 (CX25821_VERSION_CODE >> 16) & 0xff,
1507 (CX25821_VERSION_CODE >> 8) & 0xff, 1505 (CX25821_VERSION_CODE >> 8) & 0xff,
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index 0d8d75670516..ab05392386e8 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -27,7 +27,6 @@
27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 28
29#include "cx25821-video.h" 29#include "cx25821-video.h"
30#include <linux/smp_lock.h>
31 30
32MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); 31MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
33MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); 32MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
@@ -815,7 +814,7 @@ static int video_open(struct file *file)
815 if (NULL == fh) 814 if (NULL == fh)
816 return -ENOMEM; 815 return -ENOMEM;
817 816
818 lock_kernel(); 817 mutex_lock(&cx25821_devlist_mutex);
819 818
820 list_for_each(list, &cx25821_devlist) 819 list_for_each(list, &cx25821_devlist)
821 { 820 {
@@ -832,8 +831,8 @@ static int video_open(struct file *file)
832 } 831 }
833 832
834 if (NULL == dev) { 833 if (NULL == dev) {
835 unlock_kernel(); 834 mutex_unlock(&cx25821_devlist_mutex);
836 return -ENODEV; 835 return -ENODEV;
837 } 836 }
838 837
839 file->private_data = fh; 838 file->private_data = fh;
@@ -862,7 +861,7 @@ static int video_open(struct file *file)
862 sizeof(struct cx25821_buffer), fh, NULL); 861 sizeof(struct cx25821_buffer), fh, NULL);
863 862
864 dprintk(1, "post videobuf_queue_init()\n"); 863 dprintk(1, "post videobuf_queue_init()\n");
865 unlock_kernel(); 864 mutex_unlock(&cx25821_devlist_mutex);
866 865
867 return 0; 866 return 0;
868} 867}
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
index 55115235f7f6..6230243e2ccb 100644
--- a/drivers/staging/cx25821/cx25821.h
+++ b/drivers/staging/cx25821/cx25821.h
@@ -31,7 +31,6 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/kdev_t.h> 33#include <linux/kdev_t.h>
34#include <linux/smp_lock.h>
35 34
36#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
37#include <media/v4l2-device.h> 36#include <media/v4l2-device.h>
@@ -445,6 +444,8 @@ static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
445 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) 444 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
446 445
447extern struct list_head cx25821_devlist; 446extern struct list_head cx25821_devlist;
447extern struct mutex cx25821_devlist_mutex;
448
448extern struct cx25821_board cx25821_boards[]; 449extern struct cx25821_board cx25821_boards[];
449extern struct cx25821_subid cx25821_subids[]; 450extern struct cx25821_subid cx25821_subids[];
450 451
diff --git a/drivers/staging/cxd2099/Kconfig b/drivers/staging/cxd2099/Kconfig
new file mode 100644
index 000000000000..9d638c30735d
--- /dev/null
+++ b/drivers/staging/cxd2099/Kconfig
@@ -0,0 +1,11 @@
1config DVB_CXD2099
2 tristate "CXD2099AR Common Interface driver"
3 depends on DVB_CORE && PCI && I2C && DVB_NGENE
4 ---help---
5 Support for the CI module found on cineS2 DVB-S2, supported by
6 the Micronas PCIe device driver (ngene).
7
8 For now, data is passed through '/dev/dvb/adapterX/sec0':
9 - Encrypted data must be written to 'sec0'.
10 - Decrypted data can be read from 'sec0'.
11 - Setup the CAM using device 'ca0'.
diff --git a/drivers/staging/cxd2099/Makefile b/drivers/staging/cxd2099/Makefile
new file mode 100644
index 000000000000..72b14558c119
--- /dev/null
+++ b/drivers/staging/cxd2099/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
2
3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
4EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/
5EXTRA_CFLAGS += -Idrivers/media/common/tuners/
diff --git a/drivers/staging/cxd2099/TODO b/drivers/staging/cxd2099/TODO
new file mode 100644
index 000000000000..375bb6f8ee2c
--- /dev/null
+++ b/drivers/staging/cxd2099/TODO
@@ -0,0 +1,12 @@
1For now, data is passed through '/dev/dvb/adapterX/sec0':
2 - Encrypted data must be written to 'sec0'.
3 - Decrypted data can be read from 'sec0'.
4 - Setup the CAM using device 'ca0'.
5
6But this is wrong. There are some discussions about the proper way for
7doing it, as seen at:
8 http://www.mail-archive.com/linux-media@vger.kernel.org/msg22196.html
9
10While there's no proper fix for it, the driver should be kept in staging.
11
12Patches should be submitted to: linux-media@vger.kernel.org.
diff --git a/drivers/staging/cxd2099/cxd2099.c b/drivers/staging/cxd2099/cxd2099.c
new file mode 100644
index 000000000000..b49186c74eb3
--- /dev/null
+++ b/drivers/staging/cxd2099/cxd2099.c
@@ -0,0 +1,574 @@
1/*
2 * cxd2099.c: Driver for the CXD2099AR Common Interface Controller
3 *
4 * Copyright (C) 2010 DigitalDevices UG
5 *
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 only, as published by the Free Software Foundation.
10 *
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA
22 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 */
24
25#include <linux/version.h>
26#include <linux/slab.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/i2c.h>
32#include <linux/wait.h>
33#include <linux/delay.h>
34#include <linux/mutex.h>
35#include <linux/io.h>
36
37#include "cxd2099.h"
38
39#define MAX_BUFFER_SIZE 248
40
41struct cxd {
42 struct dvb_ca_en50221 en;
43
44 struct i2c_adapter *i2c;
45 u8 adr;
46 u8 regs[0x23];
47 u8 lastaddress;
48 u8 clk_reg_f;
49 u8 clk_reg_b;
50 int mode;
51 u32 bitrate;
52 int ready;
53 int dr;
54 int slot_stat;
55
56 u8 amem[1024];
57 int amem_read;
58
59 int cammode;
60 struct mutex lock;
61};
62
63static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr,
64 u8 reg, u8 data)
65{
66 u8 m[2] = {reg, data};
67 struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2};
68
69 if (i2c_transfer(adapter, &msg, 1) != 1) {
70 printk(KERN_ERR "Failed to write to I2C register %02x@%02x!\n",
71 reg, adr);
72 return -1;
73 }
74 return 0;
75}
76
77static int i2c_write(struct i2c_adapter *adapter, u8 adr,
78 u8 *data, u8 len)
79{
80 struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len};
81
82 if (i2c_transfer(adapter, &msg, 1) != 1) {
83 printk(KERN_ERR "Failed to write to I2C!\n");
84 return -1;
85 }
86 return 0;
87}
88
89static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
90 u8 reg, u8 *val)
91{
92 struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
93 .buf = &reg, .len = 1 },
94 {.addr = adr, .flags = I2C_M_RD,
95 .buf = val, .len = 1 } };
96
97 if (i2c_transfer(adapter, msgs, 2) != 2) {
98 printk(KERN_ERR "error in i2c_read_reg\n");
99 return -1;
100 }
101 return 0;
102}
103
104static int i2c_read(struct i2c_adapter *adapter, u8 adr,
105 u8 reg, u8 *data, u8 n)
106{
107 struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
108 .buf = &reg, .len = 1 },
109 {.addr = adr, .flags = I2C_M_RD,
110 .buf = data, .len = n } };
111
112 if (i2c_transfer(adapter, msgs, 2) != 2) {
113 printk(KERN_ERR "error in i2c_read\n");
114 return -1;
115 }
116 return 0;
117}
118
119static int read_block(struct cxd *ci, u8 adr, u8 *data, u8 n)
120{
121 int status;
122
123 status = i2c_write_reg(ci->i2c, ci->adr, 0, adr);
124 if (!status) {
125 ci->lastaddress = adr;
126 status = i2c_read(ci->i2c, ci->adr, 1, data, n);
127 }
128 return status;
129}
130
131static int read_reg(struct cxd *ci, u8 reg, u8 *val)
132{
133 return read_block(ci, reg, val, 1);
134}
135
136
137static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
138{
139 int status;
140 u8 addr[3] = { 2, address&0xff, address>>8 };
141
142 status = i2c_write(ci->i2c, ci->adr, addr, 3);
143 if (!status)
144 status = i2c_read(ci->i2c, ci->adr, 3, data, n);
145 return status;
146}
147
148static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
149{
150 int status;
151 u8 addr[3] = { 2, address&0xff, address>>8 };
152
153 status = i2c_write(ci->i2c, ci->adr, addr, 3);
154 if (!status) {
155 u8 buf[256] = {3};
156 memcpy(buf+1, data, n);
157 status = i2c_write(ci->i2c, ci->adr, buf, n+1);
158 }
159 return status;
160}
161
162static int read_io(struct cxd *ci, u16 address, u8 *val)
163{
164 int status;
165 u8 addr[3] = { 2, address&0xff, address>>8 };
166
167 status = i2c_write(ci->i2c, ci->adr, addr, 3);
168 if (!status)
169 status = i2c_read(ci->i2c, ci->adr, 3, val, 1);
170 return status;
171}
172
173static int write_io(struct cxd *ci, u16 address, u8 val)
174{
175 int status;
176 u8 addr[3] = { 2, address&0xff, address>>8 };
177 u8 buf[2] = { 3, val };
178
179 status = i2c_write(ci->i2c, ci->adr, addr, 3);
180 if (!status)
181 status = i2c_write(ci->i2c, ci->adr, buf, 2);
182
183 return status;
184}
185
186
187static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)
188{
189 int status;
190
191 status = i2c_write_reg(ci->i2c, ci->adr, 0, reg);
192 if (!status && reg >= 6 && reg <= 8 && mask != 0xff)
193 status = i2c_read_reg(ci->i2c, ci->adr, 1, &ci->regs[reg]);
194 ci->regs[reg] = (ci->regs[reg]&(~mask))|val;
195 if (!status) {
196 ci->lastaddress = reg;
197 status = i2c_write_reg(ci->i2c, ci->adr, 1, ci->regs[reg]);
198 }
199 if (reg == 0x20)
200 ci->regs[reg] &= 0x7f;
201 return status;
202}
203
204static int write_reg(struct cxd *ci, u8 reg, u8 val)
205{
206 return write_regm(ci, reg, val, 0xff);
207}
208
209#ifdef BUFFER_MODE
210static int write_block(struct cxd *ci, u8 adr, u8 *data, int n)
211{
212 int status;
213 u8 buf[256] = {1};
214
215 status = i2c_write_reg(ci->i2c, ci->adr, 0, adr);
216 if (!status) {
217 ci->lastaddress = adr;
218 memcpy(buf+1, data, n);
219 status = i2c_write(ci->i2c, ci->adr, buf, n+1);
220 }
221 return status;
222}
223#endif
224
225static void set_mode(struct cxd *ci, int mode)
226{
227 if (mode == ci->mode)
228 return;
229
230 switch (mode) {
231 case 0x00: /* IO mem */
232 write_regm(ci, 0x06, 0x00, 0x07);
233 break;
234 case 0x01: /* ATT mem */
235 write_regm(ci, 0x06, 0x02, 0x07);
236 break;
237 default:
238 break;
239 }
240 ci->mode = mode;
241}
242
243static void cam_mode(struct cxd *ci, int mode)
244{
245 if (mode == ci->cammode)
246 return;
247
248 switch (mode) {
249 case 0x00:
250 write_regm(ci, 0x20, 0x80, 0x80);
251 break;
252 case 0x01:
253 printk(KERN_INFO "enable cam buffer mode\n");
254 /* write_reg(ci, 0x0d, 0x00); */
255 /* write_reg(ci, 0x0e, 0x01); */
256 write_regm(ci, 0x08, 0x40, 0x40);
257 /* read_reg(ci, 0x12, &dummy); */
258 write_regm(ci, 0x08, 0x80, 0x80);
259 break;
260 default:
261 break;
262 }
263 ci->cammode = mode;
264}
265
266
267
268#define CHK_ERROR(s) if ((status = s)) break
269
270static int init(struct cxd *ci)
271{
272 int status;
273
274 mutex_lock(&ci->lock);
275 ci->mode = -1;
276 do {
277 CHK_ERROR(write_reg(ci, 0x00, 0x00));
278 CHK_ERROR(write_reg(ci, 0x01, 0x00));
279 CHK_ERROR(write_reg(ci, 0x02, 0x10));
280 CHK_ERROR(write_reg(ci, 0x03, 0x00));
281 CHK_ERROR(write_reg(ci, 0x05, 0xFF));
282 CHK_ERROR(write_reg(ci, 0x06, 0x1F));
283 CHK_ERROR(write_reg(ci, 0x07, 0x1F));
284 CHK_ERROR(write_reg(ci, 0x08, 0x28));
285 CHK_ERROR(write_reg(ci, 0x14, 0x20));
286
287 CHK_ERROR(write_reg(ci, 0x09, 0x4D)); /* Input Mode C, BYPass Serial, TIVAL = low, MSB */
288 CHK_ERROR(write_reg(ci, 0x0A, 0xA7)); /* TOSTRT = 8, Mode B (gated clock), falling Edge, Serial, POL=HIGH, MSB */
289
290 /* Sync detector */
291 CHK_ERROR(write_reg(ci, 0x0B, 0x33));
292 CHK_ERROR(write_reg(ci, 0x0C, 0x33));
293
294 CHK_ERROR(write_regm(ci, 0x14, 0x00, 0x0F));
295 CHK_ERROR(write_reg(ci, 0x15, ci->clk_reg_b));
296 CHK_ERROR(write_regm(ci, 0x16, 0x00, 0x0F));
297 CHK_ERROR(write_reg(ci, 0x17, ci->clk_reg_f));
298
299 CHK_ERROR(write_reg(ci, 0x20, 0x28)); /* Integer Divider, Falling Edge, Internal Sync, */
300 CHK_ERROR(write_reg(ci, 0x21, 0x00)); /* MCLKI = TICLK/8 */
301 CHK_ERROR(write_reg(ci, 0x22, 0x07)); /* MCLKI = TICLK/8 */
302
303
304 CHK_ERROR(write_regm(ci, 0x20, 0x80, 0x80)); /* Reset CAM state machine */
305
306 CHK_ERROR(write_regm(ci, 0x03, 0x02, 02)); /* Enable IREQA Interrupt */
307 CHK_ERROR(write_reg(ci, 0x01, 0x04)); /* Enable CD Interrupt */
308 CHK_ERROR(write_reg(ci, 0x00, 0x31)); /* Enable TS1,Hot Swap,Slot A */
309 CHK_ERROR(write_regm(ci, 0x09, 0x08, 0x08)); /* Put TS in bypass */
310 ci->cammode = -1;
311#ifdef BUFFER_MODE
312 cam_mode(ci, 0);
313#endif
314 } while (0);
315 mutex_unlock(&ci->lock);
316
317 return 0;
318}
319
320
321static int read_attribute_mem(struct dvb_ca_en50221 *ca,
322 int slot, int address)
323{
324 struct cxd *ci = ca->data;
325 u8 val;
326 mutex_lock(&ci->lock);
327 set_mode(ci, 1);
328 read_pccard(ci, address, &val, 1);
329 mutex_unlock(&ci->lock);
330 return val;
331}
332
333
334static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
335 int address, u8 value)
336{
337 struct cxd *ci = ca->data;
338
339 mutex_lock(&ci->lock);
340 set_mode(ci, 1);
341 write_pccard(ci, address, &value, 1);
342 mutex_unlock(&ci->lock);
343 return 0;
344}
345
346static int read_cam_control(struct dvb_ca_en50221 *ca,
347 int slot, u8 address)
348{
349 struct cxd *ci = ca->data;
350 u8 val;
351
352 mutex_lock(&ci->lock);
353 set_mode(ci, 0);
354 read_io(ci, address, &val);
355 mutex_unlock(&ci->lock);
356 return val;
357}
358
359static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
360 u8 address, u8 value)
361{
362 struct cxd *ci = ca->data;
363
364 mutex_lock(&ci->lock);
365 set_mode(ci, 0);
366 write_io(ci, address, value);
367 mutex_unlock(&ci->lock);
368 return 0;
369}
370
371static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
372{
373 struct cxd *ci = ca->data;
374
375 mutex_lock(&ci->lock);
376 cam_mode(ci, 0);
377 write_reg(ci, 0x00, 0x21);
378 write_reg(ci, 0x06, 0x1F);
379 write_reg(ci, 0x00, 0x31);
380 write_regm(ci, 0x20, 0x80, 0x80);
381 write_reg(ci, 0x03, 0x02);
382 ci->ready = 0;
383 ci->mode = -1;
384 {
385 int i;
386 for (i = 0; i < 100; i++) {
387 msleep(10);
388 if (ci->ready)
389 break;
390 }
391 }
392 mutex_unlock(&ci->lock);
393 /* msleep(500); */
394 return 0;
395}
396
397static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
398{
399 struct cxd *ci = ca->data;
400
401 printk(KERN_INFO "slot_shutdown\n");
402 mutex_lock(&ci->lock);
403 /* write_regm(ci, 0x09, 0x08, 0x08); */
404 write_regm(ci, 0x20, 0x80, 0x80);
405 write_regm(ci, 0x06, 0x07, 0x07);
406 ci->mode = -1;
407 mutex_unlock(&ci->lock);
408 return 0; /* shutdown(ci); */
409}
410
411static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
412{
413 struct cxd *ci = ca->data;
414
415 mutex_lock(&ci->lock);
416 write_regm(ci, 0x09, 0x00, 0x08);
417 set_mode(ci, 0);
418#ifdef BUFFER_MODE
419 cam_mode(ci, 1);
420#endif
421 mutex_unlock(&ci->lock);
422 return 0;
423}
424
425
426static int campoll(struct cxd *ci)
427{
428 u8 istat;
429
430 read_reg(ci, 0x04, &istat);
431 if (!istat)
432 return 0;
433 write_reg(ci, 0x05, istat);
434
435 if (istat&0x40) {
436 ci->dr = 1;
437 printk(KERN_INFO "DR\n");
438 }
439 if (istat&0x20)
440 printk(KERN_INFO "WC\n");
441
442 if (istat&2) {
443 u8 slotstat;
444
445 read_reg(ci, 0x01, &slotstat);
446 if (!(2&slotstat)) {
447 if (!ci->slot_stat) {
448 ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
449 write_regm(ci, 0x03, 0x08, 0x08);
450 }
451
452 } else {
453 if (ci->slot_stat) {
454 ci->slot_stat = 0;
455 write_regm(ci, 0x03, 0x00, 0x08);
456 printk(KERN_INFO "NO CAM\n");
457 ci->ready = 0;
458 }
459 }
460 if (istat&8 && ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
461 ci->ready = 1;
462 ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
463 printk(KERN_INFO "READY\n");
464 }
465 }
466 return 0;
467}
468
469
470static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
471{
472 struct cxd *ci = ca->data;
473 u8 slotstat;
474
475 mutex_lock(&ci->lock);
476 campoll(ci);
477 read_reg(ci, 0x01, &slotstat);
478 mutex_unlock(&ci->lock);
479
480 return ci->slot_stat;
481}
482
483#ifdef BUFFER_MODE
484static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
485{
486 struct cxd *ci = ca->data;
487 u8 msb, lsb;
488 u16 len;
489
490 mutex_lock(&ci->lock);
491 campoll(ci);
492 mutex_unlock(&ci->lock);
493
494 printk(KERN_INFO "read_data\n");
495 if (!ci->dr)
496 return 0;
497
498 mutex_lock(&ci->lock);
499 read_reg(ci, 0x0f, &msb);
500 read_reg(ci, 0x10, &lsb);
501 len = (msb<<8)|lsb;
502 read_block(ci, 0x12, ebuf, len);
503 ci->dr = 0;
504 mutex_unlock(&ci->lock);
505
506 return len;
507}
508
509static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
510{
511 struct cxd *ci = ca->data;
512
513 mutex_lock(&ci->lock);
514 printk(KERN_INFO "write_data %d\n", ecount);
515 write_reg(ci, 0x0d, ecount>>8);
516 write_reg(ci, 0x0e, ecount&0xff);
517 write_block(ci, 0x11, ebuf, ecount);
518 mutex_unlock(&ci->lock);
519 return ecount;
520}
521#endif
522
523static struct dvb_ca_en50221 en_templ = {
524 .read_attribute_mem = read_attribute_mem,
525 .write_attribute_mem = write_attribute_mem,
526 .read_cam_control = read_cam_control,
527 .write_cam_control = write_cam_control,
528 .slot_reset = slot_reset,
529 .slot_shutdown = slot_shutdown,
530 .slot_ts_enable = slot_ts_enable,
531 .poll_slot_status = poll_slot_status,
532#ifdef BUFFER_MODE
533 .read_data = read_data,
534 .write_data = write_data,
535#endif
536
537};
538
539struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv,
540 struct i2c_adapter *i2c)
541{
542 struct cxd *ci = 0;
543 u32 bitrate = 62000000;
544 u8 val;
545
546 if (i2c_read_reg(i2c, adr, 0, &val) < 0) {
547 printk(KERN_ERR "No CXD2099 detected at %02x\n", adr);
548 return 0;
549 }
550
551 ci = kmalloc(sizeof(struct cxd), GFP_KERNEL);
552 if (!ci)
553 return 0;
554 memset(ci, 0, sizeof(*ci));
555
556 mutex_init(&ci->lock);
557 ci->i2c = i2c;
558 ci->adr = adr;
559 ci->lastaddress = 0xff;
560 ci->clk_reg_b = 0x4a;
561 ci->clk_reg_f = 0x1b;
562 ci->bitrate = bitrate;
563
564 memcpy(&ci->en, &en_templ, sizeof(en_templ));
565 ci->en.data = ci;
566 init(ci);
567 printk(KERN_INFO "Attached CXD2099AR at %02x\n", ci->adr);
568 return &ci->en;
569}
570EXPORT_SYMBOL(cxd2099_attach);
571
572MODULE_DESCRIPTION("cxd2099");
573MODULE_AUTHOR("Ralph Metzler <rjkm@metzlerbros.de>");
574MODULE_LICENSE("GPL");
diff --git a/drivers/staging/cxd2099/cxd2099.h b/drivers/staging/cxd2099/cxd2099.h
new file mode 100644
index 000000000000..bed54ff3e30b
--- /dev/null
+++ b/drivers/staging/cxd2099/cxd2099.h
@@ -0,0 +1,41 @@
1/*
2 * cxd2099.h: Driver for the CXD2099AR Common Interface Controller
3 *
4 * Copyright (C) 2010 DigitalDevices UG
5 *
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 only, as published by the Free Software Foundation.
10 *
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA
22 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 */
24
25#ifndef _CXD2099_H_
26#define _CXD2099_H_
27
28#include <dvb_ca_en50221.h>
29
30#if defined(CONFIG_DVB_CXD2099) || \
31 (defined(CONFIG_DVB_CXD2099_MODULE) && defined(MODULE))
32struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv, struct i2c_adapter *i2c);
33#else
34static inline struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv, struct i2c_adapter *i2c)
35{
36 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
37 return NULL;
38}
39#endif
40
41#endif
diff --git a/drivers/staging/dabusb/Kconfig b/drivers/staging/dabusb/Kconfig
deleted file mode 100644
index 87bdc425d3c5..000000000000
--- a/drivers/staging/dabusb/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
1config USB_DABUSB
2 tristate "DABUSB driver"
3 depends on USB
4 ---help---
5 A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
6 brought to you by the DAB-Team
7 <http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
8 as an example for URB-based bulk, control, and isochronous
9 transactions. URB's are explained in
10 <Documentation/usb/URB.txt>.
11
12 To compile this driver as a module, choose M here: the
13 module will be called dabusb.
14
diff --git a/drivers/staging/dabusb/Makefile b/drivers/staging/dabusb/Makefile
deleted file mode 100644
index 2ff2f228e5f9..000000000000
--- a/drivers/staging/dabusb/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_USB_DABUSB) += dabusb.o
2
diff --git a/drivers/staging/dabusb/TODO b/drivers/staging/dabusb/TODO
deleted file mode 100644
index f9c0314ea0c1..000000000000
--- a/drivers/staging/dabusb/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1This is a driver for an experimental sample developed in 2003. The driver
2never supported any commercial product, nor had any known user.
3If nobody takes care on it, the driver will be removed for 2.6.39.
4
5Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/dabusb/dabusb.c b/drivers/staging/dabusb/dabusb.c
deleted file mode 100644
index 21768a627750..000000000000
--- a/drivers/staging/dabusb/dabusb.c
+++ /dev/null
@@ -1,926 +0,0 @@
1/*****************************************************************************/
2
3/*
4 * dabusb.c -- dab usb driver.
5 *
6 * Copyright (C) 1999 Deti Fliegl (deti@fliegl.de)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 *
24 * $Id: dabusb.c,v 1.54 2000/07/24 21:39:39 deti Exp $
25 *
26 */
27
28/*****************************************************************************/
29
30#include <linux/module.h>
31#include <linux/socket.h>
32#include <linux/list.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/init.h>
36#include <linux/uaccess.h>
37#include <linux/atomic.h>
38#include <linux/delay.h>
39#include <linux/usb.h>
40#include <linux/mutex.h>
41#include <linux/firmware.h>
42#include <linux/ihex.h>
43
44#include "dabusb.h"
45
46/*
47 * Version Information
48 */
49#define DRIVER_VERSION "v1.54"
50#define DRIVER_AUTHOR "Deti Fliegl, deti@fliegl.de"
51#define DRIVER_DESC "DAB-USB Interface Driver for Linux (c)1999"
52
53/* --------------------------------------------------------------------- */
54
55#ifdef CONFIG_USB_DYNAMIC_MINORS
56#define NRDABUSB 256
57#else
58#define NRDABUSB 4
59#endif
60
61/*-------------------------------------------------------------------*/
62
63static dabusb_t dabusb[NRDABUSB];
64static int buffers = 256;
65static struct usb_driver dabusb_driver;
66
67/*-------------------------------------------------------------------*/
68
69static int dabusb_add_buf_tail(pdabusb_t s, struct list_head *dst,
70 struct list_head *src)
71{
72 unsigned long flags;
73 struct list_head *tmp;
74 int ret = 0;
75
76 spin_lock_irqsave(&s->lock, flags);
77
78 if (list_empty(src)) {
79 /* no elements in source buffer */
80 ret = -1;
81 goto err;
82 }
83 tmp = src->next;
84 list_move_tail(tmp, dst);
85
86err: spin_unlock_irqrestore(&s->lock, flags);
87 return ret;
88}
89/*-------------------------------------------------------------------*/
90#ifdef DEBUG
91static void dump_urb(struct urb *urb)
92{
93 dbg("urb :%p", urb);
94 dbg("dev :%p", urb->dev);
95 dbg("pipe :%08X", urb->pipe);
96 dbg("status :%d", urb->status);
97 dbg("transfer_flags :%08X", urb->transfer_flags);
98 dbg("transfer_buffer :%p", urb->transfer_buffer);
99 dbg("transfer_buffer_length:%d", urb->transfer_buffer_length);
100 dbg("actual_length :%d", urb->actual_length);
101 dbg("setup_packet :%p", urb->setup_packet);
102 dbg("start_frame :%d", urb->start_frame);
103 dbg("number_of_packets :%d", urb->number_of_packets);
104 dbg("interval :%d", urb->interval);
105 dbg("error_count :%d", urb->error_count);
106 dbg("context :%p", urb->context);
107 dbg("complete :%p", urb->complete);
108}
109#endif
110/*-------------------------------------------------------------------*/
111static int dabusb_cancel_queue(pdabusb_t s, struct list_head *q)
112{
113 unsigned long flags;
114 pbuff_t b;
115
116 dbg("dabusb_cancel_queue");
117
118 spin_lock_irqsave(&s->lock, flags);
119
120 list_for_each_entry(b, q, buff_list) {
121#ifdef DEBUG
122 dump_urb(b->purb);
123#endif
124 usb_unlink_urb(b->purb);
125 }
126 spin_unlock_irqrestore(&s->lock, flags);
127 return 0;
128}
129/*-------------------------------------------------------------------*/
130static int dabusb_free_queue(struct list_head *q)
131{
132 struct list_head *tmp;
133 struct list_head *p;
134 pbuff_t b;
135
136 dbg("dabusb_free_queue");
137 for (p = q->next; p != q;) {
138 b = list_entry(p, buff_t, buff_list);
139
140#ifdef DEBUG
141 dump_urb(b->purb);
142#endif
143 kfree(b->purb->transfer_buffer);
144 usb_free_urb(b->purb);
145 tmp = p->next;
146 list_del(p);
147 kfree(b);
148 p = tmp;
149 }
150
151 return 0;
152}
153/*-------------------------------------------------------------------*/
154static int dabusb_free_buffers(pdabusb_t s)
155{
156 unsigned long flags;
157 dbg("dabusb_free_buffers");
158
159 spin_lock_irqsave(&s->lock, flags);
160
161 dabusb_free_queue(&s->free_buff_list);
162 dabusb_free_queue(&s->rec_buff_list);
163
164 spin_unlock_irqrestore(&s->lock, flags);
165
166 s->got_mem = 0;
167 return 0;
168}
169/*-------------------------------------------------------------------*/
170static void dabusb_iso_complete(struct urb *purb)
171{
172 pbuff_t b = purb->context;
173 pdabusb_t s = b->s;
174 int i;
175 int len;
176 int dst = 0;
177 void *buf = purb->transfer_buffer;
178
179 dbg("dabusb_iso_complete");
180
181 /* process if URB was not killed */
182 if (purb->status != -ENOENT) {
183 unsigned int pipe = usb_rcvisocpipe(purb->dev, _DABUSB_ISOPIPE);
184 int pipesize = usb_maxpacket(purb->dev, pipe,
185 usb_pipeout(pipe));
186 for (i = 0; i < purb->number_of_packets; i++)
187 if (!purb->iso_frame_desc[i].status) {
188 len = purb->iso_frame_desc[i].actual_length;
189 if (len <= pipesize) {
190 memcpy(buf + dst, buf + purb->iso_frame_desc[i].offset, len);
191 dst += len;
192 } else
193 dev_err(&purb->dev->dev,
194 "dabusb_iso_complete: invalid len %d\n",
195 len);
196 } else
197 dev_warn(&purb->dev->dev,
198 "dabusb_iso_complete: corrupted packet status: %d\n",
199 purb->iso_frame_desc[i].status);
200 if (dst != purb->actual_length)
201 dev_err(&purb->dev->dev,
202 "dst!=purb->actual_length:%d!=%d\n",
203 dst, purb->actual_length);
204 }
205
206 if (atomic_dec_and_test(&s->pending_io) &&
207 !s->remove_pending && s->state != _stopped) {
208 s->overruns++;
209 dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
210 }
211 wake_up(&s->wait);
212}
213/*-------------------------------------------------------------------*/
214static int dabusb_alloc_buffers(pdabusb_t s)
215{
216 int transfer_len = 0;
217 pbuff_t b;
218 unsigned int pipe = usb_rcvisocpipe(s->usbdev, _DABUSB_ISOPIPE);
219 int pipesize = usb_maxpacket(s->usbdev, pipe, usb_pipeout(pipe));
220 int packets = _ISOPIPESIZE / pipesize;
221 int transfer_buffer_length = packets * pipesize;
222 int i;
223
224 dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d",
225 pipesize, packets, transfer_buffer_length);
226
227 while (transfer_len < (s->total_buffer_size << 10)) {
228 b = kzalloc(sizeof(buff_t), GFP_KERNEL);
229 if (!b) {
230 dev_err(&s->usbdev->dev,
231 "kzalloc(sizeof(buff_t))==NULL\n");
232 goto err;
233 }
234 b->s = s;
235 b->purb = usb_alloc_urb(packets, GFP_KERNEL);
236 if (!b->purb) {
237 dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
238 kfree(b);
239 goto err;
240 }
241
242 b->purb->transfer_buffer = kmalloc(transfer_buffer_length,
243 GFP_KERNEL);
244 if (!b->purb->transfer_buffer) {
245 kfree(b->purb);
246 kfree(b);
247 dev_err(&s->usbdev->dev,
248 "kmalloc(%d)==NULL\n", transfer_buffer_length);
249 goto err;
250 }
251
252 b->purb->transfer_buffer_length = transfer_buffer_length;
253 b->purb->number_of_packets = packets;
254 b->purb->complete = dabusb_iso_complete;
255 b->purb->context = b;
256 b->purb->dev = s->usbdev;
257 b->purb->pipe = pipe;
258 b->purb->transfer_flags = URB_ISO_ASAP;
259
260 for (i = 0; i < packets; i++) {
261 b->purb->iso_frame_desc[i].offset = i * pipesize;
262 b->purb->iso_frame_desc[i].length = pipesize;
263 }
264
265 transfer_len += transfer_buffer_length;
266 list_add_tail(&b->buff_list, &s->free_buff_list);
267 }
268 s->got_mem = transfer_len;
269
270 return 0;
271
272err:
273 dabusb_free_buffers(s);
274 return -ENOMEM;
275}
276/*-------------------------------------------------------------------*/
277static int dabusb_bulk(pdabusb_t s, pbulk_transfer_t pb)
278{
279 int ret;
280 unsigned int pipe;
281 int actual_length;
282
283 dbg("dabusb_bulk");
284
285 if (!pb->pipe)
286 pipe = usb_rcvbulkpipe(s->usbdev, 2);
287 else
288 pipe = usb_sndbulkpipe(s->usbdev, 2);
289
290 ret = usb_bulk_msg(s->usbdev, pipe, pb->data,
291 pb->size, &actual_length, 100);
292 if (ret < 0) {
293 dev_err(&s->usbdev->dev,
294 "usb_bulk_msg failed(%d)\n", ret);
295
296 if (usb_set_interface(s->usbdev, _DABUSB_IF, 1) < 0) {
297 dev_err(&s->usbdev->dev, "set_interface failed\n");
298 return -EINVAL;
299 }
300
301 }
302
303 if (ret == -EPIPE) {
304 dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
305 if (usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
306 dev_err(&s->usbdev->dev, "request failed\n");
307 }
308
309 pb->size = actual_length;
310 return ret;
311}
312/* --------------------------------------------------------------------- */
313static int dabusb_writemem(pdabusb_t s, int pos, const unsigned char *data,
314 int len)
315{
316 int ret;
317 unsigned char *transfer_buffer = kmalloc(len, GFP_KERNEL);
318
319 if (!transfer_buffer) {
320 dev_err(&s->usbdev->dev,
321 "dabusb_writemem: kmalloc(%d) failed.\n", len);
322 return -ENOMEM;
323 }
324
325 memcpy(transfer_buffer, data, len);
326
327 ret = usb_control_msg(s->usbdev, usb_sndctrlpipe(s->usbdev, 0),
328 0xa0, 0x40, pos, 0, transfer_buffer, len, 300);
329
330 kfree(transfer_buffer);
331 return ret;
332}
333/* --------------------------------------------------------------------- */
334static int dabusb_8051_reset(pdabusb_t s, unsigned char reset_bit)
335{
336 dbg("dabusb_8051_reset: %d", reset_bit);
337 return dabusb_writemem(s, CPUCS_REG, &reset_bit, 1);
338}
339/* --------------------------------------------------------------------- */
340static int dabusb_loadmem(pdabusb_t s, const char *fname)
341{
342 int ret;
343 const struct ihex_binrec *rec;
344 const struct firmware *uninitialized_var(fw);
345
346 dbg("Enter dabusb_loadmem (internal)");
347
348 ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
349 if (ret) {
350 dev_err(&s->usbdev->dev,
351 "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
352 goto out;
353 }
354 ret = dabusb_8051_reset(s, 1);
355
356 for (rec = (const struct ihex_binrec *)fw->data; rec;
357 rec = ihex_next_binrec(rec)) {
358 dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr),
359 rec->data, be16_to_cpu(rec->len));
360
361 ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
362 be16_to_cpu(rec->len));
363 if (ret < 0) {
364 dev_err(&s->usbdev->dev,
365 "dabusb_writemem failed (%d %04X %p %d)\n",
366 ret, be32_to_cpu(rec->addr),
367 rec->data, be16_to_cpu(rec->len));
368 break;
369 }
370 }
371 ret = dabusb_8051_reset(s, 0);
372 release_firmware(fw);
373 out:
374 dbg("dabusb_loadmem: exit");
375
376 return ret;
377}
378/* --------------------------------------------------------------------- */
379static int dabusb_fpga_clear(pdabusb_t s, pbulk_transfer_t b)
380{
381 b->size = 4;
382 b->data[0] = 0x2a;
383 b->data[1] = 0;
384 b->data[2] = 0;
385 b->data[3] = 0;
386
387 dbg("dabusb_fpga_clear");
388
389 return dabusb_bulk(s, b);
390}
391/* --------------------------------------------------------------------- */
392static int dabusb_fpga_init(pdabusb_t s, pbulk_transfer_t b)
393{
394 b->size = 4;
395 b->data[0] = 0x2c;
396 b->data[1] = 0;
397 b->data[2] = 0;
398 b->data[3] = 0;
399
400 dbg("dabusb_fpga_init");
401
402 return dabusb_bulk(s, b);
403}
404/* --------------------------------------------------------------------- */
405static int dabusb_fpga_download(pdabusb_t s, const char *fname)
406{
407 pbulk_transfer_t b = kmalloc(sizeof(bulk_transfer_t), GFP_KERNEL);
408 const struct firmware *fw;
409 unsigned int blen, n;
410 int ret;
411
412 dbg("Enter dabusb_fpga_download (internal)");
413
414 if (!b) {
415 dev_err(&s->usbdev->dev,
416 "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
417 return -ENOMEM;
418 }
419
420 ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
421 if (ret) {
422 dev_err(&s->usbdev->dev,
423 "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
424 kfree(b);
425 return ret;
426 }
427
428 b->pipe = 1;
429 ret = dabusb_fpga_clear(s, b);
430 mdelay(10);
431 blen = fw->data[73] + (fw->data[72] << 8);
432
433 dbg("Bitstream len: %i", blen);
434
435 b->data[0] = 0x2b;
436 b->data[1] = 0;
437 b->data[2] = 0;
438 b->data[3] = 60;
439
440 for (n = 0; n <= blen + 60; n += 60) {
441 /* some cclks for startup */
442 b->size = 64;
443 memcpy(b->data + 4, fw->data + 74 + n, 60);
444 ret = dabusb_bulk(s, b);
445 if (ret < 0) {
446 dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
447 break;
448 }
449 mdelay(1);
450 }
451
452 ret = dabusb_fpga_init(s, b);
453 kfree(b);
454 release_firmware(fw);
455
456 dbg("exit dabusb_fpga_download");
457
458 return ret;
459}
460
461static int dabusb_stop(pdabusb_t s)
462{
463 dbg("dabusb_stop");
464
465 s->state = _stopped;
466 dabusb_cancel_queue(s, &s->rec_buff_list);
467
468 dbg("pending_io: %d", s->pending_io.counter);
469
470 s->pending_io.counter = 0;
471 return 0;
472}
473
474static int dabusb_startrek(pdabusb_t s)
475{
476 if (!s->got_mem && s->state != _started) {
477
478 dbg("dabusb_startrek");
479
480 if (dabusb_alloc_buffers(s) < 0)
481 return -ENOMEM;
482 dabusb_stop(s);
483 s->state = _started;
484 s->readptr = 0;
485 }
486
487 if (!list_empty(&s->free_buff_list)) {
488 pbuff_t end;
489 int ret;
490
491 while (!dabusb_add_buf_tail(s, &s->rec_buff_list, &s->free_buff_list)) {
492
493 dbg("submitting: end:%p s->rec_buff_list:%p",
494 s->rec_buff_list.prev, &s->rec_buff_list);
495
496 end = list_entry(s->rec_buff_list.prev,
497 buff_t, buff_list);
498
499 ret = usb_submit_urb(end->purb, GFP_KERNEL);
500 if (ret) {
501 dev_err(&s->usbdev->dev,
502 "usb_submit_urb returned:%d\n", ret);
503 if (dabusb_add_buf_tail(s, &s->free_buff_list,
504 &s->rec_buff_list))
505 dev_err(&s->usbdev->dev,
506 "startrek: dabusb_add_buf_tail failed\n");
507 break;
508 } else
509 atomic_inc(&s->pending_io);
510 }
511 dbg("pending_io: %d", s->pending_io.counter);
512 }
513
514 return 0;
515}
516
517static ssize_t dabusb_read(struct file *file, char __user *buf,
518 size_t count, loff_t *ppos)
519{
520 pdabusb_t s = (pdabusb_t)file->private_data;
521 unsigned long flags;
522 unsigned ret = 0;
523 int rem;
524 int cnt;
525 pbuff_t b;
526 struct urb *purb = NULL;
527
528 dbg("dabusb_read");
529
530 if (*ppos)
531 return -ESPIPE;
532
533 if (s->remove_pending)
534 return -EIO;
535
536
537 if (!s->usbdev)
538 return -EIO;
539
540 while (count > 0) {
541 dabusb_startrek(s);
542
543 spin_lock_irqsave(&s->lock, flags);
544
545 if (list_empty(&s->rec_buff_list)) {
546
547 spin_unlock_irqrestore(&s->lock, flags);
548
549 dev_err(&s->usbdev->dev,
550 "error: rec_buf_list is empty\n");
551 goto err;
552 }
553
554 b = list_entry(s->rec_buff_list.next, buff_t, buff_list);
555 purb = b->purb;
556
557 spin_unlock_irqrestore(&s->lock, flags);
558
559 if (purb->status == -EINPROGRESS) {
560 /* return nonblocking */
561 if (file->f_flags & O_NONBLOCK) {
562 if (!ret)
563 ret = -EAGAIN;
564 goto err;
565 }
566
567 interruptible_sleep_on(&s->wait);
568
569 if (signal_pending(current)) {
570 if (!ret)
571 ret = -ERESTARTSYS;
572 goto err;
573 }
574
575 spin_lock_irqsave(&s->lock, flags);
576
577 if (list_empty(&s->rec_buff_list)) {
578 spin_unlock_irqrestore(&s->lock, flags);
579 dev_err(&s->usbdev->dev,
580 "error: still no buffer available.\n");
581 goto err;
582 }
583 spin_unlock_irqrestore(&s->lock, flags);
584 s->readptr = 0;
585 }
586 if (s->remove_pending) {
587 ret = -EIO;
588 goto err;
589 }
590
591 /* set remaining bytes to copy */
592 rem = purb->actual_length - s->readptr;
593
594 if (count >= rem)
595 cnt = rem;
596 else
597 cnt = count;
598
599 dbg("copy_to_user:%p %p %d", buf,
600 purb->transfer_buffer + s->readptr, cnt);
601
602 if (copy_to_user(buf,
603 purb->transfer_buffer + s->readptr,
604 cnt)) {
605 dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
606 if (!ret)
607 ret = -EFAULT;
608 goto err;
609 }
610
611 s->readptr += cnt;
612 count -= cnt;
613 buf += cnt;
614 ret += cnt;
615
616 if (s->readptr == purb->actual_length) {
617 /* finished, take next buffer */
618 if (dabusb_add_buf_tail(s, &s->free_buff_list,
619 &s->rec_buff_list))
620 dev_err(&s->usbdev->dev,
621 "read: dabusb_add_buf_tail failed\n");
622 s->readptr = 0;
623 }
624 }
625err: /*mutex_unlock(&s->mutex);*/
626 return ret;
627}
628
629static int dabusb_open(struct inode *inode, struct file *file)
630{
631 int devnum = iminor(inode);
632 pdabusb_t s;
633 int r;
634
635 if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))
636 return -EIO;
637
638 s = &dabusb[devnum - DABUSB_MINOR];
639
640 dbg("dabusb_open");
641 mutex_lock(&s->mutex);
642
643 while (!s->usbdev || s->opened) {
644 mutex_unlock(&s->mutex);
645
646 if (file->f_flags & O_NONBLOCK)
647 return -EBUSY;
648 msleep_interruptible(500);
649
650 if (signal_pending(current))
651 return -EAGAIN;
652 mutex_lock(&s->mutex);
653 }
654 if (usb_set_interface(s->usbdev, _DABUSB_IF, 1) < 0) {
655 mutex_unlock(&s->mutex);
656 dev_err(&s->usbdev->dev, "set_interface failed\n");
657 return -EINVAL;
658 }
659 s->opened = 1;
660 mutex_unlock(&s->mutex);
661
662 file->f_pos = 0;
663 file->private_data = s;
664
665 r = nonseekable_open(inode, file);
666 return r;
667}
668
669static int dabusb_release(struct inode *inode, struct file *file)
670{
671 pdabusb_t s = (pdabusb_t)file->private_data;
672
673 dbg("dabusb_release");
674
675 mutex_lock(&s->mutex);
676 dabusb_stop(s);
677 dabusb_free_buffers(s);
678 mutex_unlock(&s->mutex);
679
680 if (!s->remove_pending) {
681 if (usb_set_interface(s->usbdev, _DABUSB_IF, 0) < 0)
682 dev_err(&s->usbdev->dev, "set_interface failed\n");
683 } else
684 wake_up(&s->remove_ok);
685
686 s->opened = 0;
687 return 0;
688}
689
690static long dabusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
691{
692 pdabusb_t s = (pdabusb_t)file->private_data;
693 pbulk_transfer_t pbulk;
694 int ret = 0;
695 int version = DABUSB_VERSION;
696
697 dbg("dabusb_ioctl");
698
699 if (s->remove_pending)
700 return -EIO;
701
702 mutex_lock(&s->mutex);
703
704 if (!s->usbdev) {
705 mutex_unlock(&s->mutex);
706 return -EIO;
707 }
708
709 switch (cmd) {
710
711 case IOCTL_DAB_BULK:
712 pbulk = memdup_user((void __user *)arg,
713 sizeof(bulk_transfer_t));
714
715 if (IS_ERR(pbulk)) {
716 ret = PTR_ERR(pbulk);
717 break;
718 }
719
720 ret = dabusb_bulk(s, pbulk);
721 if (ret == 0)
722 if (copy_to_user((void __user *)arg, pbulk,
723 sizeof(bulk_transfer_t)))
724 ret = -EFAULT;
725 kfree(pbulk);
726 break;
727
728 case IOCTL_DAB_OVERRUNS:
729 ret = put_user(s->overruns, (unsigned int __user *) arg);
730 break;
731
732 case IOCTL_DAB_VERSION:
733 ret = put_user(version, (unsigned int __user *) arg);
734 break;
735
736 default:
737 ret = -ENOIOCTLCMD;
738 break;
739 }
740 mutex_unlock(&s->mutex);
741 return ret;
742}
743
744static const struct file_operations dabusb_fops = {
745 .owner = THIS_MODULE,
746 .llseek = no_llseek,
747 .read = dabusb_read,
748 .unlocked_ioctl = dabusb_ioctl,
749 .open = dabusb_open,
750 .release = dabusb_release,
751};
752
753static char *dabusb_devnode(struct device *dev, mode_t *mode)
754{
755 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
756}
757
758static struct usb_class_driver dabusb_class = {
759 .name = "dabusb%d",
760 .devnode = dabusb_devnode,
761 .fops = &dabusb_fops,
762 .minor_base = DABUSB_MINOR,
763};
764
765
766/* --------------------------------------------------------------------- */
767static int dabusb_probe(struct usb_interface *intf,
768 const struct usb_device_id *id)
769{
770 struct usb_device *usbdev = interface_to_usbdev(intf);
771 int retval;
772 pdabusb_t s;
773
774 dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
775 le16_to_cpu(usbdev->descriptor.idVendor),
776 le16_to_cpu(usbdev->descriptor.idProduct),
777 intf->altsetting->desc.bInterfaceNumber);
778
779 /* We don't handle multiple configurations */
780 if (usbdev->descriptor.bNumConfigurations != 1)
781 return -ENODEV;
782
783 if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
784 le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
785 return -ENODEV;
786
787
788
789 s = &dabusb[intf->minor];
790
791 mutex_lock(&s->mutex);
792 s->remove_pending = 0;
793 s->usbdev = usbdev;
794 s->devnum = intf->minor;
795
796 if (usb_reset_configuration(usbdev) < 0) {
797 dev_err(&intf->dev, "reset_configuration failed\n");
798 goto reject;
799 }
800 if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
801 dabusb_loadmem(s, NULL);
802 goto reject;
803 } else {
804 dabusb_fpga_download(s, NULL);
805
806 if (usb_set_interface(s->usbdev, _DABUSB_IF, 0) < 0) {
807 dev_err(&intf->dev, "set_interface failed\n");
808 goto reject;
809 }
810 }
811 dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
812 usb_set_intfdata(intf, s);
813 mutex_unlock(&s->mutex);
814
815 retval = usb_register_dev(intf, &dabusb_class);
816 if (retval) {
817 usb_set_intfdata(intf, NULL);
818 return -ENOMEM;
819 }
820
821 return 0;
822
823reject:
824 mutex_unlock(&s->mutex);
825 s->usbdev = NULL;
826 return -ENODEV;
827}
828
829static void dabusb_disconnect(struct usb_interface *intf)
830{
831 wait_queue_t __wait;
832 pdabusb_t s = usb_get_intfdata(intf);
833
834 dbg("dabusb_disconnect");
835
836 init_waitqueue_entry(&__wait, current);
837
838 usb_set_intfdata(intf, NULL);
839 if (s) {
840 usb_deregister_dev(intf, &dabusb_class);
841 s->remove_pending = 1;
842 wake_up(&s->wait);
843 add_wait_queue(&s->remove_ok, &__wait);
844 set_current_state(TASK_UNINTERRUPTIBLE);
845 if (s->state == _started)
846 schedule();
847 current->state = TASK_RUNNING;
848 remove_wait_queue(&s->remove_ok, &__wait);
849
850 s->usbdev = NULL;
851 s->overruns = 0;
852 }
853}
854
855static struct usb_device_id dabusb_ids[] = {
856 /* { USB_DEVICE(0x0547, 0x2131) },*/ /* An2131 chip, no boot ROM */
857 { USB_DEVICE(0x0547, 0x9999) },
858 { } /* Terminating entry */
859};
860
861MODULE_DEVICE_TABLE(usb, dabusb_ids);
862
863static struct usb_driver dabusb_driver = {
864 .name = "dabusb",
865 .probe = dabusb_probe,
866 .disconnect = dabusb_disconnect,
867 .id_table = dabusb_ids,
868};
869
870/* --------------------------------------------------------------------- */
871
872static int __init dabusb_init(void)
873{
874 int retval;
875 unsigned u;
876
877 /* initialize struct */
878 for (u = 0; u < NRDABUSB; u++) {
879 pdabusb_t s = &dabusb[u];
880 memset(s, 0, sizeof(dabusb_t));
881 mutex_init(&s->mutex);
882 s->usbdev = NULL;
883 s->total_buffer_size = buffers;
884 init_waitqueue_head(&s->wait);
885 init_waitqueue_head(&s->remove_ok);
886 spin_lock_init(&s->lock);
887 INIT_LIST_HEAD(&s->free_buff_list);
888 INIT_LIST_HEAD(&s->rec_buff_list);
889 }
890
891 /* register misc device */
892 retval = usb_register(&dabusb_driver);
893 if (retval)
894 goto out;
895
896 dbg("dabusb_init: driver registered");
897
898 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
899 DRIVER_DESC "\n");
900
901out:
902 return retval;
903}
904
905static void __exit dabusb_cleanup(void)
906{
907 dbg("dabusb_cleanup");
908
909 usb_deregister(&dabusb_driver);
910}
911
912/* --------------------------------------------------------------------- */
913
914MODULE_AUTHOR(DRIVER_AUTHOR);
915MODULE_DESCRIPTION(DRIVER_DESC);
916MODULE_LICENSE("GPL");
917MODULE_FIRMWARE("dabusb/firmware.fw");
918MODULE_FIRMWARE("dabusb/bitstream.bin");
919
920module_param(buffers, int, 0);
921MODULE_PARM_DESC(buffers, "Number of buffers (default=256)");
922
923module_init(dabusb_init);
924module_exit(dabusb_cleanup);
925
926/* --------------------------------------------------------------------- */
diff --git a/drivers/staging/dabusb/dabusb.h b/drivers/staging/dabusb/dabusb.h
deleted file mode 100644
index c1772efe7c2c..000000000000
--- a/drivers/staging/dabusb/dabusb.h
+++ /dev/null
@@ -1,80 +0,0 @@
1#define _BULK_DATA_LEN 64
2typedef struct {
3 unsigned char data[_BULK_DATA_LEN];
4 unsigned int size;
5 unsigned int pipe;
6} bulk_transfer_t, *pbulk_transfer_t;
7
8#define DABUSB_MINOR 240 /* some unassigned USB minor */
9#define DABUSB_VERSION 0x1000
10#define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t)
11#define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int)
12#define IOCTL_DAB_VERSION _IOR('d', 0x3f, int)
13
14#ifdef __KERNEL__
15
16typedef enum { _stopped = 0, _started } driver_state_t;
17
18typedef struct {
19 struct mutex mutex;
20 struct usb_device *usbdev;
21 wait_queue_head_t wait;
22 wait_queue_head_t remove_ok;
23 spinlock_t lock;
24 atomic_t pending_io;
25 driver_state_t state;
26 int remove_pending;
27 int got_mem;
28 int total_buffer_size;
29 unsigned int overruns;
30 int readptr;
31 int opened;
32 int devnum;
33 struct list_head free_buff_list;
34 struct list_head rec_buff_list;
35} dabusb_t, *pdabusb_t;
36
37typedef struct {
38 pdabusb_t s;
39 struct urb *purb;
40 struct list_head buff_list;
41} buff_t, *pbuff_t;
42
43typedef struct {
44 wait_queue_head_t wait;
45} bulk_completion_context_t, *pbulk_completion_context_t;
46
47
48#define _DABUSB_IF 2
49#define _DABUSB_ISOPIPE 0x09
50#define _ISOPIPESIZE 16384
51
52#define _BULK_DATA_LEN 64
53/* Vendor specific request code for Anchor Upload/Download
54 *This one is implemented in the core */
55#define ANCHOR_LOAD_INTERNAL 0xA0
56
57/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
58#define CPUCS_REG 0x7F92
59#define _TOTAL_BUFFERS 384
60
61#define MAX_INTEL_HEX_RECORD_LENGTH 16
62
63#ifndef _BYTE_DEFINED
64#define _BYTE_DEFINED
65typedef unsigned char BYTE;
66#endif /* !_BYTE_DEFINED */
67
68#ifndef _WORD_DEFINED
69#define _WORD_DEFINED
70typedef unsigned short WORD;
71#endif /* !_WORD_DEFINED */
72
73typedef struct _INTEL_HEX_RECORD {
74 BYTE Length;
75 WORD Address;
76 BYTE Type;
77 BYTE Data[MAX_INTEL_HEX_RECORD_LENGTH];
78} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
79
80#endif
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c
index 28a28e02c9ce..b3bd11d5879f 100644
--- a/drivers/staging/easycap/easycap_ioctl.c
+++ b/drivers/staging/easycap/easycap_ioctl.c
@@ -1391,8 +1391,7 @@ long easycap_unlocked_ioctl(struct file *file,
1391 break; 1391 break;
1392 } 1392 }
1393/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1393/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1394 case VIDIOC_S_CTRL: 1394 case VIDIOC_S_CTRL: {
1395 {
1396 struct v4l2_control v4l2_control; 1395 struct v4l2_control v4l2_control;
1397 1396
1398 JOM(8, "VIDIOC_S_CTRL\n"); 1397 JOM(8, "VIDIOC_S_CTRL\n");
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
index 6e02f1b0c46f..af789937be4e 100644
--- a/drivers/staging/hv/blkvsc_drv.c
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -124,7 +124,8 @@ static void blkvsc_shutdown(struct device *device);
124 124
125static int blkvsc_open(struct block_device *bdev, fmode_t mode); 125static int blkvsc_open(struct block_device *bdev, fmode_t mode);
126static int blkvsc_release(struct gendisk *disk, fmode_t mode); 126static int blkvsc_release(struct gendisk *disk, fmode_t mode);
127static int blkvsc_media_changed(struct gendisk *gd); 127static unsigned int blkvsc_check_events(struct gendisk *gd,
128 unsigned int clearing);
128static int blkvsc_revalidate_disk(struct gendisk *gd); 129static int blkvsc_revalidate_disk(struct gendisk *gd);
129static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg); 130static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg);
130static int blkvsc_ioctl(struct block_device *bd, fmode_t mode, 131static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
@@ -155,7 +156,7 @@ static const struct block_device_operations block_ops = {
155 .owner = THIS_MODULE, 156 .owner = THIS_MODULE,
156 .open = blkvsc_open, 157 .open = blkvsc_open,
157 .release = blkvsc_release, 158 .release = blkvsc_release,
158 .media_changed = blkvsc_media_changed, 159 .check_events = blkvsc_check_events,
159 .revalidate_disk = blkvsc_revalidate_disk, 160 .revalidate_disk = blkvsc_revalidate_disk,
160 .getgeo = blkvsc_getgeo, 161 .getgeo = blkvsc_getgeo,
161 .ioctl = blkvsc_ioctl, 162 .ioctl = blkvsc_ioctl,
@@ -357,6 +358,7 @@ static int blkvsc_probe(struct device *device)
357 else 358 else
358 blkdev->gd->first_minor = 0; 359 blkdev->gd->first_minor = 0;
359 blkdev->gd->fops = &block_ops; 360 blkdev->gd->fops = &block_ops;
361 blkdev->gd->events = DISK_EVENT_MEDIA_CHANGE;
360 blkdev->gd->private_data = blkdev; 362 blkdev->gd->private_data = blkdev;
361 blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device); 363 blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device);
362 sprintf(blkdev->gd->disk_name, "hd%c", 'a' + devnum); 364 sprintf(blkdev->gd->disk_name, "hd%c", 'a' + devnum);
@@ -1337,10 +1339,11 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode)
1337 return 0; 1339 return 0;
1338} 1340}
1339 1341
1340static int blkvsc_media_changed(struct gendisk *gd) 1342static unsigned int blkvsc_check_events(struct gendisk *gd,
1343 unsigned int clearing)
1341{ 1344{
1342 DPRINT_DBG(BLKVSC_DRV, "- enter\n"); 1345 DPRINT_DBG(BLKVSC_DRV, "- enter\n");
1343 return 1; 1346 return DISK_EVENT_MEDIA_CHANGE;
1344} 1347}
1345 1348
1346static int blkvsc_revalidate_disk(struct gendisk *gd) 1349static int blkvsc_revalidate_disk(struct gendisk *gd)
diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/lirc/Kconfig
index cdaff5903a8f..526ec0fc2f04 100644
--- a/drivers/staging/lirc/Kconfig
+++ b/drivers/staging/lirc/Kconfig
@@ -32,18 +32,6 @@ config LIRC_IMON
32 32
33 Current generation iMON devices use the input layer imon driver. 33 Current generation iMON devices use the input layer imon driver.
34 34
35config LIRC_IT87
36 tristate "ITE IT87XX CIR Port Receiver"
37 depends on LIRC && PNP
38 help
39 Driver for the ITE IT87xx IR Receiver
40
41config LIRC_ITE8709
42 tristate "ITE8709 CIR Port Receiver"
43 depends on LIRC && PNP
44 help
45 Driver for the ITE8709 IR Receiver
46
47config LIRC_PARALLEL 35config LIRC_PARALLEL
48 tristate "Homebrew Parallel Port Receiver" 36 tristate "Homebrew Parallel Port Receiver"
49 depends on LIRC && PARPORT 37 depends on LIRC && PARPORT
diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/lirc/Makefile
index 94af218d8373..d76b0fa2af53 100644
--- a/drivers/staging/lirc/Makefile
+++ b/drivers/staging/lirc/Makefile
@@ -6,8 +6,6 @@
6obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o 6obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
7obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o 7obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
8obj-$(CONFIG_LIRC_IMON) += lirc_imon.o 8obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
9obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
10obj-$(CONFIG_LIRC_ITE8709) += lirc_ite8709.o
11obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o 9obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
12obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o 10obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
13obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o 11obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/lirc/TODO.lirc_zilog
index 2d0263f07937..a97800a8e127 100644
--- a/drivers/staging/lirc/TODO.lirc_zilog
+++ b/drivers/staging/lirc/TODO.lirc_zilog
@@ -1,34 +1,33 @@
11. Both ir-kbd-i2c and lirc_zilog provide support for RX events. 11. Both ir-kbd-i2c and lirc_zilog provide support for RX events for
2The 'tx_only' lirc_zilog module parameter will allow ir-kbd-i2c 2the chips supported by lirc_zilog. Before moving lirc_zilog out of staging:
3and lirc_zilog to coexist in the kernel, if the user requires such a set-up. 3
4However the IR unit will not work well without coordination between the 4a. ir-kbd-i2c needs a module parameter added to allow the user to tell
5two modules. A shared mutex, for transceiver access locking, needs to be 5 ir-kbd-i2c to ignore Z8 IR units.
6supplied by bridge drivers, in struct IR_i2_init_data, to both ir-kbd-i2c 6
7and lirc_zilog, before they will coexist usefully. This should be fixed 7b. lirc_zilog should provide Rx key presses to the rc core like ir-kbd-i2c
8before moving out of staging. 8 does.
9 9
102. References and locking need careful examination. For cx18 and ivtv PCI 10
11cards, which are not easily "hot unplugged", the imperfect state of reference 112. lirc_zilog module ref-counting need examination. It has not been
12counting and locking is acceptable if not correct. For USB connected units 12verified that cdev and lirc_dev will take the proper module references on
13like HD PVR, PVR USB2, HVR-1900, and HVR1950, the likelyhood of an Ooops on 13lirc_zilog to prevent removal of lirc_zilog when the /dev/lircN device node
14unplug is probably great. Proper reference counting and locking needs to be 14is open.
15implemented before this module is moved out of staging. 15
16 16(The good news is ref-counting of lirc_zilog internal structures appears to be
173. The binding between hdpvr and lirc_zilog is currently disabled, 17complete. Testing has shown the cx18 module can be unloaded out from under
18due to an OOPS reported a few years ago when both the hdpvr and cx18 18irw + lircd + lirc_dev, with the /dev/lirc0 device node open, with no adverse
19drivers were loaded in his system. More details can be seen at: 19effects. The cx18 module could then be reloaded and irw properly began
20 http://www.mail-archive.com/linux-media@vger.kernel.org/msg09163.html 20receiving button presses again and ir_send worked without error.)
21More tests need to be done, in order to fix the reported issue. 21
22 22
234. In addition to providing a shared mutex for transceiver access 233. Bridge drivers, if able, should provide a chip reset() callback
24locking, bridge drivers, if able, should provide a chip reset() callback
25to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines 24to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines
26to perform Z8 chip resets via GPIO manipulations. This will allow lirc_zilog 25to perform Z8 chip resets via GPIO manipulations. This would allow lirc_zilog
27to bring the chip back to normal when it hangs, in the same places the 26to bring the chip back to normal when it hangs, in the same places the
28original lirc_pvr150 driver code does. This is not strictly needed, so it 27original lirc_pvr150 driver code does. This is not strictly needed, so it
29is not required to move lirc_zilog out of staging. 28is not required to move lirc_zilog out of staging.
30 29
315. Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed 30Note: Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed
32and installed on Hauppauge products. When working on either module, developers 31and installed on Hauppauge products. When working on either module, developers
33must consider at least the following bridge drivers which mention an IR Rx unit 32must consider at least the following bridge drivers which mention an IR Rx unit
34at address 0x71 (indicative of a Z8): 33at address 0x71 (indicative of a Z8):
diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c
index 235cab0eb087..4039eda2a15b 100644
--- a/drivers/staging/lirc/lirc_imon.c
+++ b/drivers/staging/lirc/lirc_imon.c
@@ -379,7 +379,7 @@ static ssize_t vfd_write(struct file *file, const char *buf,
379 struct imon_context *context; 379 struct imon_context *context;
380 const unsigned char vfd_packet6[] = { 380 const unsigned char vfd_packet6[] = {
381 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; 381 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
382 int *data_buf; 382 int *data_buf = NULL;
383 383
384 context = file->private_data; 384 context = file->private_data;
385 if (!context) { 385 if (!context) {
diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c
deleted file mode 100644
index 5938616f3e8f..000000000000
--- a/drivers/staging/lirc/lirc_it87.c
+++ /dev/null
@@ -1,1027 +0,0 @@
1/*
2 * LIRC driver for ITE IT8712/IT8705 CIR port
3 *
4 * Copyright (C) 2001 Hans-Gunter Lutke Uphues <hg_lu@web.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 *
21 * ITE IT8705 and IT8712(not tested) and IT8720 CIR-port support for lirc based
22 * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula
23 *
24 * Attention: Sendmode only tested with debugging logs
25 *
26 * 2001/02/27 Christoph Bartelmus <lirc@bartelmus.de> :
27 * reimplemented read function
28 * 2005/06/05 Andrew Calkin implemented support for Asus Digimatrix,
29 * based on work of the following member of the Outertrack Digimatrix
30 * Forum: Art103 <r_tay@hotmail.com>
31 * 2009/12/24 James Edwards <jimbo-lirc@edwardsclan.net> implemeted support
32 * for ITE8704/ITE8718, on my machine, the DSDT reports 8704, but the
33 * chip identifies as 18.
34 */
35
36#include <linux/module.h>
37#include <linux/sched.h>
38#include <linux/errno.h>
39#include <linux/signal.h>
40#include <linux/fs.h>
41#include <linux/interrupt.h>
42#include <linux/ioport.h>
43#include <linux/kernel.h>
44#include <linux/time.h>
45#include <linux/string.h>
46#include <linux/types.h>
47#include <linux/wait.h>
48#include <linux/mm.h>
49#include <linux/delay.h>
50#include <linux/poll.h>
51#include <asm/system.h>
52#include <linux/io.h>
53#include <linux/irq.h>
54#include <linux/fcntl.h>
55
56#include <linux/timer.h>
57#include <linux/pnp.h>
58
59#include <media/lirc.h>
60#include <media/lirc_dev.h>
61
62#include "lirc_it87.h"
63
64#ifdef LIRC_IT87_DIGIMATRIX
65static int digimatrix = 1;
66static int it87_freq = 36; /* kHz */
67static int irq = 9;
68#else
69static int digimatrix;
70static int it87_freq = 38; /* kHz */
71static int irq = IT87_CIR_DEFAULT_IRQ;
72#endif
73
74static unsigned long it87_bits_in_byte_out;
75static unsigned long it87_send_counter;
76static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN;
77
78#define RBUF_LEN 1024
79
80#define LIRC_DRIVER_NAME "lirc_it87"
81
82/* timeout for sequences in jiffies (=5/100s) */
83/* must be longer than TIME_CONST */
84#define IT87_TIMEOUT (HZ*5/100)
85
86/* module parameters */
87static int debug;
88#define dprintk(fmt, args...) \
89 do { \
90 if (debug) \
91 printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
92 fmt, ## args); \
93 } while (0)
94
95static int io = IT87_CIR_DEFAULT_IOBASE;
96/* receiver demodulator default: off */
97static int it87_enable_demodulator;
98
99static int timer_enabled;
100static DEFINE_SPINLOCK(timer_lock);
101static struct timer_list timerlist;
102/* time of last signal change detected */
103static struct timeval last_tv = {0, 0};
104/* time of last UART data ready interrupt */
105static struct timeval last_intr_tv = {0, 0};
106static int last_value;
107
108static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
109
110static DEFINE_SPINLOCK(hardware_lock);
111static DEFINE_SPINLOCK(dev_lock);
112static bool device_open;
113
114static int rx_buf[RBUF_LEN];
115unsigned int rx_tail, rx_head;
116
117static struct pnp_driver it87_pnp_driver;
118
119/* SECTION: Prototypes */
120
121/* Communication with user-space */
122static int lirc_open(struct inode *inode, struct file *file);
123static int lirc_close(struct inode *inode, struct file *file);
124static unsigned int lirc_poll(struct file *file, poll_table *wait);
125static ssize_t lirc_read(struct file *file, char *buf,
126 size_t count, loff_t *ppos);
127static ssize_t lirc_write(struct file *file, const char *buf,
128 size_t n, loff_t *pos);
129static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
130static void add_read_queue(int flag, unsigned long val);
131static int init_chrdev(void);
132static void drop_chrdev(void);
133/* Hardware */
134static irqreturn_t it87_interrupt(int irq, void *dev_id);
135static void send_space(unsigned long len);
136static void send_pulse(unsigned long len);
137static void init_send(void);
138static void terminate_send(unsigned long len);
139static int init_hardware(void);
140static void drop_hardware(void);
141/* Initialisation */
142static int init_port(void);
143static void drop_port(void);
144
145
146/* SECTION: Communication with user-space */
147
148static int lirc_open(struct inode *inode, struct file *file)
149{
150 spin_lock(&dev_lock);
151 if (device_open) {
152 spin_unlock(&dev_lock);
153 return -EBUSY;
154 }
155 device_open = true;
156 spin_unlock(&dev_lock);
157 return 0;
158}
159
160
161static int lirc_close(struct inode *inode, struct file *file)
162{
163 spin_lock(&dev_lock);
164 device_open = false;
165 spin_unlock(&dev_lock);
166 return 0;
167}
168
169
170static unsigned int lirc_poll(struct file *file, poll_table *wait)
171{
172 poll_wait(file, &lirc_read_queue, wait);
173 if (rx_head != rx_tail)
174 return POLLIN | POLLRDNORM;
175 return 0;
176}
177
178
179static ssize_t lirc_read(struct file *file, char *buf,
180 size_t count, loff_t *ppos)
181{
182 int n = 0;
183 int retval = 0;
184
185 while (n < count) {
186 if (file->f_flags & O_NONBLOCK && rx_head == rx_tail) {
187 retval = -EAGAIN;
188 break;
189 }
190 retval = wait_event_interruptible(lirc_read_queue,
191 rx_head != rx_tail);
192 if (retval)
193 break;
194
195 if (copy_to_user((void *) buf + n, (void *) (rx_buf + rx_head),
196 sizeof(int))) {
197 retval = -EFAULT;
198 break;
199 }
200 rx_head = (rx_head + 1) & (RBUF_LEN - 1);
201 n += sizeof(int);
202 }
203 if (n)
204 return n;
205 return retval;
206}
207
208
209static ssize_t lirc_write(struct file *file, const char *buf,
210 size_t n, loff_t *pos)
211{
212 int i = 0;
213 int *tx_buf;
214
215 if (n % sizeof(int))
216 return -EINVAL;
217 tx_buf = memdup_user(buf, n);
218 if (IS_ERR(tx_buf))
219 return PTR_ERR(tx_buf);
220 n /= sizeof(int);
221 init_send();
222 while (1) {
223 if (i >= n)
224 break;
225 if (tx_buf[i])
226 send_pulse(tx_buf[i]);
227 i++;
228 if (i >= n)
229 break;
230 if (tx_buf[i])
231 send_space(tx_buf[i]);
232 i++;
233 }
234 terminate_send(tx_buf[i - 1]);
235 kfree(tx_buf);
236 return n;
237}
238
239
240static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
241{
242 int retval = 0;
243 __u32 value = 0;
244 unsigned long hw_flags;
245
246 if (cmd == LIRC_GET_FEATURES)
247 value = LIRC_CAN_SEND_PULSE |
248 LIRC_CAN_SET_SEND_CARRIER |
249 LIRC_CAN_REC_MODE2;
250 else if (cmd == LIRC_GET_SEND_MODE)
251 value = LIRC_MODE_PULSE;
252 else if (cmd == LIRC_GET_REC_MODE)
253 value = LIRC_MODE_MODE2;
254
255 switch (cmd) {
256 case LIRC_GET_FEATURES:
257 case LIRC_GET_SEND_MODE:
258 case LIRC_GET_REC_MODE:
259 retval = put_user(value, (__u32 *) arg);
260 break;
261
262 case LIRC_SET_SEND_MODE:
263 case LIRC_SET_REC_MODE:
264 retval = get_user(value, (__u32 *) arg);
265 break;
266
267 case LIRC_SET_SEND_CARRIER:
268 retval = get_user(value, (__u32 *) arg);
269 if (retval)
270 return retval;
271 value /= 1000;
272 if (value > IT87_CIR_FREQ_MAX ||
273 value < IT87_CIR_FREQ_MIN)
274 return -EINVAL;
275
276 it87_freq = value;
277
278 spin_lock_irqsave(&hardware_lock, hw_flags);
279 outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) |
280 (it87_freq - IT87_CIR_FREQ_MIN) << 3),
281 io + IT87_CIR_TCR2);
282 spin_unlock_irqrestore(&hardware_lock, hw_flags);
283 dprintk("demodulation frequency: %d kHz\n", it87_freq);
284
285 break;
286
287 default:
288 retval = -EINVAL;
289 }
290
291 if (retval)
292 return retval;
293
294 if (cmd == LIRC_SET_REC_MODE) {
295 if (value != LIRC_MODE_MODE2)
296 retval = -ENOSYS;
297 } else if (cmd == LIRC_SET_SEND_MODE) {
298 if (value != LIRC_MODE_PULSE)
299 retval = -ENOSYS;
300 }
301 return retval;
302}
303
304static void add_read_queue(int flag, unsigned long val)
305{
306 unsigned int new_rx_tail;
307 int newval;
308
309 dprintk("add flag %d with val %lu\n", flag, val);
310
311 newval = val & PULSE_MASK;
312
313 /*
314 * statistically, pulses are ~TIME_CONST/2 too long. we could
315 * maybe make this more exact, but this is good enough
316 */
317 if (flag) {
318 /* pulse */
319 if (newval > TIME_CONST / 2)
320 newval -= TIME_CONST / 2;
321 else /* should not ever happen */
322 newval = 1;
323 newval |= PULSE_BIT;
324 } else
325 newval += TIME_CONST / 2;
326 new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
327 if (new_rx_tail == rx_head) {
328 dprintk("Buffer overrun.\n");
329 return;
330 }
331 rx_buf[rx_tail] = newval;
332 rx_tail = new_rx_tail;
333 wake_up_interruptible(&lirc_read_queue);
334}
335
336
337static const struct file_operations lirc_fops = {
338 .owner = THIS_MODULE,
339 .read = lirc_read,
340 .write = lirc_write,
341 .poll = lirc_poll,
342 .unlocked_ioctl = lirc_ioctl,
343#ifdef CONFIG_COMPAT
344 .compat_ioctl = lirc_ioctl,
345#endif
346 .open = lirc_open,
347 .release = lirc_close,
348 .llseek = noop_llseek,
349};
350
351static int set_use_inc(void *data)
352{
353 return 0;
354}
355
356static void set_use_dec(void *data)
357{
358}
359
360static struct lirc_driver driver = {
361 .name = LIRC_DRIVER_NAME,
362 .minor = -1,
363 .code_length = 1,
364 .sample_rate = 0,
365 .data = NULL,
366 .add_to_buf = NULL,
367 .set_use_inc = set_use_inc,
368 .set_use_dec = set_use_dec,
369 .fops = &lirc_fops,
370 .dev = NULL,
371 .owner = THIS_MODULE,
372};
373
374
375static int init_chrdev(void)
376{
377 driver.minor = lirc_register_driver(&driver);
378
379 if (driver.minor < 0) {
380 printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
381 return -EIO;
382 }
383 return 0;
384}
385
386
387static void drop_chrdev(void)
388{
389 lirc_unregister_driver(driver.minor);
390}
391
392
393/* SECTION: Hardware */
394static long delta(struct timeval *tv1, struct timeval *tv2)
395{
396 unsigned long deltv;
397
398 deltv = tv2->tv_sec - tv1->tv_sec;
399 if (deltv > 15)
400 deltv = 0xFFFFFF;
401 else
402 deltv = deltv*1000000 + tv2->tv_usec - tv1->tv_usec;
403 return deltv;
404}
405
406static void it87_timeout(unsigned long data)
407{
408 unsigned long flags;
409
410 /* avoid interference with interrupt */
411 spin_lock_irqsave(&timer_lock, flags);
412
413 if (digimatrix) {
414 /* We have timed out. Disable the RX mechanism. */
415
416 outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) |
417 IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR);
418 if (it87_RXEN_mask)
419 outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
420 io + IT87_CIR_RCR);
421 dprintk(" TIMEOUT\n");
422 timer_enabled = 0;
423
424 /* fifo clear */
425 outb(inb(io + IT87_CIR_TCR1) | IT87_CIR_TCR1_FIFOCLR,
426 io+IT87_CIR_TCR1);
427
428 } else {
429 /*
430 * if last received signal was a pulse, but receiving stopped
431 * within the 9 bit frame, we need to finish this pulse and
432 * simulate a signal change to from pulse to space. Otherwise
433 * upper layers will receive two sequences next time.
434 */
435
436 if (last_value) {
437 unsigned long pulse_end;
438
439 /* determine 'virtual' pulse end: */
440 pulse_end = delta(&last_tv, &last_intr_tv);
441 dprintk("timeout add %d for %lu usec\n",
442 last_value, pulse_end);
443 add_read_queue(last_value, pulse_end);
444 last_value = 0;
445 last_tv = last_intr_tv;
446 }
447 }
448 spin_unlock_irqrestore(&timer_lock, flags);
449}
450
451static irqreturn_t it87_interrupt(int irq, void *dev_id)
452{
453 unsigned char data;
454 struct timeval curr_tv;
455 static unsigned long deltv;
456 unsigned long deltintrtv;
457 unsigned long flags, hw_flags;
458 int iir, lsr;
459 int fifo = 0;
460 static char lastbit;
461 char bit;
462
463 /* Bit duration in microseconds */
464 const unsigned long bit_duration = 1000000ul /
465 (115200 / IT87_CIR_BAUDRATE_DIVISOR);
466
467
468 iir = inb(io + IT87_CIR_IIR);
469
470 switch (iir & IT87_CIR_IIR_IID) {
471 case 0x4:
472 case 0x6:
473 lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO |
474 IT87_CIR_RSR_RXFBC);
475 fifo = lsr & IT87_CIR_RSR_RXFBC;
476 dprintk("iir: 0x%x fifo: 0x%x\n", iir, lsr);
477
478 /* avoid interference with timer */
479 spin_lock_irqsave(&timer_lock, flags);
480 spin_lock_irqsave(&hardware_lock, hw_flags);
481 if (digimatrix) {
482 static unsigned long acc_pulse;
483 static unsigned long acc_space;
484
485 do {
486 data = inb(io + IT87_CIR_DR);
487 data = ~data;
488 fifo--;
489 if (data != 0x00) {
490 if (timer_enabled)
491 del_timer(&timerlist);
492 /*
493 * start timer for end of
494 * sequence detection
495 */
496 timerlist.expires = jiffies +
497 IT87_TIMEOUT;
498 add_timer(&timerlist);
499 timer_enabled = 1;
500 }
501 /* Loop through */
502 for (bit = 0; bit < 8; ++bit) {
503 if ((data >> bit) & 1) {
504 ++acc_pulse;
505 if (lastbit == 0) {
506 add_read_queue(0,
507 acc_space *
508 bit_duration);
509 acc_space = 0;
510 }
511 } else {
512 ++acc_space;
513 if (lastbit == 1) {
514 add_read_queue(1,
515 acc_pulse *
516 bit_duration);
517 acc_pulse = 0;
518 }
519 }
520 lastbit = (data >> bit) & 1;
521 }
522
523 } while (fifo != 0);
524 } else { /* Normal Operation */
525 do {
526 del_timer(&timerlist);
527 data = inb(io + IT87_CIR_DR);
528
529 dprintk("data=%02x\n", data);
530 do_gettimeofday(&curr_tv);
531 deltv = delta(&last_tv, &curr_tv);
532 deltintrtv = delta(&last_intr_tv, &curr_tv);
533
534 dprintk("t %lu , d %d\n",
535 deltintrtv, (int)data);
536
537 /*
538 * if nothing came in last 2 cycles,
539 * it was gap
540 */
541 if (deltintrtv > TIME_CONST * 2) {
542 if (last_value) {
543 dprintk("GAP\n");
544
545 /* simulate signal change */
546 add_read_queue(last_value,
547 deltv -
548 deltintrtv);
549 last_value = 0;
550 last_tv.tv_sec =
551 last_intr_tv.tv_sec;
552 last_tv.tv_usec =
553 last_intr_tv.tv_usec;
554 deltv = deltintrtv;
555 }
556 }
557 data = 1;
558 if (data ^ last_value) {
559 /*
560 * deltintrtv > 2*TIME_CONST,
561 * remember ? the other case is
562 * timeout
563 */
564 add_read_queue(last_value,
565 deltv-TIME_CONST);
566 last_value = data;
567 last_tv = curr_tv;
568 if (last_tv.tv_usec >= TIME_CONST)
569 last_tv.tv_usec -= TIME_CONST;
570 else {
571 last_tv.tv_sec--;
572 last_tv.tv_usec += 1000000 -
573 TIME_CONST;
574 }
575 }
576 last_intr_tv = curr_tv;
577 if (data) {
578 /*
579 * start timer for end of
580 * sequence detection
581 */
582 timerlist.expires =
583 jiffies + IT87_TIMEOUT;
584 add_timer(&timerlist);
585 }
586 outb((inb(io + IT87_CIR_RCR) &
587 ~IT87_CIR_RCR_RXEN) |
588 IT87_CIR_RCR_RXACT,
589 io + IT87_CIR_RCR);
590 if (it87_RXEN_mask)
591 outb(inb(io + IT87_CIR_RCR) |
592 IT87_CIR_RCR_RXEN,
593 io + IT87_CIR_RCR);
594 fifo--;
595 } while (fifo != 0);
596 }
597 spin_unlock_irqrestore(&hardware_lock, hw_flags);
598 spin_unlock_irqrestore(&timer_lock, flags);
599
600 return IRQ_RETVAL(IRQ_HANDLED);
601
602 default:
603 /* not our irq */
604 dprintk("unknown IRQ (shouldn't happen) !!\n");
605 return IRQ_RETVAL(IRQ_NONE);
606 }
607}
608
609
610static void send_it87(unsigned long len, unsigned long stime,
611 unsigned char send_byte, unsigned int count_bits)
612{
613 long count = len / stime;
614 long time_left = 0;
615 static unsigned char byte_out;
616 unsigned long hw_flags;
617
618 dprintk("%s: len=%ld, sb=%d\n", __func__, len, send_byte);
619
620 time_left = (long)len - (long)count * (long)stime;
621 count += ((2 * time_left) / stime);
622 while (count) {
623 long i = 0;
624 for (i = 0; i < count_bits; i++) {
625 byte_out = (byte_out << 1) | (send_byte & 1);
626 it87_bits_in_byte_out++;
627 }
628 if (it87_bits_in_byte_out == 8) {
629 dprintk("out=0x%x, tsr_txfbc: 0x%x\n",
630 byte_out,
631 inb(io + IT87_CIR_TSR) &
632 IT87_CIR_TSR_TXFBC);
633
634 while ((inb(io + IT87_CIR_TSR) &
635 IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE)
636 ;
637
638 spin_lock_irqsave(&hardware_lock, hw_flags);
639 outb(byte_out, io + IT87_CIR_DR);
640 spin_unlock_irqrestore(&hardware_lock, hw_flags);
641
642 it87_bits_in_byte_out = 0;
643 it87_send_counter++;
644 byte_out = 0;
645 }
646 count--;
647 }
648}
649
650
651/*TODO: maybe exchange space and pulse because it8705 only modulates 0-bits */
652
653static void send_space(unsigned long len)
654{
655 send_it87(len, TIME_CONST, IT87_CIR_SPACE, IT87_CIR_BAUDRATE_DIVISOR);
656}
657
658static void send_pulse(unsigned long len)
659{
660 send_it87(len, TIME_CONST, IT87_CIR_PULSE, IT87_CIR_BAUDRATE_DIVISOR);
661}
662
663
664static void init_send()
665{
666 unsigned long flags;
667
668 spin_lock_irqsave(&hardware_lock, flags);
669 /* RXEN=0: receiver disable */
670 it87_RXEN_mask = 0;
671 outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN,
672 io + IT87_CIR_RCR);
673 spin_unlock_irqrestore(&hardware_lock, flags);
674 it87_bits_in_byte_out = 0;
675 it87_send_counter = 0;
676}
677
678
679static void terminate_send(unsigned long len)
680{
681 unsigned long flags;
682 unsigned long last = 0;
683
684 last = it87_send_counter;
685 /* make sure all necessary data has been sent */
686 while (last == it87_send_counter)
687 send_space(len);
688 /* wait until all data sent */
689 while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0)
690 ;
691 /* then re-enable receiver */
692 spin_lock_irqsave(&hardware_lock, flags);
693 it87_RXEN_mask = IT87_CIR_RCR_RXEN;
694 outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
695 io + IT87_CIR_RCR);
696 spin_unlock_irqrestore(&hardware_lock, flags);
697}
698
699
700static int init_hardware(void)
701{
702 unsigned long flags;
703 unsigned char it87_rcr = 0;
704
705 spin_lock_irqsave(&hardware_lock, flags);
706 /* init cir-port */
707 /* enable r/w-access to Baudrate-Register */
708 outb(IT87_CIR_IER_BR, io + IT87_CIR_IER);
709 outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR);
710 outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR);
711 /* Baudrate Register off, define IRQs: Input only */
712 if (digimatrix) {
713 outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RFOIE, io + IT87_CIR_IER);
714 /* RX: HCFS=0, RXDCR = 001b (33,75..38,25 kHz), RXEN=1 */
715 } else {
716 outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER);
717 /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */
718 }
719 it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1;
720 if (it87_enable_demodulator)
721 it87_rcr |= IT87_CIR_RCR_RXEND;
722 outb(it87_rcr, io + IT87_CIR_RCR);
723 if (digimatrix) {
724 /* Set FIFO depth to 1 byte, and disable TX */
725 outb(inb(io + IT87_CIR_TCR1) | 0x00,
726 io + IT87_CIR_TCR1);
727
728 /*
729 * TX: it87_freq (36kHz), 'reserved' sensitivity
730 * setting (0x00)
731 */
732 outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x00,
733 io + IT87_CIR_TCR2);
734 } else {
735 /* TX: 38kHz, 13,3us (pulse-width) */
736 outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06,
737 io + IT87_CIR_TCR2);
738 }
739 spin_unlock_irqrestore(&hardware_lock, flags);
740 return 0;
741}
742
743
744static void drop_hardware(void)
745{
746 unsigned long flags;
747
748 spin_lock_irqsave(&hardware_lock, flags);
749 disable_irq(irq);
750 /* receiver disable */
751 it87_RXEN_mask = 0;
752 outb(0x1, io + IT87_CIR_RCR);
753 /* turn off irqs */
754 outb(0, io + IT87_CIR_IER);
755 /* fifo clear */
756 outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1);
757 /* reset */
758 outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
759 enable_irq(irq);
760 spin_unlock_irqrestore(&hardware_lock, flags);
761}
762
763
764static unsigned char it87_read(unsigned char port)
765{
766 outb(port, IT87_ADRPORT);
767 return inb(IT87_DATAPORT);
768}
769
770
771static void it87_write(unsigned char port, unsigned char data)
772{
773 outb(port, IT87_ADRPORT);
774 outb(data, IT87_DATAPORT);
775}
776
777
778/* SECTION: Initialisation */
779
780static int init_port(void)
781{
782 unsigned long hw_flags;
783 int retval = 0;
784
785 unsigned char init_bytes[4] = IT87_INIT;
786 unsigned char it87_chipid = 0;
787 unsigned char ldn = 0;
788 unsigned int it87_io = 0;
789 unsigned int it87_irq = 0;
790
791 /* Enter MB PnP Mode */
792 outb(init_bytes[0], IT87_ADRPORT);
793 outb(init_bytes[1], IT87_ADRPORT);
794 outb(init_bytes[2], IT87_ADRPORT);
795 outb(init_bytes[3], IT87_ADRPORT);
796
797 /* 8712 or 8705 ? */
798 it87_chipid = it87_read(IT87_CHIP_ID1);
799 if (it87_chipid != 0x87) {
800 retval = -ENXIO;
801 return retval;
802 }
803 it87_chipid = it87_read(IT87_CHIP_ID2);
804 if ((it87_chipid != 0x05) &&
805 (it87_chipid != 0x12) &&
806 (it87_chipid != 0x18) &&
807 (it87_chipid != 0x20)) {
808 printk(KERN_INFO LIRC_DRIVER_NAME
809 ": no IT8704/05/12/18/20 found (claimed IT87%02x), "
810 "exiting..\n", it87_chipid);
811 retval = -ENXIO;
812 return retval;
813 }
814 printk(KERN_INFO LIRC_DRIVER_NAME
815 ": found IT87%02x.\n",
816 it87_chipid);
817
818 /* get I/O-Port and IRQ */
819 if (it87_chipid == 0x12 || it87_chipid == 0x18)
820 ldn = IT8712_CIR_LDN;
821 else
822 ldn = IT8705_CIR_LDN;
823 it87_write(IT87_LDN, ldn);
824
825 it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 +
826 it87_read(IT87_CIR_BASE_LSB);
827 if (it87_io == 0) {
828 if (io == 0)
829 io = IT87_CIR_DEFAULT_IOBASE;
830 printk(KERN_INFO LIRC_DRIVER_NAME
831 ": set default io 0x%x\n",
832 io);
833 it87_write(IT87_CIR_BASE_MSB, io / 0x100);
834 it87_write(IT87_CIR_BASE_LSB, io % 0x100);
835 } else
836 io = it87_io;
837
838 it87_irq = it87_read(IT87_CIR_IRQ);
839 if (digimatrix || it87_irq == 0) {
840 if (irq == 0)
841 irq = IT87_CIR_DEFAULT_IRQ;
842 printk(KERN_INFO LIRC_DRIVER_NAME
843 ": set default irq 0x%x\n",
844 irq);
845 it87_write(IT87_CIR_IRQ, irq);
846 } else
847 irq = it87_irq;
848
849 spin_lock_irqsave(&hardware_lock, hw_flags);
850 /* reset */
851 outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
852 /* fifo clear */
853 outb(IT87_CIR_TCR1_FIFOCLR |
854 /* IT87_CIR_TCR1_ILE | */
855 IT87_CIR_TCR1_TXRLE |
856 IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1);
857 spin_unlock_irqrestore(&hardware_lock, hw_flags);
858
859 /* get I/O port access and IRQ line */
860 if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) {
861 printk(KERN_ERR LIRC_DRIVER_NAME
862 ": i/o port 0x%.4x already in use.\n", io);
863 /* Leaving MB PnP Mode */
864 it87_write(IT87_CFGCTRL, 0x2);
865 return -EBUSY;
866 }
867
868 /* activate CIR-Device */
869 it87_write(IT87_CIR_ACT, 0x1);
870
871 /* Leaving MB PnP Mode */
872 it87_write(IT87_CFGCTRL, 0x2);
873
874 retval = request_irq(irq, it87_interrupt, 0 /*IRQF_DISABLED*/,
875 LIRC_DRIVER_NAME, NULL);
876 if (retval < 0) {
877 printk(KERN_ERR LIRC_DRIVER_NAME
878 ": IRQ %d already in use.\n",
879 irq);
880 release_region(io, 8);
881 return retval;
882 }
883
884 printk(KERN_INFO LIRC_DRIVER_NAME
885 ": I/O port 0x%.4x, IRQ %d.\n", io, irq);
886
887 init_timer(&timerlist);
888 timerlist.function = it87_timeout;
889 timerlist.data = 0xabadcafe;
890
891 return 0;
892}
893
894
895static void drop_port(void)
896{
897#if 0
898 unsigned char init_bytes[4] = IT87_INIT;
899
900 /* Enter MB PnP Mode */
901 outb(init_bytes[0], IT87_ADRPORT);
902 outb(init_bytes[1], IT87_ADRPORT);
903 outb(init_bytes[2], IT87_ADRPORT);
904 outb(init_bytes[3], IT87_ADRPORT);
905
906 /* deactivate CIR-Device */
907 it87_write(IT87_CIR_ACT, 0x0);
908
909 /* Leaving MB PnP Mode */
910 it87_write(IT87_CFGCTRL, 0x2);
911#endif
912
913 del_timer_sync(&timerlist);
914 free_irq(irq, NULL);
915 release_region(io, 8);
916}
917
918
919static int init_lirc_it87(void)
920{
921 int retval;
922
923 init_waitqueue_head(&lirc_read_queue);
924 retval = init_port();
925 if (retval < 0)
926 return retval;
927 init_hardware();
928 printk(KERN_INFO LIRC_DRIVER_NAME ": Installed.\n");
929 return 0;
930}
931
932static int it87_probe(struct pnp_dev *pnp_dev,
933 const struct pnp_device_id *dev_id)
934{
935 int retval;
936
937 driver.dev = &pnp_dev->dev;
938
939 retval = init_chrdev();
940 if (retval < 0)
941 return retval;
942
943 retval = init_lirc_it87();
944 if (retval)
945 goto init_lirc_it87_failed;
946
947 return 0;
948
949init_lirc_it87_failed:
950 drop_chrdev();
951
952 return retval;
953}
954
955static int __init lirc_it87_init(void)
956{
957 return pnp_register_driver(&it87_pnp_driver);
958}
959
960
961static void __exit lirc_it87_exit(void)
962{
963 drop_hardware();
964 drop_chrdev();
965 drop_port();
966 pnp_unregister_driver(&it87_pnp_driver);
967 printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
968}
969
970/* SECTION: PNP for ITE8704/13/18 */
971
972static const struct pnp_device_id pnp_dev_table[] = {
973 {"ITE8704", 0},
974 {"ITE8713", 0},
975 {}
976};
977
978MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
979
980static struct pnp_driver it87_pnp_driver = {
981 .name = LIRC_DRIVER_NAME,
982 .id_table = pnp_dev_table,
983 .probe = it87_probe,
984};
985
986module_init(lirc_it87_init);
987module_exit(lirc_it87_exit);
988
989MODULE_DESCRIPTION("LIRC driver for ITE IT8704/05/12/18/20 CIR port");
990MODULE_AUTHOR("Hans-Gunter Lutke Uphues");
991MODULE_LICENSE("GPL");
992
993module_param(io, int, S_IRUGO);
994MODULE_PARM_DESC(io, "I/O base address (default: 0x310)");
995
996module_param(irq, int, S_IRUGO);
997#ifdef LIRC_IT87_DIGIMATRIX
998MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 9)");
999#else
1000MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)");
1001#endif
1002
1003module_param(it87_enable_demodulator, bool, S_IRUGO);
1004MODULE_PARM_DESC(it87_enable_demodulator,
1005 "Receiver demodulator enable/disable (1/0), default: 0");
1006
1007module_param(debug, bool, S_IRUGO | S_IWUSR);
1008MODULE_PARM_DESC(debug, "Enable debugging messages");
1009
1010module_param(digimatrix, bool, S_IRUGO | S_IWUSR);
1011#ifdef LIRC_IT87_DIGIMATRIX
1012MODULE_PARM_DESC(digimatrix,
1013 "Asus Digimatrix it87 compat. enable/disable (1/0), default: 1");
1014#else
1015MODULE_PARM_DESC(digimatrix,
1016 "Asus Digimatrix it87 compat. enable/disable (1/0), default: 0");
1017#endif
1018
1019
1020module_param(it87_freq, int, S_IRUGO);
1021#ifdef LIRC_IT87_DIGIMATRIX
1022MODULE_PARM_DESC(it87_freq,
1023 "Carrier demodulator frequency (kHz), (default: 36)");
1024#else
1025MODULE_PARM_DESC(it87_freq,
1026 "Carrier demodulator frequency (kHz), (default: 38)");
1027#endif
diff --git a/drivers/staging/lirc/lirc_it87.h b/drivers/staging/lirc/lirc_it87.h
deleted file mode 100644
index cf021c893a35..000000000000
--- a/drivers/staging/lirc/lirc_it87.h
+++ /dev/null
@@ -1,116 +0,0 @@
1/* lirc_it87.h */
2/* SECTION: Definitions */
3
4/********************************* ITE IT87xx ************************/
5
6/* based on the following documentation from ITE:
7 a) IT8712F Preliminary CIR Programming Guide V0.1
8 b) IT8705F Simple LPC I/O Preliminary Specification V0.3
9 c) IT8712F EC-LPC I/O Preliminary Specification V0.5
10*/
11
12/* IT8712/05 Ports: */
13#define IT87_ADRPORT 0x2e
14#define IT87_DATAPORT 0x2f
15#define IT87_INIT {0x87, 0x01, 0x55, 0x55}
16
17/* alternate Ports: */
18/*
19#define IT87_ADRPORT 0x4e
20#define IT87_DATAPORT 0x4f
21#define IT87_INIT {0x87, 0x01, 0x55, 0xaa}
22 */
23
24/* IT8712/05 Registers */
25#define IT87_CFGCTRL 0x2
26#define IT87_LDN 0x7
27#define IT87_CHIP_ID1 0x20
28#define IT87_CHIP_ID2 0x21
29#define IT87_CFG_VERSION 0x22
30#define IT87_SWSUSPEND 0x23
31
32#define IT8712_CIR_LDN 0xa
33#define IT8705_CIR_LDN 0x7
34
35/* CIR Configuration Registers: */
36#define IT87_CIR_ACT 0x30
37#define IT87_CIR_BASE_MSB 0x60
38#define IT87_CIR_BASE_LSB 0x61
39#define IT87_CIR_IRQ 0x70
40#define IT87_CIR_CONFIG 0xf0
41
42/* List of IT87_CIR registers: offset to BaseAddr */
43#define IT87_CIR_DR 0
44#define IT87_CIR_IER 1
45#define IT87_CIR_RCR 2
46#define IT87_CIR_TCR1 3
47#define IT87_CIR_TCR2 4
48#define IT87_CIR_TSR 5
49#define IT87_CIR_RSR 6
50#define IT87_CIR_BDLR 5
51#define IT87_CIR_BDHR 6
52#define IT87_CIR_IIR 7
53
54/* Bit Definition */
55/* IER: */
56#define IT87_CIR_IER_TM_EN 0x80
57#define IT87_CIR_IER_RESEVED 0x40
58#define IT87_CIR_IER_RESET 0x20
59#define IT87_CIR_IER_BR 0x10
60#define IT87_CIR_IER_IEC 0x8
61#define IT87_CIR_IER_RFOIE 0x4
62#define IT87_CIR_IER_RDAIE 0x2
63#define IT87_CIR_IER_TLDLIE 0x1
64
65/* RCR: */
66#define IT87_CIR_RCR_RDWOS 0x80
67#define IT87_CIR_RCR_HCFS 0x40
68#define IT87_CIR_RCR_RXEN 0x20
69#define IT87_CIR_RCR_RXEND 0x10
70#define IT87_CIR_RCR_RXACT 0x8
71#define IT87_CIR_RCR_RXDCR 0x7
72
73/* TCR1: */
74#define IT87_CIR_TCR1_FIFOCLR 0x80
75#define IT87_CIR_TCR1_ILE 0x40
76#define IT87_CIR_TCR1_FIFOTL 0x30
77#define IT87_CIR_TCR1_TXRLE 0x8
78#define IT87_CIR_TCR1_TXENDF 0x4
79#define IT87_CIR_TCR1_TXMPM 0x3
80
81/* TCR2: */
82#define IT87_CIR_TCR2_CFQ 0xf8
83#define IT87_CIR_TCR2_TXMPW 0x7
84
85/* TSR: */
86#define IT87_CIR_TSR_RESERVED 0xc0
87#define IT87_CIR_TSR_TXFBC 0x3f
88
89/* RSR: */
90#define IT87_CIR_RSR_RXFTO 0x80
91#define IT87_CIR_RSR_RESERVED 0x40
92#define IT87_CIR_RSR_RXFBC 0x3f
93
94/* IIR: */
95#define IT87_CIR_IIR_RESERVED 0xf8
96#define IT87_CIR_IIR_IID 0x6
97#define IT87_CIR_IIR_IIP 0x1
98
99/* TM: */
100#define IT87_CIR_TM_IL_SEL 0x80
101#define IT87_CIR_TM_RESERVED 0x40
102#define IT87_CIR_TM_TM_REG 0x3f
103
104#define IT87_CIR_FIFO_SIZE 32
105
106/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */
107#define IT87_CIR_BAUDRATE_DIVISOR 0x1
108#define IT87_CIR_DEFAULT_IOBASE 0x310
109#define IT87_CIR_DEFAULT_IRQ 0x7
110#define IT87_CIR_SPACE 0x00
111#define IT87_CIR_PULSE 0xff
112#define IT87_CIR_FREQ_MIN 27
113#define IT87_CIR_FREQ_MAX 58
114#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul)
115
116/********************************* ITE IT87xx ************************/
diff --git a/drivers/staging/lirc/lirc_ite8709.c b/drivers/staging/lirc/lirc_ite8709.c
deleted file mode 100644
index cb20cfdcfadd..000000000000
--- a/drivers/staging/lirc/lirc_ite8709.c
+++ /dev/null
@@ -1,542 +0,0 @@
1/*
2 * LIRC driver for ITE8709 CIR port
3 *
4 * Copyright (C) 2008 Grégory Lardière <spmf2004-lirc@yahoo.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22#include <linux/module.h>
23#include <linux/interrupt.h>
24#include <linux/sched.h>
25#include <linux/delay.h>
26#include <linux/pnp.h>
27#include <linux/io.h>
28
29#include <media/lirc.h>
30#include <media/lirc_dev.h>
31
32#define LIRC_DRIVER_NAME "lirc_ite8709"
33
34#define BUF_CHUNK_SIZE sizeof(int)
35#define BUF_SIZE (128*BUF_CHUNK_SIZE)
36
37/*
38 * The ITE8709 device seems to be the combination of IT8512 superIO chip and
39 * a specific firmware running on the IT8512's embedded micro-controller.
40 * In addition of the embedded micro-controller, the IT8512 chip contains a
41 * CIR module and several other modules. A few modules are directly accessible
42 * by the host CPU, but most of them are only accessible by the
43 * micro-controller. The CIR module is only accessible by the micro-controller.
44 * The battery-backed SRAM module is accessible by the host CPU and the
45 * micro-controller. So one of the MC's firmware role is to act as a bridge
46 * between the host CPU and the CIR module. The firmware implements a kind of
47 * communication protocol using the SRAM module as a shared memory. The IT8512
48 * specification is publicly available on ITE's web site, but the communication
49 * protocol is not, so it was reverse-engineered.
50 */
51
52/* ITE8709 Registers addresses and values (reverse-engineered) */
53#define ITE8709_MODE 0x1a
54#define ITE8709_REG_ADR 0x1b
55#define ITE8709_REG_VAL 0x1c
56#define ITE8709_IIR 0x1e /* Interrupt identification register */
57#define ITE8709_RFSR 0x1f /* Receiver FIFO status register */
58#define ITE8709_FIFO_START 0x20
59
60#define ITE8709_MODE_READY 0X00
61#define ITE8709_MODE_WRITE 0X01
62#define ITE8709_MODE_READ 0X02
63#define ITE8709_IIR_RDAI 0x02 /* Receiver data available interrupt */
64#define ITE8709_IIR_RFOI 0x04 /* Receiver FIFO overrun interrupt */
65#define ITE8709_RFSR_MASK 0x3f /* FIFO byte count mask */
66
67/*
68 * IT8512 CIR-module registers addresses and values
69 * (from IT8512 E/F specification v0.4.1)
70 */
71#define IT8512_REG_MSTCR 0x01 /* Master control register */
72#define IT8512_REG_IER 0x02 /* Interrupt enable register */
73#define IT8512_REG_CFR 0x04 /* Carrier frequency register */
74#define IT8512_REG_RCR 0x05 /* Receive control register */
75#define IT8512_REG_BDLR 0x08 /* Baud rate divisor low byte register */
76#define IT8512_REG_BDHR 0x09 /* Baud rate divisor high byte register */
77
78#define IT8512_MSTCR_RESET 0x01 /* Reset registers to default value */
79#define IT8512_MSTCR_FIFOCLR 0x02 /* Clear FIFO */
80#define IT8512_MSTCR_FIFOTL_7 0x04 /* FIFO threshold level : 7 */
81#define IT8512_MSTCR_FIFOTL_25 0x0c /* FIFO threshold level : 25 */
82#define IT8512_IER_RDAIE 0x02 /* Enable data interrupt request */
83#define IT8512_IER_RFOIE 0x04 /* Enable FIFO overrun interrupt req */
84#define IT8512_IER_IEC 0x80 /* Enable interrupt request */
85#define IT8512_CFR_CF_36KHZ 0x09 /* Carrier freq : low speed, 36kHz */
86#define IT8512_RCR_RXDCR_1 0x01 /* Demodulation carrier range : 1 */
87#define IT8512_RCR_RXACT 0x08 /* Receiver active */
88#define IT8512_RCR_RXEN 0x80 /* Receiver enable */
89#define IT8512_BDR_6 6 /* Baud rate divisor : 6 */
90
91/* Actual values used by this driver */
92#define CFG_FIFOTL IT8512_MSTCR_FIFOTL_25
93#define CFG_CR_FREQ IT8512_CFR_CF_36KHZ
94#define CFG_DCR IT8512_RCR_RXDCR_1
95#define CFG_BDR IT8512_BDR_6
96#define CFG_TIMEOUT 100000 /* Rearm interrupt when a space is > 100 ms */
97
98static int debug;
99
100struct ite8709_device {
101 int use_count;
102 int io;
103 int irq;
104 spinlock_t hardware_lock;
105 __u64 acc_pulse;
106 __u64 acc_space;
107 char lastbit;
108 struct timeval last_tv;
109 struct lirc_driver driver;
110 struct tasklet_struct tasklet;
111 char force_rearm;
112 char rearmed;
113 char device_busy;
114};
115
116#define dprintk(fmt, args...) \
117 do { \
118 if (debug) \
119 printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
120 fmt, ## args); \
121 } while (0)
122
123
124static unsigned char ite8709_read(struct ite8709_device *dev,
125 unsigned char port)
126{
127 outb(port, dev->io);
128 return inb(dev->io+1);
129}
130
131static void ite8709_write(struct ite8709_device *dev, unsigned char port,
132 unsigned char data)
133{
134 outb(port, dev->io);
135 outb(data, dev->io+1);
136}
137
138static void ite8709_wait_device(struct ite8709_device *dev)
139{
140 int i = 0;
141 /*
142 * loop until device tells it's ready to continue
143 * iterations count is usually ~750 but can sometimes achieve 13000
144 */
145 for (i = 0; i < 15000; i++) {
146 udelay(2);
147 if (ite8709_read(dev, ITE8709_MODE) == ITE8709_MODE_READY)
148 break;
149 }
150}
151
152static void ite8709_write_register(struct ite8709_device *dev,
153 unsigned char reg_adr, unsigned char reg_value)
154{
155 ite8709_wait_device(dev);
156
157 ite8709_write(dev, ITE8709_REG_VAL, reg_value);
158 ite8709_write(dev, ITE8709_REG_ADR, reg_adr);
159 ite8709_write(dev, ITE8709_MODE, ITE8709_MODE_WRITE);
160}
161
162static void ite8709_init_hardware(struct ite8709_device *dev)
163{
164 spin_lock_irq(&dev->hardware_lock);
165 dev->device_busy = 1;
166 spin_unlock_irq(&dev->hardware_lock);
167
168 ite8709_write_register(dev, IT8512_REG_BDHR, (CFG_BDR >> 8) & 0xff);
169 ite8709_write_register(dev, IT8512_REG_BDLR, CFG_BDR & 0xff);
170 ite8709_write_register(dev, IT8512_REG_CFR, CFG_CR_FREQ);
171 ite8709_write_register(dev, IT8512_REG_IER,
172 IT8512_IER_IEC | IT8512_IER_RFOIE | IT8512_IER_RDAIE);
173 ite8709_write_register(dev, IT8512_REG_RCR, CFG_DCR);
174 ite8709_write_register(dev, IT8512_REG_MSTCR,
175 CFG_FIFOTL | IT8512_MSTCR_FIFOCLR);
176 ite8709_write_register(dev, IT8512_REG_RCR,
177 IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR);
178
179 spin_lock_irq(&dev->hardware_lock);
180 dev->device_busy = 0;
181 spin_unlock_irq(&dev->hardware_lock);
182
183 tasklet_enable(&dev->tasklet);
184}
185
186static void ite8709_drop_hardware(struct ite8709_device *dev)
187{
188 tasklet_disable(&dev->tasklet);
189
190 spin_lock_irq(&dev->hardware_lock);
191 dev->device_busy = 1;
192 spin_unlock_irq(&dev->hardware_lock);
193
194 ite8709_write_register(dev, IT8512_REG_RCR, 0);
195 ite8709_write_register(dev, IT8512_REG_MSTCR,
196 IT8512_MSTCR_RESET | IT8512_MSTCR_FIFOCLR);
197
198 spin_lock_irq(&dev->hardware_lock);
199 dev->device_busy = 0;
200 spin_unlock_irq(&dev->hardware_lock);
201}
202
203static int ite8709_set_use_inc(void *data)
204{
205 struct ite8709_device *dev;
206 dev = data;
207 if (dev->use_count == 0)
208 ite8709_init_hardware(dev);
209 dev->use_count++;
210 return 0;
211}
212
213static void ite8709_set_use_dec(void *data)
214{
215 struct ite8709_device *dev;
216 dev = data;
217 dev->use_count--;
218 if (dev->use_count == 0)
219 ite8709_drop_hardware(dev);
220}
221
222static void ite8709_add_read_queue(struct ite8709_device *dev, int flag,
223 __u64 val)
224{
225 int value;
226
227 dprintk("add a %llu usec %s\n", val, flag ? "pulse" : "space");
228
229 value = (val > PULSE_MASK) ? PULSE_MASK : val;
230 if (flag)
231 value |= PULSE_BIT;
232
233 if (!lirc_buffer_full(dev->driver.rbuf)) {
234 lirc_buffer_write(dev->driver.rbuf, (void *) &value);
235 wake_up(&dev->driver.rbuf->wait_poll);
236 }
237}
238
239static irqreturn_t ite8709_interrupt(int irq, void *dev_id)
240{
241 unsigned char data;
242 int iir, rfsr, i;
243 int fifo = 0;
244 char bit;
245 struct timeval curr_tv;
246
247 /* Bit duration in microseconds */
248 const unsigned long bit_duration = 1000000ul / (115200 / CFG_BDR);
249
250 struct ite8709_device *dev;
251 dev = dev_id;
252
253 /*
254 * If device is busy, we simply discard data because we are in one of
255 * these two cases : shutting down or rearming the device, so this
256 * doesn't really matter and this avoids waiting too long in IRQ ctx
257 */
258 spin_lock(&dev->hardware_lock);
259 if (dev->device_busy) {
260 spin_unlock(&dev->hardware_lock);
261 return IRQ_RETVAL(IRQ_HANDLED);
262 }
263
264 iir = ite8709_read(dev, ITE8709_IIR);
265
266 switch (iir) {
267 case ITE8709_IIR_RFOI:
268 dprintk("fifo overrun, scheduling forced rearm just in case\n");
269 dev->force_rearm = 1;
270 tasklet_schedule(&dev->tasklet);
271 spin_unlock(&dev->hardware_lock);
272 return IRQ_RETVAL(IRQ_HANDLED);
273
274 case ITE8709_IIR_RDAI:
275 rfsr = ite8709_read(dev, ITE8709_RFSR);
276 fifo = rfsr & ITE8709_RFSR_MASK;
277 if (fifo > 32)
278 fifo = 32;
279 dprintk("iir: 0x%x rfsr: 0x%x fifo: %d\n", iir, rfsr, fifo);
280
281 if (dev->rearmed) {
282 do_gettimeofday(&curr_tv);
283 dev->acc_space += 1000000ull
284 * (curr_tv.tv_sec - dev->last_tv.tv_sec)
285 + (curr_tv.tv_usec - dev->last_tv.tv_usec);
286 dev->rearmed = 0;
287 }
288 for (i = 0; i < fifo; i++) {
289 data = ite8709_read(dev, i+ITE8709_FIFO_START);
290 data = ~data;
291 /* Loop through */
292 for (bit = 0; bit < 8; ++bit) {
293 if ((data >> bit) & 1) {
294 dev->acc_pulse += bit_duration;
295 if (dev->lastbit == 0) {
296 ite8709_add_read_queue(dev, 0,
297 dev->acc_space);
298 dev->acc_space = 0;
299 }
300 } else {
301 dev->acc_space += bit_duration;
302 if (dev->lastbit == 1) {
303 ite8709_add_read_queue(dev, 1,
304 dev->acc_pulse);
305 dev->acc_pulse = 0;
306 }
307 }
308 dev->lastbit = (data >> bit) & 1;
309 }
310 }
311 ite8709_write(dev, ITE8709_RFSR, 0);
312
313 if (dev->acc_space > CFG_TIMEOUT) {
314 dprintk("scheduling rearm IRQ\n");
315 do_gettimeofday(&dev->last_tv);
316 dev->force_rearm = 0;
317 tasklet_schedule(&dev->tasklet);
318 }
319
320 spin_unlock(&dev->hardware_lock);
321 return IRQ_RETVAL(IRQ_HANDLED);
322
323 default:
324 /* not our irq */
325 dprintk("unknown IRQ (shouldn't happen) !!\n");
326 spin_unlock(&dev->hardware_lock);
327 return IRQ_RETVAL(IRQ_NONE);
328 }
329}
330
331static void ite8709_rearm_irq(unsigned long data)
332{
333 struct ite8709_device *dev;
334 unsigned long flags;
335 dev = (struct ite8709_device *) data;
336
337 spin_lock_irqsave(&dev->hardware_lock, flags);
338 dev->device_busy = 1;
339 spin_unlock_irqrestore(&dev->hardware_lock, flags);
340
341 if (dev->force_rearm || dev->acc_space > CFG_TIMEOUT) {
342 dprintk("rearming IRQ\n");
343 ite8709_write_register(dev, IT8512_REG_RCR,
344 IT8512_RCR_RXACT | CFG_DCR);
345 ite8709_write_register(dev, IT8512_REG_MSTCR,
346 CFG_FIFOTL | IT8512_MSTCR_FIFOCLR);
347 ite8709_write_register(dev, IT8512_REG_RCR,
348 IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR);
349 if (!dev->force_rearm)
350 dev->rearmed = 1;
351 dev->force_rearm = 0;
352 }
353
354 spin_lock_irqsave(&dev->hardware_lock, flags);
355 dev->device_busy = 0;
356 spin_unlock_irqrestore(&dev->hardware_lock, flags);
357}
358
359static int ite8709_cleanup(struct ite8709_device *dev, int stage, int errno,
360 char *msg)
361{
362 if (msg != NULL)
363 printk(KERN_ERR LIRC_DRIVER_NAME ": %s\n", msg);
364
365 switch (stage) {
366 case 6:
367 if (dev->use_count > 0)
368 ite8709_drop_hardware(dev);
369 case 5:
370 free_irq(dev->irq, dev);
371 case 4:
372 release_region(dev->io, 2);
373 case 3:
374 lirc_unregister_driver(dev->driver.minor);
375 case 2:
376 lirc_buffer_free(dev->driver.rbuf);
377 kfree(dev->driver.rbuf);
378 case 1:
379 kfree(dev);
380 case 0:
381 ;
382 }
383
384 return errno;
385}
386
387static int __devinit ite8709_pnp_probe(struct pnp_dev *dev,
388 const struct pnp_device_id *dev_id)
389{
390 struct lirc_driver *driver;
391 struct ite8709_device *ite8709_dev;
392 int ret;
393
394 /* Check resources validity */
395 if (!pnp_irq_valid(dev, 0))
396 return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IRQ");
397 if (!pnp_port_valid(dev, 2))
398 return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IO port");
399
400 /* Allocate memory for device struct */
401 ite8709_dev = kzalloc(sizeof(struct ite8709_device), GFP_KERNEL);
402 if (ite8709_dev == NULL)
403 return ite8709_cleanup(NULL, 0, -ENOMEM, "kzalloc failed");
404 pnp_set_drvdata(dev, ite8709_dev);
405
406 /* Initialize device struct */
407 ite8709_dev->use_count = 0;
408 ite8709_dev->irq = pnp_irq(dev, 0);
409 ite8709_dev->io = pnp_port_start(dev, 2);
410 ite8709_dev->hardware_lock =
411 __SPIN_LOCK_UNLOCKED(ite8709_dev->hardware_lock);
412 ite8709_dev->acc_pulse = 0;
413 ite8709_dev->acc_space = 0;
414 ite8709_dev->lastbit = 0;
415 do_gettimeofday(&ite8709_dev->last_tv);
416 tasklet_init(&ite8709_dev->tasklet, ite8709_rearm_irq,
417 (long) ite8709_dev);
418 ite8709_dev->force_rearm = 0;
419 ite8709_dev->rearmed = 0;
420 ite8709_dev->device_busy = 0;
421
422 /* Initialize driver struct */
423 driver = &ite8709_dev->driver;
424 strcpy(driver->name, LIRC_DRIVER_NAME);
425 driver->minor = -1;
426 driver->code_length = sizeof(int) * 8;
427 driver->sample_rate = 0;
428 driver->features = LIRC_CAN_REC_MODE2;
429 driver->data = ite8709_dev;
430 driver->add_to_buf = NULL;
431 driver->set_use_inc = ite8709_set_use_inc;
432 driver->set_use_dec = ite8709_set_use_dec;
433 driver->dev = &dev->dev;
434 driver->owner = THIS_MODULE;
435
436 /* Initialize LIRC buffer */
437 driver->rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
438 if (!driver->rbuf)
439 return ite8709_cleanup(ite8709_dev, 1, -ENOMEM,
440 "can't allocate lirc_buffer");
441 if (lirc_buffer_init(driver->rbuf, BUF_CHUNK_SIZE, BUF_SIZE))
442 return ite8709_cleanup(ite8709_dev, 1, -ENOMEM,
443 "lirc_buffer_init() failed");
444
445 /* Register LIRC driver */
446 ret = lirc_register_driver(driver);
447 if (ret < 0)
448 return ite8709_cleanup(ite8709_dev, 2, ret,
449 "lirc_register_driver() failed");
450
451 /* Reserve I/O port access */
452 if (!request_region(ite8709_dev->io, 2, LIRC_DRIVER_NAME))
453 return ite8709_cleanup(ite8709_dev, 3, -EBUSY,
454 "i/o port already in use");
455
456 /* Reserve IRQ line */
457 ret = request_irq(ite8709_dev->irq, ite8709_interrupt, 0,
458 LIRC_DRIVER_NAME, ite8709_dev);
459 if (ret < 0)
460 return ite8709_cleanup(ite8709_dev, 4, ret,
461 "IRQ already in use");
462
463 /* Initialize hardware */
464 ite8709_drop_hardware(ite8709_dev); /* Shutdown hw until first use */
465
466 printk(KERN_INFO LIRC_DRIVER_NAME ": device found : irq=%d io=0x%x\n",
467 ite8709_dev->irq, ite8709_dev->io);
468
469 return 0;
470}
471
472static void __devexit ite8709_pnp_remove(struct pnp_dev *dev)
473{
474 struct ite8709_device *ite8709_dev;
475 ite8709_dev = pnp_get_drvdata(dev);
476
477 ite8709_cleanup(ite8709_dev, 6, 0, NULL);
478
479 printk(KERN_INFO LIRC_DRIVER_NAME ": device removed\n");
480}
481
482#ifdef CONFIG_PM
483static int ite8709_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
484{
485 struct ite8709_device *ite8709_dev;
486 ite8709_dev = pnp_get_drvdata(dev);
487
488 if (ite8709_dev->use_count > 0)
489 ite8709_drop_hardware(ite8709_dev);
490
491 return 0;
492}
493
494static int ite8709_pnp_resume(struct pnp_dev *dev)
495{
496 struct ite8709_device *ite8709_dev;
497 ite8709_dev = pnp_get_drvdata(dev);
498
499 if (ite8709_dev->use_count > 0)
500 ite8709_init_hardware(ite8709_dev);
501
502 return 0;
503}
504#else
505#define ite8709_pnp_suspend NULL
506#define ite8709_pnp_resume NULL
507#endif
508
509static const struct pnp_device_id pnp_dev_table[] = {
510 {"ITE8709", 0},
511 {}
512};
513
514MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
515
516static struct pnp_driver ite8709_pnp_driver = {
517 .name = LIRC_DRIVER_NAME,
518 .probe = ite8709_pnp_probe,
519 .remove = __devexit_p(ite8709_pnp_remove),
520 .suspend = ite8709_pnp_suspend,
521 .resume = ite8709_pnp_resume,
522 .id_table = pnp_dev_table,
523};
524
525static int __init ite8709_init_module(void)
526{
527 return pnp_register_driver(&ite8709_pnp_driver);
528}
529module_init(ite8709_init_module);
530
531static void __exit ite8709_cleanup_module(void)
532{
533 pnp_unregister_driver(&ite8709_pnp_driver);
534}
535module_exit(ite8709_cleanup_module);
536
537MODULE_DESCRIPTION("LIRC driver for ITE8709 CIR port");
538MODULE_AUTHOR("Grégory Lardière");
539MODULE_LICENSE("GPL");
540
541module_param(debug, bool, S_IRUGO | S_IWUSR);
542MODULE_PARM_DESC(debug, "Enable debugging messages");
diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c
index 925eabe14854..63a438d1c849 100644
--- a/drivers/staging/lirc/lirc_sasem.c
+++ b/drivers/staging/lirc/lirc_sasem.c
@@ -364,7 +364,7 @@ static ssize_t vfd_write(struct file *file, const char *buf,
364 int i; 364 int i;
365 int retval = 0; 365 int retval = 0;
366 struct sasem_context *context; 366 struct sasem_context *context;
367 int *data_buf; 367 int *data_buf = NULL;
368 368
369 context = (struct sasem_context *) file->private_data; 369 context = (struct sasem_context *) file->private_data;
370 if (!context) { 370 if (!context) {
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
index 0aad0d7a74a3..dd6a57c3c3a3 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/lirc/lirc_zilog.c
@@ -63,14 +63,16 @@
63#include <media/lirc_dev.h> 63#include <media/lirc_dev.h>
64#include <media/lirc.h> 64#include <media/lirc.h>
65 65
66struct IR;
67
66struct IR_rx { 68struct IR_rx {
69 struct kref ref;
70 struct IR *ir;
71
67 /* RX device */ 72 /* RX device */
73 struct mutex client_lock;
68 struct i2c_client *c; 74 struct i2c_client *c;
69 75
70 /* RX device buffer & lock */
71 struct lirc_buffer buf;
72 struct mutex buf_lock;
73
74 /* RX polling thread data */ 76 /* RX polling thread data */
75 struct task_struct *task; 77 struct task_struct *task;
76 78
@@ -80,7 +82,11 @@ struct IR_rx {
80}; 82};
81 83
82struct IR_tx { 84struct IR_tx {
85 struct kref ref;
86 struct IR *ir;
87
83 /* TX device */ 88 /* TX device */
89 struct mutex client_lock;
84 struct i2c_client *c; 90 struct i2c_client *c;
85 91
86 /* TX additional actions needed */ 92 /* TX additional actions needed */
@@ -89,19 +95,34 @@ struct IR_tx {
89}; 95};
90 96
91struct IR { 97struct IR {
98 struct kref ref;
99 struct list_head list;
100
101 /* FIXME spinlock access to l.features */
92 struct lirc_driver l; 102 struct lirc_driver l;
103 struct lirc_buffer rbuf;
93 104
94 struct mutex ir_lock; 105 struct mutex ir_lock;
95 int open; 106 atomic_t open_count;
96 107
97 struct i2c_adapter *adapter; 108 struct i2c_adapter *adapter;
109
110 spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */
98 struct IR_rx *rx; 111 struct IR_rx *rx;
112
113 spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */
99 struct IR_tx *tx; 114 struct IR_tx *tx;
100}; 115};
101 116
102/* Minor -> data mapping */ 117/* IR transceiver instance object list */
103static struct mutex ir_devices_lock; 118/*
104static struct IR *ir_devices[MAX_IRCTL_DEVICES]; 119 * This lock is used for the following:
120 * a. ir_devices_list access, insertions, deletions
121 * b. struct IR kref get()s and put()s
122 * c. serialization of ir_probe() for the two i2c_clients for a Z8
123 */
124static DEFINE_MUTEX(ir_devices_lock);
125static LIST_HEAD(ir_devices_list);
105 126
106/* Block size for IR transmitter */ 127/* Block size for IR transmitter */
107#define TX_BLOCK_SIZE 99 128#define TX_BLOCK_SIZE 99
@@ -147,6 +168,157 @@ static int minor = -1; /* minor number */
147 ## args); \ 168 ## args); \
148 } while (0) 169 } while (0)
149 170
171
172/* struct IR reference counting */
173static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held)
174{
175 if (ir_devices_lock_held) {
176 kref_get(&ir->ref);
177 } else {
178 mutex_lock(&ir_devices_lock);
179 kref_get(&ir->ref);
180 mutex_unlock(&ir_devices_lock);
181 }
182 return ir;
183}
184
185static void release_ir_device(struct kref *ref)
186{
187 struct IR *ir = container_of(ref, struct IR, ref);
188
189 /*
190 * Things should be in this state by now:
191 * ir->rx set to NULL and deallocated - happens before ir->rx->ir put()
192 * ir->rx->task kthread stopped - happens before ir->rx->ir put()
193 * ir->tx set to NULL and deallocated - happens before ir->tx->ir put()
194 * ir->open_count == 0 - happens on final close()
195 * ir_lock, tx_ref_lock, rx_ref_lock, all released
196 */
197 if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) {
198 lirc_unregister_driver(ir->l.minor);
199 ir->l.minor = MAX_IRCTL_DEVICES;
200 }
201 if (ir->rbuf.fifo_initialized)
202 lirc_buffer_free(&ir->rbuf);
203 list_del(&ir->list);
204 kfree(ir);
205}
206
207static int put_ir_device(struct IR *ir, bool ir_devices_lock_held)
208{
209 int released;
210
211 if (ir_devices_lock_held)
212 return kref_put(&ir->ref, release_ir_device);
213
214 mutex_lock(&ir_devices_lock);
215 released = kref_put(&ir->ref, release_ir_device);
216 mutex_unlock(&ir_devices_lock);
217
218 return released;
219}
220
221/* struct IR_rx reference counting */
222static struct IR_rx *get_ir_rx(struct IR *ir)
223{
224 struct IR_rx *rx;
225
226 spin_lock(&ir->rx_ref_lock);
227 rx = ir->rx;
228 if (rx != NULL)
229 kref_get(&rx->ref);
230 spin_unlock(&ir->rx_ref_lock);
231 return rx;
232}
233
234static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held)
235{
236 /* end up polling thread */
237 if (!IS_ERR_OR_NULL(rx->task)) {
238 kthread_stop(rx->task);
239 rx->task = NULL;
240 /* Put the ir ptr that ir_probe() gave to the rx poll thread */
241 put_ir_device(rx->ir, ir_devices_lock_held);
242 }
243}
244
245static void release_ir_rx(struct kref *ref)
246{
247 struct IR_rx *rx = container_of(ref, struct IR_rx, ref);
248 struct IR *ir = rx->ir;
249
250 /*
251 * This release function can't do all the work, as we want
252 * to keep the rx_ref_lock a spinlock, and killing the poll thread
253 * and releasing the ir reference can cause a sleep. That work is
254 * performed by put_ir_rx()
255 */
256 ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
257 /* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
258 ir->rx = NULL;
259 /* Don't do the kfree(rx) here; we still need to kill the poll thread */
260 return;
261}
262
263static int put_ir_rx(struct IR_rx *rx, bool ir_devices_lock_held)
264{
265 int released;
266 struct IR *ir = rx->ir;
267
268 spin_lock(&ir->rx_ref_lock);
269 released = kref_put(&rx->ref, release_ir_rx);
270 spin_unlock(&ir->rx_ref_lock);
271 /* Destroy the rx kthread while not holding the spinlock */
272 if (released) {
273 destroy_rx_kthread(rx, ir_devices_lock_held);
274 kfree(rx);
275 /* Make sure we're not still in a poll_table somewhere */
276 wake_up_interruptible(&ir->rbuf.wait_poll);
277 }
278 /* Do a reference put() for the rx->ir reference, if we released rx */
279 if (released)
280 put_ir_device(ir, ir_devices_lock_held);
281 return released;
282}
283
284/* struct IR_tx reference counting */
285static struct IR_tx *get_ir_tx(struct IR *ir)
286{
287 struct IR_tx *tx;
288
289 spin_lock(&ir->tx_ref_lock);
290 tx = ir->tx;
291 if (tx != NULL)
292 kref_get(&tx->ref);
293 spin_unlock(&ir->tx_ref_lock);
294 return tx;
295}
296
297static void release_ir_tx(struct kref *ref)
298{
299 struct IR_tx *tx = container_of(ref, struct IR_tx, ref);
300 struct IR *ir = tx->ir;
301
302 ir->l.features &= ~LIRC_CAN_SEND_PULSE;
303 /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
304 ir->tx = NULL;
305 kfree(tx);
306}
307
308static int put_ir_tx(struct IR_tx *tx, bool ir_devices_lock_held)
309{
310 int released;
311 struct IR *ir = tx->ir;
312
313 spin_lock(&ir->tx_ref_lock);
314 released = kref_put(&tx->ref, release_ir_tx);
315 spin_unlock(&ir->tx_ref_lock);
316 /* Do a reference put() for the tx->ir reference, if we released tx */
317 if (released)
318 put_ir_device(ir, ir_devices_lock_held);
319 return released;
320}
321
150static int add_to_buf(struct IR *ir) 322static int add_to_buf(struct IR *ir)
151{ 323{
152 __u16 code; 324 __u16 code;
@@ -156,23 +328,38 @@ static int add_to_buf(struct IR *ir)
156 int ret; 328 int ret;
157 int failures = 0; 329 int failures = 0;
158 unsigned char sendbuf[1] = { 0 }; 330 unsigned char sendbuf[1] = { 0 };
159 struct IR_rx *rx = ir->rx; 331 struct lirc_buffer *rbuf = ir->l.rbuf;
332 struct IR_rx *rx;
333 struct IR_tx *tx;
160 334
335 if (lirc_buffer_full(rbuf)) {
336 dprintk("buffer overflow\n");
337 return -EOVERFLOW;
338 }
339
340 rx = get_ir_rx(ir);
161 if (rx == NULL) 341 if (rx == NULL)
162 return -ENXIO; 342 return -ENXIO;
163 343
164 if (lirc_buffer_full(&rx->buf)) { 344 /* Ensure our rx->c i2c_client remains valid for the duration */
165 dprintk("buffer overflow\n"); 345 mutex_lock(&rx->client_lock);
166 return -EOVERFLOW; 346 if (rx->c == NULL) {
347 mutex_unlock(&rx->client_lock);
348 put_ir_rx(rx, false);
349 return -ENXIO;
167 } 350 }
168 351
352 tx = get_ir_tx(ir);
353
169 /* 354 /*
170 * service the device as long as it is returning 355 * service the device as long as it is returning
171 * data and we have space 356 * data and we have space
172 */ 357 */
173 do { 358 do {
174 if (kthread_should_stop()) 359 if (kthread_should_stop()) {
175 return -ENODATA; 360 ret = -ENODATA;
361 break;
362 }
176 363
177 /* 364 /*
178 * Lock i2c bus for the duration. RX/TX chips interfere so 365 * Lock i2c bus for the duration. RX/TX chips interfere so
@@ -182,7 +369,8 @@ static int add_to_buf(struct IR *ir)
182 369
183 if (kthread_should_stop()) { 370 if (kthread_should_stop()) {
184 mutex_unlock(&ir->ir_lock); 371 mutex_unlock(&ir->ir_lock);
185 return -ENODATA; 372 ret = -ENODATA;
373 break;
186 } 374 }
187 375
188 /* 376 /*
@@ -196,7 +384,7 @@ static int add_to_buf(struct IR *ir)
196 mutex_unlock(&ir->ir_lock); 384 mutex_unlock(&ir->ir_lock);
197 zilog_error("unable to read from the IR chip " 385 zilog_error("unable to read from the IR chip "
198 "after 3 resets, giving up\n"); 386 "after 3 resets, giving up\n");
199 return ret; 387 break;
200 } 388 }
201 389
202 /* Looks like the chip crashed, reset it */ 390 /* Looks like the chip crashed, reset it */
@@ -206,19 +394,23 @@ static int add_to_buf(struct IR *ir)
206 set_current_state(TASK_UNINTERRUPTIBLE); 394 set_current_state(TASK_UNINTERRUPTIBLE);
207 if (kthread_should_stop()) { 395 if (kthread_should_stop()) {
208 mutex_unlock(&ir->ir_lock); 396 mutex_unlock(&ir->ir_lock);
209 return -ENODATA; 397 ret = -ENODATA;
398 break;
210 } 399 }
211 schedule_timeout((100 * HZ + 999) / 1000); 400 schedule_timeout((100 * HZ + 999) / 1000);
212 ir->tx->need_boot = 1; 401 if (tx != NULL)
402 tx->need_boot = 1;
213 403
214 ++failures; 404 ++failures;
215 mutex_unlock(&ir->ir_lock); 405 mutex_unlock(&ir->ir_lock);
406 ret = 0;
216 continue; 407 continue;
217 } 408 }
218 409
219 if (kthread_should_stop()) { 410 if (kthread_should_stop()) {
220 mutex_unlock(&ir->ir_lock); 411 mutex_unlock(&ir->ir_lock);
221 return -ENODATA; 412 ret = -ENODATA;
413 break;
222 } 414 }
223 ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf)); 415 ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
224 mutex_unlock(&ir->ir_lock); 416 mutex_unlock(&ir->ir_lock);
@@ -234,12 +426,17 @@ static int add_to_buf(struct IR *ir)
234 426
235 /* key pressed ? */ 427 /* key pressed ? */
236 if (rx->hdpvr_data_fmt) { 428 if (rx->hdpvr_data_fmt) {
237 if (got_data && (keybuf[0] == 0x80)) 429 if (got_data && (keybuf[0] == 0x80)) {
238 return 0; 430 ret = 0;
239 else if (got_data && (keybuf[0] == 0x00)) 431 break;
240 return -ENODATA; 432 } else if (got_data && (keybuf[0] == 0x00)) {
241 } else if ((rx->b[0] & 0x80) == 0) 433 ret = -ENODATA;
242 return got_data ? 0 : -ENODATA; 434 break;
435 }
436 } else if ((rx->b[0] & 0x80) == 0) {
437 ret = got_data ? 0 : -ENODATA;
438 break;
439 }
243 440
244 /* look what we have */ 441 /* look what we have */
245 code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2); 442 code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2);
@@ -248,11 +445,16 @@ static int add_to_buf(struct IR *ir)
248 codes[1] = code & 0xff; 445 codes[1] = code & 0xff;
249 446
250 /* return it */ 447 /* return it */
251 lirc_buffer_write(&rx->buf, codes); 448 lirc_buffer_write(rbuf, codes);
252 ++got_data; 449 ++got_data;
253 } while (!lirc_buffer_full(&rx->buf)); 450 ret = 0;
451 } while (!lirc_buffer_full(rbuf));
254 452
255 return 0; 453 mutex_unlock(&rx->client_lock);
454 if (tx != NULL)
455 put_ir_tx(tx, false);
456 put_ir_rx(rx, false);
457 return ret;
256} 458}
257 459
258/* 460/*
@@ -268,19 +470,19 @@ static int add_to_buf(struct IR *ir)
268static int lirc_thread(void *arg) 470static int lirc_thread(void *arg)
269{ 471{
270 struct IR *ir = arg; 472 struct IR *ir = arg;
271 struct IR_rx *rx = ir->rx; 473 struct lirc_buffer *rbuf = ir->l.rbuf;
272 474
273 dprintk("poll thread started\n"); 475 dprintk("poll thread started\n");
274 476
275 while (!kthread_should_stop()) { 477 while (!kthread_should_stop()) {
276 set_current_state(TASK_INTERRUPTIBLE);
277
278 /* if device not opened, we can sleep half a second */ 478 /* if device not opened, we can sleep half a second */
279 if (!ir->open) { 479 if (atomic_read(&ir->open_count) == 0) {
280 schedule_timeout(HZ/2); 480 schedule_timeout(HZ/2);
281 continue; 481 continue;
282 } 482 }
283 483
484 set_current_state(TASK_INTERRUPTIBLE);
485
284 /* 486 /*
285 * This is ~113*2 + 24 + jitter (2*repeat gap + code length). 487 * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
286 * We use this interval as the chip resets every time you poll 488 * We use this interval as the chip resets every time you poll
@@ -295,7 +497,7 @@ static int lirc_thread(void *arg)
295 if (kthread_should_stop()) 497 if (kthread_should_stop())
296 break; 498 break;
297 if (!add_to_buf(ir)) 499 if (!add_to_buf(ir))
298 wake_up_interruptible(&rx->buf.wait_poll); 500 wake_up_interruptible(&rbuf->wait_poll);
299 } 501 }
300 502
301 dprintk("poll thread ended\n"); 503 dprintk("poll thread ended\n");
@@ -304,34 +506,12 @@ static int lirc_thread(void *arg)
304 506
305static int set_use_inc(void *data) 507static int set_use_inc(void *data)
306{ 508{
307 struct IR *ir = data;
308
309 if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0)
310 return -ENODEV;
311
312 /* lock bttv in memory while /dev/lirc is in use */
313 /*
314 * this is completely broken code. lirc_unregister_driver()
315 * must be possible even when the device is open
316 */
317 if (ir->rx != NULL)
318 i2c_use_client(ir->rx->c);
319 if (ir->tx != NULL)
320 i2c_use_client(ir->tx->c);
321
322 return 0; 509 return 0;
323} 510}
324 511
325static void set_use_dec(void *data) 512static void set_use_dec(void *data)
326{ 513{
327 struct IR *ir = data; 514 return;
328
329 if (ir->rx)
330 i2c_release_client(ir->rx->c);
331 if (ir->tx)
332 i2c_release_client(ir->tx->c);
333 if (ir->l.owner != NULL)
334 module_put(ir->l.owner);
335} 515}
336 516
337/* safe read of a uint32 (always network byte order) */ 517/* safe read of a uint32 (always network byte order) */
@@ -585,7 +765,7 @@ static int fw_load(struct IR_tx *tx)
585 } 765 }
586 766
587 /* Request codeset data file */ 767 /* Request codeset data file */
588 ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &tx->c->dev); 768 ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev);
589 if (ret != 0) { 769 if (ret != 0) {
590 zilog_error("firmware haup-ir-blaster.bin not available " 770 zilog_error("firmware haup-ir-blaster.bin not available "
591 "(%d)\n", ret); 771 "(%d)\n", ret);
@@ -711,59 +891,32 @@ out:
711 return ret; 891 return ret;
712} 892}
713 893
714/* initialise the IR TX device */
715static int tx_init(struct IR_tx *tx)
716{
717 int ret;
718
719 /* Load 'firmware' */
720 ret = fw_load(tx);
721 if (ret != 0)
722 return ret;
723
724 /* Send boot block */
725 ret = send_boot_data(tx);
726 if (ret != 0)
727 return ret;
728 tx->need_boot = 0;
729
730 /* Looks good */
731 return 0;
732}
733
734/* do nothing stub to make LIRC happy */
735static loff_t lseek(struct file *filep, loff_t offset, int orig)
736{
737 return -ESPIPE;
738}
739
740/* copied from lirc_dev */ 894/* copied from lirc_dev */
741static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) 895static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
742{ 896{
743 struct IR *ir = filep->private_data; 897 struct IR *ir = filep->private_data;
744 struct IR_rx *rx = ir->rx; 898 struct IR_rx *rx;
745 int ret = 0, written = 0; 899 struct lirc_buffer *rbuf = ir->l.rbuf;
900 int ret = 0, written = 0, retries = 0;
901 unsigned int m;
746 DECLARE_WAITQUEUE(wait, current); 902 DECLARE_WAITQUEUE(wait, current);
747 903
748 dprintk("read called\n"); 904 dprintk("read called\n");
749 if (rx == NULL) 905 if (n % rbuf->chunk_size) {
750 return -ENODEV;
751
752 if (mutex_lock_interruptible(&rx->buf_lock))
753 return -ERESTARTSYS;
754
755 if (n % rx->buf.chunk_size) {
756 dprintk("read result = -EINVAL\n"); 906 dprintk("read result = -EINVAL\n");
757 mutex_unlock(&rx->buf_lock);
758 return -EINVAL; 907 return -EINVAL;
759 } 908 }
760 909
910 rx = get_ir_rx(ir);
911 if (rx == NULL)
912 return -ENXIO;
913
761 /* 914 /*
762 * we add ourselves to the task queue before buffer check 915 * we add ourselves to the task queue before buffer check
763 * to avoid losing scan code (in case when queue is awaken somewhere 916 * to avoid losing scan code (in case when queue is awaken somewhere
764 * between while condition checking and scheduling) 917 * between while condition checking and scheduling)
765 */ 918 */
766 add_wait_queue(&rx->buf.wait_poll, &wait); 919 add_wait_queue(&rbuf->wait_poll, &wait);
767 set_current_state(TASK_INTERRUPTIBLE); 920 set_current_state(TASK_INTERRUPTIBLE);
768 921
769 /* 922 /*
@@ -771,7 +924,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
771 * mode and 'copy_to_user' is happy, wait for data. 924 * mode and 'copy_to_user' is happy, wait for data.
772 */ 925 */
773 while (written < n && ret == 0) { 926 while (written < n && ret == 0) {
774 if (lirc_buffer_empty(&rx->buf)) { 927 if (lirc_buffer_empty(rbuf)) {
775 /* 928 /*
776 * According to the read(2) man page, 'written' can be 929 * According to the read(2) man page, 'written' can be
777 * returned as less than 'n', instead of blocking 930 * returned as less than 'n', instead of blocking
@@ -791,20 +944,27 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
791 schedule(); 944 schedule();
792 set_current_state(TASK_INTERRUPTIBLE); 945 set_current_state(TASK_INTERRUPTIBLE);
793 } else { 946 } else {
794 unsigned char buf[rx->buf.chunk_size]; 947 unsigned char buf[rbuf->chunk_size];
795 lirc_buffer_read(&rx->buf, buf); 948 m = lirc_buffer_read(rbuf, buf);
796 ret = copy_to_user((void *)outbuf+written, buf, 949 if (m == rbuf->chunk_size) {
797 rx->buf.chunk_size); 950 ret = copy_to_user((void *)outbuf+written, buf,
798 written += rx->buf.chunk_size; 951 rbuf->chunk_size);
952 written += rbuf->chunk_size;
953 } else {
954 retries++;
955 }
956 if (retries >= 5) {
957 zilog_error("Buffer read failed!\n");
958 ret = -EIO;
959 }
799 } 960 }
800 } 961 }
801 962
802 remove_wait_queue(&rx->buf.wait_poll, &wait); 963 remove_wait_queue(&rbuf->wait_poll, &wait);
964 put_ir_rx(rx, false);
803 set_current_state(TASK_RUNNING); 965 set_current_state(TASK_RUNNING);
804 mutex_unlock(&rx->buf_lock);
805 966
806 dprintk("read result = %s (%d)\n", 967 dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK");
807 ret ? "-EFAULT" : "OK", ret);
808 968
809 return ret ? ret : written; 969 return ret ? ret : written;
810} 970}
@@ -931,17 +1091,27 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
931 loff_t *ppos) 1091 loff_t *ppos)
932{ 1092{
933 struct IR *ir = filep->private_data; 1093 struct IR *ir = filep->private_data;
934 struct IR_tx *tx = ir->tx; 1094 struct IR_tx *tx;
935 size_t i; 1095 size_t i;
936 int failures = 0; 1096 int failures = 0;
937 1097
938 if (tx == NULL)
939 return -ENODEV;
940
941 /* Validate user parameters */ 1098 /* Validate user parameters */
942 if (n % sizeof(int)) 1099 if (n % sizeof(int))
943 return -EINVAL; 1100 return -EINVAL;
944 1101
1102 /* Get a struct IR_tx reference */
1103 tx = get_ir_tx(ir);
1104 if (tx == NULL)
1105 return -ENXIO;
1106
1107 /* Ensure our tx->c i2c_client remains valid for the duration */
1108 mutex_lock(&tx->client_lock);
1109 if (tx->c == NULL) {
1110 mutex_unlock(&tx->client_lock);
1111 put_ir_tx(tx, false);
1112 return -ENXIO;
1113 }
1114
945 /* Lock i2c bus for the duration */ 1115 /* Lock i2c bus for the duration */
946 mutex_lock(&ir->ir_lock); 1116 mutex_lock(&ir->ir_lock);
947 1117
@@ -952,11 +1122,24 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
952 1122
953 if (copy_from_user(&command, buf + i, sizeof(command))) { 1123 if (copy_from_user(&command, buf + i, sizeof(command))) {
954 mutex_unlock(&ir->ir_lock); 1124 mutex_unlock(&ir->ir_lock);
1125 mutex_unlock(&tx->client_lock);
1126 put_ir_tx(tx, false);
955 return -EFAULT; 1127 return -EFAULT;
956 } 1128 }
957 1129
958 /* Send boot data first if required */ 1130 /* Send boot data first if required */
959 if (tx->need_boot == 1) { 1131 if (tx->need_boot == 1) {
1132 /* Make sure we have the 'firmware' loaded, first */
1133 ret = fw_load(tx);
1134 if (ret != 0) {
1135 mutex_unlock(&ir->ir_lock);
1136 mutex_unlock(&tx->client_lock);
1137 put_ir_tx(tx, false);
1138 if (ret != -ENOMEM)
1139 ret = -EIO;
1140 return ret;
1141 }
1142 /* Prep the chip for transmitting codes */
960 ret = send_boot_data(tx); 1143 ret = send_boot_data(tx);
961 if (ret == 0) 1144 if (ret == 0)
962 tx->need_boot = 0; 1145 tx->need_boot = 0;
@@ -968,6 +1151,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
968 (unsigned)command & 0xFFFF); 1151 (unsigned)command & 0xFFFF);
969 if (ret == -EPROTO) { 1152 if (ret == -EPROTO) {
970 mutex_unlock(&ir->ir_lock); 1153 mutex_unlock(&ir->ir_lock);
1154 mutex_unlock(&tx->client_lock);
1155 put_ir_tx(tx, false);
971 return ret; 1156 return ret;
972 } 1157 }
973 } 1158 }
@@ -985,6 +1170,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
985 zilog_error("unable to send to the IR chip " 1170 zilog_error("unable to send to the IR chip "
986 "after 3 resets, giving up\n"); 1171 "after 3 resets, giving up\n");
987 mutex_unlock(&ir->ir_lock); 1172 mutex_unlock(&ir->ir_lock);
1173 mutex_unlock(&tx->client_lock);
1174 put_ir_tx(tx, false);
988 return ret; 1175 return ret;
989 } 1176 }
990 set_current_state(TASK_UNINTERRUPTIBLE); 1177 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -998,6 +1185,11 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
998 /* Release i2c bus */ 1185 /* Release i2c bus */
999 mutex_unlock(&ir->ir_lock); 1186 mutex_unlock(&ir->ir_lock);
1000 1187
1188 mutex_unlock(&tx->client_lock);
1189
1190 /* Give back our struct IR_tx reference */
1191 put_ir_tx(tx, false);
1192
1001 /* All looks good */ 1193 /* All looks good */
1002 return n; 1194 return n;
1003} 1195}
@@ -1006,23 +1198,32 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
1006static unsigned int poll(struct file *filep, poll_table *wait) 1198static unsigned int poll(struct file *filep, poll_table *wait)
1007{ 1199{
1008 struct IR *ir = filep->private_data; 1200 struct IR *ir = filep->private_data;
1009 struct IR_rx *rx = ir->rx; 1201 struct IR_rx *rx;
1202 struct lirc_buffer *rbuf = ir->l.rbuf;
1010 unsigned int ret; 1203 unsigned int ret;
1011 1204
1012 dprintk("poll called\n"); 1205 dprintk("poll called\n");
1013 if (rx == NULL)
1014 return -ENODEV;
1015
1016 mutex_lock(&rx->buf_lock);
1017 1206
1018 poll_wait(filep, &rx->buf.wait_poll, wait); 1207 rx = get_ir_rx(ir);
1208 if (rx == NULL) {
1209 /*
1210 * Revisit this, if our poll function ever reports writeable
1211 * status for Tx
1212 */
1213 dprintk("poll result = POLLERR\n");
1214 return POLLERR;
1215 }
1019 1216
1020 dprintk("poll result = %s\n", 1217 /*
1021 lirc_buffer_empty(&rx->buf) ? "0" : "POLLIN|POLLRDNORM"); 1218 * Add our lirc_buffer's wait_queue to the poll_table. A wake up on
1219 * that buffer's wait queue indicates we may have a new poll status.
1220 */
1221 poll_wait(filep, &rbuf->wait_poll, wait);
1022 1222
1023 ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM); 1223 /* Indicate what ops could happen immediately without blocking */
1224 ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM);
1024 1225
1025 mutex_unlock(&rx->buf_lock); 1226 dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none");
1026 return ret; 1227 return ret;
1027} 1228}
1028 1229
@@ -1030,11 +1231,9 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
1030{ 1231{
1031 struct IR *ir = filep->private_data; 1232 struct IR *ir = filep->private_data;
1032 int result; 1233 int result;
1033 unsigned long mode, features = 0; 1234 unsigned long mode, features;
1034 1235
1035 features |= LIRC_CAN_SEND_PULSE; 1236 features = ir->l.features;
1036 if (ir->rx != NULL)
1037 features |= LIRC_CAN_REC_LIRCCODE;
1038 1237
1039 switch (cmd) { 1238 switch (cmd) {
1040 case LIRC_GET_LENGTH: 1239 case LIRC_GET_LENGTH:
@@ -1061,9 +1260,15 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
1061 result = -EINVAL; 1260 result = -EINVAL;
1062 break; 1261 break;
1063 case LIRC_GET_SEND_MODE: 1262 case LIRC_GET_SEND_MODE:
1263 if (!(features&LIRC_CAN_SEND_MASK))
1264 return -ENOSYS;
1265
1064 result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); 1266 result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg);
1065 break; 1267 break;
1066 case LIRC_SET_SEND_MODE: 1268 case LIRC_SET_SEND_MODE:
1269 if (!(features&LIRC_CAN_SEND_MASK))
1270 return -ENOSYS;
1271
1067 result = get_user(mode, (unsigned long *) arg); 1272 result = get_user(mode, (unsigned long *) arg);
1068 if (!result && mode != LIRC_MODE_PULSE) 1273 if (!result && mode != LIRC_MODE_PULSE)
1069 return -EINVAL; 1274 return -EINVAL;
@@ -1074,13 +1279,24 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
1074 return result; 1279 return result;
1075} 1280}
1076 1281
1077/* ir_devices_lock must be held */ 1282static struct IR *get_ir_device_by_minor(unsigned int minor)
1078static struct IR *find_ir_device_by_minor(unsigned int minor)
1079{ 1283{
1080 if (minor >= MAX_IRCTL_DEVICES) 1284 struct IR *ir;
1081 return NULL; 1285 struct IR *ret = NULL;
1286
1287 mutex_lock(&ir_devices_lock);
1288
1289 if (!list_empty(&ir_devices_list)) {
1290 list_for_each_entry(ir, &ir_devices_list, list) {
1291 if (ir->l.minor == minor) {
1292 ret = get_ir_device(ir, true);
1293 break;
1294 }
1295 }
1296 }
1082 1297
1083 return ir_devices[minor]; 1298 mutex_unlock(&ir_devices_lock);
1299 return ret;
1084} 1300}
1085 1301
1086/* 1302/*
@@ -1090,31 +1306,20 @@ static struct IR *find_ir_device_by_minor(unsigned int minor)
1090static int open(struct inode *node, struct file *filep) 1306static int open(struct inode *node, struct file *filep)
1091{ 1307{
1092 struct IR *ir; 1308 struct IR *ir;
1093 int ret;
1094 unsigned int minor = MINOR(node->i_rdev); 1309 unsigned int minor = MINOR(node->i_rdev);
1095 1310
1096 /* find our IR struct */ 1311 /* find our IR struct */
1097 mutex_lock(&ir_devices_lock); 1312 ir = get_ir_device_by_minor(minor);
1098 ir = find_ir_device_by_minor(minor);
1099 mutex_unlock(&ir_devices_lock);
1100 1313
1101 if (ir == NULL) 1314 if (ir == NULL)
1102 return -ENODEV; 1315 return -ENODEV;
1103 1316
1104 /* increment in use count */ 1317 atomic_inc(&ir->open_count);
1105 mutex_lock(&ir->ir_lock);
1106 ++ir->open;
1107 ret = set_use_inc(ir);
1108 if (ret != 0) {
1109 --ir->open;
1110 mutex_unlock(&ir->ir_lock);
1111 return ret;
1112 }
1113 mutex_unlock(&ir->ir_lock);
1114 1318
1115 /* stash our IR struct */ 1319 /* stash our IR struct */
1116 filep->private_data = ir; 1320 filep->private_data = ir;
1117 1321
1322 nonseekable_open(node, filep);
1118 return 0; 1323 return 0;
1119} 1324}
1120 1325
@@ -1128,22 +1333,12 @@ static int close(struct inode *node, struct file *filep)
1128 return -ENODEV; 1333 return -ENODEV;
1129 } 1334 }
1130 1335
1131 /* decrement in use count */ 1336 atomic_dec(&ir->open_count);
1132 mutex_lock(&ir->ir_lock);
1133 --ir->open;
1134 set_use_dec(ir);
1135 mutex_unlock(&ir->ir_lock);
1136 1337
1338 put_ir_device(ir, false);
1137 return 0; 1339 return 0;
1138} 1340}
1139 1341
1140static struct lirc_driver lirc_template = {
1141 .name = "lirc_zilog",
1142 .set_use_inc = set_use_inc,
1143 .set_use_dec = set_use_dec,
1144 .owner = THIS_MODULE
1145};
1146
1147static int ir_remove(struct i2c_client *client); 1342static int ir_remove(struct i2c_client *client);
1148static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id); 1343static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
1149 1344
@@ -1170,7 +1365,7 @@ static struct i2c_driver driver = {
1170 1365
1171static const struct file_operations lirc_fops = { 1366static const struct file_operations lirc_fops = {
1172 .owner = THIS_MODULE, 1367 .owner = THIS_MODULE,
1173 .llseek = lseek, 1368 .llseek = no_llseek,
1174 .read = read, 1369 .read = read,
1175 .write = write, 1370 .write = write,
1176 .poll = poll, 1371 .poll = poll,
@@ -1182,97 +1377,64 @@ static const struct file_operations lirc_fops = {
1182 .release = close 1377 .release = close
1183}; 1378};
1184 1379
1185static void destroy_rx_kthread(struct IR_rx *rx) 1380static struct lirc_driver lirc_template = {
1186{ 1381 .name = "lirc_zilog",
1187 /* end up polling thread */ 1382 .minor = -1,
1188 if (rx != NULL && !IS_ERR_OR_NULL(rx->task)) { 1383 .code_length = 13,
1189 kthread_stop(rx->task); 1384 .buffer_size = BUFLEN / 2,
1190 rx->task = NULL; 1385 .sample_rate = 0, /* tell lirc_dev to not start its own kthread */
1191 } 1386 .chunk_size = 2,
1192} 1387 .set_use_inc = set_use_inc,
1388 .set_use_dec = set_use_dec,
1389 .fops = &lirc_fops,
1390 .owner = THIS_MODULE,
1391};
1193 1392
1194/* ir_devices_lock must be held */ 1393static int ir_remove(struct i2c_client *client)
1195static int add_ir_device(struct IR *ir)
1196{ 1394{
1197 int i; 1395 if (strncmp("ir_tx_z8", client->name, 8) == 0) {
1198 1396 struct IR_tx *tx = i2c_get_clientdata(client);
1199 for (i = 0; i < MAX_IRCTL_DEVICES; i++) 1397 if (tx != NULL) {
1200 if (ir_devices[i] == NULL) { 1398 mutex_lock(&tx->client_lock);
1201 ir_devices[i] = ir; 1399 tx->c = NULL;
1202 break; 1400 mutex_unlock(&tx->client_lock);
1401 put_ir_tx(tx, false);
1203 } 1402 }
1204 1403 } else if (strncmp("ir_rx_z8", client->name, 8) == 0) {
1205 return i == MAX_IRCTL_DEVICES ? -ENOMEM : i; 1404 struct IR_rx *rx = i2c_get_clientdata(client);
1206} 1405 if (rx != NULL) {
1207 1406 mutex_lock(&rx->client_lock);
1208/* ir_devices_lock must be held */ 1407 rx->c = NULL;
1209static void del_ir_device(struct IR *ir) 1408 mutex_unlock(&rx->client_lock);
1210{ 1409 put_ir_rx(rx, false);
1211 int i;
1212
1213 for (i = 0; i < MAX_IRCTL_DEVICES; i++)
1214 if (ir_devices[i] == ir) {
1215 ir_devices[i] = NULL;
1216 break;
1217 } 1410 }
1218}
1219
1220static int ir_remove(struct i2c_client *client)
1221{
1222 struct IR *ir = i2c_get_clientdata(client);
1223
1224 mutex_lock(&ir_devices_lock);
1225
1226 if (ir == NULL) {
1227 /* We destroyed everything when the first client came through */
1228 mutex_unlock(&ir_devices_lock);
1229 return 0;
1230 } 1411 }
1231
1232 /* Good-bye LIRC */
1233 lirc_unregister_driver(ir->l.minor);
1234
1235 /* Good-bye Rx */
1236 destroy_rx_kthread(ir->rx);
1237 if (ir->rx != NULL) {
1238 if (ir->rx->buf.fifo_initialized)
1239 lirc_buffer_free(&ir->rx->buf);
1240 i2c_set_clientdata(ir->rx->c, NULL);
1241 kfree(ir->rx);
1242 }
1243
1244 /* Good-bye Tx */
1245 i2c_set_clientdata(ir->tx->c, NULL);
1246 kfree(ir->tx);
1247
1248 /* Good-bye IR */
1249 del_ir_device(ir);
1250 kfree(ir);
1251
1252 mutex_unlock(&ir_devices_lock);
1253 return 0; 1412 return 0;
1254} 1413}
1255 1414
1256 1415
1257/* ir_devices_lock must be held */ 1416/* ir_devices_lock must be held */
1258static struct IR *find_ir_device_by_adapter(struct i2c_adapter *adapter) 1417static struct IR *get_ir_device_by_adapter(struct i2c_adapter *adapter)
1259{ 1418{
1260 int i; 1419 struct IR *ir;
1261 struct IR *ir = NULL;
1262 1420
1263 for (i = 0; i < MAX_IRCTL_DEVICES; i++) 1421 if (list_empty(&ir_devices_list))
1264 if (ir_devices[i] != NULL && 1422 return NULL;
1265 ir_devices[i]->adapter == adapter) { 1423
1266 ir = ir_devices[i]; 1424 list_for_each_entry(ir, &ir_devices_list, list)
1267 break; 1425 if (ir->adapter == adapter) {
1426 get_ir_device(ir, true);
1427 return ir;
1268 } 1428 }
1269 1429
1270 return ir; 1430 return NULL;
1271} 1431}
1272 1432
1273static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) 1433static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
1274{ 1434{
1275 struct IR *ir; 1435 struct IR *ir;
1436 struct IR_tx *tx;
1437 struct IR_rx *rx;
1276 struct i2c_adapter *adap = client->adapter; 1438 struct i2c_adapter *adap = client->adapter;
1277 int ret; 1439 int ret;
1278 bool tx_probe = false; 1440 bool tx_probe = false;
@@ -1296,133 +1458,170 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
1296 mutex_lock(&ir_devices_lock); 1458 mutex_lock(&ir_devices_lock);
1297 1459
1298 /* Use a single struct IR instance for both the Rx and Tx functions */ 1460 /* Use a single struct IR instance for both the Rx and Tx functions */
1299 ir = find_ir_device_by_adapter(adap); 1461 ir = get_ir_device_by_adapter(adap);
1300 if (ir == NULL) { 1462 if (ir == NULL) {
1301 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 1463 ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
1302 if (ir == NULL) { 1464 if (ir == NULL) {
1303 ret = -ENOMEM; 1465 ret = -ENOMEM;
1304 goto out_no_ir; 1466 goto out_no_ir;
1305 } 1467 }
1468 kref_init(&ir->ref);
1469
1306 /* store for use in ir_probe() again, and open() later on */ 1470 /* store for use in ir_probe() again, and open() later on */
1307 ret = add_ir_device(ir); 1471 INIT_LIST_HEAD(&ir->list);
1308 if (ret) 1472 list_add_tail(&ir->list, &ir_devices_list);
1309 goto out_free_ir;
1310 1473
1311 ir->adapter = adap; 1474 ir->adapter = adap;
1312 mutex_init(&ir->ir_lock); 1475 mutex_init(&ir->ir_lock);
1476 atomic_set(&ir->open_count, 0);
1477 spin_lock_init(&ir->tx_ref_lock);
1478 spin_lock_init(&ir->rx_ref_lock);
1313 1479
1314 /* set lirc_dev stuff */ 1480 /* set lirc_dev stuff */
1315 memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); 1481 memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
1316 ir->l.minor = minor; /* module option */ 1482 /*
1317 ir->l.code_length = 13; 1483 * FIXME this is a pointer reference to us, but no refcount.
1318 ir->l.rbuf = NULL; 1484 *
1319 ir->l.fops = &lirc_fops; 1485 * This OK for now, since lirc_dev currently won't touch this
1320 ir->l.data = ir; 1486 * buffer as we provide our own lirc_fops.
1321 ir->l.dev = &adap->dev; 1487 *
1322 ir->l.sample_rate = 0; 1488 * Currently our own lirc_fops rely on this ir->l.rbuf pointer
1489 */
1490 ir->l.rbuf = &ir->rbuf;
1491 ir->l.dev = &adap->dev;
1492 ret = lirc_buffer_init(ir->l.rbuf,
1493 ir->l.chunk_size, ir->l.buffer_size);
1494 if (ret)
1495 goto out_put_ir;
1323 } 1496 }
1324 1497
1325 if (tx_probe) { 1498 if (tx_probe) {
1499 /* Get the IR_rx instance for later, if already allocated */
1500 rx = get_ir_rx(ir);
1501
1326 /* Set up a struct IR_tx instance */ 1502 /* Set up a struct IR_tx instance */
1327 ir->tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL); 1503 tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL);
1328 if (ir->tx == NULL) { 1504 if (tx == NULL) {
1329 ret = -ENOMEM; 1505 ret = -ENOMEM;
1330 goto out_free_xx; 1506 goto out_put_xx;
1331 } 1507 }
1332 1508 kref_init(&tx->ref);
1333 ir->tx->c = client; 1509 ir->tx = tx;
1334 ir->tx->need_boot = 1; 1510
1335 ir->tx->post_tx_ready_poll = 1511 ir->l.features |= LIRC_CAN_SEND_PULSE;
1512 mutex_init(&tx->client_lock);
1513 tx->c = client;
1514 tx->need_boot = 1;
1515 tx->post_tx_ready_poll =
1336 (id->driver_data & ID_FLAG_HDPVR) ? false : true; 1516 (id->driver_data & ID_FLAG_HDPVR) ? false : true;
1517
1518 /* An ir ref goes to the struct IR_tx instance */
1519 tx->ir = get_ir_device(ir, true);
1520
1521 /* A tx ref goes to the i2c_client */
1522 i2c_set_clientdata(client, get_ir_tx(ir));
1523
1524 /*
1525 * Load the 'firmware'. We do this before registering with
1526 * lirc_dev, so the first firmware load attempt does not happen
1527 * after a open() or write() call on the device.
1528 *
1529 * Failure here is not deemed catastrophic, so the receiver will
1530 * still be usable. Firmware load will be retried in write(),
1531 * if it is needed.
1532 */
1533 fw_load(tx);
1534
1535 /* Proceed only if the Rx client is also ready or not needed */
1536 if (rx == NULL && !tx_only) {
1537 zilog_info("probe of IR Tx on %s (i2c-%d) done. Waiting"
1538 " on IR Rx.\n", adap->name, adap->nr);
1539 goto out_ok;
1540 }
1337 } else { 1541 } else {
1542 /* Get the IR_tx instance for later, if already allocated */
1543 tx = get_ir_tx(ir);
1544
1338 /* Set up a struct IR_rx instance */ 1545 /* Set up a struct IR_rx instance */
1339 ir->rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL); 1546 rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL);
1340 if (ir->rx == NULL) { 1547 if (rx == NULL) {
1341 ret = -ENOMEM; 1548 ret = -ENOMEM;
1342 goto out_free_xx; 1549 goto out_put_xx;
1343 } 1550 }
1551 kref_init(&rx->ref);
1552 ir->rx = rx;
1344 1553
1345 ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2); 1554 ir->l.features |= LIRC_CAN_REC_LIRCCODE;
1346 if (ret) 1555 mutex_init(&rx->client_lock);
1347 goto out_free_xx; 1556 rx->c = client;
1348 1557 rx->hdpvr_data_fmt =
1349 mutex_init(&ir->rx->buf_lock);
1350 ir->rx->c = client;
1351 ir->rx->hdpvr_data_fmt =
1352 (id->driver_data & ID_FLAG_HDPVR) ? true : false; 1558 (id->driver_data & ID_FLAG_HDPVR) ? true : false;
1353 1559
1354 /* set lirc_dev stuff */ 1560 /* An ir ref goes to the struct IR_rx instance */
1355 ir->l.rbuf = &ir->rx->buf; 1561 rx->ir = get_ir_device(ir, true);
1356 }
1357
1358 i2c_set_clientdata(client, ir);
1359 1562
1360 /* Proceed only if we have the required Tx and Rx clients ready to go */ 1563 /* An rx ref goes to the i2c_client */
1361 if (ir->tx == NULL || 1564 i2c_set_clientdata(client, get_ir_rx(ir));
1362 (ir->rx == NULL && !tx_only)) {
1363 zilog_info("probe of IR %s on %s (i2c-%d) done. Waiting on "
1364 "IR %s.\n", tx_probe ? "Tx" : "Rx", adap->name,
1365 adap->nr, tx_probe ? "Rx" : "Tx");
1366 goto out_ok;
1367 }
1368 1565
1369 /* initialise RX device */ 1566 /*
1370 if (ir->rx != NULL) { 1567 * Start the polling thread.
1371 /* try to fire up polling thread */ 1568 * It will only perform an empty loop around schedule_timeout()
1372 ir->rx->task = kthread_run(lirc_thread, ir, 1569 * until we register with lirc_dev and the first user open()
1373 "zilog-rx-i2c-%d", adap->nr); 1570 */
1374 if (IS_ERR(ir->rx->task)) { 1571 /* An ir ref goes to the new rx polling kthread */
1375 ret = PTR_ERR(ir->rx->task); 1572 rx->task = kthread_run(lirc_thread, get_ir_device(ir, true),
1573 "zilog-rx-i2c-%d", adap->nr);
1574 if (IS_ERR(rx->task)) {
1575 ret = PTR_ERR(rx->task);
1376 zilog_error("%s: could not start IR Rx polling thread" 1576 zilog_error("%s: could not start IR Rx polling thread"
1377 "\n", __func__); 1577 "\n", __func__);
1378 goto out_free_xx; 1578 /* Failed kthread, so put back the ir ref */
1579 put_ir_device(ir, true);
1580 /* Failure exit, so put back rx ref from i2c_client */
1581 i2c_set_clientdata(client, NULL);
1582 put_ir_rx(rx, true);
1583 ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
1584 goto out_put_xx;
1585 }
1586
1587 /* Proceed only if the Tx client is also ready */
1588 if (tx == NULL) {
1589 zilog_info("probe of IR Rx on %s (i2c-%d) done. Waiting"
1590 " on IR Tx.\n", adap->name, adap->nr);
1591 goto out_ok;
1379 } 1592 }
1380 } 1593 }
1381 1594
1382 /* register with lirc */ 1595 /* register with lirc */
1596 ir->l.minor = minor; /* module option: user requested minor number */
1383 ir->l.minor = lirc_register_driver(&ir->l); 1597 ir->l.minor = lirc_register_driver(&ir->l);
1384 if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { 1598 if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) {
1385 zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n", 1599 zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n",
1386 __func__, MAX_IRCTL_DEVICES-1, ir->l.minor); 1600 __func__, MAX_IRCTL_DEVICES-1, ir->l.minor);
1387 ret = -EBADRQC; 1601 ret = -EBADRQC;
1388 goto out_free_thread; 1602 goto out_put_xx;
1389 } 1603 }
1604 zilog_info("IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
1605 adap->name, adap->nr, ir->l.minor);
1390 1606
1391 /*
1392 * if we have the tx device, load the 'firmware'. We do this
1393 * after registering with lirc as otherwise hotplug seems to take
1394 * 10s to create the lirc device.
1395 */
1396 ret = tx_init(ir->tx);
1397 if (ret != 0)
1398 goto out_unregister;
1399
1400 zilog_info("probe of IR %s on %s (i2c-%d) done. IR unit ready.\n",
1401 tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
1402out_ok: 1607out_ok:
1608 if (rx != NULL)
1609 put_ir_rx(rx, true);
1610 if (tx != NULL)
1611 put_ir_tx(tx, true);
1612 put_ir_device(ir, true);
1613 zilog_info("probe of IR %s on %s (i2c-%d) done\n",
1614 tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
1403 mutex_unlock(&ir_devices_lock); 1615 mutex_unlock(&ir_devices_lock);
1404 return 0; 1616 return 0;
1405 1617
1406out_unregister: 1618out_put_xx:
1407 lirc_unregister_driver(ir->l.minor); 1619 if (rx != NULL)
1408out_free_thread: 1620 put_ir_rx(rx, true);
1409 destroy_rx_kthread(ir->rx); 1621 if (tx != NULL)
1410out_free_xx: 1622 put_ir_tx(tx, true);
1411 if (ir->rx != NULL) { 1623out_put_ir:
1412 if (ir->rx->buf.fifo_initialized) 1624 put_ir_device(ir, true);
1413 lirc_buffer_free(&ir->rx->buf);
1414 if (ir->rx->c != NULL)
1415 i2c_set_clientdata(ir->rx->c, NULL);
1416 kfree(ir->rx);
1417 }
1418 if (ir->tx != NULL) {
1419 if (ir->tx->c != NULL)
1420 i2c_set_clientdata(ir->tx->c, NULL);
1421 kfree(ir->tx);
1422 }
1423out_free_ir:
1424 del_ir_device(ir);
1425 kfree(ir);
1426out_no_ir: 1625out_no_ir:
1427 zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n", 1626 zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n",
1428 __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, 1627 __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr,
@@ -1438,7 +1637,6 @@ static int __init zilog_init(void)
1438 zilog_notify("Zilog/Hauppauge IR driver initializing\n"); 1637 zilog_notify("Zilog/Hauppauge IR driver initializing\n");
1439 1638
1440 mutex_init(&tx_data_lock); 1639 mutex_init(&tx_data_lock);
1441 mutex_init(&ir_devices_lock);
1442 1640
1443 request_module("firmware_class"); 1641 request_module("firmware_class");
1444 1642
diff --git a/drivers/staging/se401/Kconfig b/drivers/staging/se401/Kconfig
deleted file mode 100644
index b7f8222ad21b..000000000000
--- a/drivers/staging/se401/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
1config USB_SE401
2 tristate "USB SE401 Camera support (DEPRECATED)"
3 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && USB
4 ---help---
5 Say Y here if you want to connect this type of camera to your
6 computer's USB port. See <file:Documentation/video4linux/se401.txt>
7 for more information and for a list of supported cameras.
8
9 This driver uses the deprecated V4L1 API and will be removed in
10 2.6.39, unless someone converts it to the V4L2 API.
11
12 To compile this driver as a module, choose M here: the
13 module will be called se401.
diff --git a/drivers/staging/se401/Makefile b/drivers/staging/se401/Makefile
deleted file mode 100644
index b465d49783af..000000000000
--- a/drivers/staging/se401/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_USB_SE401) += se401.o
diff --git a/drivers/staging/se401/TODO b/drivers/staging/se401/TODO
deleted file mode 100644
index 3b2c03836286..000000000000
--- a/drivers/staging/se401/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1This is an obsolete driver for some old webcams that still use V4L1 API.
2As V4L1 support is being removed from kernel, if nobody take care on it,
3the driver will be removed for 2.6.39.
4
5Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/se401/se401.c b/drivers/staging/se401/se401.c
deleted file mode 100644
index 41360d7c3e96..000000000000
--- a/drivers/staging/se401/se401.c
+++ /dev/null
@@ -1,1492 +0,0 @@
1/*
2 * Endpoints (formerly known as AOX) se401 USB Camera Driver
3 *
4 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
5 *
6 * Still somewhat based on the Linux ov511 driver.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on
24 * their chipset available and supporting me while writing this driver.
25 * - Jeroen Vreeken
26 */
27
28static const char version[] = "0.24";
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/vmalloc.h>
33#include <linux/slab.h>
34#include <linux/pagemap.h>
35#include <linux/usb.h>
36#include "se401.h"
37
38static int flickerless;
39static int video_nr = -1;
40
41static struct usb_device_id device_table[] = {
42 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
43 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
44 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
45 { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
46 { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
47 { }
48};
49
50MODULE_DEVICE_TABLE(usb, device_table);
51
52MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
53MODULE_DESCRIPTION("SE401 USB Camera Driver");
54MODULE_LICENSE("GPL");
55module_param(flickerless, int, 0);
56MODULE_PARM_DESC(flickerless,
57 "Net frequency to adjust exposure time to (0/50/60)");
58module_param(video_nr, int, 0);
59
60static struct usb_driver se401_driver;
61
62
63/**********************************************************************
64 *
65 * Memory management
66 *
67 **********************************************************************/
68static void *rvmalloc(unsigned long size)
69{
70 void *mem;
71 unsigned long adr;
72
73 size = PAGE_ALIGN(size);
74 mem = vmalloc_32(size);
75 if (!mem)
76 return NULL;
77
78 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
79 adr = (unsigned long) mem;
80 while (size > 0) {
81 SetPageReserved(vmalloc_to_page((void *)adr));
82 adr += PAGE_SIZE;
83 size -= PAGE_SIZE;
84 }
85
86 return mem;
87}
88
89static void rvfree(void *mem, unsigned long size)
90{
91 unsigned long adr;
92
93 if (!mem)
94 return;
95
96 adr = (unsigned long) mem;
97 while ((long) size > 0) {
98 ClearPageReserved(vmalloc_to_page((void *)adr));
99 adr += PAGE_SIZE;
100 size -= PAGE_SIZE;
101 }
102 vfree(mem);
103}
104
105
106
107/****************************************************************************
108 *
109 * se401 register read/write functions
110 *
111 ***************************************************************************/
112
113static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
114 unsigned short value, unsigned char *cp, int size)
115{
116 return usb_control_msg(
117 se401->dev,
118 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
119 req,
120 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
121 value,
122 0,
123 cp,
124 size,
125 1000
126 );
127}
128
129static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
130 unsigned short param)
131{
132 /* specs say that the selector (address) should go in the value field
133 and the param in index, but in the logs of the windows driver they do
134 this the other way around...
135 */
136 return usb_control_msg(
137 se401->dev,
138 usb_sndctrlpipe(se401->dev, 0),
139 SE401_REQ_SET_EXT_FEATURE,
140 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
141 param,
142 selector,
143 NULL,
144 0,
145 1000
146 );
147}
148
149static unsigned short se401_get_feature(struct usb_se401 *se401,
150 unsigned short selector)
151{
152 /* For 'set' the selecetor should be in index, not sure if the spec is
153 wrong here to....
154 */
155 unsigned char cp[2];
156 usb_control_msg(
157 se401->dev,
158 usb_rcvctrlpipe(se401->dev, 0),
159 SE401_REQ_GET_EXT_FEATURE,
160 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
161 0,
162 selector,
163 cp,
164 2,
165 1000
166 );
167 return cp[0]+cp[1]*256;
168}
169
170/****************************************************************************
171 *
172 * Camera control
173 *
174 ***************************************************************************/
175
176
177static int se401_send_pict(struct usb_se401 *se401)
178{
179 /* integration time low */
180 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);
181 /* integration time mid */
182 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);
183 /* integration time mid */
184 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);
185 /* reset level value */
186 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
187 /* red color gain */
188 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);
189 /* green color gain */
190 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);
191 /* blue color gain */
192 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);
193
194 return 0;
195}
196
197static void se401_set_exposure(struct usb_se401 *se401, int brightness)
198{
199 int integration = brightness << 5;
200
201 if (flickerless == 50)
202 integration = integration-integration % 106667;
203 if (flickerless == 60)
204 integration = integration-integration % 88889;
205 se401->brightness = integration >> 5;
206 se401->expose_h = (integration >> 16) & 0xff;
207 se401->expose_m = (integration >> 8) & 0xff;
208 se401->expose_l = integration & 0xff;
209}
210
211static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
212{
213 p->brightness = se401->brightness;
214 if (se401->enhance)
215 p->whiteness = 32768;
216 else
217 p->whiteness = 0;
218
219 p->colour = 65535;
220 p->contrast = 65535;
221 p->hue = se401->rgain << 10;
222 p->palette = se401->palette;
223 p->depth = 3; /* rgb24 */
224 return 0;
225}
226
227
228static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
229{
230 if (p->palette != VIDEO_PALETTE_RGB24)
231 return 1;
232 se401->palette = p->palette;
233 if (p->hue != se401->hue) {
234 se401->rgain = p->hue >> 10;
235 se401->bgain = 0x40-(p->hue >> 10);
236 se401->hue = p->hue;
237 }
238 if (p->brightness != se401->brightness)
239 se401_set_exposure(se401, p->brightness);
240
241 if (p->whiteness >= 32768)
242 se401->enhance = 1;
243 else
244 se401->enhance = 0;
245 se401_send_pict(se401);
246 se401_send_pict(se401);
247 return 0;
248}
249
250/*
251 Hyundai have some really nice docs about this and other sensor related
252 stuff on their homepage: www.hei.co.kr
253*/
254static void se401_auto_resetlevel(struct usb_se401 *se401)
255{
256 unsigned int ahrc, alrc;
257 int oldreset = se401->resetlevel;
258
259 /* For some reason this normally read-only register doesn't get reset
260 to zero after reading them just once...
261 */
262 se401_get_feature(se401, HV7131_REG_HIREFNOH);
263 se401_get_feature(se401, HV7131_REG_HIREFNOL);
264 se401_get_feature(se401, HV7131_REG_LOREFNOH);
265 se401_get_feature(se401, HV7131_REG_LOREFNOL);
266 ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
267 se401_get_feature(se401, HV7131_REG_HIREFNOL);
268 alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
269 se401_get_feature(se401, HV7131_REG_LOREFNOL);
270
271 /* Not an exact science, but it seems to work pretty well... */
272 if (alrc > 10) {
273 while (alrc >= 10 && se401->resetlevel < 63) {
274 se401->resetlevel++;
275 alrc /= 2;
276 }
277 } else if (ahrc > 20) {
278 while (ahrc >= 20 && se401->resetlevel > 0) {
279 se401->resetlevel--;
280 ahrc /= 2;
281 }
282 }
283 if (se401->resetlevel != oldreset)
284 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
285
286 return;
287}
288
289/* irq handler for snapshot button */
290static void se401_button_irq(struct urb *urb)
291{
292 struct usb_se401 *se401 = urb->context;
293 int status;
294
295 if (!se401->dev) {
296 dev_info(&urb->dev->dev, "device vapourished\n");
297 return;
298 }
299
300 switch (urb->status) {
301 case 0:
302 /* success */
303 break;
304 case -ECONNRESET:
305 case -ENOENT:
306 case -ESHUTDOWN:
307 /* this urb is terminated, clean up */
308 dbg("%s - urb shutting down with status: %d",
309 __func__, urb->status);
310 return;
311 default:
312 dbg("%s - nonzero urb status received: %d",
313 __func__, urb->status);
314 goto exit;
315 }
316
317 if (urb->actual_length >= 2)
318 if (se401->button)
319 se401->buttonpressed = 1;
320exit:
321 status = usb_submit_urb(urb, GFP_ATOMIC);
322 if (status)
323 err("%s - usb_submit_urb failed with result %d",
324 __func__, status);
325}
326
327static void se401_video_irq(struct urb *urb)
328{
329 struct usb_se401 *se401 = urb->context;
330 int length = urb->actual_length;
331
332 /* ohoh... */
333 if (!se401->streaming)
334 return;
335
336 if (!se401->dev) {
337 dev_info(&urb->dev->dev, "device vapourished\n");
338 return;
339 }
340
341 /* 0 sized packets happen if we are to fast, but sometimes the camera
342 keeps sending them forever...
343 */
344 if (length && !urb->status) {
345 se401->nullpackets = 0;
346 switch (se401->scratch[se401->scratch_next].state) {
347 case BUFFER_READY:
348 case BUFFER_BUSY:
349 se401->dropped++;
350 break;
351 case BUFFER_UNUSED:
352 memcpy(se401->scratch[se401->scratch_next].data,
353 (unsigned char *)urb->transfer_buffer, length);
354 se401->scratch[se401->scratch_next].state
355 = BUFFER_READY;
356 se401->scratch[se401->scratch_next].offset
357 = se401->bayeroffset;
358 se401->scratch[se401->scratch_next].length = length;
359 if (waitqueue_active(&se401->wq))
360 wake_up_interruptible(&se401->wq);
361 se401->scratch_overflow = 0;
362 se401->scratch_next++;
363 if (se401->scratch_next >= SE401_NUMSCRATCH)
364 se401->scratch_next = 0;
365 break;
366 }
367 se401->bayeroffset += length;
368 if (se401->bayeroffset >= se401->cheight * se401->cwidth)
369 se401->bayeroffset = 0;
370 } else {
371 se401->nullpackets++;
372 if (se401->nullpackets > SE401_MAX_NULLPACKETS)
373 if (waitqueue_active(&se401->wq))
374 wake_up_interruptible(&se401->wq);
375 }
376
377 /* Resubmit urb for new data */
378 urb->status = 0;
379 urb->dev = se401->dev;
380 if (usb_submit_urb(urb, GFP_KERNEL))
381 dev_info(&urb->dev->dev, "urb burned down\n");
382 return;
383}
384
385static void se401_send_size(struct usb_se401 *se401, int width, int height)
386{
387 int i = 0;
388 int mode = 0x03; /* No compression */
389 int sendheight = height;
390 int sendwidth = width;
391
392 /* JangGu compression can only be used with the camera supported sizes,
393 but bayer seems to work with any size that fits on the sensor.
394 We check if we can use compression with the current size with either
395 4 or 16 times subcapturing, if not we use uncompressed bayer data
396 but this will result in cutouts of the maximum size....
397 */
398 while (i < se401->sizes && !(se401->width[i] == width &&
399 se401->height[i] == height))
400 i++;
401 while (i < se401->sizes) {
402 if (se401->width[i] == width * 2 &&
403 se401->height[i] == height * 2) {
404 sendheight = se401->height[i];
405 sendwidth = se401->width[i];
406 mode = 0x40;
407 }
408 if (se401->width[i] == width * 4 &&
409 se401->height[i] == height * 4) {
410 sendheight = se401->height[i];
411 sendwidth = se401->width[i];
412 mode = 0x42;
413 }
414 i++;
415 }
416
417 se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
418 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
419 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
420
421 if (mode == 0x03)
422 se401->format = FMT_BAYER;
423 else
424 se401->format = FMT_JANGGU;
425}
426
427/*
428 In this function se401_send_pict is called several times,
429 for some reason (depending on the state of the sensor and the phase of
430 the moon :) doing this only in either place doesn't always work...
431*/
432static int se401_start_stream(struct usb_se401 *se401)
433{
434 struct urb *urb;
435 int err = 0, i;
436 se401->streaming = 1;
437
438 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
439 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
440
441 /* Set picture settings */
442 /* windowed + pix intg */
443 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);
444 se401_send_pict(se401);
445
446 se401_send_size(se401, se401->cwidth, se401->cheight);
447
448 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE,
449 0, NULL, 0);
450
451 /* Do some memory allocation */
452 for (i = 0; i < SE401_NUMFRAMES; i++) {
453 se401->frame[i].data = se401->fbuf + i * se401->maxframesize;
454 se401->frame[i].curpix = 0;
455 }
456 for (i = 0; i < SE401_NUMSBUF; i++) {
457 se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
458 if (!se401->sbuf[i].data) {
459 for (i = i - 1; i >= 0; i--) {
460 kfree(se401->sbuf[i].data);
461 se401->sbuf[i].data = NULL;
462 }
463 return -ENOMEM;
464 }
465 }
466
467 se401->bayeroffset = 0;
468 se401->scratch_next = 0;
469 se401->scratch_use = 0;
470 se401->scratch_overflow = 0;
471 for (i = 0; i < SE401_NUMSCRATCH; i++) {
472 se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
473 if (!se401->scratch[i].data) {
474 for (i = i - 1; i >= 0; i--) {
475 kfree(se401->scratch[i].data);
476 se401->scratch[i].data = NULL;
477 }
478 goto nomem_sbuf;
479 }
480 se401->scratch[i].state = BUFFER_UNUSED;
481 }
482
483 for (i = 0; i < SE401_NUMSBUF; i++) {
484 urb = usb_alloc_urb(0, GFP_KERNEL);
485 if (!urb) {
486 for (i = i - 1; i >= 0; i--) {
487 usb_kill_urb(se401->urb[i]);
488 usb_free_urb(se401->urb[i]);
489 se401->urb[i] = NULL;
490 }
491 goto nomem_scratch;
492 }
493
494 usb_fill_bulk_urb(urb, se401->dev,
495 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
496 se401->sbuf[i].data, SE401_PACKETSIZE,
497 se401_video_irq,
498 se401);
499
500 se401->urb[i] = urb;
501
502 err = usb_submit_urb(se401->urb[i], GFP_KERNEL);
503 if (err)
504 err("urb burned down");
505 }
506
507 se401->framecount = 0;
508
509 return 0;
510
511 nomem_scratch:
512 for (i = 0; i < SE401_NUMSCRATCH; i++) {
513 kfree(se401->scratch[i].data);
514 se401->scratch[i].data = NULL;
515 }
516 nomem_sbuf:
517 for (i = 0; i < SE401_NUMSBUF; i++) {
518 kfree(se401->sbuf[i].data);
519 se401->sbuf[i].data = NULL;
520 }
521 return -ENOMEM;
522}
523
524static int se401_stop_stream(struct usb_se401 *se401)
525{
526 int i;
527
528 if (!se401->streaming || !se401->dev)
529 return 1;
530
531 se401->streaming = 0;
532
533 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
534
535 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
536 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
537
538 for (i = 0; i < SE401_NUMSBUF; i++)
539 if (se401->urb[i]) {
540 usb_kill_urb(se401->urb[i]);
541 usb_free_urb(se401->urb[i]);
542 se401->urb[i] = NULL;
543 kfree(se401->sbuf[i].data);
544 }
545 for (i = 0; i < SE401_NUMSCRATCH; i++) {
546 kfree(se401->scratch[i].data);
547 se401->scratch[i].data = NULL;
548 }
549
550 return 0;
551}
552
553static int se401_set_size(struct usb_se401 *se401, int width, int height)
554{
555 int wasstreaming = se401->streaming;
556 /* Check to see if we need to change */
557 if (se401->cwidth == width && se401->cheight == height)
558 return 0;
559
560 /* Check for a valid mode */
561 if (!width || !height)
562 return 1;
563 if ((width & 1) || (height & 1))
564 return 1;
565 if (width > se401->width[se401->sizes-1])
566 return 1;
567 if (height > se401->height[se401->sizes-1])
568 return 1;
569
570 /* Stop a current stream and start it again at the new size */
571 if (wasstreaming)
572 se401_stop_stream(se401);
573 se401->cwidth = width;
574 se401->cheight = height;
575 if (wasstreaming)
576 se401_start_stream(se401);
577 return 0;
578}
579
580
581/****************************************************************************
582 *
583 * Video Decoding
584 *
585 ***************************************************************************/
586
587/*
588 This shouldn't really be done in a v4l driver....
589 But it does make the image look a lot more usable.
590 Basically it lifts the dark pixels more than the light pixels.
591*/
592static inline void enhance_picture(unsigned char *frame, int len)
593{
594 while (len--) {
595 *frame = (((*frame^255)*(*frame^255))/255)^255;
596 frame++;
597 }
598}
599
600static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
601{
602 struct se401_frame *frame = &se401->frame[se401->curframe];
603 int linelength = se401->cwidth * 3;
604
605 if (frame->curlinepix >= linelength) {
606 frame->curlinepix = 0;
607 frame->curline += linelength;
608 }
609
610 /* First three are absolute, all others relative.
611 * Format is rgb from right to left (mirrorred image),
612 * we flip it to get bgr from left to right. */
613 if (frame->curlinepix < 3)
614 *(frame->curline-frame->curlinepix) = 1 + data * 4;
615 else
616 *(frame->curline-frame->curlinepix) =
617 *(frame->curline-frame->curlinepix + 3) + data * 4;
618 frame->curlinepix++;
619}
620
621static inline void decode_JangGu_vlc(struct usb_se401 *se401,
622 unsigned char *data, int bit_exp, int packetlength)
623{
624 int pos = 0;
625 int vlc_cod = 0;
626 int vlc_size = 0;
627 int vlc_data = 0;
628 int bit_cur;
629 int bit;
630 data += 4;
631 while (pos < packetlength) {
632 bit_cur = 8;
633 while (bit_cur && bit_exp) {
634 bit = ((*data) >> (bit_cur-1))&1;
635 if (!vlc_cod) {
636 if (bit) {
637 vlc_size++;
638 } else {
639 if (!vlc_size)
640 decode_JangGu_integrate(se401, 0);
641 else {
642 vlc_cod = 2;
643 vlc_data = 0;
644 }
645 }
646 } else {
647 if (vlc_cod == 2) {
648 if (!bit)
649 vlc_data = -(1 << vlc_size) + 1;
650 vlc_cod--;
651 }
652 vlc_size--;
653 vlc_data += bit << vlc_size;
654 if (!vlc_size) {
655 decode_JangGu_integrate(se401, vlc_data);
656 vlc_cod = 0;
657 }
658 }
659 bit_cur--;
660 bit_exp--;
661 }
662 pos++;
663 data++;
664 }
665}
666
667static inline void decode_JangGu(struct usb_se401 *se401,
668 struct se401_scratch *buffer)
669{
670 unsigned char *data = buffer->data;
671 int len = buffer->length;
672 int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size;
673 int datapos = 0;
674
675 /* New image? */
676 if (!se401->frame[se401->curframe].curpix) {
677 se401->frame[se401->curframe].curlinepix = 0;
678 se401->frame[se401->curframe].curline =
679 se401->frame[se401->curframe].data+
680 se401->cwidth * 3 - 1;
681 if (se401->frame[se401->curframe].grabstate == FRAME_READY)
682 se401->frame[se401->curframe].grabstate = FRAME_GRABBING;
683 se401->vlcdatapos = 0;
684 }
685 while (datapos < len) {
686 size = 1024 - se401->vlcdatapos;
687 if (size+datapos > len)
688 size = len-datapos;
689 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
690 se401->vlcdatapos += size;
691 packetlength = 0;
692 if (se401->vlcdatapos >= 4) {
693 bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8);
694 pix_exp = se401->vlcdata[1] +
695 ((se401->vlcdata[0] & 0x3f) << 8);
696 frameinfo = se401->vlcdata[0] & 0xc0;
697 packetlength = ((bit_exp + 47) >> 4) << 1;
698 if (packetlength > 1024) {
699 se401->vlcdatapos = 0;
700 datapos = len;
701 packetlength = 0;
702 se401->error++;
703 se401->frame[se401->curframe].curpix = 0;
704 }
705 }
706 if (packetlength && se401->vlcdatapos >= packetlength) {
707 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp,
708 packetlength);
709 se401->frame[se401->curframe].curpix += pix_exp * 3;
710 datapos += size-(se401->vlcdatapos-packetlength);
711 se401->vlcdatapos = 0;
712 if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) {
713 if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) {
714 if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) {
715 se401->frame[se401->curframe].grabstate = FRAME_DONE;
716 se401->framecount++;
717 se401->readcount++;
718 }
719 if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY)
720 se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1);
721 } else
722 se401->error++;
723 se401->frame[se401->curframe].curpix = 0;
724 datapos = len;
725 }
726 } else
727 datapos += size;
728 }
729}
730
731static inline void decode_bayer(struct usb_se401 *se401,
732 struct se401_scratch *buffer)
733{
734 unsigned char *data = buffer->data;
735 int len = buffer->length;
736 int offset = buffer->offset;
737 int datasize = se401->cwidth * se401->cheight;
738 struct se401_frame *frame = &se401->frame[se401->curframe];
739 unsigned char *framedata = frame->data, *curline, *nextline;
740 int width = se401->cwidth;
741 int blineoffset = 0, bline;
742 int linelength = width * 3, i;
743
744
745 if (frame->curpix == 0) {
746 if (frame->grabstate == FRAME_READY)
747 frame->grabstate = FRAME_GRABBING;
748
749 frame->curline = framedata + linelength;
750 frame->curlinepix = 0;
751 }
752
753 if (offset != frame->curpix) {
754 /* Regard frame as lost :( */
755 frame->curpix = 0;
756 se401->error++;
757 return;
758 }
759
760 /* Check if we have to much data */
761 if (frame->curpix + len > datasize)
762 len = datasize-frame->curpix;
763
764 if (se401->cheight % 4)
765 blineoffset = 1;
766 bline = frame->curpix / se401->cwidth+blineoffset;
767
768 curline = frame->curline;
769 nextline = curline + linelength;
770 if (nextline >= framedata+datasize * 3)
771 nextline = curline;
772 while (len) {
773 if (frame->curlinepix >= width) {
774 frame->curlinepix -= width;
775 bline = frame->curpix / width + blineoffset;
776 curline += linelength*2;
777 nextline += linelength*2;
778 if (curline >= framedata+datasize * 3) {
779 frame->curlinepix++;
780 curline -= 3;
781 nextline -= 3;
782 len--;
783 data++;
784 frame->curpix++;
785 }
786 if (nextline >= framedata+datasize*3)
787 nextline = curline;
788 }
789 if (bline & 1) {
790 if (frame->curlinepix & 1) {
791 *(curline + 2) = *data;
792 *(curline - 1) = *data;
793 *(nextline + 2) = *data;
794 *(nextline - 1) = *data;
795 } else {
796 *(curline + 1) =
797 (*(curline + 1) + *data) / 2;
798 *(curline-2) =
799 (*(curline - 2) + *data) / 2;
800 *(nextline + 1) = *data;
801 *(nextline - 2) = *data;
802 }
803 } else {
804 if (frame->curlinepix & 1) {
805 *(curline + 1) =
806 (*(curline + 1) + *data) / 2;
807 *(curline - 2) =
808 (*(curline - 2) + *data) / 2;
809 *(nextline + 1) = *data;
810 *(nextline - 2) = *data;
811 } else {
812 *curline = *data;
813 *(curline - 3) = *data;
814 *nextline = *data;
815 *(nextline - 3) = *data;
816 }
817 }
818 frame->curlinepix++;
819 curline -= 3;
820 nextline -= 3;
821 len--;
822 data++;
823 frame->curpix++;
824 }
825 frame->curline = curline;
826
827 if (frame->curpix >= datasize) {
828 /* Fix the top line */
829 framedata += linelength;
830 for (i = 0; i < linelength; i++) {
831 framedata--;
832 *framedata = *(framedata + linelength);
833 }
834 /* Fix the left side (green is already present) */
835 for (i = 0; i < se401->cheight; i++) {
836 *framedata = *(framedata + 3);
837 *(framedata + 1) = *(framedata + 4);
838 *(framedata + 2) = *(framedata + 5);
839 framedata += linelength;
840 }
841 frame->curpix = 0;
842 frame->grabstate = FRAME_DONE;
843 se401->framecount++;
844 se401->readcount++;
845 if (se401->frame[(se401->curframe + 1) &
846 (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) {
847 se401->curframe = (se401->curframe+1) &
848 (SE401_NUMFRAMES-1);
849 }
850 }
851}
852
853static int se401_newframe(struct usb_se401 *se401, int framenr)
854{
855 DECLARE_WAITQUEUE(wait, current);
856 int errors = 0;
857
858 while (se401->streaming &&
859 (se401->frame[framenr].grabstate == FRAME_READY ||
860 se401->frame[framenr].grabstate == FRAME_GRABBING)) {
861 if (!se401->frame[framenr].curpix)
862 errors++;
863
864 wait_interruptible(
865 se401->scratch[se401->scratch_use].state != BUFFER_READY,
866 &se401->wq, &wait);
867 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
868 se401->nullpackets = 0;
869 dev_info(&se401->dev->dev,
870 "too many null length packets, restarting capture\n");
871 se401_stop_stream(se401);
872 se401_start_stream(se401);
873 } else {
874 if (se401->scratch[se401->scratch_use].state !=
875 BUFFER_READY) {
876 se401->frame[framenr].grabstate = FRAME_ERROR;
877 return -EIO;
878 }
879 se401->scratch[se401->scratch_use].state = BUFFER_BUSY;
880 if (se401->format == FMT_JANGGU)
881 decode_JangGu(se401,
882 &se401->scratch[se401->scratch_use]);
883 else
884 decode_bayer(se401,
885 &se401->scratch[se401->scratch_use]);
886
887 se401->scratch[se401->scratch_use].state =
888 BUFFER_UNUSED;
889 se401->scratch_use++;
890 if (se401->scratch_use >= SE401_NUMSCRATCH)
891 se401->scratch_use = 0;
892 if (errors > SE401_MAX_ERRORS) {
893 errors = 0;
894 dev_info(&se401->dev->dev,
895 "too many errors, restarting capture\n");
896 se401_stop_stream(se401);
897 se401_start_stream(se401);
898 }
899 }
900 }
901
902 if (se401->frame[framenr].grabstate == FRAME_DONE)
903 if (se401->enhance)
904 enhance_picture(se401->frame[framenr].data,
905 se401->cheight * se401->cwidth * 3);
906 return 0;
907}
908
909static void usb_se401_remove_disconnected(struct usb_se401 *se401)
910{
911 int i;
912
913 se401->dev = NULL;
914
915 for (i = 0; i < SE401_NUMSBUF; i++)
916 if (se401->urb[i]) {
917 usb_kill_urb(se401->urb[i]);
918 usb_free_urb(se401->urb[i]);
919 se401->urb[i] = NULL;
920 kfree(se401->sbuf[i].data);
921 }
922
923 for (i = 0; i < SE401_NUMSCRATCH; i++)
924 kfree(se401->scratch[i].data);
925
926 if (se401->inturb) {
927 usb_kill_urb(se401->inturb);
928 usb_free_urb(se401->inturb);
929 }
930 dev_info(&se401->dev->dev, "%s disconnected", se401->camera_name);
931
932 /* Free the memory */
933 kfree(se401->width);
934 kfree(se401->height);
935 kfree(se401);
936}
937
938
939
940/****************************************************************************
941 *
942 * Video4Linux
943 *
944 ***************************************************************************/
945
946
947static int se401_open(struct file *file)
948{
949 struct video_device *dev = video_devdata(file);
950 struct usb_se401 *se401 = (struct usb_se401 *)dev;
951 int err = 0;
952
953 mutex_lock(&se401->lock);
954 if (se401->user) {
955 mutex_unlock(&se401->lock);
956 return -EBUSY;
957 }
958 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
959 if (se401->fbuf)
960 file->private_data = dev;
961 else
962 err = -ENOMEM;
963 se401->user = !err;
964 mutex_unlock(&se401->lock);
965
966 return err;
967}
968
969static int se401_close(struct file *file)
970{
971 struct video_device *dev = file->private_data;
972 struct usb_se401 *se401 = (struct usb_se401 *)dev;
973 int i;
974
975 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
976 if (se401->removed) {
977 dev_info(&se401->dev->dev, "device unregistered\n");
978 usb_se401_remove_disconnected(se401);
979 } else {
980 for (i = 0; i < SE401_NUMFRAMES; i++)
981 se401->frame[i].grabstate = FRAME_UNUSED;
982 if (se401->streaming)
983 se401_stop_stream(se401);
984 se401->user = 0;
985 }
986 file->private_data = NULL;
987 return 0;
988}
989
990static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
991{
992 struct video_device *vdev = file->private_data;
993 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
994
995 if (!se401->dev)
996 return -EIO;
997
998 switch (cmd) {
999 case VIDIOCGCAP:
1000 {
1001 struct video_capability *b = arg;
1002 strcpy(b->name, se401->camera_name);
1003 b->type = VID_TYPE_CAPTURE;
1004 b->channels = 1;
1005 b->audios = 0;
1006 b->maxwidth = se401->width[se401->sizes-1];
1007 b->maxheight = se401->height[se401->sizes-1];
1008 b->minwidth = se401->width[0];
1009 b->minheight = se401->height[0];
1010 return 0;
1011 }
1012 case VIDIOCGCHAN:
1013 {
1014 struct video_channel *v = arg;
1015
1016 if (v->channel != 0)
1017 return -EINVAL;
1018 v->flags = 0;
1019 v->tuners = 0;
1020 v->type = VIDEO_TYPE_CAMERA;
1021 strcpy(v->name, "Camera");
1022 return 0;
1023 }
1024 case VIDIOCSCHAN:
1025 {
1026 struct video_channel *v = arg;
1027
1028 if (v->channel != 0)
1029 return -EINVAL;
1030 return 0;
1031 }
1032 case VIDIOCGPICT:
1033 {
1034 struct video_picture *p = arg;
1035
1036 se401_get_pict(se401, p);
1037 return 0;
1038 }
1039 case VIDIOCSPICT:
1040 {
1041 struct video_picture *p = arg;
1042
1043 if (se401_set_pict(se401, p))
1044 return -EINVAL;
1045 return 0;
1046 }
1047 case VIDIOCSWIN:
1048 {
1049 struct video_window *vw = arg;
1050
1051 if (vw->flags)
1052 return -EINVAL;
1053 if (vw->clipcount)
1054 return -EINVAL;
1055 if (se401_set_size(se401, vw->width, vw->height))
1056 return -EINVAL;
1057 return 0;
1058 }
1059 case VIDIOCGWIN:
1060 {
1061 struct video_window *vw = arg;
1062
1063 vw->x = 0; /* FIXME */
1064 vw->y = 0;
1065 vw->chromakey = 0;
1066 vw->flags = 0;
1067 vw->clipcount = 0;
1068 vw->width = se401->cwidth;
1069 vw->height = se401->cheight;
1070 return 0;
1071 }
1072 case VIDIOCGMBUF:
1073 {
1074 struct video_mbuf *vm = arg;
1075 int i;
1076
1077 memset(vm, 0, sizeof(*vm));
1078 vm->size = SE401_NUMFRAMES * se401->maxframesize;
1079 vm->frames = SE401_NUMFRAMES;
1080 for (i = 0; i < SE401_NUMFRAMES; i++)
1081 vm->offsets[i] = se401->maxframesize * i;
1082 return 0;
1083 }
1084 case VIDIOCMCAPTURE:
1085 {
1086 struct video_mmap *vm = arg;
1087
1088 if (vm->format != VIDEO_PALETTE_RGB24)
1089 return -EINVAL;
1090 if (vm->frame >= SE401_NUMFRAMES)
1091 return -EINVAL;
1092 if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1093 return -EBUSY;
1094
1095 /* Is this according to the v4l spec??? */
1096 if (se401_set_size(se401, vm->width, vm->height))
1097 return -EINVAL;
1098 se401->frame[vm->frame].grabstate = FRAME_READY;
1099
1100 if (!se401->streaming)
1101 se401_start_stream(se401);
1102
1103 /* Set the picture properties */
1104 if (se401->framecount == 0)
1105 se401_send_pict(se401);
1106 /* Calibrate the reset level after a few frames. */
1107 if (se401->framecount % 20 == 1)
1108 se401_auto_resetlevel(se401);
1109
1110 return 0;
1111 }
1112 case VIDIOCSYNC:
1113 {
1114 int *frame = arg;
1115 int ret = 0;
1116
1117 if (*frame < 0 || *frame >= SE401_NUMFRAMES)
1118 return -EINVAL;
1119
1120 ret = se401_newframe(se401, *frame);
1121 se401->frame[*frame].grabstate = FRAME_UNUSED;
1122 return ret;
1123 }
1124 case VIDIOCGFBUF:
1125 {
1126 struct video_buffer *vb = arg;
1127
1128 memset(vb, 0, sizeof(*vb));
1129 return 0;
1130 }
1131 case VIDIOCKEY:
1132 return 0;
1133 case VIDIOCCAPTURE:
1134 return -EINVAL;
1135 case VIDIOCSFBUF:
1136 return -EINVAL;
1137 case VIDIOCGTUNER:
1138 case VIDIOCSTUNER:
1139 return -EINVAL;
1140 case VIDIOCGFREQ:
1141 case VIDIOCSFREQ:
1142 return -EINVAL;
1143 case VIDIOCGAUDIO:
1144 case VIDIOCSAUDIO:
1145 return -EINVAL;
1146 default:
1147 return -ENOIOCTLCMD;
1148 } /* end switch */
1149
1150 return 0;
1151}
1152
1153static long se401_ioctl(struct file *file,
1154 unsigned int cmd, unsigned long arg)
1155{
1156 return video_usercopy(file, cmd, arg, se401_do_ioctl);
1157}
1158
1159static ssize_t se401_read(struct file *file, char __user *buf,
1160 size_t count, loff_t *ppos)
1161{
1162 int realcount = count, ret = 0;
1163 struct video_device *dev = file->private_data;
1164 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1165
1166
1167 if (se401->dev == NULL)
1168 return -EIO;
1169 if (realcount > se401->cwidth*se401->cheight*3)
1170 realcount = se401->cwidth*se401->cheight*3;
1171
1172 /* Shouldn't happen: */
1173 if (se401->frame[0].grabstate == FRAME_GRABBING)
1174 return -EBUSY;
1175 se401->frame[0].grabstate = FRAME_READY;
1176 se401->frame[1].grabstate = FRAME_UNUSED;
1177 se401->curframe = 0;
1178
1179 if (!se401->streaming)
1180 se401_start_stream(se401);
1181
1182 /* Set the picture properties */
1183 if (se401->framecount == 0)
1184 se401_send_pict(se401);
1185 /* Calibrate the reset level after a few frames. */
1186 if (se401->framecount%20 == 1)
1187 se401_auto_resetlevel(se401);
1188
1189 ret = se401_newframe(se401, 0);
1190
1191 se401->frame[0].grabstate = FRAME_UNUSED;
1192 if (ret)
1193 return ret;
1194 if (copy_to_user(buf, se401->frame[0].data, realcount))
1195 return -EFAULT;
1196
1197 return realcount;
1198}
1199
1200static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1201{
1202 struct video_device *dev = file->private_data;
1203 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1204 unsigned long start = vma->vm_start;
1205 unsigned long size = vma->vm_end-vma->vm_start;
1206 unsigned long page, pos;
1207
1208 mutex_lock(&se401->lock);
1209
1210 if (se401->dev == NULL) {
1211 mutex_unlock(&se401->lock);
1212 return -EIO;
1213 }
1214 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1)
1215 & ~(PAGE_SIZE - 1))) {
1216 mutex_unlock(&se401->lock);
1217 return -EINVAL;
1218 }
1219 pos = (unsigned long)se401->fbuf;
1220 while (size > 0) {
1221 page = vmalloc_to_pfn((void *)pos);
1222 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1223 mutex_unlock(&se401->lock);
1224 return -EAGAIN;
1225 }
1226 start += PAGE_SIZE;
1227 pos += PAGE_SIZE;
1228 if (size > PAGE_SIZE)
1229 size -= PAGE_SIZE;
1230 else
1231 size = 0;
1232 }
1233 mutex_unlock(&se401->lock);
1234
1235 return 0;
1236}
1237
1238static const struct v4l2_file_operations se401_fops = {
1239 .owner = THIS_MODULE,
1240 .open = se401_open,
1241 .release = se401_close,
1242 .read = se401_read,
1243 .mmap = se401_mmap,
1244 .ioctl = se401_ioctl,
1245};
1246static struct video_device se401_template = {
1247 .name = "se401 USB camera",
1248 .fops = &se401_fops,
1249 .release = video_device_release_empty,
1250};
1251
1252
1253
1254/***************************/
1255static int se401_init(struct usb_se401 *se401, int button)
1256{
1257 int i = 0, rc;
1258 unsigned char cp[0x40];
1259 char temp[200];
1260 int slen;
1261
1262 /* led on */
1263 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1264
1265 /* get camera descriptor */
1266 rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0,
1267 cp, sizeof(cp));
1268 if (cp[1] != 0x41) {
1269 err("Wrong descriptor type");
1270 return 1;
1271 }
1272 slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]);
1273
1274 se401->sizes = cp[4] + cp[5] * 256;
1275 se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1276 if (!se401->width)
1277 return 1;
1278 se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1279 if (!se401->height) {
1280 kfree(se401->width);
1281 return 1;
1282 }
1283 for (i = 0; i < se401->sizes; i++) {
1284 se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256;
1285 se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256;
1286 }
1287 slen += snprintf(temp + slen, 200 - slen, " Sizes:");
1288 for (i = 0; i < se401->sizes; i++) {
1289 slen += snprintf(temp + slen, 200 - slen,
1290 " %dx%d", se401->width[i], se401->height[i]);
1291 }
1292 dev_info(&se401->dev->dev, "%s\n", temp);
1293 se401->maxframesize = se401->width[se401->sizes-1] *
1294 se401->height[se401->sizes - 1] * 3;
1295
1296 rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1297 se401->cwidth = cp[0]+cp[1]*256;
1298 rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1299 se401->cheight = cp[0]+cp[1]*256;
1300
1301 if (!(cp[2] & SE401_FORMAT_BAYER)) {
1302 err("Bayer format not supported!");
1303 return 1;
1304 }
1305 /* set output mode (BAYER) */
1306 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE,
1307 SE401_FORMAT_BAYER, NULL, 0);
1308
1309 rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1310 se401->brightness = cp[0]+cp[1]*256;
1311 /* some default values */
1312 se401->resetlevel = 0x2d;
1313 se401->rgain = 0x20;
1314 se401->ggain = 0x20;
1315 se401->bgain = 0x20;
1316 se401_set_exposure(se401, 20000);
1317 se401->palette = VIDEO_PALETTE_RGB24;
1318 se401->enhance = 1;
1319 se401->dropped = 0;
1320 se401->error = 0;
1321 se401->framecount = 0;
1322 se401->readcount = 0;
1323
1324 /* Start interrupt transfers for snapshot button */
1325 if (button) {
1326 se401->inturb = usb_alloc_urb(0, GFP_KERNEL);
1327 if (!se401->inturb) {
1328 dev_info(&se401->dev->dev,
1329 "Allocation of inturb failed\n");
1330 return 1;
1331 }
1332 usb_fill_int_urb(se401->inturb, se401->dev,
1333 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1334 &se401->button, sizeof(se401->button),
1335 se401_button_irq,
1336 se401,
1337 8
1338 );
1339 if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1340 dev_info(&se401->dev->dev, "int urb burned down\n");
1341 return 1;
1342 }
1343 } else
1344 se401->inturb = NULL;
1345
1346 /* Flash the led */
1347 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1348 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1349 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1350 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1351
1352 return 0;
1353}
1354
1355static int se401_probe(struct usb_interface *intf,
1356 const struct usb_device_id *id)
1357{
1358 struct usb_device *dev = interface_to_usbdev(intf);
1359 struct usb_interface_descriptor *interface;
1360 struct usb_se401 *se401;
1361 char *camera_name = NULL;
1362 int button = 1;
1363
1364 /* We don't handle multi-config cameras */
1365 if (dev->descriptor.bNumConfigurations != 1)
1366 return -ENODEV;
1367
1368 interface = &intf->cur_altsetting->desc;
1369
1370 /* Is it an se401? */
1371 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1372 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1373 camera_name = "Endpoints/Aox SE401";
1374 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1375 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1376 camera_name = "Philips PCVC665K";
1377 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1378 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1379 camera_name = "Kensington VideoCAM 67014";
1380 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1381 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1382 camera_name = "Kensington VideoCAM 6701(5/7)";
1383 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1384 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1385 camera_name = "Kensington VideoCAM 67016";
1386 button = 0;
1387 } else
1388 return -ENODEV;
1389
1390 /* Checking vendor/product should be enough, but what the hell */
1391 if (interface->bInterfaceClass != 0x00)
1392 return -ENODEV;
1393 if (interface->bInterfaceSubClass != 0x00)
1394 return -ENODEV;
1395
1396 /* We found one */
1397 dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name);
1398
1399 se401 = kzalloc(sizeof(*se401), GFP_KERNEL);
1400 if (se401 == NULL) {
1401 err("couldn't kmalloc se401 struct");
1402 return -ENOMEM;
1403 }
1404
1405 se401->dev = dev;
1406 se401->iface = interface->bInterfaceNumber;
1407 se401->camera_name = camera_name;
1408
1409 dev_info(&intf->dev, "firmware version: %02x\n",
1410 le16_to_cpu(dev->descriptor.bcdDevice) & 255);
1411
1412 if (se401_init(se401, button)) {
1413 kfree(se401);
1414 return -EIO;
1415 }
1416
1417 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1418 memcpy(se401->vdev.name, se401->camera_name,
1419 strlen(se401->camera_name));
1420 init_waitqueue_head(&se401->wq);
1421 mutex_init(&se401->lock);
1422 wmb();
1423
1424 if (video_register_device(&se401->vdev,
1425 VFL_TYPE_GRABBER, video_nr) < 0) {
1426 kfree(se401);
1427 err("video_register_device failed");
1428 return -EIO;
1429 }
1430 dev_info(&intf->dev, "registered new video device: %s\n",
1431 video_device_node_name(&se401->vdev));
1432
1433 usb_set_intfdata(intf, se401);
1434 return 0;
1435}
1436
1437static void se401_disconnect(struct usb_interface *intf)
1438{
1439 struct usb_se401 *se401 = usb_get_intfdata(intf);
1440
1441 usb_set_intfdata(intf, NULL);
1442 if (se401) {
1443 video_unregister_device(&se401->vdev);
1444 if (!se401->user)
1445 usb_se401_remove_disconnected(se401);
1446 else {
1447 se401->frame[0].grabstate = FRAME_ERROR;
1448 se401->frame[0].grabstate = FRAME_ERROR;
1449
1450 se401->streaming = 0;
1451
1452 wake_up_interruptible(&se401->wq);
1453 se401->removed = 1;
1454 }
1455 }
1456}
1457
1458static struct usb_driver se401_driver = {
1459 .name = "se401",
1460 .id_table = device_table,
1461 .probe = se401_probe,
1462 .disconnect = se401_disconnect,
1463};
1464
1465
1466
1467/****************************************************************************
1468 *
1469 * Module routines
1470 *
1471 ***************************************************************************/
1472
1473static int __init usb_se401_init(void)
1474{
1475 printk(KERN_INFO "SE401 usb camera driver version %s registering\n",
1476 version);
1477 if (flickerless)
1478 if (flickerless != 50 && flickerless != 60) {
1479 printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n");
1480 return -1;
1481 }
1482 return usb_register(&se401_driver);
1483}
1484
1485static void __exit usb_se401_exit(void)
1486{
1487 usb_deregister(&se401_driver);
1488 printk(KERN_INFO "SE401 driver deregistered\frame");
1489}
1490
1491module_init(usb_se401_init);
1492module_exit(usb_se401_exit);
diff --git a/drivers/staging/se401/se401.h b/drivers/staging/se401/se401.h
deleted file mode 100644
index 2758f4716c3d..000000000000
--- a/drivers/staging/se401/se401.h
+++ /dev/null
@@ -1,236 +0,0 @@
1
2#ifndef __LINUX_se401_H
3#define __LINUX_se401_H
4
5#include <linux/uaccess.h>
6#include "videodev.h"
7#include <media/v4l2-common.h>
8#include <media/v4l2-ioctl.h>
9#include <linux/mutex.h>
10
11#define se401_DEBUG /* Turn on debug messages */
12
13#ifdef se401_DEBUG
14# define PDEBUG(level, fmt, args...) \
15if (debug >= level) \
16 info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
17#else
18# define PDEBUG(level, fmt, args...) do {} while (0)
19#endif
20
21/* An almost drop-in replacement for sleep_on_interruptible */
22#define wait_interruptible(test, queue, wait) \
23{ \
24 add_wait_queue(queue, wait); \
25 set_current_state(TASK_INTERRUPTIBLE); \
26 if (test) \
27 schedule(); \
28 remove_wait_queue(queue, wait); \
29 set_current_state(TASK_RUNNING); \
30 if (signal_pending(current)) \
31 break; \
32}
33
34#define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06
35#define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41
36#define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42
37#define SE401_REQ_CAPTURE_FRAME 0x43
38#define SE401_REQ_GET_BRT 0x44
39#define SE401_REQ_SET_BRT 0x45
40#define SE401_REQ_GET_WIDTH 0x4c
41#define SE401_REQ_SET_WIDTH 0x4d
42#define SE401_REQ_GET_HEIGHT 0x4e
43#define SE401_REQ_SET_HEIGHT 0x4f
44#define SE401_REQ_GET_OUTPUT_MODE 0x50
45#define SE401_REQ_SET_OUTPUT_MODE 0x51
46#define SE401_REQ_GET_EXT_FEATURE 0x52
47#define SE401_REQ_SET_EXT_FEATURE 0x53
48#define SE401_REQ_CAMERA_POWER 0x56
49#define SE401_REQ_LED_CONTROL 0x57
50#define SE401_REQ_BIOS 0xff
51
52#define SE401_BIOS_READ 0x07
53
54#define SE401_FORMAT_BAYER 0x40
55
56/* Hyundai hv7131b registers
57 7121 and 7141 should be the same (haven't really checked...) */
58/* Mode registers: */
59#define HV7131_REG_MODE_A 0x00
60#define HV7131_REG_MODE_B 0x01
61#define HV7131_REG_MODE_C 0x02
62/* Frame registers: */
63#define HV7131_REG_FRSU 0x10
64#define HV7131_REG_FRSL 0x11
65#define HV7131_REG_FCSU 0x12
66#define HV7131_REG_FCSL 0x13
67#define HV7131_REG_FWHU 0x14
68#define HV7131_REG_FWHL 0x15
69#define HV7131_REG_FWWU 0x16
70#define HV7131_REG_FWWL 0x17
71/* Timing registers: */
72#define HV7131_REG_THBU 0x20
73#define HV7131_REG_THBL 0x21
74#define HV7131_REG_TVBU 0x22
75#define HV7131_REG_TVBL 0x23
76#define HV7131_REG_TITU 0x25
77#define HV7131_REG_TITM 0x26
78#define HV7131_REG_TITL 0x27
79#define HV7131_REG_TMCD 0x28
80/* Adjust Registers: */
81#define HV7131_REG_ARLV 0x30
82#define HV7131_REG_ARCG 0x31
83#define HV7131_REG_AGCG 0x32
84#define HV7131_REG_ABCG 0x33
85#define HV7131_REG_APBV 0x34
86#define HV7131_REG_ASLP 0x54
87/* Offset Registers: */
88#define HV7131_REG_OFSR 0x50
89#define HV7131_REG_OFSG 0x51
90#define HV7131_REG_OFSB 0x52
91/* REset level statistics registers: */
92#define HV7131_REG_LOREFNOH 0x57
93#define HV7131_REG_LOREFNOL 0x58
94#define HV7131_REG_HIREFNOH 0x59
95#define HV7131_REG_HIREFNOL 0x5a
96
97/* se401 registers */
98#define SE401_OPERATINGMODE 0x2000
99
100
101/* size of usb transfers */
102#define SE401_PACKETSIZE 4096
103/* number of queued bulk transfers to use, should be about 8 */
104#define SE401_NUMSBUF 1
105/* read the usb specs for this one :) */
106#define SE401_VIDEO_ENDPOINT 1
107#define SE401_BUTTON_ENDPOINT 2
108/* number of frames supported by the v4l part */
109#define SE401_NUMFRAMES 2
110/* scratch buffers for passing data to the decoders */
111#define SE401_NUMSCRATCH 32
112/* maximum amount of data in a JangGu packet */
113#define SE401_VLCDATALEN 1024
114/* number of nul sized packets to receive before kicking the camera */
115#define SE401_MAX_NULLPACKETS 4000
116/* number of decoding errors before kicking the camera */
117#define SE401_MAX_ERRORS 200
118
119struct usb_device;
120
121struct se401_sbuf {
122 unsigned char *data;
123};
124
125enum {
126 FRAME_UNUSED, /* Unused (no MCAPTURE) */
127 FRAME_READY, /* Ready to start grabbing */
128 FRAME_GRABBING, /* In the process of being grabbed into */
129 FRAME_DONE, /* Finished grabbing, but not been synced yet */
130 FRAME_ERROR, /* Something bad happened while processing */
131};
132
133enum {
134 FMT_BAYER,
135 FMT_JANGGU,
136};
137
138enum {
139 BUFFER_UNUSED,
140 BUFFER_READY,
141 BUFFER_BUSY,
142 BUFFER_DONE,
143};
144
145struct se401_scratch {
146 unsigned char *data;
147 volatile int state;
148 int offset;
149 int length;
150};
151
152struct se401_frame {
153 unsigned char *data; /* Frame buffer */
154
155 volatile int grabstate; /* State of grabbing */
156
157 unsigned char *curline;
158 int curlinepix;
159 int curpix;
160};
161
162struct usb_se401 {
163 struct video_device vdev;
164
165 /* Device structure */
166 struct usb_device *dev;
167
168 unsigned char iface;
169
170 char *camera_name;
171
172 int change;
173 int brightness;
174 int hue;
175 int rgain;
176 int ggain;
177 int bgain;
178 int expose_h;
179 int expose_m;
180 int expose_l;
181 int resetlevel;
182
183 int enhance;
184
185 int format;
186 int sizes;
187 int *width;
188 int *height;
189 int cwidth; /* current width */
190 int cheight; /* current height */
191 int palette;
192 int maxframesize;
193 int cframesize; /* current framesize */
194
195 struct mutex lock;
196 int user; /* user count for exclusive use */
197 int removed; /* device disconnected */
198
199 int streaming; /* Are we streaming video? */
200
201 char *fbuf; /* Videodev buffer area */
202
203 struct urb *urb[SE401_NUMSBUF];
204 struct urb *inturb;
205
206 int button;
207 int buttonpressed;
208
209 int curframe; /* Current receiving frame */
210 struct se401_frame frame[SE401_NUMFRAMES];
211 int readcount;
212 int framecount;
213 int error;
214 int dropped;
215
216 int scratch_next;
217 int scratch_use;
218 int scratch_overflow;
219 struct se401_scratch scratch[SE401_NUMSCRATCH];
220
221 /* Decoder specific data: */
222 unsigned char vlcdata[SE401_VLCDATALEN];
223 int vlcdatapos;
224 int bayeroffset;
225
226 struct se401_sbuf sbuf[SE401_NUMSBUF];
227
228 wait_queue_head_t wq; /* Processes waiting */
229
230 int nullpackets;
231};
232
233
234
235#endif
236
diff --git a/drivers/staging/se401/videodev.h b/drivers/staging/se401/videodev.h
deleted file mode 100644
index f11efbef1c05..000000000000
--- a/drivers/staging/se401/videodev.h
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2 * Video for Linux version 1 - OBSOLETE
3 *
4 * Header file for v4l1 drivers and applications, for
5 * Linux kernels 2.2.x or 2.4.x.
6 *
7 * Provides header for legacy drivers and applications
8 *
9 * See http://linuxtv.org for more info
10 *
11 */
12#ifndef __LINUX_VIDEODEV_H
13#define __LINUX_VIDEODEV_H
14
15#include <linux/types.h>
16#include <linux/ioctl.h>
17#include <linux/videodev2.h>
18
19#define VID_TYPE_CAPTURE 1 /* Can capture */
20#define VID_TYPE_TUNER 2 /* Can tune */
21#define VID_TYPE_TELETEXT 4 /* Does teletext */
22#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
23#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
24#define VID_TYPE_CLIPPING 32 /* Can clip */
25#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
26#define VID_TYPE_SCALES 128 /* Scalable */
27#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
28#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
29#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
30#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
31#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
32#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
33
34struct video_capability
35{
36 char name[32];
37 int type;
38 int channels; /* Num channels */
39 int audios; /* Num audio devices */
40 int maxwidth; /* Supported width */
41 int maxheight; /* And height */
42 int minwidth; /* Supported width */
43 int minheight; /* And height */
44};
45
46
47struct video_channel
48{
49 int channel;
50 char name[32];
51 int tuners;
52 __u32 flags;
53#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
54#define VIDEO_VC_AUDIO 2 /* Channel has audio */
55 __u16 type;
56#define VIDEO_TYPE_TV 1
57#define VIDEO_TYPE_CAMERA 2
58 __u16 norm; /* Norm set by channel */
59};
60
61struct video_tuner
62{
63 int tuner;
64 char name[32];
65 unsigned long rangelow, rangehigh; /* Tuner range */
66 __u32 flags;
67#define VIDEO_TUNER_PAL 1
68#define VIDEO_TUNER_NTSC 2
69#define VIDEO_TUNER_SECAM 4
70#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
71#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
72#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
73#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
74#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
75 __u16 mode; /* PAL/NTSC/SECAM/OTHER */
76#define VIDEO_MODE_PAL 0
77#define VIDEO_MODE_NTSC 1
78#define VIDEO_MODE_SECAM 2
79#define VIDEO_MODE_AUTO 3
80 __u16 signal; /* Signal strength 16bit scale */
81};
82
83struct video_picture
84{
85 __u16 brightness;
86 __u16 hue;
87 __u16 colour;
88 __u16 contrast;
89 __u16 whiteness; /* Black and white only */
90 __u16 depth; /* Capture depth */
91 __u16 palette; /* Palette in use */
92#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
93#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
94#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
95#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
96#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
97#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
98#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
99#define VIDEO_PALETTE_YUYV 8
100#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
101#define VIDEO_PALETTE_YUV420 10
102#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
103#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
104#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
105#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
106#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
107#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
108#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
109#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
110};
111
112struct video_audio
113{
114 int audio; /* Audio channel */
115 __u16 volume; /* If settable */
116 __u16 bass, treble;
117 __u32 flags;
118#define VIDEO_AUDIO_MUTE 1
119#define VIDEO_AUDIO_MUTABLE 2
120#define VIDEO_AUDIO_VOLUME 4
121#define VIDEO_AUDIO_BASS 8
122#define VIDEO_AUDIO_TREBLE 16
123#define VIDEO_AUDIO_BALANCE 32
124 char name[16];
125#define VIDEO_SOUND_MONO 1
126#define VIDEO_SOUND_STEREO 2
127#define VIDEO_SOUND_LANG1 4
128#define VIDEO_SOUND_LANG2 8
129 __u16 mode;
130 __u16 balance; /* Stereo balance */
131 __u16 step; /* Step actual volume uses */
132};
133
134struct video_clip
135{
136 __s32 x,y;
137 __s32 width, height;
138 struct video_clip *next; /* For user use/driver use only */
139};
140
141struct video_window
142{
143 __u32 x,y; /* Position of window */
144 __u32 width,height; /* Its size */
145 __u32 chromakey;
146 __u32 flags;
147 struct video_clip __user *clips; /* Set only */
148 int clipcount;
149#define VIDEO_WINDOW_INTERLACE 1
150#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
151#define VIDEO_CLIP_BITMAP -1
152/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
153#define VIDEO_CLIPMAP_SIZE (128 * 625)
154};
155
156struct video_capture
157{
158 __u32 x,y; /* Offsets into image */
159 __u32 width, height; /* Area to capture */
160 __u16 decimation; /* Decimation divider */
161 __u16 flags; /* Flags for capture */
162#define VIDEO_CAPTURE_ODD 0 /* Temporal */
163#define VIDEO_CAPTURE_EVEN 1
164};
165
166struct video_buffer
167{
168 void *base;
169 int height,width;
170 int depth;
171 int bytesperline;
172};
173
174struct video_mmap
175{
176 unsigned int frame; /* Frame (0 - n) for double buffer */
177 int height,width;
178 unsigned int format; /* should be VIDEO_PALETTE_* */
179};
180
181struct video_key
182{
183 __u8 key[8];
184 __u32 flags;
185};
186
187struct video_mbuf
188{
189 int size; /* Total memory to map */
190 int frames; /* Frames */
191 int offsets[VIDEO_MAX_FRAME];
192};
193
194#define VIDEO_NO_UNIT (-1)
195
196struct video_unit
197{
198 int video; /* Video minor */
199 int vbi; /* VBI minor */
200 int radio; /* Radio minor */
201 int audio; /* Audio minor */
202 int teletext; /* Teletext minor */
203};
204
205struct vbi_format {
206 __u32 sampling_rate; /* in Hz */
207 __u32 samples_per_line;
208 __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
209 __s32 start[2]; /* starting line for each frame */
210 __u32 count[2]; /* count of lines for each frame */
211 __u32 flags;
212#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
213#define VBI_INTERLACED 2 /* lines are interlaced */
214};
215
216/* video_info is biased towards hardware mpeg encode/decode */
217/* but it could apply generically to any hardware compressor/decompressor */
218struct video_info
219{
220 __u32 frame_count; /* frames output since decode/encode began */
221 __u32 h_size; /* current unscaled horizontal size */
222 __u32 v_size; /* current unscaled veritcal size */
223 __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */
224 __u32 picture_type; /* current picture type */
225 __u32 temporal_reference; /* current temporal reference */
226 __u8 user_data[256]; /* user data last found in compressed stream */
227 /* user_data[0] contains user data flags, user_data[1] has count */
228};
229
230/* generic structure for setting playback modes */
231struct video_play_mode
232{
233 int mode;
234 int p1;
235 int p2;
236};
237
238/* for loading microcode / fpga programming */
239struct video_code
240{
241 char loadwhat[16]; /* name or tag of file being passed */
242 int datasize;
243 __u8 *data;
244};
245
246#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
247#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
248#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
249#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
250#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
251#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
252#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
253#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
254#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
255#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
256#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
257#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
258#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
259#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
260#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
261#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
262#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
263#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
264#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
265#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
266#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */
267#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */
268#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */
269#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */
270#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */
271#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */
272#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */
273#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
274#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
275
276
277#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
278
279/* VIDIOCSWRITEMODE */
280#define VID_WRITE_MPEG_AUD 0
281#define VID_WRITE_MPEG_VID 1
282#define VID_WRITE_OSD 2
283#define VID_WRITE_TTX 3
284#define VID_WRITE_CC 4
285#define VID_WRITE_MJPEG 5
286
287/* VIDIOCSPLAYMODE */
288#define VID_PLAY_VID_OUT_MODE 0
289 /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
290#define VID_PLAY_GENLOCK 1
291 /* p1: 0 = OFF, 1 = ON */
292 /* p2: GENLOCK FINE DELAY value */
293#define VID_PLAY_NORMAL 2
294#define VID_PLAY_PAUSE 3
295#define VID_PLAY_SINGLE_FRAME 4
296#define VID_PLAY_FAST_FORWARD 5
297#define VID_PLAY_SLOW_MOTION 6
298#define VID_PLAY_IMMEDIATE_NORMAL 7
299#define VID_PLAY_SWITCH_CHANNELS 8
300#define VID_PLAY_FREEZE_FRAME 9
301#define VID_PLAY_STILL_MODE 10
302#define VID_PLAY_MASTER_MODE 11
303 /* p1: see below */
304#define VID_PLAY_MASTER_NONE 1
305#define VID_PLAY_MASTER_VIDEO 2
306#define VID_PLAY_MASTER_AUDIO 3
307#define VID_PLAY_ACTIVE_SCANLINES 12
308 /* p1 = first active; p2 = last active */
309#define VID_PLAY_RESET 13
310#define VID_PLAY_END_MARK 14
311
312#endif /* __LINUX_VIDEODEV_H */
313
314/*
315 * Local variables:
316 * c-basic-offset: 8
317 * End:
318 */
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 184cc505ed86..acb03172a887 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -76,14 +76,11 @@ MODULE_PARM_DESC(debug, "enable debug messages");
76static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip) 76static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
77{ 77{
78 struct tm6000_core *core = chip->core; 78 struct tm6000_core *core = chip->core;
79 int val;
80 79
81 dprintk(1, "Starting audio DMA\n"); 80 dprintk(1, "Starting audio DMA\n");
82 81
83 /* Enables audio */ 82 /* Enables audio */
84 val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0); 83 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x40, 0x40);
85 val |= 0x20;
86 tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
87 84
88 tm6000_set_audio_bitrate(core, 48000); 85 tm6000_set_audio_bitrate(core, 48000);
89 86
@@ -98,13 +95,11 @@ static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
98static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip) 95static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
99{ 96{
100 struct tm6000_core *core = chip->core; 97 struct tm6000_core *core = chip->core;
101 int val; 98
102 dprintk(1, "Stopping audio DMA\n"); 99 dprintk(1, "Stopping audio DMA\n");
103 100
104 /* Enables audio */ 101 /* Disables audio */
105 val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0); 102 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x00, 0x40);
106 val &= ~0x20;
107 tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
108 103
109 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0); 104 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0);
110 105
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 455038bdfc9f..146c7e86deca 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -50,6 +50,9 @@
50#define TM6010_BOARD_BEHOLD_VOYAGER 11 50#define TM6010_BOARD_BEHOLD_VOYAGER 11
51#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12 51#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
52#define TM6010_BOARD_TWINHAN_TU501 13 52#define TM6010_BOARD_TWINHAN_TU501 13
53#define TM6010_BOARD_BEHOLD_WANDER_LITE 14
54#define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15
55#define TM5600_BOARD_TERRATEC_GRABSTER 16
53 56
54#define TM6000_MAXBOARDS 16 57#define TM6000_MAXBOARDS 16
55static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET }; 58static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
@@ -63,6 +66,8 @@ struct tm6000_board {
63 char *name; 66 char *name;
64 67
65 struct tm6000_capabilities caps; 68 struct tm6000_capabilities caps;
69 enum tm6000_inaudio aradio;
70 enum tm6000_inaudio avideo;
66 71
67 enum tm6000_devtype type; /* variant of the chipset */ 72 enum tm6000_devtype type; /* variant of the chipset */
68 int tuner_type; /* type of the tuner */ 73 int tuner_type; /* type of the tuner */
@@ -227,12 +232,16 @@ struct tm6000_board tm6000_boards[] = {
227 .tuner_addr = 0xc2 >> 1, 232 .tuner_addr = 0xc2 >> 1,
228 .demod_addr = 0x1e >> 1, 233 .demod_addr = 0x1e >> 1,
229 .type = TM6010, 234 .type = TM6010,
235 .avideo = TM6000_AIP_SIF1,
236 .aradio = TM6000_AIP_LINE1,
230 .caps = { 237 .caps = {
231 .has_tuner = 1, 238 .has_tuner = 1,
232 .has_dvb = 1, 239 .has_dvb = 1,
233 .has_zl10353 = 1, 240 .has_zl10353 = 1,
234 .has_eeprom = 1, 241 .has_eeprom = 1,
235 .has_remote = 1, 242 .has_remote = 1,
243 .has_input_comp = 1,
244 .has_input_svid = 1,
236 }, 245 },
237 .gpio = { 246 .gpio = {
238 .tuner_reset = TM6010_GPIO_0, 247 .tuner_reset = TM6010_GPIO_0,
@@ -245,12 +254,16 @@ struct tm6000_board tm6000_boards[] = {
245 .tuner_type = TUNER_XC5000, 254 .tuner_type = TUNER_XC5000,
246 .tuner_addr = 0xc2 >> 1, 255 .tuner_addr = 0xc2 >> 1,
247 .type = TM6010, 256 .type = TM6010,
257 .avideo = TM6000_AIP_SIF1,
258 .aradio = TM6000_AIP_LINE1,
248 .caps = { 259 .caps = {
249 .has_tuner = 1, 260 .has_tuner = 1,
250 .has_dvb = 0, 261 .has_dvb = 0,
251 .has_zl10353 = 0, 262 .has_zl10353 = 0,
252 .has_eeprom = 1, 263 .has_eeprom = 1,
253 .has_remote = 1, 264 .has_remote = 1,
265 .has_input_comp = 1,
266 .has_input_svid = 1,
254 }, 267 },
255 .gpio = { 268 .gpio = {
256 .tuner_reset = TM6010_GPIO_0, 269 .tuner_reset = TM6010_GPIO_0,
@@ -281,6 +294,11 @@ struct tm6000_board tm6000_boards[] = {
281 }, 294 },
282 .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, 295 .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
283 }, 296 },
297 [TM5600_BOARD_TERRATEC_GRABSTER] = {
298 .name = "Terratec Grabster AV 150/250 MX",
299 .type = TM5600,
300 .tuner_type = TUNER_ABSENT,
301 },
284 [TM6010_BOARD_TWINHAN_TU501] = { 302 [TM6010_BOARD_TWINHAN_TU501] = {
285 .name = "Twinhan TU501(704D1)", 303 .name = "Twinhan TU501(704D1)",
286 .tuner_type = TUNER_XC2028, /* has a XC3028 */ 304 .tuner_type = TUNER_XC2028, /* has a XC3028 */
@@ -303,7 +321,51 @@ struct tm6000_board tm6000_boards[] = {
303 .dvb_led = TM6010_GPIO_5, 321 .dvb_led = TM6010_GPIO_5,
304 .ir = TM6010_GPIO_0, 322 .ir = TM6010_GPIO_0,
305 }, 323 },
306 } 324 },
325 [TM6010_BOARD_BEHOLD_WANDER_LITE] = {
326 .name = "Beholder Wander Lite DVB-T/TV/FM USB2.0",
327 .tuner_type = TUNER_XC5000,
328 .tuner_addr = 0xc2 >> 1,
329 .demod_addr = 0x1e >> 1,
330 .type = TM6010,
331 .avideo = TM6000_AIP_SIF1,
332 .aradio = TM6000_AIP_LINE1,
333 .caps = {
334 .has_tuner = 1,
335 .has_dvb = 1,
336 .has_zl10353 = 1,
337 .has_eeprom = 1,
338 .has_remote = 0,
339 .has_input_comp = 0,
340 .has_input_svid = 0,
341 },
342 .gpio = {
343 .tuner_reset = TM6010_GPIO_0,
344 .demod_reset = TM6010_GPIO_1,
345 .power_led = TM6010_GPIO_6,
346 },
347 },
348 [TM6010_BOARD_BEHOLD_VOYAGER_LITE] = {
349 .name = "Beholder Voyager Lite TV/FM USB2.0",
350 .tuner_type = TUNER_XC5000,
351 .tuner_addr = 0xc2 >> 1,
352 .type = TM6010,
353 .avideo = TM6000_AIP_SIF1,
354 .aradio = TM6000_AIP_LINE1,
355 .caps = {
356 .has_tuner = 1,
357 .has_dvb = 0,
358 .has_zl10353 = 0,
359 .has_eeprom = 1,
360 .has_remote = 0,
361 .has_input_comp = 0,
362 .has_input_svid = 0,
363 },
364 .gpio = {
365 .tuner_reset = TM6010_GPIO_0,
366 .power_led = TM6010_GPIO_6,
367 },
368 },
307}; 369};
308 370
309/* table of devices that work with this driver */ 371/* table of devices that work with this driver */
@@ -321,10 +383,13 @@ struct usb_device_id tm6000_id_table[] = {
321 { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER }, 383 { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER },
322 { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE }, 384 { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
323 { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE }, 385 { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
386 { USB_DEVICE(0x0ccd, 0x0079), .driver_info = TM5600_BOARD_TERRATEC_GRABSTER },
324 { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 387 { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
325 { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 388 { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
326 { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 389 { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
327 { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 390 { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
391 { USB_DEVICE(0x6000, 0xdec2), .driver_info = TM6010_BOARD_BEHOLD_WANDER_LITE },
392 { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE },
328 { }, 393 { },
329}; 394};
330 395
@@ -346,6 +411,8 @@ void tm6000_flash_led(struct tm6000_core *dev, u8 state)
346 break; 411 break;
347 case TM6010_BOARD_BEHOLD_WANDER: 412 case TM6010_BOARD_BEHOLD_WANDER:
348 case TM6010_BOARD_BEHOLD_VOYAGER: 413 case TM6010_BOARD_BEHOLD_VOYAGER:
414 case TM6010_BOARD_BEHOLD_WANDER_LITE:
415 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
349 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 416 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
350 dev->gpio.power_led, 0x01); 417 dev->gpio.power_led, 0x01);
351 break; 418 break;
@@ -362,6 +429,8 @@ void tm6000_flash_led(struct tm6000_core *dev, u8 state)
362 break; 429 break;
363 case TM6010_BOARD_BEHOLD_WANDER: 430 case TM6010_BOARD_BEHOLD_WANDER:
364 case TM6010_BOARD_BEHOLD_VOYAGER: 431 case TM6010_BOARD_BEHOLD_VOYAGER:
432 case TM6010_BOARD_BEHOLD_WANDER_LITE:
433 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
365 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 434 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
366 dev->gpio.power_led, 0x00); 435 dev->gpio.power_led, 0x00);
367 break; 436 break;
@@ -520,6 +589,7 @@ int tm6000_cards_setup(struct tm6000_core *dev)
520 msleep(15); 589 msleep(15);
521 break; 590 break;
522 case TM6010_BOARD_BEHOLD_WANDER: 591 case TM6010_BOARD_BEHOLD_WANDER:
592 case TM6010_BOARD_BEHOLD_WANDER_LITE:
523 /* Power led on (blue) */ 593 /* Power led on (blue) */
524 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01); 594 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
525 msleep(15); 595 msleep(15);
@@ -530,6 +600,7 @@ int tm6000_cards_setup(struct tm6000_core *dev)
530 msleep(15); 600 msleep(15);
531 break; 601 break;
532 case TM6010_BOARD_BEHOLD_VOYAGER: 602 case TM6010_BOARD_BEHOLD_VOYAGER:
603 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
533 /* Power led on (blue) */ 604 /* Power led on (blue) */
534 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01); 605 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
535 msleep(15); 606 msleep(15);
@@ -588,8 +659,6 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
588 tun_setup.mode_mask = 0; 659 tun_setup.mode_mask = 0;
589 if (dev->caps.has_tuner) 660 if (dev->caps.has_tuner)
590 tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO); 661 tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO);
591 if (dev->caps.has_dvb)
592 tun_setup.mode_mask |= T_DIGITAL_TV;
593 662
594 switch (dev->tuner_type) { 663 switch (dev->tuner_type) {
595 case TUNER_XC2028: 664 case TUNER_XC2028:
@@ -644,13 +713,12 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
644 struct xc5000_config ctl = { 713 struct xc5000_config ctl = {
645 .i2c_address = dev->tuner_addr, 714 .i2c_address = dev->tuner_addr,
646 .if_khz = 4570, 715 .if_khz = 4570,
647 .radio_input = XC5000_RADIO_FM1, 716 .radio_input = XC5000_RADIO_FM1_MONO,
648 }; 717 };
649 718
650 xc5000_cfg.tuner = TUNER_XC5000; 719 xc5000_cfg.tuner = TUNER_XC5000;
651 xc5000_cfg.priv = &ctl; 720 xc5000_cfg.priv = &ctl;
652 721
653
654 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, 722 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
655 &xc5000_cfg); 723 &xc5000_cfg);
656 } 724 }
@@ -683,6 +751,8 @@ static int tm6000_init_dev(struct tm6000_core *dev)
683 751
684 dev->caps = tm6000_boards[dev->model].caps; 752 dev->caps = tm6000_boards[dev->model].caps;
685 753
754 dev->avideo = tm6000_boards[dev->model].avideo;
755 dev->aradio = tm6000_boards[dev->model].aradio;
686 /* initialize hardware */ 756 /* initialize hardware */
687 rc = tm6000_init(dev); 757 rc = tm6000_init(dev);
688 if (rc < 0) 758 if (rc < 0)
@@ -957,6 +1027,8 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
957 break; 1027 break;
958 case TM6010_BOARD_BEHOLD_WANDER: 1028 case TM6010_BOARD_BEHOLD_WANDER:
959 case TM6010_BOARD_BEHOLD_VOYAGER: 1029 case TM6010_BOARD_BEHOLD_VOYAGER:
1030 case TM6010_BOARD_BEHOLD_WANDER_LITE:
1031 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
960 /* Power led off */ 1032 /* Power led off */
961 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 1033 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
962 dev->gpio.power_led, 0x00); 1034 dev->gpio.power_led, 0x00);
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 96aed4ace467..778e53413afb 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -116,6 +116,29 @@ int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
116} 116}
117EXPORT_SYMBOL_GPL(tm6000_get_reg); 117EXPORT_SYMBOL_GPL(tm6000_get_reg);
118 118
119int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
120 u16 index, u16 mask)
121{
122 int rc;
123 u8 buf[1];
124 u8 new_index;
125
126 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
127 value, index, buf, 1);
128
129 if (rc < 0)
130 return rc;
131
132 new_index = (buf[0] & ~mask) | (index & mask);
133
134 if (new_index == index)
135 return 0;
136
137 return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
138 req, value, new_index, NULL, 0);
139}
140EXPORT_SYMBOL_GPL(tm6000_set_reg_mask);
141
119int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index) 142int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index)
120{ 143{
121 int rc; 144 int rc;
@@ -245,17 +268,12 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
245 struct v4l2_frequency f; 268 struct v4l2_frequency f;
246 269
247 if (dev->dev_type == TM6010) { 270 if (dev->dev_type == TM6010) {
248 int val;
249
250 /* Enable video */ 271 /* Enable video */
251 val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0);
252 val |= 0x60;
253 tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
254 val = tm6000_get_reg(dev,
255 TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0);
256 val &= ~0x40;
257 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val);
258 272
273 tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
274 0x60, 0x60);
275 tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
276 0x00, 0x40);
259 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc); 277 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
260 278
261 } else { 279 } else {
@@ -268,11 +286,11 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
268 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80); 286 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
269 287
270 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88); 288 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88);
271 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23); 289 tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x23);
272 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xc0); 290 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xc0);
273 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xd8); 291 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xd8);
274 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x06); 292 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x06);
275 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x1f); 293 tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f);
276 294
277 /* AP Software reset */ 295 /* AP Software reset */
278 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08); 296 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
@@ -284,8 +302,8 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
284 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00); 302 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
285 303
286 /* E3: Select input 0 - TV tuner */ 304 /* E3: Select input 0 - TV tuner */
287 tm6000_set_reg(dev, TM6010_REQ07_RE3_OUT_SEL1, 0x00); 305 tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
288 tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, 0x60); 306 tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x60);
289 307
290 /* This controls input */ 308 /* This controls input */
291 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0); 309 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0);
@@ -344,21 +362,21 @@ int tm6000_init_digital_mode(struct tm6000_core *dev)
344 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08); 362 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
345 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00); 363 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
346 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); 364 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
347 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x08); 365 tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x08);
348 tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c); 366 tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c);
349 tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff); 367 tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff);
350 tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8); 368 tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0xd8);
351 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40); 369 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40);
352 tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0); 370 tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
353 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09); 371 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09);
354 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x37); 372 tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x37);
355 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xd8); 373 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xd8);
356 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xc0); 374 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xc0);
357 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x60); 375 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x60);
358 376
359 tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c); 377 tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c);
360 tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff); 378 tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff);
361 tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08); 379 tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x08);
362 msleep(50); 380 msleep(50);
363 381
364 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00); 382 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
@@ -388,18 +406,19 @@ struct reg_init {
388/* The meaning of those initializations are unknown */ 406/* The meaning of those initializations are unknown */
389struct reg_init tm6000_init_tab[] = { 407struct reg_init tm6000_init_tab[] = {
390 /* REG VALUE */ 408 /* REG VALUE */
391 { TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x1f }, 409 { TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f },
392 { TM6010_REQ07_RFF_SOFT_RESET, 0x08 }, 410 { TM6010_REQ07_RFF_SOFT_RESET, 0x08 },
393 { TM6010_REQ07_RFF_SOFT_RESET, 0x00 }, 411 { TM6010_REQ07_RFF_SOFT_RESET, 0x00 },
394 { TM6010_REQ07_RD5_POWERSAVE, 0x4f }, 412 { TM6010_REQ07_RD5_POWERSAVE, 0x4f },
395 { TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23 }, 413 { TM6000_REQ07_RDA_CLK_SEL, 0x23 },
396 { TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0x08 }, 414 { TM6000_REQ07_RDB_OUT_SEL, 0x08 },
397 { TM6010_REQ07_RE2_OUT_SEL2, 0x00 }, 415 { TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x00 },
398 { TM6010_REQ07_RE3_OUT_SEL1, 0x10 }, 416 { TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10 },
399 { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0x00 }, 417 { TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00 },
400 { TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0x00 }, 418 { TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00 },
401 { REQ_07_SET_GET_AVREG, 0xeb, 0x64 }, /* 48000 bits/sample, external input */ 419 { TM6000_REQ07_REB_VADC_AADC_MODE, 0x64 }, /* 48000 bits/sample, external input */
402 { REQ_07_SET_GET_AVREG, 0xee, 0xc2 }, 420 { TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL, 0xc2 },
421
403 { TM6010_REQ07_R3F_RESET, 0x01 }, /* Start of soft reset */ 422 { TM6010_REQ07_R3F_RESET, 0x01 }, /* Start of soft reset */
404 { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 }, 423 { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
405 { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 }, 424 { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 },
@@ -470,6 +489,14 @@ struct reg_init tm6010_init_tab[] = {
470 { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 }, 489 { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 },
471 { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 }, 490 { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 },
472 { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 }, 491 { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 },
492 { TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00},
493 { TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80},
494 { TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a},
495 { TM6010_REQ08_R0D_A_AMD_THRES, 0x40},
496 { TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64},
497 { TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20},
498 { TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe},
499 { TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01},
473 { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc }, 500 { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc },
474 501
475 { TM6010_REQ07_R3F_RESET, 0x01 }, 502 { TM6010_REQ07_R3F_RESET, 0x01 },
@@ -590,38 +617,213 @@ int tm6000_init(struct tm6000_core *dev)
590 617
591int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate) 618int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
592{ 619{
593 int val; 620 int val = 0;
621 u8 areg_f0 = 0x60; /* ADC MCLK = 250 Fs */
622 u8 areg_0a = 0x91; /* SIF 48KHz */
594 623
624 switch (bitrate) {
625 case 48000:
626 areg_f0 = 0x60; /* ADC MCLK = 250 Fs */
627 areg_0a = 0x91; /* SIF 48KHz */
628 dev->audio_bitrate = bitrate;
629 break;
630 case 32000:
631 areg_f0 = 0x00; /* ADC MCLK = 375 Fs */
632 areg_0a = 0x90; /* SIF 32KHz */
633 dev->audio_bitrate = bitrate;
634 break;
635 default:
636 return -EINVAL;
637 }
638
639
640 /* enable I2S, if we use sif or external I2S device */
595 if (dev->dev_type == TM6010) { 641 if (dev->dev_type == TM6010) {
596 val = tm6000_get_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0); 642 val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, areg_0a);
597 if (val < 0) 643 if (val < 0)
598 return val; 644 return val;
599 val = (val & 0xf0) | 0x1; /* 48 kHz, not muted */ 645
600 val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, val); 646 val = tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
647 areg_f0, 0xf0);
648 if (val < 0)
649 return val;
650 } else {
651 val = tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE,
652 areg_f0, 0xf0);
601 if (val < 0) 653 if (val < 0)
602 return val; 654 return val;
603 } 655 }
656 return 0;
657}
658EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
604 659
605 val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0); 660int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp)
606 if (val < 0) 661{
607 return val; 662 if (dev->dev_type == TM6010) {
663 /* Audio crossbar setting, default SIF1 */
664 u8 areg_f0 = 0x03;
608 665
609 val &= 0x0f; /* Preserve the audio input control bits */ 666 switch (ainp) {
610 switch (bitrate) { 667 case TM6000_AIP_SIF1:
611 case 44100: 668 case TM6000_AIP_SIF2:
612 val |= 0xd0; 669 areg_f0 = 0x03;
613 dev->audio_bitrate = bitrate; 670 break;
671 case TM6000_AIP_LINE1:
672 areg_f0 = 0x00;
673 break;
674 case TM6000_AIP_LINE2:
675 areg_f0 = 0x08;
676 break;
677 default:
678 return 0;
679 break;
680 }
681 /* Set audio input crossbar */
682 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
683 areg_f0, 0x0f);
684 } else {
685 /* Audio setting, default LINE1 */
686 u8 areg_eb = 0x00;
687
688 switch (ainp) {
689 case TM6000_AIP_LINE1:
690 areg_eb = 0x00;
691 break;
692 case TM6000_AIP_LINE2:
693 areg_eb = 0x04;
694 break;
695 default:
696 return 0;
697 break;
698 }
699 /* Set audio input */
700 tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE,
701 areg_eb, 0x0f);
702 }
703 return 0;
704}
705EXPORT_SYMBOL_GPL(tm6000_set_audio_input);
706
707void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
708{
709 u8 mute_reg = 0;
710
711 if (mute)
712 mute_reg = 0x08;
713
714 tm6000_set_reg_mask(dev, TM6010_REQ08_R0A_A_I2S_MOD, mute_reg, 0x08);
715}
716
717void tm6010_set_mute_adc(struct tm6000_core *dev, u8 mute)
718{
719 u8 mute_reg = 0;
720
721 if (mute)
722 mute_reg = 0x20;
723
724 if (dev->dev_type == TM6010) {
725 tm6000_set_reg_mask(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL,
726 mute_reg, 0x20);
727 tm6000_set_reg_mask(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL,
728 mute_reg, 0x20);
729 } else {
730 tm6000_set_reg_mask(dev, TM6000_REQ07_REC_VADC_AADC_LVOL,
731 mute_reg, 0x20);
732 tm6000_set_reg_mask(dev, TM6000_REQ07_RED_VADC_AADC_RVOL,
733 mute_reg, 0x20);
734 }
735}
736
737int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
738{
739 enum tm6000_inaudio ainp;
740
741 if (dev->radio)
742 ainp = dev->aradio;
743 else
744 ainp = dev->avideo;
745
746 switch (ainp) {
747 case TM6000_AIP_SIF1:
748 case TM6000_AIP_SIF2:
749 if (dev->dev_type == TM6010)
750 tm6010_set_mute_sif(dev, mute);
751 else {
752 printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has"
753 " SIF audio inputs. Please check the %s"
754 " configuration.\n", dev->name);
755 return -EINVAL;
756 }
614 break; 757 break;
615 case 48000: 758 case TM6000_AIP_LINE1:
616 val |= 0x60; 759 case TM6000_AIP_LINE2:
617 dev->audio_bitrate = bitrate; 760 tm6010_set_mute_adc(dev, mute);
761 break;
762 default:
763 return -EINVAL;
618 break; 764 break;
619 } 765 }
620 val = tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, val); 766 return 0;
767}
768EXPORT_SYMBOL_GPL(tm6000_tvaudio_set_mute);
769
770void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
771{
772 u8 vol_reg;
773
774 vol_reg = vol & 0x0F;
775
776 if (vol < 0)
777 vol_reg |= 0x40;
778
779 tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, vol_reg);
780 tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, vol_reg);
781}
782
783void tm6010_set_volume_adc(struct tm6000_core *dev, int vol)
784{
785 u8 vol_reg;
786
787 vol_reg = (vol + 0x10) & 0x1f;
788
789 if (dev->dev_type == TM6010) {
790 tm6000_set_reg(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL, vol_reg);
791 tm6000_set_reg(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL, vol_reg);
792 } else {
793 tm6000_set_reg(dev, TM6000_REQ07_REC_VADC_AADC_LVOL, vol_reg);
794 tm6000_set_reg(dev, TM6000_REQ07_RED_VADC_AADC_RVOL, vol_reg);
795 }
796}
797
798void tm6000_set_volume(struct tm6000_core *dev, int vol)
799{
800 enum tm6000_inaudio ainp;
801
802 if (dev->radio) {
803 ainp = dev->aradio;
804 vol += 8; /* Offset to 0 dB */
805 } else
806 ainp = dev->avideo;
621 807
622 return val; 808 switch (ainp) {
809 case TM6000_AIP_SIF1:
810 case TM6000_AIP_SIF2:
811 if (dev->dev_type == TM6010)
812 tm6010_set_volume_sif(dev, vol);
813 else
814 printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has"
815 " SIF audio inputs. Please check the %s"
816 " configuration.\n", dev->name);
817 break;
818 case TM6000_AIP_LINE1:
819 case TM6000_AIP_LINE2:
820 tm6010_set_volume_adc(dev, vol);
821 break;
822 default:
823 break;
824 }
623} 825}
624EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); 826EXPORT_SYMBOL_GPL(tm6000_set_volume);
625 827
626static LIST_HEAD(tm6000_devlist); 828static LIST_HEAD(tm6000_devlist);
627static DEFINE_MUTEX(tm6000_devlist_mutex); 829static DEFINE_MUTEX(tm6000_devlist_mutex);
diff --git a/drivers/staging/tm6000/tm6000-regs.h b/drivers/staging/tm6000/tm6000-regs.h
index 1f0ced8fa20f..5375a8347374 100644
--- a/drivers/staging/tm6000/tm6000-regs.h
+++ b/drivers/staging/tm6000/tm6000-regs.h
@@ -97,6 +97,34 @@ enum {
97 TM6000_URB_MSG_ERR, 97 TM6000_URB_MSG_ERR,
98}; 98};
99 99
100/* Define specific TM6000 Video decoder registers */
101#define TM6000_REQ07_RD8_TEST_SEL 0x07, 0xd8
102#define TM6000_REQ07_RD9_A_SIM_SEL 0x07, 0xd9
103#define TM6000_REQ07_RDA_CLK_SEL 0x07, 0xda
104#define TM6000_REQ07_RDB_OUT_SEL 0x07, 0xdb
105#define TM6000_REQ07_RDC_NSEL_I2S 0x07, 0xdc
106#define TM6000_REQ07_RDD_GPIO2_MDRV 0x07, 0xdd
107#define TM6000_REQ07_RDE_GPIO1_MDRV 0x07, 0xde
108#define TM6000_REQ07_RDF_PWDOWN_ACLK 0x07, 0xdf
109#define TM6000_REQ07_RE0_VADC_REF_CTL 0x07, 0xe0
110#define TM6000_REQ07_RE1_VADC_DACLIMP 0x07, 0xe1
111#define TM6000_REQ07_RE2_VADC_STATUS_CTL 0x07, 0xe2
112#define TM6000_REQ07_RE3_VADC_INP_LPF_SEL1 0x07, 0xe3
113#define TM6000_REQ07_RE4_VADC_TARGET1 0x07, 0xe4
114#define TM6000_REQ07_RE5_VADC_INP_LPF_SEL2 0x07, 0xe5
115#define TM6000_REQ07_RE6_VADC_TARGET2 0x07, 0xe6
116#define TM6000_REQ07_RE7_VADC_AGAIN_CTL 0x07, 0xe7
117#define TM6000_REQ07_RE8_VADC_PWDOWN_CTL 0x07, 0xe8
118#define TM6000_REQ07_RE9_VADC_INPUT_CTL1 0x07, 0xe9
119#define TM6000_REQ07_REA_VADC_INPUT_CTL2 0x07, 0xea
120#define TM6000_REQ07_REB_VADC_AADC_MODE 0x07, 0xeb
121#define TM6000_REQ07_REC_VADC_AADC_LVOL 0x07, 0xec
122#define TM6000_REQ07_RED_VADC_AADC_RVOL 0x07, 0xed
123#define TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL 0x07, 0xee
124#define TM6000_REQ07_REF_VADC_GAIN_MAP_CTL 0x07, 0xef
125#define TM6000_REQ07_RFD_BIST_ERR_VST_LOW 0x07, 0xfd
126#define TM6000_REQ07_RFE_BIST_ERR_VST_HIGH 0x07, 0xfe
127
100/* Define TM6000/TM6010 Video decoder registers */ 128/* Define TM6000/TM6010 Video decoder registers */
101#define TM6010_REQ07_R00_VIDEO_CONTROL0 0x07, 0x00 129#define TM6010_REQ07_R00_VIDEO_CONTROL0 0x07, 0x00
102#define TM6010_REQ07_R01_VIDEO_CONTROL1 0x07, 0x01 130#define TM6010_REQ07_R01_VIDEO_CONTROL1 0x07, 0x01
@@ -241,6 +269,7 @@ enum {
241#define TM6010_REQ07_RC9_VEND1 0x07, 0xc9 269#define TM6010_REQ07_RC9_VEND1 0x07, 0xc9
242#define TM6010_REQ07_RCA_VEND0 0x07, 0xca 270#define TM6010_REQ07_RCA_VEND0 0x07, 0xca
243#define TM6010_REQ07_RCB_DELAY 0x07, 0xcb 271#define TM6010_REQ07_RCB_DELAY 0x07, 0xcb
272/* ONLY for TM6010 */
244#define TM6010_REQ07_RCC_ACTIVE_VIDEO_IF 0x07, 0xcc 273#define TM6010_REQ07_RCC_ACTIVE_VIDEO_IF 0x07, 0xcc
245#define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL 0x07, 0xd0 274#define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL 0x07, 0xd0
246#define TM6010_REQ07_RD1_ADDR_FOR_REQ1 0x07, 0xd1 275#define TM6010_REQ07_RD1_ADDR_FOR_REQ1 0x07, 0xd1
@@ -250,32 +279,59 @@ enum {
250#define TM6010_REQ07_RD5_POWERSAVE 0x07, 0xd5 279#define TM6010_REQ07_RD5_POWERSAVE 0x07, 0xd5
251#define TM6010_REQ07_RD6_ENDP_REQ1_REQ2 0x07, 0xd6 280#define TM6010_REQ07_RD6_ENDP_REQ1_REQ2 0x07, 0xd6
252#define TM6010_REQ07_RD7_ENDP_REQ3_REQ4 0x07, 0xd7 281#define TM6010_REQ07_RD7_ENDP_REQ3_REQ4 0x07, 0xd7
282/* ONLY for TM6010 */
253#define TM6010_REQ07_RD8_IR 0x07, 0xd8 283#define TM6010_REQ07_RD8_IR 0x07, 0xd8
284/* ONLY for TM6010 */
254#define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9 285#define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9
286/* ONLY for TM6010 */
255#define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda 287#define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda
288/* ONLY for TM6010 */
256#define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb 289#define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb
290/* ONLY for TM6010 */
257#define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc 291#define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc
292/* ONLY for TM6010 */
258#define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd 293#define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd
294/* ONLY for TM6010 */
259#define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde 295#define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde
296/* ONLY for TM6010 */
260#define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf 297#define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf
298/* ONLY for TM6010 */
261#define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0 299#define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0
300/* ONLY for TM6010 */
262#define TM6010_REQ07_RE0_DVIDEO_SOURCE_IF 0x07, 0xe1 301#define TM6010_REQ07_RE0_DVIDEO_SOURCE_IF 0x07, 0xe1
302/* ONLY for TM6010 */
263#define TM6010_REQ07_RE2_OUT_SEL2 0x07, 0xe2 303#define TM6010_REQ07_RE2_OUT_SEL2 0x07, 0xe2
304/* ONLY for TM6010 */
264#define TM6010_REQ07_RE3_OUT_SEL1 0x07, 0xe3 305#define TM6010_REQ07_RE3_OUT_SEL1 0x07, 0xe3
306/* ONLY for TM6010 */
265#define TM6010_REQ07_RE4_OUT_SEL0 0x07, 0xe4 307#define TM6010_REQ07_RE4_OUT_SEL0 0x07, 0xe4
308/* ONLY for TM6010 */
266#define TM6010_REQ07_RE5_REMOTE_WAKEUP 0x07, 0xe5 309#define TM6010_REQ07_RE5_REMOTE_WAKEUP 0x07, 0xe5
310/* ONLY for TM6010 */
267#define TM6010_REQ07_RE7_PUB_GPIO 0x07, 0xe7 311#define TM6010_REQ07_RE7_PUB_GPIO 0x07, 0xe7
312/* ONLY for TM6010 */
268#define TM6010_REQ07_RE8_TYPESEL_MOS_I2S 0x07, 0xe8 313#define TM6010_REQ07_RE8_TYPESEL_MOS_I2S 0x07, 0xe8
314/* ONLY for TM6010 */
269#define TM6010_REQ07_RE9_TYPESEL_MOS_TS 0x07, 0xe9 315#define TM6010_REQ07_RE9_TYPESEL_MOS_TS 0x07, 0xe9
316/* ONLY for TM6010 */
270#define TM6010_REQ07_REA_TYPESEL_MOS_CCIR 0x07, 0xea 317#define TM6010_REQ07_REA_TYPESEL_MOS_CCIR 0x07, 0xea
318/* ONLY for TM6010 */
271#define TM6010_REQ07_RF0_BIST_CRC_RESULT0 0x07, 0xf0 319#define TM6010_REQ07_RF0_BIST_CRC_RESULT0 0x07, 0xf0
320/* ONLY for TM6010 */
272#define TM6010_REQ07_RF1_BIST_CRC_RESULT1 0x07, 0xf1 321#define TM6010_REQ07_RF1_BIST_CRC_RESULT1 0x07, 0xf1
322/* ONLY for TM6010 */
273#define TM6010_REQ07_RF2_BIST_CRC_RESULT2 0x07, 0xf2 323#define TM6010_REQ07_RF2_BIST_CRC_RESULT2 0x07, 0xf2
324/* ONLY for TM6010 */
274#define TM6010_REQ07_RF3_BIST_CRC_RESULT3 0x07, 0xf3 325#define TM6010_REQ07_RF3_BIST_CRC_RESULT3 0x07, 0xf3
326/* ONLY for TM6010 */
275#define TM6010_REQ07_RF4_BIST_ERR_VST2 0x07, 0xf4 327#define TM6010_REQ07_RF4_BIST_ERR_VST2 0x07, 0xf4
328/* ONLY for TM6010 */
276#define TM6010_REQ07_RF5_BIST_ERR_VST1 0x07, 0xf5 329#define TM6010_REQ07_RF5_BIST_ERR_VST1 0x07, 0xf5
330/* ONLY for TM6010 */
277#define TM6010_REQ07_RF6_BIST_ERR_VST0 0x07, 0xf6 331#define TM6010_REQ07_RF6_BIST_ERR_VST0 0x07, 0xf6
332/* ONLY for TM6010 */
278#define TM6010_REQ07_RF7_BIST 0x07, 0xf7 333#define TM6010_REQ07_RF7_BIST 0x07, 0xf7
334/* ONLY for TM6010 */
279#define TM6010_REQ07_RFE_POWER_DOWN 0x07, 0xfe 335#define TM6010_REQ07_RFE_POWER_DOWN 0x07, 0xfe
280#define TM6010_REQ07_RFF_SOFT_RESET 0x07, 0xff 336#define TM6010_REQ07_RFF_SOFT_RESET 0x07, 0xff
281 337
@@ -477,7 +533,8 @@ enum {
477#define TM6010_REQ05_RC4_DATA_FIFO14 0x05, 0xf8 533#define TM6010_REQ05_RC4_DATA_FIFO14 0x05, 0xf8
478#define TM6010_REQ05_RC4_DATA_FIFO15 0x05, 0xfc 534#define TM6010_REQ05_RC4_DATA_FIFO15 0x05, 0xfc
479 535
480/* Define TM6000/TM6010 Audio decoder registers */ 536/* Define TM6010 Audio decoder registers */
537/* This core available only in TM6010 */
481#define TM6010_REQ08_R00_A_VERSION 0x08, 0x00 538#define TM6010_REQ08_R00_A_VERSION 0x08, 0x00
482#define TM6010_REQ08_R01_A_INIT 0x08, 0x01 539#define TM6010_REQ08_R01_A_INIT 0x08, 0x01
483#define TM6010_REQ08_R02_A_FIX_GAIN_CTRL 0x08, 0x02 540#define TM6010_REQ08_R02_A_FIX_GAIN_CTRL 0x08, 0x02
@@ -518,7 +575,7 @@ enum {
518#define TM6010_REQ08_R27_A_NOISE_AMP 0x08, 0x27 575#define TM6010_REQ08_R27_A_NOISE_AMP 0x08, 0x27
519#define TM6010_REQ08_R28_A_AUDIO_MODE_RES 0x08, 0x28 576#define TM6010_REQ08_R28_A_AUDIO_MODE_RES 0x08, 0x28
520 577
521/* Define TM6000/TM6010 Video ADC registers */ 578/* Define TM6010 Video ADC registers */
522#define TM6010_REQ08_RE0_ADC_REF 0x08, 0xe0 579#define TM6010_REQ08_RE0_ADC_REF 0x08, 0xe0
523#define TM6010_REQ08_RE1_DAC_CLMP 0x08, 0xe1 580#define TM6010_REQ08_RE1_DAC_CLMP 0x08, 0xe1
524#define TM6010_REQ08_RE2_POWER_DOWN_CTRL1 0x08, 0xe2 581#define TM6010_REQ08_RE2_POWER_DOWN_CTRL1 0x08, 0xe2
@@ -534,7 +591,7 @@ enum {
534#define TM6010_REQ08_REC_REVERSE_YC_CTRL 0x08, 0xec 591#define TM6010_REQ08_REC_REVERSE_YC_CTRL 0x08, 0xec
535#define TM6010_REQ08_RED_GAIN_SEL 0x08, 0xed 592#define TM6010_REQ08_RED_GAIN_SEL 0x08, 0xed
536 593
537/* Define TM6000/TM6010 Audio ADC registers */ 594/* Define TM6010 Audio ADC registers */
538#define TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG 0x08, 0xf0 595#define TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG 0x08, 0xf0
539#define TM6010_REQ08_RF1_AADC_POWER_DOWN 0x08, 0xf1 596#define TM6010_REQ08_RF1_AADC_POWER_DOWN 0x08, 0xf1
540#define TM6010_REQ08_RF2_LEFT_CHANNEL_VOL 0x08, 0xf2 597#define TM6010_REQ08_RF2_LEFT_CHANNEL_VOL 0x08, 0xf2
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index cc7b8664fc20..da3e51bde109 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -952,6 +952,22 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
952 uint8_t mono_flag = 0; /* No mono */ 952 uint8_t mono_flag = 0; /* No mono */
953 uint8_t nicam_flag = 0; /* No NICAM */ 953 uint8_t nicam_flag = 0; /* No NICAM */
954 954
955 if (dev->radio) {
956 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
957 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
958 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
959 tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80);
960 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
961 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
962 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
963 tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a);
964 tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40);
965 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
966 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
967 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
968 return 0;
969 }
970
955 switch (std) { 971 switch (std) {
956#if 0 972#if 0
957 case DK_MONO: 973 case DK_MONO:
@@ -984,20 +1000,6 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
984 case EIAJ: 1000 case EIAJ:
985 areg_05 = 0x02; 1001 areg_05 = 0x02;
986 break; 1002 break;
987 case FM_RADIO:
988 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
989 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
990 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
991 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
992 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
993 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
994 tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91);
995 tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe);
996 tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01);
997 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
998 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
999 return 0;
1000 break;
1001 case I_NICAM: 1003 case I_NICAM:
1002 areg_05 = 0x08; 1004 areg_05 = 0x08;
1003 nicam_flag = 1; 1005 nicam_flag = 1;
@@ -1010,6 +1012,9 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
1010 areg_05 = 0x0a; 1012 areg_05 = 0x0a;
1011 nicam_flag = 1; 1013 nicam_flag = 1;
1012 break; 1014 break;
1015 default:
1016 /* do nothink */
1017 break;
1013 } 1018 }
1014 1019
1015#if 0 1020#if 0
@@ -1156,8 +1161,6 @@ int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm)
1156 rc = tm6000_load_std(dev, svideo_stds[i].common, 1161 rc = tm6000_load_std(dev, svideo_stds[i].common,
1157 sizeof(svideo_stds[i]. 1162 sizeof(svideo_stds[i].
1158 common)); 1163 common));
1159 tm6000_set_audio_std(dev, svideo_stds[i].audio_default_std);
1160
1161 goto ret; 1164 goto ret;
1162 } 1165 }
1163 } 1166 }
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index eb9b9f1bc138..c80a316d9d8f 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -53,11 +53,17 @@
53/* Declare static vars that will be used as parameters */ 53/* Declare static vars that will be used as parameters */
54static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 54static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
55static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 55static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
56static int radio_nr = -1; /* /dev/radioN, -1 for autodetect */
56 57
57/* Debug level */ 58/* Debug level */
58int tm6000_debug; 59int tm6000_debug;
59EXPORT_SYMBOL_GPL(tm6000_debug); 60EXPORT_SYMBOL_GPL(tm6000_debug);
60 61
62static const struct v4l2_queryctrl no_ctrl = {
63 .name = "42",
64 .flags = V4L2_CTRL_FLAG_DISABLED,
65};
66
61/* supported controls */ 67/* supported controls */
62static struct v4l2_queryctrl tm6000_qctrl[] = { 68static struct v4l2_queryctrl tm6000_qctrl[] = {
63 { 69 {
@@ -96,9 +102,26 @@ static struct v4l2_queryctrl tm6000_qctrl[] = {
96 .step = 0x1, 102 .step = 0x1,
97 .default_value = 0, 103 .default_value = 0,
98 .flags = 0, 104 .flags = 0,
105 },
106 /* --- audio --- */
107 {
108 .id = V4L2_CID_AUDIO_MUTE,
109 .name = "Mute",
110 .minimum = 0,
111 .maximum = 1,
112 .type = V4L2_CTRL_TYPE_BOOLEAN,
113 }, {
114 .id = V4L2_CID_AUDIO_VOLUME,
115 .name = "Volume",
116 .minimum = -15,
117 .maximum = 15,
118 .step = 1,
119 .default_value = 0,
120 .type = V4L2_CTRL_TYPE_INTEGER,
99 } 121 }
100}; 122};
101 123
124static const unsigned int CTRLS = ARRAY_SIZE(tm6000_qctrl);
102static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)]; 125static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)];
103 126
104static struct tm6000_fmt format[] = { 127static struct tm6000_fmt format[] = {
@@ -117,6 +140,16 @@ static struct tm6000_fmt format[] = {
117 } 140 }
118}; 141};
119 142
143static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
144{
145 unsigned int i;
146
147 for (i = 0; i < CTRLS; i++)
148 if (tm6000_qctrl[i].id == id)
149 return tm6000_qctrl+i;
150 return NULL;
151}
152
120/* ------------------------------------------------------------------ 153/* ------------------------------------------------------------------
121 * DMA and thread functions 154 * DMA and thread functions
122 * ------------------------------------------------------------------ 155 * ------------------------------------------------------------------
@@ -199,13 +232,17 @@ static int copy_streams(u8 *data, unsigned long len,
199 char *voutp = NULL; 232 char *voutp = NULL;
200 unsigned int linewidth; 233 unsigned int linewidth;
201 234
202 /* get video buffer */ 235 if (!dev->radio) {
203 get_next_buf(dma_q, &vbuf); 236 /* get video buffer */
204 if (!vbuf) 237 get_next_buf(dma_q, &vbuf);
205 return rc; 238
206 voutp = videobuf_to_vmalloc(&vbuf->vb); 239 if (!vbuf)
207 if (!voutp) 240 return rc;
208 return 0; 241 voutp = videobuf_to_vmalloc(&vbuf->vb);
242
243 if (!voutp)
244 return 0;
245 }
209 246
210 for (ptr = data; ptr < endp;) { 247 for (ptr = data; ptr < endp;) {
211 if (!dev->isoc_ctl.cmd) { 248 if (!dev->isoc_ctl.cmd) {
@@ -257,29 +294,31 @@ static int copy_streams(u8 *data, unsigned long len,
257 */ 294 */
258 switch (cmd) { 295 switch (cmd) {
259 case TM6000_URB_MSG_VIDEO: 296 case TM6000_URB_MSG_VIDEO:
260 if ((dev->isoc_ctl.vfield != field) && 297 if (!dev->radio) {
261 (field == 1)) { 298 if ((dev->isoc_ctl.vfield != field) &&
299 (field == 1)) {
262 /* Announces that a new buffer 300 /* Announces that a new buffer
263 * were filled 301 * were filled
264 */ 302 */
265 buffer_filled(dev, dma_q, vbuf); 303 buffer_filled(dev, dma_q, vbuf);
266 dprintk(dev, V4L2_DEBUG_ISOC, 304 dprintk(dev, V4L2_DEBUG_ISOC,
267 "new buffer filled\n"); 305 "new buffer filled\n");
268 get_next_buf(dma_q, &vbuf); 306 get_next_buf(dma_q, &vbuf);
269 if (!vbuf) 307 if (!vbuf)
270 return rc; 308 return rc;
271 voutp = videobuf_to_vmalloc(&vbuf->vb); 309 voutp = videobuf_to_vmalloc(&vbuf->vb);
272 if (!voutp) 310 if (!voutp)
273 return rc; 311 return rc;
274 memset(voutp, 0, vbuf->vb.size); 312 memset(voutp, 0, vbuf->vb.size);
275 } 313 }
276 linewidth = vbuf->vb.width << 1; 314 linewidth = vbuf->vb.width << 1;
277 pos = ((line << 1) - field - 1) * linewidth + 315 pos = ((line << 1) - field - 1) *
278 block * TM6000_URB_MSG_LEN; 316 linewidth + block * TM6000_URB_MSG_LEN;
279 /* Don't allow to write out of the buffer */ 317 /* Don't allow to write out of the buffer */
280 if (pos + size > vbuf->vb.size) 318 if (pos + size > vbuf->vb.size)
281 cmd = TM6000_URB_MSG_ERR; 319 cmd = TM6000_URB_MSG_ERR;
282 dev->isoc_ctl.vfield = field; 320 dev->isoc_ctl.vfield = field;
321 }
283 break; 322 break;
284 case TM6000_URB_MSG_VBI: 323 case TM6000_URB_MSG_VBI:
285 break; 324 break;
@@ -537,7 +576,7 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
537/* 576/*
538 * Allocate URBs and start IRQ 577 * Allocate URBs and start IRQ
539 */ 578 */
540static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) 579static int tm6000_prepare_isoc(struct tm6000_core *dev)
541{ 580{
542 struct tm6000_dmaqueue *dma_q = &dev->vidq; 581 struct tm6000_dmaqueue *dma_q = &dev->vidq;
543 int i, j, sb_size, pipe, size, max_packets, num_bufs = 8; 582 int i, j, sb_size, pipe, size, max_packets, num_bufs = 8;
@@ -566,11 +605,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
566 605
567 dev->isoc_ctl.max_pkt_size = size; 606 dev->isoc_ctl.max_pkt_size = size;
568 607
569 max_packets = (framesize + size - 1) / size; 608 max_packets = TM6000_MAX_ISO_PACKETS;
570
571 if (max_packets > TM6000_MAX_ISO_PACKETS)
572 max_packets = TM6000_MAX_ISO_PACKETS;
573
574 sb_size = max_packets * size; 609 sb_size = max_packets * size;
575 610
576 dev->isoc_ctl.num_bufs = num_bufs; 611 dev->isoc_ctl.num_bufs = num_bufs;
@@ -746,7 +781,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
746 urb_init = 1; 781 urb_init = 1;
747 782
748 if (urb_init) { 783 if (urb_init) {
749 rc = tm6000_prepare_isoc(dev, buf->vb.size); 784 rc = tm6000_prepare_isoc(dev);
750 if (rc < 0) 785 if (rc < 0)
751 goto fail; 786 goto fail;
752 787
@@ -1045,18 +1080,27 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
1045static int vidioc_enum_input(struct file *file, void *priv, 1080static int vidioc_enum_input(struct file *file, void *priv,
1046 struct v4l2_input *inp) 1081 struct v4l2_input *inp)
1047{ 1082{
1083 struct tm6000_fh *fh = priv;
1084 struct tm6000_core *dev = fh->dev;
1085
1048 switch (inp->index) { 1086 switch (inp->index) {
1049 case TM6000_INPUT_TV: 1087 case TM6000_INPUT_TV:
1050 inp->type = V4L2_INPUT_TYPE_TUNER; 1088 inp->type = V4L2_INPUT_TYPE_TUNER;
1051 strcpy(inp->name, "Television"); 1089 strcpy(inp->name, "Television");
1052 break; 1090 break;
1053 case TM6000_INPUT_COMPOSITE: 1091 case TM6000_INPUT_COMPOSITE:
1054 inp->type = V4L2_INPUT_TYPE_CAMERA; 1092 if (dev->caps.has_input_comp) {
1055 strcpy(inp->name, "Composite"); 1093 inp->type = V4L2_INPUT_TYPE_CAMERA;
1094 strcpy(inp->name, "Composite");
1095 } else
1096 return -EINVAL;
1056 break; 1097 break;
1057 case TM6000_INPUT_SVIDEO: 1098 case TM6000_INPUT_SVIDEO:
1058 inp->type = V4L2_INPUT_TYPE_CAMERA; 1099 if (dev->caps.has_input_svid) {
1059 strcpy(inp->name, "S-Video"); 1100 inp->type = V4L2_INPUT_TYPE_CAMERA;
1101 strcpy(inp->name, "S-Video");
1102 } else
1103 return -EINVAL;
1060 break; 1104 break;
1061 default: 1105 default:
1062 return -EINVAL; 1106 return -EINVAL;
@@ -1143,6 +1187,12 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1143 case V4L2_CID_HUE: 1187 case V4L2_CID_HUE:
1144 val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0); 1188 val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0);
1145 return 0; 1189 return 0;
1190 case V4L2_CID_AUDIO_MUTE:
1191 val = dev->ctl_mute;
1192 return 0;
1193 case V4L2_CID_AUDIO_VOLUME:
1194 val = dev->ctl_volume;
1195 return 0;
1146 default: 1196 default:
1147 return -EINVAL; 1197 return -EINVAL;
1148 } 1198 }
@@ -1174,6 +1224,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1174 case V4L2_CID_HUE: 1224 case V4L2_CID_HUE:
1175 tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val); 1225 tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val);
1176 return 0; 1226 return 0;
1227 case V4L2_CID_AUDIO_MUTE:
1228 dev->ctl_mute = val;
1229 tm6000_tvaudio_set_mute(dev, val);
1230 return 0;
1231 case V4L2_CID_AUDIO_VOLUME:
1232 dev->ctl_volume = val;
1233 tm6000_set_volume(dev, val);
1234 return 0;
1177 } 1235 }
1178 return -EINVAL; 1236 return -EINVAL;
1179} 1237}
@@ -1221,7 +1279,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1221 if (unlikely(UNSET == dev->tuner_type)) 1279 if (unlikely(UNSET == dev->tuner_type))
1222 return -EINVAL; 1280 return -EINVAL;
1223 1281
1224 f->type = V4L2_TUNER_ANALOG_TV; 1282 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1225 f->frequency = dev->freq; 1283 f->frequency = dev->freq;
1226 1284
1227 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f); 1285 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f);
@@ -1235,13 +1293,14 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1235 struct tm6000_fh *fh = priv; 1293 struct tm6000_fh *fh = priv;
1236 struct tm6000_core *dev = fh->dev; 1294 struct tm6000_core *dev = fh->dev;
1237 1295
1238 if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
1239 return -EINVAL;
1240
1241 if (unlikely(UNSET == dev->tuner_type)) 1296 if (unlikely(UNSET == dev->tuner_type))
1242 return -EINVAL; 1297 return -EINVAL;
1243 if (unlikely(f->tuner != 0)) 1298 if (unlikely(f->tuner != 0))
1244 return -EINVAL; 1299 return -EINVAL;
1300 if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1301 return -EINVAL;
1302 if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1303 return -EINVAL;
1245 1304
1246 dev->freq = f->frequency; 1305 dev->freq = f->frequency;
1247 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); 1306 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
@@ -1249,6 +1308,122 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1249 return 0; 1308 return 0;
1250} 1309}
1251 1310
1311static int radio_querycap(struct file *file, void *priv,
1312 struct v4l2_capability *cap)
1313{
1314 struct tm6000_fh *fh = file->private_data;
1315 struct tm6000_core *dev = fh->dev;
1316
1317 strcpy(cap->driver, "tm6000");
1318 strlcpy(cap->card, dev->name, sizeof(dev->name));
1319 sprintf(cap->bus_info, "USB%04x:%04x",
1320 le16_to_cpu(dev->udev->descriptor.idVendor),
1321 le16_to_cpu(dev->udev->descriptor.idProduct));
1322 cap->version = dev->dev_type;
1323 cap->capabilities = V4L2_CAP_TUNER;
1324
1325 return 0;
1326}
1327
1328static int radio_g_tuner(struct file *file, void *priv,
1329 struct v4l2_tuner *t)
1330{
1331 struct tm6000_fh *fh = file->private_data;
1332 struct tm6000_core *dev = fh->dev;
1333
1334 if (0 != t->index)
1335 return -EINVAL;
1336
1337 memset(t, 0, sizeof(*t));
1338 strcpy(t->name, "Radio");
1339 t->type = V4L2_TUNER_RADIO;
1340
1341 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
1342
1343 if ((dev->aradio == TM6000_AIP_LINE1) ||
1344 (dev->aradio == TM6000_AIP_LINE2)) {
1345 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1346 }
1347 else {
1348 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
1349 }
1350
1351 return 0;
1352}
1353
1354static int radio_s_tuner(struct file *file, void *priv,
1355 struct v4l2_tuner *t)
1356{
1357 struct tm6000_fh *fh = file->private_data;
1358 struct tm6000_core *dev = fh->dev;
1359
1360 if (0 != t->index)
1361 return -EINVAL;
1362
1363 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
1364
1365 return 0;
1366}
1367
1368static int radio_enum_input(struct file *file, void *priv,
1369 struct v4l2_input *i)
1370{
1371 if (i->index != 0)
1372 return -EINVAL;
1373
1374 strcpy(i->name, "Radio");
1375 i->type = V4L2_INPUT_TYPE_TUNER;
1376
1377 return 0;
1378}
1379
1380static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
1381{
1382 *i = 0;
1383 return 0;
1384}
1385
1386static int radio_g_audio(struct file *file, void *priv,
1387 struct v4l2_audio *a)
1388{
1389 memset(a, 0, sizeof(*a));
1390 strcpy(a->name, "Radio");
1391 return 0;
1392}
1393
1394static int radio_s_audio(struct file *file, void *priv,
1395 struct v4l2_audio *a)
1396{
1397 return 0;
1398}
1399
1400static int radio_s_input(struct file *filp, void *priv, unsigned int i)
1401{
1402 return 0;
1403}
1404
1405static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm)
1406{
1407 return 0;
1408}
1409
1410static int radio_queryctrl(struct file *file, void *priv,
1411 struct v4l2_queryctrl *c)
1412{
1413 const struct v4l2_queryctrl *ctrl;
1414
1415 if (c->id < V4L2_CID_BASE ||
1416 c->id >= V4L2_CID_LASTP1)
1417 return -EINVAL;
1418 if (c->id == V4L2_CID_AUDIO_MUTE) {
1419 ctrl = ctrl_by_id(c->id);
1420 *c = *ctrl;
1421 } else
1422 *c = no_ctrl;
1423
1424 return 0;
1425}
1426
1252/* ------------------------------------------------------------------ 1427/* ------------------------------------------------------------------
1253 File operations for the device 1428 File operations for the device
1254 ------------------------------------------------------------------*/ 1429 ------------------------------------------------------------------*/
@@ -1260,6 +1435,7 @@ static int tm6000_open(struct file *file)
1260 struct tm6000_fh *fh; 1435 struct tm6000_fh *fh;
1261 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1436 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1262 int i, rc; 1437 int i, rc;
1438 int radio = 0;
1263 1439
1264 printk(KERN_INFO "tm6000: open called (dev=%s)\n", 1440 printk(KERN_INFO "tm6000: open called (dev=%s)\n",
1265 video_device_node_name(vdev)); 1441 video_device_node_name(vdev));
@@ -1267,6 +1443,17 @@ static int tm6000_open(struct file *file)
1267 dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n", 1443 dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n",
1268 video_device_node_name(vdev)); 1444 video_device_node_name(vdev));
1269 1445
1446 switch (vdev->vfl_type) {
1447 case VFL_TYPE_GRABBER:
1448 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1449 break;
1450 case VFL_TYPE_VBI:
1451 type = V4L2_BUF_TYPE_VBI_CAPTURE;
1452 break;
1453 case VFL_TYPE_RADIO:
1454 radio = 1;
1455 break;
1456 }
1270 1457
1271 /* If more than one user, mutex should be added */ 1458 /* If more than one user, mutex should be added */
1272 dev->users++; 1459 dev->users++;
@@ -1284,8 +1471,9 @@ static int tm6000_open(struct file *file)
1284 1471
1285 file->private_data = fh; 1472 file->private_data = fh;
1286 fh->dev = dev; 1473 fh->dev = dev;
1287 1474 fh->radio = radio;
1288 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1475 dev->radio = radio;
1476 fh->type = type;
1289 dev->fourcc = format[0].fourcc; 1477 dev->fourcc = format[0].fourcc;
1290 1478
1291 fh->fmt = format_by_fourcc(dev->fourcc); 1479 fh->fmt = format_by_fourcc(dev->fourcc);
@@ -1322,6 +1510,19 @@ static int tm6000_open(struct file *file)
1322 V4L2_FIELD_INTERLACED, 1510 V4L2_FIELD_INTERLACED,
1323 sizeof(struct tm6000_buffer), fh, &dev->lock); 1511 sizeof(struct tm6000_buffer), fh, &dev->lock);
1324 1512
1513 if (fh->radio) {
1514 dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n");
1515 tm6000_set_audio_input(dev, dev->aradio);
1516 tm6000_set_volume(dev, dev->ctl_volume);
1517 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
1518 tm6000_prepare_isoc(dev);
1519 tm6000_start_thread(dev);
1520 }
1521 else {
1522 tm6000_set_audio_input(dev, dev->avideo);
1523 tm6000_set_volume(dev, dev->ctl_volume);
1524 }
1525
1325 return 0; 1526 return 0;
1326} 1527}
1327 1528
@@ -1445,6 +1646,36 @@ static struct video_device tm6000_template = {
1445 .current_norm = V4L2_STD_NTSC_M, 1646 .current_norm = V4L2_STD_NTSC_M,
1446}; 1647};
1447 1648
1649static const struct v4l2_file_operations radio_fops = {
1650 .owner = THIS_MODULE,
1651 .open = tm6000_open,
1652 .release = tm6000_release,
1653 .ioctl = video_ioctl2,
1654};
1655
1656static const struct v4l2_ioctl_ops radio_ioctl_ops = {
1657 .vidioc_querycap = radio_querycap,
1658 .vidioc_g_tuner = radio_g_tuner,
1659 .vidioc_enum_input = radio_enum_input,
1660 .vidioc_g_audio = radio_g_audio,
1661 .vidioc_s_tuner = radio_s_tuner,
1662 .vidioc_s_audio = radio_s_audio,
1663 .vidioc_s_input = radio_s_input,
1664 .vidioc_s_std = radio_s_std,
1665 .vidioc_queryctrl = radio_queryctrl,
1666 .vidioc_g_input = radio_g_input,
1667 .vidioc_g_ctrl = vidioc_g_ctrl,
1668 .vidioc_s_ctrl = vidioc_s_ctrl,
1669 .vidioc_g_frequency = vidioc_g_frequency,
1670 .vidioc_s_frequency = vidioc_s_frequency,
1671};
1672
1673struct video_device tm6000_radio_template = {
1674 .name = "tm6000",
1675 .fops = &radio_fops,
1676 .ioctl_ops = &radio_ioctl_ops,
1677};
1678
1448/* ----------------------------------------------------------------- 1679/* -----------------------------------------------------------------
1449 * Initialization and module stuff 1680 * Initialization and module stuff
1450 * ------------------------------------------------------------------ 1681 * ------------------------------------------------------------------
@@ -1499,6 +1730,25 @@ int tm6000_v4l2_register(struct tm6000_core *dev)
1499 printk(KERN_INFO "%s: registered device %s\n", 1730 printk(KERN_INFO "%s: registered device %s\n",
1500 dev->name, video_device_node_name(dev->vfd)); 1731 dev->name, video_device_node_name(dev->vfd));
1501 1732
1733 dev->radio_dev = vdev_init(dev, &tm6000_radio_template,
1734 "radio");
1735 if (!dev->radio_dev) {
1736 printk(KERN_INFO "%s: can't register radio device\n",
1737 dev->name);
1738 return ret; /* FIXME release resource */
1739 }
1740
1741 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
1742 radio_nr);
1743 if (ret < 0) {
1744 printk(KERN_INFO "%s: can't register radio device\n",
1745 dev->name);
1746 return ret; /* FIXME release resource */
1747 }
1748
1749 printk(KERN_INFO "%s: registered device %s\n",
1750 dev->name, video_device_node_name(dev->radio_dev));
1751
1502 printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); 1752 printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret);
1503 return ret; 1753 return ret;
1504} 1754}
@@ -1507,6 +1757,14 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev)
1507{ 1757{
1508 video_unregister_device(dev->vfd); 1758 video_unregister_device(dev->vfd);
1509 1759
1760 if (dev->radio_dev) {
1761 if (video_is_registered(dev->radio_dev))
1762 video_unregister_device(dev->radio_dev);
1763 else
1764 video_device_release(dev->radio_dev);
1765 dev->radio_dev = NULL;
1766 }
1767
1510 return 0; 1768 return 0;
1511} 1769}
1512 1770
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index bf11eeec92c7..99ae50e82b28 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -53,6 +53,14 @@ enum tm6000_devtype {
53 TM6010, 53 TM6010,
54}; 54};
55 55
56enum tm6000_inaudio {
57 TM6000_AIP_UNK = 0,
58 TM6000_AIP_SIF1,
59 TM6000_AIP_SIF2,
60 TM6000_AIP_LINE1,
61 TM6000_AIP_LINE2,
62};
63
56/* ------------------------------------------------------------------ 64/* ------------------------------------------------------------------
57 * Basic structures 65 * Basic structures
58 * ------------------------------------------------------------------ 66 * ------------------------------------------------------------------
@@ -121,6 +129,8 @@ struct tm6000_capabilities {
121 unsigned int has_zl10353:1; 129 unsigned int has_zl10353:1;
122 unsigned int has_eeprom:1; 130 unsigned int has_eeprom:1;
123 unsigned int has_remote:1; 131 unsigned int has_remote:1;
132 unsigned int has_input_comp:1;
133 unsigned int has_input_svid:1;
124}; 134};
125 135
126struct tm6000_dvb { 136struct tm6000_dvb {
@@ -174,6 +184,8 @@ struct tm6000_core {
174 184
175 char *ir_codes; 185 char *ir_codes;
176 186
187 __u8 radio;
188
177 /* Demodulator configuration */ 189 /* Demodulator configuration */
178 int demod_addr; /* demodulator address */ 190 int demod_addr; /* demodulator address */
179 191
@@ -194,6 +206,7 @@ struct tm6000_core {
194 bool is_res_read; 206 bool is_res_read;
195 207
196 struct video_device *vfd; 208 struct video_device *vfd;
209 struct video_device *radio_dev;
197 struct tm6000_dmaqueue vidq; 210 struct tm6000_dmaqueue vidq;
198 struct v4l2_device v4l2_dev; 211 struct v4l2_device v4l2_dev;
199 212
@@ -203,6 +216,9 @@ struct tm6000_core {
203 216
204 enum tm6000_mode mode; 217 enum tm6000_mode mode;
205 218
219 int ctl_mute; /* audio */
220 int ctl_volume;
221
206 /* DVB-T support */ 222 /* DVB-T support */
207 struct tm6000_dvb *dvb; 223 struct tm6000_dvb *dvb;
208 224
@@ -210,7 +226,8 @@ struct tm6000_core {
210 struct snd_tm6000_card *adev; 226 struct snd_tm6000_card *adev;
211 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ 227 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
212 atomic_t stream_started; /* stream should be running if true */ 228 atomic_t stream_started; /* stream should be running if true */
213 229 enum tm6000_inaudio avideo;
230 enum tm6000_inaudio aradio;
214 231
215 struct tm6000_IR *ir; 232 struct tm6000_IR *ir;
216 233
@@ -248,6 +265,7 @@ struct tm6000_ops {
248 265
249struct tm6000_fh { 266struct tm6000_fh {
250 struct tm6000_core *dev; 267 struct tm6000_core *dev;
268 unsigned int radio;
251 269
252 /* video capture */ 270 /* video capture */
253 struct tm6000_fmt *fmt; 271 struct tm6000_fmt *fmt;
@@ -276,12 +294,17 @@ int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
276int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index); 294int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
277int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index); 295int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
278int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index); 296int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
297int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
298 u16 index, u16 mask);
279int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep); 299int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
280int tm6000_init(struct tm6000_core *dev); 300int tm6000_init(struct tm6000_core *dev);
281 301
282int tm6000_init_analog_mode(struct tm6000_core *dev); 302int tm6000_init_analog_mode(struct tm6000_core *dev);
283int tm6000_init_digital_mode(struct tm6000_core *dev); 303int tm6000_init_digital_mode(struct tm6000_core *dev);
284int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate); 304int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
305int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp);
306int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute);
307void tm6000_set_volume(struct tm6000_core *dev, int vol);
285 308
286int tm6000_v4l2_register(struct tm6000_core *dev); 309int tm6000_v4l2_register(struct tm6000_core *dev);
287int tm6000_v4l2_unregister(struct tm6000_core *dev); 310int tm6000_v4l2_unregister(struct tm6000_core *dev);
diff --git a/drivers/staging/usbvideo/Kconfig b/drivers/staging/usbvideo/Kconfig
deleted file mode 100644
index 566d659e6ff3..000000000000
--- a/drivers/staging/usbvideo/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
1config VIDEO_USBVIDEO
2 tristate
3
4config USB_VICAM
5 tristate "USB 3com HomeConnect (aka vicam) support (DEPRECATED)"
6 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && USB
7 select VIDEO_USBVIDEO
8 ---help---
9 Say Y here if you have 3com homeconnect camera (vicam).
10
11 This driver uses the deprecated V4L1 API and will be removed in
12 2.6.39, unless someone converts it to the V4L2 API.
13
14 To compile this driver as a module, choose M here: the
15 module will be called vicam.
diff --git a/drivers/staging/usbvideo/Makefile b/drivers/staging/usbvideo/Makefile
deleted file mode 100644
index 3c99a9a2d8d3..000000000000
--- a/drivers/staging/usbvideo/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o
2obj-$(CONFIG_USB_VICAM) += vicam.o
diff --git a/drivers/staging/usbvideo/TODO b/drivers/staging/usbvideo/TODO
deleted file mode 100644
index 3b2c03836286..000000000000
--- a/drivers/staging/usbvideo/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1This is an obsolete driver for some old webcams that still use V4L1 API.
2As V4L1 support is being removed from kernel, if nobody take care on it,
3the driver will be removed for 2.6.39.
4
5Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/usbvideo/usbvideo.c b/drivers/staging/usbvideo/usbvideo.c
deleted file mode 100644
index cd4c73af99ab..000000000000
--- a/drivers/staging/usbvideo/usbvideo.c
+++ /dev/null
@@ -1,2222 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/list.h>
20#include <linux/slab.h>
21#include <linux/module.h>
22#include <linux/mm.h>
23#include <linux/vmalloc.h>
24#include <linux/init.h>
25#include <linux/spinlock.h>
26
27#include <linux/io.h>
28
29#include "usbvideo.h"
30
31#if defined(MAP_NR)
32#define virt_to_page(v) MAP_NR(v) /* Kernels 2.2.x */
33#endif
34
35static int video_nr = -1;
36module_param(video_nr, int, 0);
37
38/*
39 * Local prototypes.
40 */
41static void usbvideo_Disconnect(struct usb_interface *intf);
42static void usbvideo_CameraRelease(struct uvd *uvd);
43
44static long usbvideo_v4l_ioctl(struct file *file,
45 unsigned int cmd, unsigned long arg);
46static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma);
47static int usbvideo_v4l_open(struct file *file);
48static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
49 size_t count, loff_t *ppos);
50static int usbvideo_v4l_close(struct file *file);
51
52static int usbvideo_StartDataPump(struct uvd *uvd);
53static void usbvideo_StopDataPump(struct uvd *uvd);
54static int usbvideo_GetFrame(struct uvd *uvd, int frameNum);
55static int usbvideo_NewFrame(struct uvd *uvd, int framenum);
56static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
57 struct usbvideo_frame *frame);
58
59/*******************************/
60/* Memory management functions */
61/*******************************/
62static void *usbvideo_rvmalloc(unsigned long size)
63{
64 void *mem;
65 unsigned long adr;
66
67 size = PAGE_ALIGN(size);
68 mem = vmalloc_32(size);
69 if (!mem)
70 return NULL;
71
72 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
73 adr = (unsigned long) mem;
74 while (size > 0) {
75 SetPageReserved(vmalloc_to_page((void *)adr));
76 adr += PAGE_SIZE;
77 size -= PAGE_SIZE;
78 }
79
80 return mem;
81}
82
83static void usbvideo_rvfree(void *mem, unsigned long size)
84{
85 unsigned long adr;
86
87 if (!mem)
88 return;
89
90 adr = (unsigned long) mem;
91 while ((long) size > 0) {
92 ClearPageReserved(vmalloc_to_page((void *)adr));
93 adr += PAGE_SIZE;
94 size -= PAGE_SIZE;
95 }
96 vfree(mem);
97}
98
99static void RingQueue_Initialize(struct RingQueue *rq)
100{
101 assert(rq != NULL);
102 init_waitqueue_head(&rq->wqh);
103}
104
105static void RingQueue_Allocate(struct RingQueue *rq, int rqLen)
106{
107 /* Make sure the requested size is a power of 2 and
108 round up if necessary. This allows index wrapping
109 using masks rather than modulo */
110
111 int i = 1;
112 assert(rq != NULL);
113 assert(rqLen > 0);
114
115 while (rqLen >> i)
116 i++;
117 if (rqLen != 1 << (i-1))
118 rqLen = 1 << i;
119
120 rq->length = rqLen;
121 rq->ri = rq->wi = 0;
122 rq->queue = usbvideo_rvmalloc(rq->length);
123 assert(rq->queue != NULL);
124}
125
126static int RingQueue_IsAllocated(const struct RingQueue *rq)
127{
128 if (rq == NULL)
129 return 0;
130 return (rq->queue != NULL) && (rq->length > 0);
131}
132
133static void RingQueue_Free(struct RingQueue *rq)
134{
135 assert(rq != NULL);
136 if (RingQueue_IsAllocated(rq)) {
137 usbvideo_rvfree(rq->queue, rq->length);
138 rq->queue = NULL;
139 rq->length = 0;
140 }
141}
142
143int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len)
144{
145 int rql, toread;
146
147 assert(rq != NULL);
148 assert(dst != NULL);
149
150 rql = RingQueue_GetLength(rq);
151 if (!rql)
152 return 0;
153
154 /* Clip requested length to available data */
155 if (len > rql)
156 len = rql;
157
158 toread = len;
159 if (rq->ri > rq->wi) {
160 /* Read data from tail */
161 int read = (toread < (rq->length - rq->ri)) ? toread : rq->length - rq->ri;
162 memcpy(dst, rq->queue + rq->ri, read);
163 toread -= read;
164 dst += read;
165 rq->ri = (rq->ri + read) & (rq->length-1);
166 }
167 if (toread) {
168 /* Read data from head */
169 memcpy(dst, rq->queue + rq->ri, toread);
170 rq->ri = (rq->ri + toread) & (rq->length-1);
171 }
172 return len;
173}
174
175EXPORT_SYMBOL(RingQueue_Dequeue);
176
177int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n)
178{
179 int enqueued = 0;
180
181 assert(rq != NULL);
182 assert(cdata != NULL);
183 assert(rq->length > 0);
184 while (n > 0) {
185 int m, q_avail;
186
187 /* Calculate the largest chunk that fits the tail of the ring */
188 q_avail = rq->length - rq->wi;
189 if (q_avail <= 0) {
190 rq->wi = 0;
191 q_avail = rq->length;
192 }
193 m = n;
194 assert(q_avail > 0);
195 if (m > q_avail)
196 m = q_avail;
197
198 memcpy(rq->queue + rq->wi, cdata, m);
199 RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
200 cdata += m;
201 enqueued += m;
202 n -= m;
203 }
204 return enqueued;
205}
206
207EXPORT_SYMBOL(RingQueue_Enqueue);
208
209static void RingQueue_InterruptibleSleepOn(struct RingQueue *rq)
210{
211 assert(rq != NULL);
212 interruptible_sleep_on(&rq->wqh);
213}
214
215void RingQueue_WakeUpInterruptible(struct RingQueue *rq)
216{
217 assert(rq != NULL);
218 if (waitqueue_active(&rq->wqh))
219 wake_up_interruptible(&rq->wqh);
220}
221
222EXPORT_SYMBOL(RingQueue_WakeUpInterruptible);
223
224void RingQueue_Flush(struct RingQueue *rq)
225{
226 assert(rq != NULL);
227 rq->ri = 0;
228 rq->wi = 0;
229}
230
231EXPORT_SYMBOL(RingQueue_Flush);
232
233
234/*
235 * usbvideo_VideosizeToString()
236 *
237 * This procedure converts given videosize value to readable string.
238 *
239 * History:
240 * 07-Aug-2000 Created.
241 * 19-Oct-2000 Reworked for usbvideo module.
242 */
243static void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs)
244{
245 char tmp[40];
246 int n;
247
248 n = 1 + sprintf(tmp, "%ldx%ld", VIDEOSIZE_X(vs), VIDEOSIZE_Y(vs));
249 assert(n < sizeof(tmp));
250 if ((buf == NULL) || (bufLen < n))
251 err("usbvideo_VideosizeToString: buffer is too small.");
252 else
253 memmove(buf, tmp, n);
254}
255
256/*
257 * usbvideo_OverlayChar()
258 *
259 * History:
260 * 01-Feb-2000 Created.
261 */
262static void usbvideo_OverlayChar(struct uvd *uvd, struct usbvideo_frame *frame,
263 int x, int y, int ch)
264{
265 static const unsigned short digits[16] = {
266 0xF6DE, /* 0 */
267 0x2492, /* 1 */
268 0xE7CE, /* 2 */
269 0xE79E, /* 3 */
270 0xB792, /* 4 */
271 0xF39E, /* 5 */
272 0xF3DE, /* 6 */
273 0xF492, /* 7 */
274 0xF7DE, /* 8 */
275 0xF79E, /* 9 */
276 0x77DA, /* a */
277 0xD75C, /* b */
278 0xF24E, /* c */
279 0xD6DC, /* d */
280 0xF34E, /* e */
281 0xF348 /* f */
282 };
283 unsigned short digit;
284 int ix, iy;
285 int value;
286
287 if ((uvd == NULL) || (frame == NULL))
288 return;
289
290 value = hex_to_bin(ch);
291 if (value < 0)
292 return;
293 digit = digits[value];
294
295 for (iy = 0; iy < 5; iy++) {
296 for (ix = 0; ix < 3; ix++) {
297 if (digit & 0x8000) {
298 if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))
299/* TODO */ RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
300 }
301 digit = digit << 1;
302 }
303 }
304}
305
306/*
307 * usbvideo_OverlayString()
308 *
309 * History:
310 * 01-Feb-2000 Created.
311 */
312static void usbvideo_OverlayString(struct uvd *uvd, struct usbvideo_frame *frame,
313 int x, int y, const char *str)
314{
315 while (*str) {
316 usbvideo_OverlayChar(uvd, frame, x, y, *str);
317 str++;
318 x += 4; /* 3 pixels character + 1 space */
319 }
320}
321
322/*
323 * usbvideo_OverlayStats()
324 *
325 * Overlays important debugging information.
326 *
327 * History:
328 * 01-Feb-2000 Created.
329 */
330static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame)
331{
332 const int y_diff = 8;
333 char tmp[16];
334 int x = 10, y = 10;
335 long i, j, barLength;
336 const int qi_x1 = 60, qi_y1 = 10;
337 const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10;
338
339 /* Call the user callback, see if we may proceed after that */
340 if (VALID_CALLBACK(uvd, overlayHook)) {
341 if (GET_CALLBACK(uvd, overlayHook)(uvd, frame) < 0)
342 return;
343 }
344
345 /*
346 * We draw a (mostly) hollow rectangle with qi_xxx coordinates.
347 * Left edge symbolizes the queue index 0; right edge symbolizes
348 * the full capacity of the queue.
349 */
350 barLength = qi_x2 - qi_x1 - 2;
351 if ((barLength > 10) && (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))) {
352/* TODO */ long u_lo, u_hi, q_used;
353 long m_ri, m_wi, m_lo, m_hi;
354
355 /*
356 * Determine fill zones (used areas of the queue):
357 * 0 xxxxxxx u_lo ...... uvd->dp.ri xxxxxxxx u_hi ..... uvd->dp.length
358 *
359 * if u_lo < 0 then there is no first filler.
360 */
361
362 q_used = RingQueue_GetLength(&uvd->dp);
363 if ((uvd->dp.ri + q_used) >= uvd->dp.length) {
364 u_hi = uvd->dp.length;
365 u_lo = (q_used + uvd->dp.ri) & (uvd->dp.length-1);
366 } else {
367 u_hi = (q_used + uvd->dp.ri);
368 u_lo = -1;
369 }
370
371 /* Convert byte indices into screen units */
372 m_ri = qi_x1 + ((barLength * uvd->dp.ri) / uvd->dp.length);
373 m_wi = qi_x1 + ((barLength * uvd->dp.wi) / uvd->dp.length);
374 m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1;
375 m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length);
376
377 for (j = qi_y1; j < (qi_y1 + qi_h); j++) {
378 for (i = qi_x1; i < qi_x2; i++) {
379 /* Draw border lines */
380 if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) ||
381 (i == qi_x1) || (i == (qi_x2 - 1))) {
382 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0xFF, 0xFF);
383 continue;
384 }
385 /* For all other points the Y coordinate does not matter */
386 if ((i >= m_ri) && (i <= (m_ri + 3)))
387 RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00);
388 else if ((i >= m_wi) && (i <= (m_wi + 3)))
389 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00);
390 else if ((i < m_lo) || ((i > m_ri) && (i < m_hi)))
391 RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF);
392 }
393 }
394 }
395
396 sprintf(tmp, "%8lx", uvd->stats.frame_num);
397 usbvideo_OverlayString(uvd, frame, x, y, tmp);
398 y += y_diff;
399
400 sprintf(tmp, "%8lx", uvd->stats.urb_count);
401 usbvideo_OverlayString(uvd, frame, x, y, tmp);
402 y += y_diff;
403
404 sprintf(tmp, "%8lx", uvd->stats.urb_length);
405 usbvideo_OverlayString(uvd, frame, x, y, tmp);
406 y += y_diff;
407
408 sprintf(tmp, "%8lx", uvd->stats.data_count);
409 usbvideo_OverlayString(uvd, frame, x, y, tmp);
410 y += y_diff;
411
412 sprintf(tmp, "%8lx", uvd->stats.header_count);
413 usbvideo_OverlayString(uvd, frame, x, y, tmp);
414 y += y_diff;
415
416 sprintf(tmp, "%8lx", uvd->stats.iso_skip_count);
417 usbvideo_OverlayString(uvd, frame, x, y, tmp);
418 y += y_diff;
419
420 sprintf(tmp, "%8lx", uvd->stats.iso_err_count);
421 usbvideo_OverlayString(uvd, frame, x, y, tmp);
422 y += y_diff;
423
424 sprintf(tmp, "%8x", uvd->vpic.colour);
425 usbvideo_OverlayString(uvd, frame, x, y, tmp);
426 y += y_diff;
427
428 sprintf(tmp, "%8x", uvd->vpic.hue);
429 usbvideo_OverlayString(uvd, frame, x, y, tmp);
430 y += y_diff;
431
432 sprintf(tmp, "%8x", uvd->vpic.brightness >> 8);
433 usbvideo_OverlayString(uvd, frame, x, y, tmp);
434 y += y_diff;
435
436 sprintf(tmp, "%8x", uvd->vpic.contrast >> 12);
437 usbvideo_OverlayString(uvd, frame, x, y, tmp);
438 y += y_diff;
439
440 sprintf(tmp, "%8d", uvd->vpic.whiteness >> 8);
441 usbvideo_OverlayString(uvd, frame, x, y, tmp);
442 y += y_diff;
443}
444
445/*
446 * usbvideo_ReportStatistics()
447 *
448 * This procedure prints packet and transfer statistics.
449 *
450 * History:
451 * 14-Jan-2000 Corrected default multiplier.
452 */
453static void usbvideo_ReportStatistics(const struct uvd *uvd)
454{
455 if ((uvd != NULL) && (uvd->stats.urb_count > 0)) {
456 unsigned long allPackets, badPackets, goodPackets, percent;
457 allPackets = uvd->stats.urb_count * CAMERA_URB_FRAMES;
458 badPackets = uvd->stats.iso_skip_count + uvd->stats.iso_err_count;
459 goodPackets = allPackets - badPackets;
460 /* Calculate percentage wisely, remember integer limits */
461 assert(allPackets != 0);
462 if (goodPackets < (((unsigned long)-1)/100))
463 percent = (100 * goodPackets) / allPackets;
464 else
465 percent = goodPackets / (allPackets / 100);
466 dev_info(&uvd->dev->dev,
467 "Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%\n",
468 allPackets, badPackets, percent);
469 if (uvd->iso_packet_len > 0) {
470 unsigned long allBytes, xferBytes;
471 char multiplier = ' ';
472 allBytes = allPackets * uvd->iso_packet_len;
473 xferBytes = uvd->stats.data_count;
474 assert(allBytes != 0);
475 if (xferBytes < (((unsigned long)-1)/100))
476 percent = (100 * xferBytes) / allBytes;
477 else
478 percent = xferBytes / (allBytes / 100);
479 /* Scale xferBytes for easy reading */
480 if (xferBytes > 10*1024) {
481 xferBytes /= 1024;
482 multiplier = 'K';
483 if (xferBytes > 10*1024) {
484 xferBytes /= 1024;
485 multiplier = 'M';
486 if (xferBytes > 10*1024) {
487 xferBytes /= 1024;
488 multiplier = 'G';
489 if (xferBytes > 10*1024) {
490 xferBytes /= 1024;
491 multiplier = 'T';
492 }
493 }
494 }
495 }
496 dev_info(&uvd->dev->dev,
497 "Transfer Statistics: Transferred=%lu%cB Usage=%lu%%\n",
498 xferBytes, multiplier, percent);
499 }
500 }
501}
502
503/*
504 * usbvideo_TestPattern()
505 *
506 * Procedure forms a test pattern (yellow grid on blue background).
507 *
508 * Parameters:
509 * fullframe: if TRUE then entire frame is filled, otherwise the procedure
510 * continues from the current scanline.
511 * pmode 0: fill the frame with solid blue color (like on VCR or TV)
512 * 1: Draw a colored grid
513 *
514 * History:
515 * 01-Feb-2000 Created.
516 */
517void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode)
518{
519 struct usbvideo_frame *frame;
520 int num_cell = 0;
521 int scan_length = 0;
522 static int num_pass;
523
524 if (uvd == NULL) {
525 err("%s: uvd == NULL", __func__);
526 return;
527 }
528 if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
529 err("%s: uvd->curframe=%d.", __func__, uvd->curframe);
530 return;
531 }
532
533 /* Grab the current frame */
534 frame = &uvd->frame[uvd->curframe];
535
536 /* Optionally start at the beginning */
537 if (fullframe) {
538 frame->curline = 0;
539 frame->seqRead_Length = 0;
540 }
541#if 0
542 { /* For debugging purposes only */
543 char tmp[20];
544 usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request);
545 dev_info(&uvd->dev->dev, "testpattern: frame=%s\n", tmp);
546 }
547#endif
548 /* Form every scan line */
549 for (; frame->curline < VIDEOSIZE_Y(frame->request); frame->curline++) {
550 int i;
551 unsigned char *f = frame->data +
552 (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline);
553 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
554 unsigned char cb = 0x80;
555 unsigned char cg = 0;
556 unsigned char cr = 0;
557
558 if (pmode == 1) {
559 if (frame->curline % 32 == 0)
560 cb = 0, cg = cr = 0xFF;
561 else if (i % 32 == 0) {
562 if (frame->curline % 32 == 1)
563 num_cell++;
564 cb = 0, cg = cr = 0xFF;
565 } else {
566 cb = ((num_cell*7) + num_pass) & 0xFF;
567 cg = ((num_cell*5) + num_pass*2) & 0xFF;
568 cr = ((num_cell*3) + num_pass*3) & 0xFF;
569 }
570 } else {
571 /* Just the blue screen */
572 }
573
574 *f++ = cb;
575 *f++ = cg;
576 *f++ = cr;
577 scan_length += 3;
578 }
579 }
580
581 frame->frameState = FrameState_Done;
582 frame->seqRead_Length += scan_length;
583 ++num_pass;
584
585 /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
586 usbvideo_OverlayStats(uvd, frame);
587}
588
589EXPORT_SYMBOL(usbvideo_TestPattern);
590
591
592#ifdef DEBUG
593/*
594 * usbvideo_HexDump()
595 *
596 * A debugging tool. Prints hex dumps.
597 *
598 * History:
599 * 29-Jul-2000 Added printing of offsets.
600 */
601void usbvideo_HexDump(const unsigned char *data, int len)
602{
603 const int bytes_per_line = 32;
604 char tmp[128]; /* 32*3 + 5 */
605 int i, k;
606
607 for (i = k = 0; len > 0; i++, len--) {
608 if (i > 0 && ((i % bytes_per_line) == 0)) {
609 printk("%s\n", tmp);
610 k = 0;
611 }
612 if ((i % bytes_per_line) == 0)
613 k += sprintf(&tmp[k], "%04x: ", i);
614 k += sprintf(&tmp[k], "%02x ", data[i]);
615 }
616 if (k > 0)
617 printk("%s\n", tmp);
618}
619
620EXPORT_SYMBOL(usbvideo_HexDump);
621
622#endif
623
624/* ******************************************************************** */
625
626/* XXX: this piece of crap really wants some error handling.. */
627static int usbvideo_ClientIncModCount(struct uvd *uvd)
628{
629 if (uvd == NULL) {
630 err("%s: uvd == NULL", __func__);
631 return -EINVAL;
632 }
633 if (uvd->handle == NULL) {
634 err("%s: uvd->handle == NULL", __func__);
635 return -EINVAL;
636 }
637 if (!try_module_get(uvd->handle->md_module)) {
638 err("%s: try_module_get() == 0", __func__);
639 return -ENODEV;
640 }
641 return 0;
642}
643
644static void usbvideo_ClientDecModCount(struct uvd *uvd)
645{
646 if (uvd == NULL) {
647 err("%s: uvd == NULL", __func__);
648 return;
649 }
650 if (uvd->handle == NULL) {
651 err("%s: uvd->handle == NULL", __func__);
652 return;
653 }
654 if (uvd->handle->md_module == NULL) {
655 err("%s: uvd->handle->md_module == NULL", __func__);
656 return;
657 }
658 module_put(uvd->handle->md_module);
659}
660
661int usbvideo_register(
662 struct usbvideo **pCams,
663 const int num_cams,
664 const int num_extra,
665 const char *driverName,
666 const struct usbvideo_cb *cbTbl,
667 struct module *md,
668 const struct usb_device_id *id_table)
669{
670 struct usbvideo *cams;
671 int i, base_size, result;
672
673 /* Check parameters for sanity */
674 if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) {
675 err("%s: Illegal call", __func__);
676 return -EINVAL;
677 }
678
679 /* Check registration callback - must be set! */
680 if (cbTbl->probe == NULL) {
681 err("%s: probe() is required!", __func__);
682 return -EINVAL;
683 }
684
685 base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo);
686 cams = kzalloc(base_size, GFP_KERNEL);
687 if (cams == NULL) {
688 err("Failed to allocate %d. bytes for usbvideo struct", base_size);
689 return -ENOMEM;
690 }
691 dbg("%s: Allocated $%p (%d. bytes) for %d. cameras",
692 __func__, cams, base_size, num_cams);
693
694 /* Copy callbacks, apply defaults for those that are not set */
695 memmove(&cams->cb, cbTbl, sizeof(cams->cb));
696 if (cams->cb.getFrame == NULL)
697 cams->cb.getFrame = usbvideo_GetFrame;
698 if (cams->cb.disconnect == NULL)
699 cams->cb.disconnect = usbvideo_Disconnect;
700 if (cams->cb.startDataPump == NULL)
701 cams->cb.startDataPump = usbvideo_StartDataPump;
702 if (cams->cb.stopDataPump == NULL)
703 cams->cb.stopDataPump = usbvideo_StopDataPump;
704
705 cams->num_cameras = num_cams;
706 cams->cam = (struct uvd *) &cams[1];
707 cams->md_module = md;
708 mutex_init(&cams->lock); /* to 1 == available */
709
710 for (i = 0; i < num_cams; i++) {
711 struct uvd *up = &cams->cam[i];
712
713 up->handle = cams;
714
715 /* Allocate user_data separately because of kmalloc's limits */
716 if (num_extra > 0) {
717 up->user_size = num_cams * num_extra;
718 up->user_data = kmalloc(up->user_size, GFP_KERNEL);
719 if (up->user_data == NULL) {
720 err("%s: Failed to allocate user_data (%d. bytes)",
721 __func__, up->user_size);
722 while (i) {
723 up = &cams->cam[--i];
724 kfree(up->user_data);
725 }
726 kfree(cams);
727 return -ENOMEM;
728 }
729 dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)",
730 __func__, i, up->user_data, up->user_size);
731 }
732 }
733
734 /*
735 * Register ourselves with USB stack.
736 */
737 strcpy(cams->drvName, (driverName != NULL) ? driverName : "Unknown");
738 cams->usbdrv.name = cams->drvName;
739 cams->usbdrv.probe = cams->cb.probe;
740 cams->usbdrv.disconnect = cams->cb.disconnect;
741 cams->usbdrv.id_table = id_table;
742
743 /*
744 * Update global handle to usbvideo. This is very important
745 * because probe() can be called before usb_register() returns.
746 * If the handle is not yet updated then the probe() will fail.
747 */
748 *pCams = cams;
749 result = usb_register(&cams->usbdrv);
750 if (result) {
751 for (i = 0; i < num_cams; i++) {
752 struct uvd *up = &cams->cam[i];
753 kfree(up->user_data);
754 }
755 kfree(cams);
756 }
757
758 return result;
759}
760
761EXPORT_SYMBOL(usbvideo_register);
762
763/*
764 * usbvideo_Deregister()
765 *
766 * Procedure frees all usbvideo and user data structures. Be warned that
767 * if you had some dynamically allocated components in ->user field then
768 * you should free them before calling here.
769 */
770void usbvideo_Deregister(struct usbvideo **pCams)
771{
772 struct usbvideo *cams;
773 int i;
774
775 if (pCams == NULL) {
776 err("%s: pCams == NULL", __func__);
777 return;
778 }
779 cams = *pCams;
780 if (cams == NULL) {
781 err("%s: cams == NULL", __func__);
782 return;
783 }
784
785 dbg("%s: Deregistering %s driver.", __func__, cams->drvName);
786 usb_deregister(&cams->usbdrv);
787
788 dbg("%s: Deallocating cams=$%p (%d. cameras)", __func__, cams, cams->num_cameras);
789 for (i = 0; i < cams->num_cameras; i++) {
790 struct uvd *up = &cams->cam[i];
791 int warning = 0;
792
793 if (up->user_data != NULL) {
794 if (up->user_size <= 0)
795 ++warning;
796 } else {
797 if (up->user_size > 0)
798 ++warning;
799 }
800 if (warning) {
801 err("%s: Warning: user_data=$%p user_size=%d.",
802 __func__, up->user_data, up->user_size);
803 } else {
804 dbg("%s: Freeing %d. $%p->user_data=$%p",
805 __func__, i, up, up->user_data);
806 kfree(up->user_data);
807 }
808 }
809 /* Whole array was allocated in one chunk */
810 dbg("%s: Freed %d uvd structures",
811 __func__, cams->num_cameras);
812 kfree(cams);
813 *pCams = NULL;
814}
815
816EXPORT_SYMBOL(usbvideo_Deregister);
817
818/*
819 * usbvideo_Disconnect()
820 *
821 * This procedure stops all driver activity. Deallocation of
822 * the interface-private structure (pointed by 'ptr') is done now
823 * (if we don't have any open files) or later, when those files
824 * are closed. After that driver should be removable.
825 *
826 * This code handles surprise removal. The uvd->user is a counter which
827 * increments on open() and decrements on close(). If we see here that
828 * this counter is not 0 then we have a client who still has us opened.
829 * We set uvd->remove_pending flag as early as possible, and after that
830 * all access to the camera will gracefully fail. These failures should
831 * prompt client to (eventually) close the video device, and then - in
832 * usbvideo_v4l_close() - we decrement uvd->uvd_used and usage counter.
833 *
834 * History:
835 * 22-Jan-2000 Added polling of MOD_IN_USE to delay removal until all users gone.
836 * 27-Jan-2000 Reworked to allow pending disconnects; see xxx_close()
837 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
838 * 19-Oct-2000 Moved to usbvideo module.
839 */
840static void usbvideo_Disconnect(struct usb_interface *intf)
841{
842 struct uvd *uvd = usb_get_intfdata(intf);
843 int i;
844
845 if (uvd == NULL) {
846 err("%s($%p): Illegal call.", __func__, intf);
847 return;
848 }
849
850 usb_set_intfdata(intf, NULL);
851
852 usbvideo_ClientIncModCount(uvd);
853 if (uvd->debug > 0)
854 dev_info(&intf->dev, "%s(%p.)\n", __func__, intf);
855
856 mutex_lock(&uvd->lock);
857 uvd->remove_pending = 1; /* Now all ISO data will be ignored */
858
859 /* At this time we ask to cancel outstanding URBs */
860 GET_CALLBACK(uvd, stopDataPump)(uvd);
861
862 for (i = 0; i < USBVIDEO_NUMSBUF; i++)
863 usb_free_urb(uvd->sbuf[i].urb);
864
865 usb_put_dev(uvd->dev);
866 uvd->dev = NULL; /* USB device is no more */
867
868 video_unregister_device(&uvd->vdev);
869 if (uvd->debug > 0)
870 dev_info(&intf->dev, "%s: Video unregistered.\n", __func__);
871
872 if (uvd->user)
873 dev_info(&intf->dev, "%s: In use, disconnect pending.\n",
874 __func__);
875 else
876 usbvideo_CameraRelease(uvd);
877 mutex_unlock(&uvd->lock);
878 dev_info(&intf->dev, "USB camera disconnected.\n");
879
880 usbvideo_ClientDecModCount(uvd);
881}
882
883/*
884 * usbvideo_CameraRelease()
885 *
886 * This code does final release of uvd. This happens
887 * after the device is disconnected -and- all clients
888 * closed their files.
889 *
890 * History:
891 * 27-Jan-2000 Created.
892 */
893static void usbvideo_CameraRelease(struct uvd *uvd)
894{
895 if (uvd == NULL) {
896 err("%s: Illegal call", __func__);
897 return;
898 }
899
900 RingQueue_Free(&uvd->dp);
901 if (VALID_CALLBACK(uvd, userFree))
902 GET_CALLBACK(uvd, userFree)(uvd);
903 uvd->uvd_used = 0; /* This is atomic, no need to take mutex */
904}
905
906/*
907 * usbvideo_find_struct()
908 *
909 * This code searches the array of preallocated (static) structures
910 * and returns index of the first one that isn't in use. Returns -1
911 * if there are no free structures.
912 *
913 * History:
914 * 27-Jan-2000 Created.
915 */
916static int usbvideo_find_struct(struct usbvideo *cams)
917{
918 int u, rv = -1;
919
920 if (cams == NULL) {
921 err("No usbvideo handle?");
922 return -1;
923 }
924 mutex_lock(&cams->lock);
925 for (u = 0; u < cams->num_cameras; u++) {
926 struct uvd *uvd = &cams->cam[u];
927 if (!uvd->uvd_used) { /* This one is free */
928 uvd->uvd_used = 1; /* In use now */
929 mutex_init(&uvd->lock); /* to 1 == available */
930 uvd->dev = NULL;
931 rv = u;
932 break;
933 }
934 }
935 mutex_unlock(&cams->lock);
936 return rv;
937}
938
939static const struct v4l2_file_operations usbvideo_fops = {
940 .owner = THIS_MODULE,
941 .open = usbvideo_v4l_open,
942 .release = usbvideo_v4l_close,
943 .read = usbvideo_v4l_read,
944 .mmap = usbvideo_v4l_mmap,
945 .ioctl = usbvideo_v4l_ioctl,
946};
947static const struct video_device usbvideo_template = {
948 .fops = &usbvideo_fops,
949};
950
951struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams)
952{
953 int i, devnum;
954 struct uvd *uvd = NULL;
955
956 if (cams == NULL) {
957 err("No usbvideo handle?");
958 return NULL;
959 }
960
961 devnum = usbvideo_find_struct(cams);
962 if (devnum == -1) {
963 err("IBM USB camera driver: Too many devices!");
964 return NULL;
965 }
966 uvd = &cams->cam[devnum];
967 dbg("Device entry #%d. at $%p", devnum, uvd);
968
969 /* Not relying upon caller we increase module counter ourselves */
970 usbvideo_ClientIncModCount(uvd);
971
972 mutex_lock(&uvd->lock);
973 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
974 uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
975 if (uvd->sbuf[i].urb == NULL) {
976 err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC);
977 uvd->uvd_used = 0;
978 uvd = NULL;
979 goto allocate_done;
980 }
981 }
982 uvd->user = 0;
983 uvd->remove_pending = 0;
984 uvd->last_error = 0;
985 RingQueue_Initialize(&uvd->dp);
986
987 /* Initialize video device structure */
988 uvd->vdev = usbvideo_template;
989 sprintf(uvd->vdev.name, "%.20s USB Camera", cams->drvName);
990 /*
991 * The client is free to overwrite those because we
992 * return control to the client's probe function right now.
993 */
994allocate_done:
995 mutex_unlock(&uvd->lock);
996 usbvideo_ClientDecModCount(uvd);
997 return uvd;
998}
999
1000EXPORT_SYMBOL(usbvideo_AllocateDevice);
1001
1002int usbvideo_RegisterVideoDevice(struct uvd *uvd)
1003{
1004 char tmp1[20], tmp2[20]; /* Buffers for printing */
1005
1006 if (uvd == NULL) {
1007 err("%s: Illegal call.", __func__);
1008 return -EINVAL;
1009 }
1010 if (uvd->video_endp == 0) {
1011 dev_info(&uvd->dev->dev,
1012 "%s: No video endpoint specified; data pump disabled.\n",
1013 __func__);
1014 }
1015 if (uvd->paletteBits == 0) {
1016 err("%s: No palettes specified!", __func__);
1017 return -EINVAL;
1018 }
1019 if (uvd->defaultPalette == 0) {
1020 dev_info(&uvd->dev->dev, "%s: No default palette!\n",
1021 __func__);
1022 }
1023
1024 uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) *
1025 VIDEOSIZE_Y(uvd->canvas) * V4L_BYTES_PER_PIXEL;
1026 usbvideo_VideosizeToString(tmp1, sizeof(tmp1), uvd->videosize);
1027 usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas);
1028
1029 if (uvd->debug > 0) {
1030 dev_info(&uvd->dev->dev,
1031 "%s: iface=%d. endpoint=$%02x paletteBits=$%08lx\n",
1032 __func__, uvd->iface, uvd->video_endp,
1033 uvd->paletteBits);
1034 }
1035 if (uvd->dev == NULL) {
1036 err("%s: uvd->dev == NULL", __func__);
1037 return -EINVAL;
1038 }
1039 uvd->vdev.parent = &uvd->dev->dev;
1040 uvd->vdev.release = video_device_release_empty;
1041 if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1042 err("%s: video_register_device failed", __func__);
1043 return -EPIPE;
1044 }
1045 if (uvd->debug > 1) {
1046 dev_info(&uvd->dev->dev,
1047 "%s: video_register_device() successful\n", __func__);
1048 }
1049
1050 dev_info(&uvd->dev->dev, "%s on %s: canvas=%s videosize=%s\n",
1051 (uvd->handle != NULL) ? uvd->handle->drvName : "???",
1052 video_device_node_name(&uvd->vdev), tmp2, tmp1);
1053
1054 usb_get_dev(uvd->dev);
1055 return 0;
1056}
1057
1058EXPORT_SYMBOL(usbvideo_RegisterVideoDevice);
1059
1060/* ******************************************************************** */
1061
1062static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma)
1063{
1064 struct uvd *uvd = file->private_data;
1065 unsigned long start = vma->vm_start;
1066 unsigned long size = vma->vm_end-vma->vm_start;
1067 unsigned long page, pos;
1068
1069 if (!CAMERA_IS_OPERATIONAL(uvd))
1070 return -EFAULT;
1071
1072 if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
1073 return -EINVAL;
1074
1075 pos = (unsigned long) uvd->fbuf;
1076 while (size > 0) {
1077 page = vmalloc_to_pfn((void *)pos);
1078 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1079 return -EAGAIN;
1080
1081 start += PAGE_SIZE;
1082 pos += PAGE_SIZE;
1083 if (size > PAGE_SIZE)
1084 size -= PAGE_SIZE;
1085 else
1086 size = 0;
1087 }
1088
1089 return 0;
1090}
1091
1092/*
1093 * usbvideo_v4l_open()
1094 *
1095 * This is part of Video 4 Linux API. The driver can be opened by one
1096 * client only (checks internal counter 'uvdser'). The procedure
1097 * then allocates buffers needed for video processing.
1098 *
1099 * History:
1100 * 22-Jan-2000 Rewrote, moved scratch buffer allocation here. Now the
1101 * camera is also initialized here (once per connect), at
1102 * expense of V4L client (it waits on open() call).
1103 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1104 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
1105 */
1106static int usbvideo_v4l_open(struct file *file)
1107{
1108 struct video_device *dev = video_devdata(file);
1109 struct uvd *uvd = (struct uvd *) dev;
1110 const int sb_size = FRAMES_PER_DESC * uvd->iso_packet_len;
1111 int i, errCode = 0;
1112
1113 if (uvd->debug > 1)
1114 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev);
1115
1116 if (usbvideo_ClientIncModCount(uvd) < 0)
1117 return -ENODEV;
1118 mutex_lock(&uvd->lock);
1119
1120 if (uvd->user) {
1121 err("%s: Someone tried to open an already opened device!", __func__);
1122 errCode = -EBUSY;
1123 } else {
1124 /* Clear statistics */
1125 memset(&uvd->stats, 0, sizeof(uvd->stats));
1126
1127 /* Clean pointers so we know if we allocated something */
1128 for (i = 0; i < USBVIDEO_NUMSBUF; i++)
1129 uvd->sbuf[i].data = NULL;
1130
1131 /* Allocate memory for the frame buffers */
1132 uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size;
1133 uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size);
1134 RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE);
1135 if ((uvd->fbuf == NULL) ||
1136 (!RingQueue_IsAllocated(&uvd->dp))) {
1137 err("%s: Failed to allocate fbuf or dp", __func__);
1138 errCode = -ENOMEM;
1139 } else {
1140 /* Allocate all buffers */
1141 for (i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1142 uvd->frame[i].frameState = FrameState_Unused;
1143 uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size);
1144 /*
1145 * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
1146 * is not used (using read() instead).
1147 */
1148 uvd->frame[i].canvas = uvd->canvas;
1149 uvd->frame[i].seqRead_Index = 0;
1150 }
1151 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1152 uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
1153 if (uvd->sbuf[i].data == NULL) {
1154 errCode = -ENOMEM;
1155 break;
1156 }
1157 }
1158 }
1159 if (errCode != 0) {
1160 /* Have to free all that memory */
1161 if (uvd->fbuf != NULL) {
1162 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1163 uvd->fbuf = NULL;
1164 }
1165 RingQueue_Free(&uvd->dp);
1166 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1167 kfree(uvd->sbuf[i].data);
1168 uvd->sbuf[i].data = NULL;
1169 }
1170 }
1171 }
1172
1173 /* If so far no errors then we shall start the camera */
1174 if (errCode == 0) {
1175 /* Start data pump if we have valid endpoint */
1176 if (uvd->video_endp != 0)
1177 errCode = GET_CALLBACK(uvd, startDataPump)(uvd);
1178 if (errCode == 0) {
1179 if (VALID_CALLBACK(uvd, setupOnOpen)) {
1180 if (uvd->debug > 1)
1181 dev_info(&uvd->dev->dev,
1182 "%s: setupOnOpen callback\n",
1183 __func__);
1184 errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd);
1185 if (errCode < 0) {
1186 err("%s: setupOnOpen callback failed (%d.).",
1187 __func__, errCode);
1188 } else if (uvd->debug > 1) {
1189 dev_info(&uvd->dev->dev,
1190 "%s: setupOnOpen callback successful\n",
1191 __func__);
1192 }
1193 }
1194 if (errCode == 0) {
1195 uvd->settingsAdjusted = 0;
1196 if (uvd->debug > 1)
1197 dev_info(&uvd->dev->dev,
1198 "%s: Open succeeded.\n",
1199 __func__);
1200 uvd->user++;
1201 file->private_data = uvd;
1202 }
1203 }
1204 }
1205 mutex_unlock(&uvd->lock);
1206 if (errCode != 0)
1207 usbvideo_ClientDecModCount(uvd);
1208 if (uvd->debug > 0)
1209 dev_info(&uvd->dev->dev, "%s: Returning %d.\n", __func__,
1210 errCode);
1211 return errCode;
1212}
1213
1214/*
1215 * usbvideo_v4l_close()
1216 *
1217 * This is part of Video 4 Linux API. The procedure
1218 * stops streaming and deallocates all buffers that were earlier
1219 * allocated in usbvideo_v4l_open().
1220 *
1221 * History:
1222 * 22-Jan-2000 Moved scratch buffer deallocation here.
1223 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1224 * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep.
1225 */
1226static int usbvideo_v4l_close(struct file *file)
1227{
1228 struct video_device *dev = file->private_data;
1229 struct uvd *uvd = (struct uvd *) dev;
1230 int i;
1231
1232 if (uvd->debug > 1)
1233 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev);
1234
1235 mutex_lock(&uvd->lock);
1236 GET_CALLBACK(uvd, stopDataPump)(uvd);
1237 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1238 uvd->fbuf = NULL;
1239 RingQueue_Free(&uvd->dp);
1240
1241 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1242 kfree(uvd->sbuf[i].data);
1243 uvd->sbuf[i].data = NULL;
1244 }
1245
1246#if USBVIDEO_REPORT_STATS
1247 usbvideo_ReportStatistics(uvd);
1248#endif
1249
1250 uvd->user--;
1251 if (uvd->remove_pending) {
1252 if (uvd->debug > 0)
1253 dev_info(&uvd->dev->dev, "%s: Final disconnect.\n",
1254 __func__);
1255 usbvideo_CameraRelease(uvd);
1256 }
1257 mutex_unlock(&uvd->lock);
1258 usbvideo_ClientDecModCount(uvd);
1259
1260 if (uvd->debug > 1)
1261 dev_info(&uvd->dev->dev, "%s: Completed.\n", __func__);
1262 file->private_data = NULL;
1263 return 0;
1264}
1265
1266/*
1267 * usbvideo_v4l_ioctl()
1268 *
1269 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
1270 *
1271 * History:
1272 * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
1273 */
1274static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1275{
1276 struct uvd *uvd = file->private_data;
1277
1278 if (!CAMERA_IS_OPERATIONAL(uvd))
1279 return -EIO;
1280
1281 switch (cmd) {
1282 case VIDIOCGCAP:
1283 {
1284 struct video_capability *b = arg;
1285 *b = uvd->vcap;
1286 return 0;
1287 }
1288 case VIDIOCGCHAN:
1289 {
1290 struct video_channel *v = arg;
1291 *v = uvd->vchan;
1292 return 0;
1293 }
1294 case VIDIOCSCHAN:
1295 {
1296 struct video_channel *v = arg;
1297 if (v->channel != 0)
1298 return -EINVAL;
1299 return 0;
1300 }
1301 case VIDIOCGPICT:
1302 {
1303 struct video_picture *pic = arg;
1304 *pic = uvd->vpic;
1305 return 0;
1306 }
1307 case VIDIOCSPICT:
1308 {
1309 struct video_picture *pic = arg;
1310 /*
1311 * Use temporary 'video_picture' structure to preserve our
1312 * own settings (such as color depth, palette) that we
1313 * aren't allowing everyone (V4L client) to change.
1314 */
1315 uvd->vpic.brightness = pic->brightness;
1316 uvd->vpic.hue = pic->hue;
1317 uvd->vpic.colour = pic->colour;
1318 uvd->vpic.contrast = pic->contrast;
1319 uvd->settingsAdjusted = 0; /* Will force new settings */
1320 return 0;
1321 }
1322 case VIDIOCSWIN:
1323 {
1324 struct video_window *vw = arg;
1325
1326 if (VALID_CALLBACK(uvd, setVideoMode))
1327 return GET_CALLBACK(uvd, setVideoMode)(uvd, vw);
1328
1329 if (vw->flags)
1330 return -EINVAL;
1331 if (vw->clipcount)
1332 return -EINVAL;
1333 if (vw->width != VIDEOSIZE_X(uvd->canvas))
1334 return -EINVAL;
1335 if (vw->height != VIDEOSIZE_Y(uvd->canvas))
1336 return -EINVAL;
1337
1338 return 0;
1339 }
1340 case VIDIOCGWIN:
1341 {
1342 struct video_window *vw = arg;
1343
1344 vw->x = 0;
1345 vw->y = 0;
1346 vw->width = VIDEOSIZE_X(uvd->videosize);
1347 vw->height = VIDEOSIZE_Y(uvd->videosize);
1348 vw->chromakey = 0;
1349 if (VALID_CALLBACK(uvd, getFPS))
1350 vw->flags = GET_CALLBACK(uvd, getFPS)(uvd);
1351 else
1352 vw->flags = 10; /* FIXME: do better! */
1353 return 0;
1354 }
1355 case VIDIOCGMBUF:
1356 {
1357 struct video_mbuf *vm = arg;
1358 int i;
1359
1360 memset(vm, 0, sizeof(*vm));
1361 vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES;
1362 vm->frames = USBVIDEO_NUMFRAMES;
1363 for (i = 0; i < USBVIDEO_NUMFRAMES; i++)
1364 vm->offsets[i] = i * uvd->max_frame_size;
1365
1366 return 0;
1367 }
1368 case VIDIOCMCAPTURE:
1369 {
1370 struct video_mmap *vm = arg;
1371
1372 if (uvd->debug >= 1) {
1373 dev_info(&uvd->dev->dev,
1374 "VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.\n",
1375 vm->frame, vm->width, vm->height, vm->format);
1376 }
1377 /*
1378 * Check if the requested size is supported. If the requestor
1379 * requests too big a frame then we may be tricked into accessing
1380 * outside of own preallocated frame buffer (in uvd->frame).
1381 * This will cause oops or a security hole. Theoretically, we
1382 * could only clamp the size down to acceptable bounds, but then
1383 * we'd need to figure out how to insert our smaller buffer into
1384 * larger caller's buffer... this is not an easy question. So we
1385 * here just flatly reject too large requests, assuming that the
1386 * caller will resubmit with smaller size. Callers should know
1387 * what size we support (returned by VIDIOCGCAP). However vidcat,
1388 * for one, does not care and allows to ask for any size.
1389 */
1390 if ((vm->width > VIDEOSIZE_X(uvd->canvas)) ||
1391 (vm->height > VIDEOSIZE_Y(uvd->canvas))) {
1392 if (uvd->debug > 0) {
1393 dev_info(&uvd->dev->dev,
1394 "VIDIOCMCAPTURE: Size=%dx%d "
1395 "too large; allowed only up "
1396 "to %ldx%ld\n", vm->width,
1397 vm->height,
1398 VIDEOSIZE_X(uvd->canvas),
1399 VIDEOSIZE_Y(uvd->canvas));
1400 }
1401 return -EINVAL;
1402 }
1403 /* Check if the palette is supported */
1404 if (((1L << vm->format) & uvd->paletteBits) == 0) {
1405 if (uvd->debug > 0) {
1406 dev_info(&uvd->dev->dev,
1407 "VIDIOCMCAPTURE: format=%d. "
1408 "not supported "
1409 "(paletteBits=$%08lx)\n",
1410 vm->format, uvd->paletteBits);
1411 }
1412 return -EINVAL;
1413 }
1414 if ((vm->frame < 0) || (vm->frame >= USBVIDEO_NUMFRAMES)) {
1415 err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm->frame, USBVIDEO_NUMFRAMES-1);
1416 return -EINVAL;
1417 }
1418 if (uvd->frame[vm->frame].frameState == FrameState_Grabbing) {
1419 /* Not an error - can happen */
1420 }
1421 uvd->frame[vm->frame].request = VIDEOSIZE(vm->width, vm->height);
1422 uvd->frame[vm->frame].palette = vm->format;
1423
1424 /* Mark it as ready */
1425 uvd->frame[vm->frame].frameState = FrameState_Ready;
1426
1427 return usbvideo_NewFrame(uvd, vm->frame);
1428 }
1429 case VIDIOCSYNC:
1430 {
1431 int *frameNum = arg;
1432 int ret;
1433
1434 if (*frameNum < 0 || *frameNum >= USBVIDEO_NUMFRAMES)
1435 return -EINVAL;
1436
1437 if (uvd->debug >= 1)
1438 dev_info(&uvd->dev->dev,
1439 "VIDIOCSYNC: syncing to frame %d.\n",
1440 *frameNum);
1441 if (uvd->flags & FLAGS_NO_DECODING)
1442 ret = usbvideo_GetFrame(uvd, *frameNum);
1443 else if (VALID_CALLBACK(uvd, getFrame)) {
1444 ret = GET_CALLBACK(uvd, getFrame)(uvd, *frameNum);
1445 if ((ret < 0) && (uvd->debug >= 1))
1446 err("VIDIOCSYNC: getFrame() returned %d.", ret);
1447 } else {
1448 err("VIDIOCSYNC: getFrame is not set");
1449 ret = -EFAULT;
1450 }
1451
1452 /*
1453 * The frame is in FrameState_Done_Hold state. Release it
1454 * right now because its data is already mapped into
1455 * the user space and it's up to the application to
1456 * make use of it until it asks for another frame.
1457 */
1458 uvd->frame[*frameNum].frameState = FrameState_Unused;
1459 return ret;
1460 }
1461 case VIDIOCGFBUF:
1462 {
1463 struct video_buffer *vb = arg;
1464
1465 memset(vb, 0, sizeof(*vb));
1466 return 0;
1467 }
1468 case VIDIOCKEY:
1469 return 0;
1470
1471 case VIDIOCCAPTURE:
1472 return -EINVAL;
1473
1474 case VIDIOCSFBUF:
1475
1476 case VIDIOCGTUNER:
1477 case VIDIOCSTUNER:
1478
1479 case VIDIOCGFREQ:
1480 case VIDIOCSFREQ:
1481
1482 case VIDIOCGAUDIO:
1483 case VIDIOCSAUDIO:
1484 return -EINVAL;
1485
1486 default:
1487 return -ENOIOCTLCMD;
1488 }
1489 return 0;
1490}
1491
1492static long usbvideo_v4l_ioctl(struct file *file,
1493 unsigned int cmd, unsigned long arg)
1494{
1495 return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl);
1496}
1497
1498/*
1499 * usbvideo_v4l_read()
1500 *
1501 * This is mostly boring stuff. We simply ask for a frame and when it
1502 * arrives copy all the video data from it into user space. There is
1503 * no obvious need to override this method.
1504 *
1505 * History:
1506 * 20-Oct-2000 Created.
1507 * 01-Nov-2000 Added mutex (uvd->lock).
1508 */
1509static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
1510 size_t count, loff_t *ppos)
1511{
1512 struct uvd *uvd = file->private_data;
1513 int noblock = file->f_flags & O_NONBLOCK;
1514 int frmx = -1, i;
1515 struct usbvideo_frame *frame;
1516
1517 if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
1518 return -EFAULT;
1519
1520 if (uvd->debug >= 1)
1521 dev_info(&uvd->dev->dev,
1522 "%s: %Zd. bytes, noblock=%d.\n",
1523 __func__, count, noblock);
1524
1525 mutex_lock(&uvd->lock);
1526
1527 /* See if a frame is completed, then use it. */
1528 for (i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1529 if ((uvd->frame[i].frameState == FrameState_Done) ||
1530 (uvd->frame[i].frameState == FrameState_Done_Hold) ||
1531 (uvd->frame[i].frameState == FrameState_Error)) {
1532 frmx = i;
1533 break;
1534 }
1535 }
1536
1537 /* FIXME: If we don't start a frame here then who ever does? */
1538 if (noblock && (frmx == -1)) {
1539 count = -EAGAIN;
1540 goto read_done;
1541 }
1542
1543 /*
1544 * If no FrameState_Done, look for a FrameState_Grabbing state.
1545 * See if a frame is in process (grabbing), then use it.
1546 * We will need to wait until it becomes cooked, of course.
1547 */
1548 if (frmx == -1) {
1549 for (i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1550 if (uvd->frame[i].frameState == FrameState_Grabbing) {
1551 frmx = i;
1552 break;
1553 }
1554 }
1555 }
1556
1557 /*
1558 * If no frame is active, start one. We don't care which one
1559 * it will be, so #0 is as good as any.
1560 * In read access mode we don't have convenience of VIDIOCMCAPTURE
1561 * to specify the requested palette (video format) on per-frame
1562 * basis. This means that we have to return data in -some- format
1563 * and just hope that the client knows what to do with it.
1564 * The default format is configured in uvd->defaultPalette field
1565 * as one of VIDEO_PALETTE_xxx values. We stuff it into the new
1566 * frame and initiate the frame filling process.
1567 */
1568 if (frmx == -1) {
1569 if (uvd->defaultPalette == 0) {
1570 err("%s: No default palette; don't know what to do!", __func__);
1571 count = -EFAULT;
1572 goto read_done;
1573 }
1574 frmx = 0;
1575 /*
1576 * We have no per-frame control over video size.
1577 * Therefore we only can use whatever size was
1578 * specified as default.
1579 */
1580 uvd->frame[frmx].request = uvd->videosize;
1581 uvd->frame[frmx].palette = uvd->defaultPalette;
1582 uvd->frame[frmx].frameState = FrameState_Ready;
1583 usbvideo_NewFrame(uvd, frmx);
1584 /* Now frame 0 is supposed to start filling... */
1585 }
1586
1587 /*
1588 * Get a pointer to the active frame. It is either previously
1589 * completed frame or frame in progress but not completed yet.
1590 */
1591 frame = &uvd->frame[frmx];
1592
1593 /*
1594 * Sit back & wait until the frame gets filled and postprocessed.
1595 * If we fail to get the picture [in time] then return the error.
1596 * In this call we specify that we want the frame to be waited for,
1597 * postprocessed and switched into FrameState_Done_Hold state. This
1598 * state is used to hold the frame as "fully completed" between
1599 * subsequent partial reads of the same frame.
1600 */
1601 if (frame->frameState != FrameState_Done_Hold) {
1602 long rv = -EFAULT;
1603 if (uvd->flags & FLAGS_NO_DECODING)
1604 rv = usbvideo_GetFrame(uvd, frmx);
1605 else if (VALID_CALLBACK(uvd, getFrame))
1606 rv = GET_CALLBACK(uvd, getFrame)(uvd, frmx);
1607 else
1608 err("getFrame is not set");
1609 if ((rv != 0) || (frame->frameState != FrameState_Done_Hold)) {
1610 count = rv;
1611 goto read_done;
1612 }
1613 }
1614
1615 /*
1616 * Copy bytes to user space. We allow for partial reads, which
1617 * means that the user application can request read less than
1618 * the full frame size. It is up to the application to issue
1619 * subsequent calls until entire frame is read.
1620 *
1621 * First things first, make sure we don't copy more than we
1622 * have - even if the application wants more. That would be
1623 * a big security embarassment!
1624 */
1625 if ((count + frame->seqRead_Index) > frame->seqRead_Length)
1626 count = frame->seqRead_Length - frame->seqRead_Index;
1627
1628 /*
1629 * Copy requested amount of data to user space. We start
1630 * copying from the position where we last left it, which
1631 * will be zero for a new frame (not read before).
1632 */
1633 if (copy_to_user(buf, frame->data + frame->seqRead_Index, count)) {
1634 count = -EFAULT;
1635 goto read_done;
1636 }
1637
1638 /* Update last read position */
1639 frame->seqRead_Index += count;
1640 if (uvd->debug >= 1) {
1641 err("%s: {copy} count used=%Zd, new seqRead_Index=%ld",
1642 __func__, count, frame->seqRead_Index);
1643 }
1644
1645 /* Finally check if the frame is done with and "release" it */
1646 if (frame->seqRead_Index >= frame->seqRead_Length) {
1647 /* All data has been read */
1648 frame->seqRead_Index = 0;
1649
1650 /* Mark it as available to be used again. */
1651 uvd->frame[frmx].frameState = FrameState_Unused;
1652 if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES))
1653 err("%s: usbvideo_NewFrame failed.", __func__);
1654 }
1655read_done:
1656 mutex_unlock(&uvd->lock);
1657 return count;
1658}
1659
1660/*
1661 * Make all of the blocks of data contiguous
1662 */
1663static int usbvideo_CompressIsochronous(struct uvd *uvd, struct urb *urb)
1664{
1665 char *cdata;
1666 int i, totlen = 0;
1667
1668 for (i = 0; i < urb->number_of_packets; i++) {
1669 int n = urb->iso_frame_desc[i].actual_length;
1670 int st = urb->iso_frame_desc[i].status;
1671
1672 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
1673
1674 /* Detect and ignore errored packets */
1675 if (st < 0) {
1676 if (uvd->debug >= 1)
1677 err("Data error: packet=%d. len=%d. status=%d.", i, n, st);
1678 uvd->stats.iso_err_count++;
1679 continue;
1680 }
1681
1682 /* Detect and ignore empty packets */
1683 if (n <= 0) {
1684 uvd->stats.iso_skip_count++;
1685 continue;
1686 }
1687 totlen += n; /* Little local accounting */
1688 RingQueue_Enqueue(&uvd->dp, cdata, n);
1689 }
1690 return totlen;
1691}
1692
1693static void usbvideo_IsocIrq(struct urb *urb)
1694{
1695 int i, ret, len;
1696 struct uvd *uvd = urb->context;
1697
1698 /* We don't want to do anything if we are about to be removed! */
1699 if (!CAMERA_IS_OPERATIONAL(uvd))
1700 return;
1701#if 0
1702 if (urb->actual_length > 0) {
1703 dev_info(&uvd->dev->dev,
1704 "urb=$%p status=%d. errcount=%d. length=%d.\n",
1705 urb, urb->status, urb->error_count,
1706 urb->actual_length);
1707 } else {
1708 static int c = 0;
1709 if (c++ % 100 == 0)
1710 dev_info(&uvd->dev->dev, "No Isoc data\n");
1711 }
1712#endif
1713
1714 if (!uvd->streaming) {
1715 if (uvd->debug >= 1)
1716 dev_info(&uvd->dev->dev,
1717 "Not streaming, but interrupt!\n");
1718 return;
1719 }
1720
1721 uvd->stats.urb_count++;
1722 if (urb->actual_length <= 0)
1723 goto urb_done_with;
1724
1725 /* Copy the data received into ring queue */
1726 len = usbvideo_CompressIsochronous(uvd, urb);
1727 uvd->stats.urb_length = len;
1728 if (len <= 0)
1729 goto urb_done_with;
1730
1731 /* Here we got some data */
1732 uvd->stats.data_count += len;
1733 RingQueue_WakeUpInterruptible(&uvd->dp);
1734
1735urb_done_with:
1736 for (i = 0; i < FRAMES_PER_DESC; i++) {
1737 urb->iso_frame_desc[i].status = 0;
1738 urb->iso_frame_desc[i].actual_length = 0;
1739 }
1740 urb->status = 0;
1741 urb->dev = uvd->dev;
1742 ret = usb_submit_urb(urb, GFP_KERNEL);
1743 if (ret)
1744 err("usb_submit_urb error (%d)", ret);
1745 return;
1746}
1747
1748/*
1749 * usbvideo_StartDataPump()
1750 *
1751 * History:
1752 * 27-Jan-2000 Used ibmcam->iface, ibmcam->ifaceAltActive instead
1753 * of hardcoded values. Simplified by using for loop,
1754 * allowed any number of URBs.
1755 */
1756static int usbvideo_StartDataPump(struct uvd *uvd)
1757{
1758 struct usb_device *dev = uvd->dev;
1759 int i, errFlag;
1760
1761 if (uvd->debug > 1)
1762 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd);
1763
1764 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1765 err("%s: Camera is not operational", __func__);
1766 return -EFAULT;
1767 }
1768 uvd->curframe = -1;
1769
1770 /* Alternate interface 1 is is the biggest frame size */
1771 i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
1772 if (i < 0) {
1773 err("%s: usb_set_interface error", __func__);
1774 uvd->last_error = i;
1775 return -EBUSY;
1776 }
1777 if (VALID_CALLBACK(uvd, videoStart))
1778 GET_CALLBACK(uvd, videoStart)(uvd);
1779 else
1780 err("%s: videoStart not set", __func__);
1781
1782 /* We double buffer the Iso lists */
1783 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1784 int j, k;
1785 struct urb *urb = uvd->sbuf[i].urb;
1786 urb->dev = dev;
1787 urb->context = uvd;
1788 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
1789 urb->interval = 1;
1790 urb->transfer_flags = URB_ISO_ASAP;
1791 urb->transfer_buffer = uvd->sbuf[i].data;
1792 urb->complete = usbvideo_IsocIrq;
1793 urb->number_of_packets = FRAMES_PER_DESC;
1794 urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC;
1795 for (j = k = 0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) {
1796 urb->iso_frame_desc[j].offset = k;
1797 urb->iso_frame_desc[j].length = uvd->iso_packet_len;
1798 }
1799 }
1800
1801 /* Submit all URBs */
1802 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1803 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
1804 if (errFlag)
1805 err("%s: usb_submit_isoc(%d) ret %d", __func__, i, errFlag);
1806 }
1807
1808 uvd->streaming = 1;
1809 if (uvd->debug > 1)
1810 dev_info(&uvd->dev->dev,
1811 "%s: streaming=1 video_endp=$%02x\n", __func__,
1812 uvd->video_endp);
1813 return 0;
1814}
1815
1816/*
1817 * usbvideo_StopDataPump()
1818 *
1819 * This procedure stops streaming and deallocates URBs. Then it
1820 * activates zero-bandwidth alt. setting of the video interface.
1821 *
1822 * History:
1823 * 22-Jan-2000 Corrected order of actions to work after surprise removal.
1824 * 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values.
1825 */
1826static void usbvideo_StopDataPump(struct uvd *uvd)
1827{
1828 int i, j;
1829
1830 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
1831 return;
1832
1833 if (uvd->debug > 1)
1834 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd);
1835
1836 /* Unschedule all of the iso td's */
1837 for (i = 0; i < USBVIDEO_NUMSBUF; i++)
1838 usb_kill_urb(uvd->sbuf[i].urb);
1839 if (uvd->debug > 1)
1840 dev_info(&uvd->dev->dev, "%s: streaming=0\n", __func__);
1841 uvd->streaming = 0;
1842
1843 if (!uvd->remove_pending) {
1844 /* Invoke minidriver's magic to stop the camera */
1845 if (VALID_CALLBACK(uvd, videoStop))
1846 GET_CALLBACK(uvd, videoStop)(uvd);
1847 else
1848 err("%s: videoStop not set", __func__);
1849
1850 /* Set packet size to 0 */
1851 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
1852 if (j < 0) {
1853 err("%s: usb_set_interface() error %d.", __func__, j);
1854 uvd->last_error = j;
1855 }
1856 }
1857}
1858
1859/*
1860 * usbvideo_NewFrame()
1861 *
1862 * History:
1863 * 29-Mar-00 Added copying of previous frame into the current one.
1864 * 6-Aug-00 Added model 3 video sizes, removed redundant width, height.
1865 */
1866static int usbvideo_NewFrame(struct uvd *uvd, int framenum)
1867{
1868 struct usbvideo_frame *frame;
1869 int n;
1870
1871 if (uvd->debug > 1)
1872 dev_info(&uvd->dev->dev, "usbvideo_NewFrame($%p,%d.)\n", uvd,
1873 framenum);
1874
1875 /* If we're not grabbing a frame right now and the other frame is */
1876 /* ready to be grabbed into, then use it instead */
1877 if (uvd->curframe != -1)
1878 return 0;
1879
1880 /* If necessary we adjust picture settings between frames */
1881 if (!uvd->settingsAdjusted) {
1882 if (VALID_CALLBACK(uvd, adjustPicture))
1883 GET_CALLBACK(uvd, adjustPicture)(uvd);
1884 uvd->settingsAdjusted = 1;
1885 }
1886
1887 n = (framenum + 1) % USBVIDEO_NUMFRAMES;
1888 if (uvd->frame[n].frameState == FrameState_Ready)
1889 framenum = n;
1890
1891 frame = &uvd->frame[framenum];
1892
1893 frame->frameState = FrameState_Grabbing;
1894 frame->scanstate = ScanState_Scanning;
1895 frame->seqRead_Length = 0; /* Accumulated in xxx_parse_data() */
1896 frame->deinterlace = Deinterlace_None;
1897 frame->flags = 0; /* No flags yet, up to minidriver (or us) to set them */
1898 uvd->curframe = framenum;
1899
1900 /*
1901 * Normally we would want to copy previous frame into the current one
1902 * before we even start filling it with data; this allows us to stop
1903 * filling at any moment; top portion of the frame will be new and
1904 * bottom portion will stay as it was in previous frame. If we don't
1905 * do that then missing chunks of video stream will result in flickering
1906 * portions of old data whatever it was before.
1907 *
1908 * If we choose not to copy previous frame (to, for example, save few
1909 * bus cycles - the frame can be pretty large!) then we have an option
1910 * to clear the frame before using. If we experience losses in this
1911 * mode then missing picture will be black (no flickering).
1912 *
1913 * Finally, if user chooses not to clean the current frame before
1914 * filling it with data then the old data will be visible if we fail
1915 * to refill entire frame with new data.
1916 */
1917 if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
1918 /* This copies previous frame into this one to mask losses */
1919 int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
1920 memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size);
1921 } else {
1922 if (uvd->flags & FLAGS_CLEAN_FRAMES) {
1923 /* This provides a "clean" frame but slows things down */
1924 memset(frame->data, 0, uvd->max_frame_size);
1925 }
1926 }
1927 return 0;
1928}
1929
1930/*
1931 * usbvideo_CollectRawData()
1932 *
1933 * This procedure can be used instead of 'processData' callback if you
1934 * only want to dump the raw data from the camera into the output
1935 * device (frame buffer). You can look at it with V4L client, but the
1936 * image will be unwatchable. The main purpose of this code and of the
1937 * mode FLAGS_NO_DECODING is debugging and capturing of datastreams from
1938 * new, unknown cameras. This procedure will be automatically invoked
1939 * instead of the specified callback handler when uvd->flags has bit
1940 * FLAGS_NO_DECODING set. Therefore, any regular build of any driver
1941 * based on usbvideo can use this feature at any time.
1942 */
1943static void usbvideo_CollectRawData(struct uvd *uvd, struct usbvideo_frame *frame)
1944{
1945 int n;
1946
1947 assert(uvd != NULL);
1948 assert(frame != NULL);
1949
1950 /* Try to move data from queue into frame buffer */
1951 n = RingQueue_GetLength(&uvd->dp);
1952 if (n > 0) {
1953 int m;
1954 /* See how much space we have left */
1955 m = uvd->max_frame_size - frame->seqRead_Length;
1956 if (n > m)
1957 n = m;
1958 /* Now move that much data into frame buffer */
1959 RingQueue_Dequeue(
1960 &uvd->dp,
1961 frame->data + frame->seqRead_Length,
1962 m);
1963 frame->seqRead_Length += m;
1964 }
1965 /* See if we filled the frame */
1966 if (frame->seqRead_Length >= uvd->max_frame_size) {
1967 frame->frameState = FrameState_Done;
1968 uvd->curframe = -1;
1969 uvd->stats.frame_num++;
1970 }
1971}
1972
1973static int usbvideo_GetFrame(struct uvd *uvd, int frameNum)
1974{
1975 struct usbvideo_frame *frame = &uvd->frame[frameNum];
1976
1977 if (uvd->debug >= 2)
1978 dev_info(&uvd->dev->dev, "%s($%p,%d.)\n", __func__, uvd,
1979 frameNum);
1980
1981 switch (frame->frameState) {
1982 case FrameState_Unused:
1983 if (uvd->debug >= 2)
1984 dev_info(&uvd->dev->dev, "%s: FrameState_Unused\n",
1985 __func__);
1986 return -EINVAL;
1987 case FrameState_Ready:
1988 case FrameState_Grabbing:
1989 case FrameState_Error:
1990 {
1991 int ntries, signalPending;
1992redo:
1993 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1994 if (uvd->debug >= 2)
1995 dev_info(&uvd->dev->dev,
1996 "%s: Camera is not operational (1)\n",
1997 __func__);
1998 return -EIO;
1999 }
2000 ntries = 0;
2001 do {
2002 RingQueue_InterruptibleSleepOn(&uvd->dp);
2003 signalPending = signal_pending(current);
2004 if (!CAMERA_IS_OPERATIONAL(uvd)) {
2005 if (uvd->debug >= 2)
2006 dev_info(&uvd->dev->dev,
2007 "%s: Camera is not "
2008 "operational (2)\n", __func__);
2009 return -EIO;
2010 }
2011 assert(uvd->fbuf != NULL);
2012 if (signalPending) {
2013 if (uvd->debug >= 2)
2014 dev_info(&uvd->dev->dev,
2015 "%s: Signal=$%08x\n", __func__,
2016 signalPending);
2017 if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) {
2018 usbvideo_TestPattern(uvd, 1, 0);
2019 uvd->curframe = -1;
2020 uvd->stats.frame_num++;
2021 if (uvd->debug >= 2)
2022 dev_info(&uvd->dev->dev,
2023 "%s: Forced test "
2024 "pattern screen\n",
2025 __func__);
2026 return 0;
2027 } else {
2028 /* Standard answer: Interrupted! */
2029 if (uvd->debug >= 2)
2030 dev_info(&uvd->dev->dev,
2031 "%s: Interrupted!\n",
2032 __func__);
2033 return -EINTR;
2034 }
2035 } else {
2036 /* No signals - we just got new data in dp queue */
2037 if (uvd->flags & FLAGS_NO_DECODING)
2038 usbvideo_CollectRawData(uvd, frame);
2039 else if (VALID_CALLBACK(uvd, processData))
2040 GET_CALLBACK(uvd, processData)(uvd, frame);
2041 else
2042 err("%s: processData not set", __func__);
2043 }
2044 } while (frame->frameState == FrameState_Grabbing);
2045 if (uvd->debug >= 2) {
2046 dev_info(&uvd->dev->dev,
2047 "%s: Grabbing done; state=%d. (%lu. bytes)\n",
2048 __func__, frame->frameState,
2049 frame->seqRead_Length);
2050 }
2051 if (frame->frameState == FrameState_Error) {
2052 int ret = usbvideo_NewFrame(uvd, frameNum);
2053 if (ret < 0) {
2054 err("%s: usbvideo_NewFrame() failed (%d.)", __func__, ret);
2055 return ret;
2056 }
2057 goto redo;
2058 }
2059 /* Note that we fall through to meet our destiny below */
2060 }
2061 case FrameState_Done:
2062 /*
2063 * Do all necessary postprocessing of data prepared in
2064 * "interrupt" code and the collecting code above. The
2065 * frame gets marked as FrameState_Done by queue parsing code.
2066 * This status means that we collected enough data and
2067 * most likely processed it as we went through. However
2068 * the data may need postprocessing, such as deinterlacing
2069 * or picture adjustments implemented in software (horror!)
2070 *
2071 * As soon as the frame becomes "final" it gets promoted to
2072 * FrameState_Done_Hold status where it will remain until the
2073 * caller consumed all the video data from the frame. Then
2074 * the empty shell of ex-frame is thrown out for dogs to eat.
2075 * But we, worried about pets, will recycle the frame!
2076 */
2077 uvd->stats.frame_num++;
2078 if ((uvd->flags & FLAGS_NO_DECODING) == 0) {
2079 if (VALID_CALLBACK(uvd, postProcess))
2080 GET_CALLBACK(uvd, postProcess)(uvd, frame);
2081 if (frame->flags & USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST)
2082 usbvideo_SoftwareContrastAdjustment(uvd, frame);
2083 }
2084 frame->frameState = FrameState_Done_Hold;
2085 if (uvd->debug >= 2)
2086 dev_info(&uvd->dev->dev,
2087 "%s: Entered FrameState_Done_Hold state.\n",
2088 __func__);
2089 return 0;
2090
2091 case FrameState_Done_Hold:
2092 /*
2093 * We stay in this state indefinitely until someone external,
2094 * like ioctl() or read() call finishes digesting the frame
2095 * data. Then it will mark the frame as FrameState_Unused and
2096 * it will be released back into the wild to roam freely.
2097 */
2098 if (uvd->debug >= 2)
2099 dev_info(&uvd->dev->dev,
2100 "%s: FrameState_Done_Hold state.\n",
2101 __func__);
2102 return 0;
2103 }
2104
2105 /* Catch-all for other cases. We shall not be here. */
2106 err("%s: Invalid state %d.", __func__, frame->frameState);
2107 frame->frameState = FrameState_Unused;
2108 return 0;
2109}
2110
2111/*
2112 * usbvideo_DeinterlaceFrame()
2113 *
2114 * This procedure deinterlaces the given frame. Some cameras produce
2115 * only half of scanlines - sometimes only even lines, sometimes only
2116 * odd lines. The deinterlacing method is stored in frame->deinterlace
2117 * variable.
2118 *
2119 * Here we scan the frame vertically and replace missing scanlines with
2120 * average between surrounding ones - before and after. If we have no
2121 * line above then we just copy next line. Similarly, if we need to
2122 * create a last line then preceding line is used.
2123 */
2124void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame)
2125{
2126 if ((uvd == NULL) || (frame == NULL))
2127 return;
2128
2129 if ((frame->deinterlace == Deinterlace_FillEvenLines) ||
2130 (frame->deinterlace == Deinterlace_FillOddLines)) {
2131 const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2132 int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1;
2133
2134 for (; i < VIDEOSIZE_Y(frame->request); i += 2) {
2135 const unsigned char *fs1, *fs2;
2136 unsigned char *fd;
2137 int ip, in, j; /* Previous and next lines */
2138
2139 /*
2140 * Need to average lines before and after 'i'.
2141 * If we go out of bounds seeking those lines then
2142 * we point back to existing line.
2143 */
2144 ip = i - 1; /* First, get rough numbers */
2145 in = i + 1;
2146
2147 /* Now validate */
2148 if (ip < 0)
2149 ip = in;
2150 if (in >= VIDEOSIZE_Y(frame->request))
2151 in = ip;
2152
2153 /* Sanity check */
2154 if ((ip < 0) || (in < 0) ||
2155 (ip >= VIDEOSIZE_Y(frame->request)) ||
2156 (in >= VIDEOSIZE_Y(frame->request))) {
2157 err("Error: ip=%d. in=%d. req.height=%ld.",
2158 ip, in, VIDEOSIZE_Y(frame->request));
2159 break;
2160 }
2161
2162 /* Now we need to average lines 'ip' and 'in' to produce line 'i' */
2163 fs1 = frame->data + (v4l_linesize * ip);
2164 fs2 = frame->data + (v4l_linesize * in);
2165 fd = frame->data + (v4l_linesize * i);
2166
2167 /* Average lines around destination */
2168 for (j = 0; j < v4l_linesize; j++) {
2169 fd[j] = (unsigned char)((((unsigned) fs1[j]) +
2170 ((unsigned)fs2[j])) >> 1);
2171 }
2172 }
2173 }
2174
2175 /* Optionally display statistics on the screen */
2176 if (uvd->flags & FLAGS_OVERLAY_STATS)
2177 usbvideo_OverlayStats(uvd, frame);
2178}
2179
2180EXPORT_SYMBOL(usbvideo_DeinterlaceFrame);
2181
2182/*
2183 * usbvideo_SoftwareContrastAdjustment()
2184 *
2185 * This code adjusts the contrast of the frame, assuming RGB24 format.
2186 * As most software image processing, this job is CPU-intensive.
2187 * Get a camera that supports hardware adjustment!
2188 *
2189 * History:
2190 * 09-Feb-2001 Created.
2191 */
2192static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
2193 struct usbvideo_frame *frame)
2194{
2195 int i, j, v4l_linesize;
2196 signed long adj;
2197 const int ccm = 128; /* Color correction median - see below */
2198
2199 if ((uvd == NULL) || (frame == NULL)) {
2200 err("%s: Illegal call.", __func__);
2201 return;
2202 }
2203 adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
2204 RESTRICT_TO_RANGE(adj, -ccm, ccm+1);
2205 if (adj == 0) {
2206 /* In rare case of no adjustment */
2207 return;
2208 }
2209 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2210 for (i = 0; i < VIDEOSIZE_Y(frame->request); i++) {
2211 unsigned char *fd = frame->data + (v4l_linesize * i);
2212 for (j = 0; j < v4l_linesize; j++) {
2213 signed long v = (signed long) fd[j];
2214 /* Magnify up to 2 times, reduce down to zero */
2215 v = 128 + ((ccm + adj) * (v - 128)) / ccm;
2216 RESTRICT_TO_RANGE(v, 0, 0xFF); /* Must flatten tails */
2217 fd[j] = (unsigned char) v;
2218 }
2219 }
2220}
2221
2222MODULE_LICENSE("GPL");
diff --git a/drivers/staging/usbvideo/usbvideo.h b/drivers/staging/usbvideo/usbvideo.h
deleted file mode 100644
index 95638a072b19..000000000000
--- a/drivers/staging/usbvideo/usbvideo.h
+++ /dev/null
@@ -1,395 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16#ifndef usbvideo_h
17#define usbvideo_h
18
19#include "videodev.h"
20#include <media/v4l2-common.h>
21#include <media/v4l2-ioctl.h>
22#include <linux/usb.h>
23#include <linux/mutex.h>
24
25/* Most helpful debugging aid */
26#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
27
28#define USBVIDEO_REPORT_STATS 1 /* Set to 0 to block statistics on close */
29
30/* Bit flags (options) */
31#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)
32#define FLAGS_MONOCHROME (1 << 1)
33#define FLAGS_DISPLAY_HINTS (1 << 2)
34#define FLAGS_OVERLAY_STATS (1 << 3)
35#define FLAGS_FORCE_TESTPATTERN (1 << 4)
36#define FLAGS_SEPARATE_FRAMES (1 << 5)
37#define FLAGS_CLEAN_FRAMES (1 << 6)
38#define FLAGS_NO_DECODING (1 << 7)
39
40/* Bit flags for frames (apply to the frame where they are specified) */
41#define USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST (1 << 0)
42
43/* Camera capabilities (maximum) */
44#define CAMERA_URB_FRAMES 32
45#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */
46#define FRAMES_PER_DESC (CAMERA_URB_FRAMES)
47#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET)
48
49/* This macro restricts an int variable to an inclusive range */
50#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
51
52#define V4L_BYTES_PER_PIXEL 3 /* Because we produce RGB24 */
53
54/*
55 * Use this macro to construct constants for different video sizes.
56 * We have to deal with different video sizes that have to be
57 * configured in the device or compared against when we receive
58 * a data. Normally one would define a bunch of VIDEOSIZE_x_by_y
59 * #defines and that's the end of story. However this solution
60 * does not allow to convert between real pixel sizes and the
61 * constant (integer) value that may be used to tag a frame or
62 * whatever. The set of macros below constructs videosize constants
63 * from the pixel size and allows to reconstruct the pixel size
64 * from the combined value later.
65 */
66#define VIDEOSIZE(x,y) (((x) & 0xFFFFL) | (((y) & 0xFFFFL) << 16))
67#define VIDEOSIZE_X(vs) ((vs) & 0xFFFFL)
68#define VIDEOSIZE_Y(vs) (((vs) >> 16) & 0xFFFFL)
69typedef unsigned long videosize_t;
70
71/*
72 * This macro checks if the camera is still operational. The 'uvd'
73 * pointer must be valid, uvd->dev must be valid, we are not
74 * removing the device and the device has not erred on us.
75 */
76#define CAMERA_IS_OPERATIONAL(uvd) (\
77 (uvd != NULL) && \
78 ((uvd)->dev != NULL) && \
79 ((uvd)->last_error == 0) && \
80 (!(uvd)->remove_pending))
81
82/*
83 * We use macros to do YUV -> RGB conversion because this is
84 * very important for speed and totally unimportant for size.
85 *
86 * YUV -> RGB Conversion
87 * ---------------------
88 *
89 * B = 1.164*(Y-16) + 2.018*(V-128)
90 * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
91 * R = 1.164*(Y-16) + 1.596*(U-128)
92 *
93 * If you fancy integer arithmetics (as you should), hear this:
94 *
95 * 65536*B = 76284*(Y-16) + 132252*(V-128)
96 * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
97 * 65536*R = 76284*(Y-16) + 104595*(U-128)
98 *
99 * Make sure the output values are within [0..255] range.
100 */
101#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
102#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
103 int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
104 mm_y = (my) - 16; \
105 mm_u = (mu) - 128; \
106 mm_v = (mv) - 128; \
107 mm_yc= mm_y * 76284; \
108 mm_b = (mm_yc + 132252*mm_v ) >> 16; \
109 mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
110 mm_r = (mm_yc + 104595*mm_u ) >> 16; \
111 mb = LIMIT_RGB(mm_b); \
112 mg = LIMIT_RGB(mm_g); \
113 mr = LIMIT_RGB(mm_r); \
114}
115
116#define RING_QUEUE_SIZE (128*1024) /* Must be a power of 2 */
117#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) & ((rq)->length-1)
118#define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
119#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) & ((rq)->length-1)])
120
121struct RingQueue {
122 unsigned char *queue; /* Data from the Isoc data pump */
123 int length; /* How many bytes allocated for the queue */
124 int wi; /* That's where we write */
125 int ri; /* Read from here until you hit write index */
126 wait_queue_head_t wqh; /* Processes waiting */
127};
128
129enum ScanState {
130 ScanState_Scanning, /* Scanning for header */
131 ScanState_Lines /* Parsing lines */
132};
133
134/* Completion states of the data parser */
135enum ParseState {
136 scan_Continue, /* Just parse next item */
137 scan_NextFrame, /* Frame done, send it to V4L */
138 scan_Out, /* Not enough data for frame */
139 scan_EndParse /* End parsing */
140};
141
142enum FrameState {
143 FrameState_Unused, /* Unused (no MCAPTURE) */
144 FrameState_Ready, /* Ready to start grabbing */
145 FrameState_Grabbing, /* In the process of being grabbed into */
146 FrameState_Done, /* Finished grabbing, but not been synced yet */
147 FrameState_Done_Hold, /* Are syncing or reading */
148 FrameState_Error, /* Something bad happened while processing */
149};
150
151/*
152 * Some frames may contain only even or odd lines. This type
153 * specifies what type of deinterlacing is required.
154 */
155enum Deinterlace {
156 Deinterlace_None=0,
157 Deinterlace_FillOddLines,
158 Deinterlace_FillEvenLines
159};
160
161#define USBVIDEO_NUMFRAMES 2 /* How many frames we work with */
162#define USBVIDEO_NUMSBUF 2 /* How many URBs linked in a ring */
163
164/* This structure represents one Isoc request - URB and buffer */
165struct usbvideo_sbuf {
166 char *data;
167 struct urb *urb;
168};
169
170struct usbvideo_frame {
171 char *data; /* Frame buffer */
172 unsigned long header; /* Significant bits from the header */
173
174 videosize_t canvas; /* The canvas (max. image) allocated */
175 videosize_t request; /* That's what the application asked for */
176 unsigned short palette; /* The desired format */
177
178 enum FrameState frameState;/* State of grabbing */
179 enum ScanState scanstate; /* State of scanning */
180 enum Deinterlace deinterlace;
181 int flags; /* USBVIDEO_FRAME_FLAG_xxx bit flags */
182
183 int curline; /* Line of frame we're working on */
184
185 long seqRead_Length; /* Raw data length of frame */
186 long seqRead_Index; /* Amount of data that has been already read */
187
188 void *user; /* Additional data that user may need */
189};
190
191/* Statistics that can be overlaid on screen */
192struct usbvideo_statistics {
193 unsigned long frame_num; /* Sequential number of the frame */
194 unsigned long urb_count; /* How many URBs we received so far */
195 unsigned long urb_length; /* Length of last URB */
196 unsigned long data_count; /* How many bytes we received */
197 unsigned long header_count; /* How many frame headers we found */
198 unsigned long iso_skip_count; /* How many empty ISO packets received */
199 unsigned long iso_err_count; /* How many bad ISO packets received */
200};
201
202struct usbvideo;
203
204struct uvd {
205 struct video_device vdev; /* Must be the first field! */
206 struct usb_device *dev;
207 struct usbvideo *handle; /* Points back to the struct usbvideo */
208 void *user_data; /* Camera-dependent data */
209 int user_size; /* Size of that camera-dependent data */
210 int debug; /* Debug level for usbvideo */
211 unsigned char iface; /* Video interface number */
212 unsigned char video_endp;
213 unsigned char ifaceAltActive;
214 unsigned char ifaceAltInactive; /* Alt settings */
215 unsigned long flags; /* FLAGS_USBVIDEO_xxx */
216 unsigned long paletteBits; /* Which palettes we accept? */
217 unsigned short defaultPalette; /* What palette to use for read() */
218 struct mutex lock;
219 int user; /* user count for exclusive use */
220
221 videosize_t videosize; /* Current setting */
222 videosize_t canvas; /* This is the width,height of the V4L canvas */
223 int max_frame_size; /* Bytes in one video frame */
224
225 int uvd_used; /* Is this structure in use? */
226 int streaming; /* Are we streaming Isochronous? */
227 int grabbing; /* Are we grabbing? */
228 int settingsAdjusted; /* Have we adjusted contrast etc.? */
229 int last_error; /* What calamity struck us? */
230
231 char *fbuf; /* Videodev buffer area */
232 int fbuf_size; /* Videodev buffer size */
233
234 int curframe;
235 int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */
236
237 struct RingQueue dp; /* Isoc data pump */
238 struct usbvideo_frame frame[USBVIDEO_NUMFRAMES];
239 struct usbvideo_sbuf sbuf[USBVIDEO_NUMSBUF];
240
241 volatile int remove_pending; /* If set then about to exit */
242
243 struct video_picture vpic, vpic_old; /* Picture settings */
244 struct video_capability vcap; /* Video capabilities */
245 struct video_channel vchan; /* May be used for tuner support */
246 struct usbvideo_statistics stats;
247 char videoName[32]; /* Holds name like "video7" */
248};
249
250/*
251 * usbvideo callbacks (virtual methods). They are set when usbvideo
252 * services are registered. All of these default to NULL, except those
253 * that default to usbvideo-provided methods.
254 */
255struct usbvideo_cb {
256 int (*probe)(struct usb_interface *, const struct usb_device_id *);
257 void (*userFree)(struct uvd *);
258 void (*disconnect)(struct usb_interface *);
259 int (*setupOnOpen)(struct uvd *);
260 void (*videoStart)(struct uvd *);
261 void (*videoStop)(struct uvd *);
262 void (*processData)(struct uvd *, struct usbvideo_frame *);
263 void (*postProcess)(struct uvd *, struct usbvideo_frame *);
264 void (*adjustPicture)(struct uvd *);
265 int (*getFPS)(struct uvd *);
266 int (*overlayHook)(struct uvd *, struct usbvideo_frame *);
267 int (*getFrame)(struct uvd *, int);
268 int (*startDataPump)(struct uvd *uvd);
269 void (*stopDataPump)(struct uvd *uvd);
270 int (*setVideoMode)(struct uvd *uvd, struct video_window *vw);
271};
272
273struct usbvideo {
274 int num_cameras; /* As allocated */
275 struct usb_driver usbdrv; /* Interface to the USB stack */
276 char drvName[80]; /* Driver name */
277 struct mutex lock; /* Mutex protecting camera structures */
278 struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */
279 struct video_device vdt; /* Video device template */
280 struct uvd *cam; /* Array of camera structures */
281 struct module *md_module; /* Minidriver module */
282};
283
284
285/*
286 * This macro retrieves callback address from the struct uvd object.
287 * No validity checks are done here, so be sure to check the
288 * callback beforehand with VALID_CALLBACK.
289 */
290#define GET_CALLBACK(uvd,cbName) ((uvd)->handle->cb.cbName)
291
292/*
293 * This macro returns either callback pointer or NULL. This is safe
294 * macro, meaning that most of components of data structures involved
295 * may be NULL - this only results in NULL being returned. You may
296 * wish to use this macro to make sure that the callback is callable.
297 * However keep in mind that those checks take time.
298 */
299#define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
300 ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
301
302int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len);
303int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n);
304void RingQueue_WakeUpInterruptible(struct RingQueue *rq);
305void RingQueue_Flush(struct RingQueue *rq);
306
307static inline int RingQueue_GetLength(const struct RingQueue *rq)
308{
309 return (rq->wi - rq->ri + rq->length) & (rq->length-1);
310}
311
312static inline int RingQueue_GetFreeSpace(const struct RingQueue *rq)
313{
314 return rq->length - RingQueue_GetLength(rq);
315}
316
317void usbvideo_DrawLine(
318 struct usbvideo_frame *frame,
319 int x1, int y1,
320 int x2, int y2,
321 unsigned char cr, unsigned char cg, unsigned char cb);
322void usbvideo_HexDump(const unsigned char *data, int len);
323void usbvideo_SayAndWait(const char *what);
324void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode);
325
326/* Memory allocation routines */
327unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
328
329int usbvideo_register(
330 struct usbvideo **pCams,
331 const int num_cams,
332 const int num_extra,
333 const char *driverName,
334 const struct usbvideo_cb *cbTable,
335 struct module *md,
336 const struct usb_device_id *id_table);
337struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams);
338int usbvideo_RegisterVideoDevice(struct uvd *uvd);
339void usbvideo_Deregister(struct usbvideo **uvt);
340
341int usbvideo_v4l_initialize(struct video_device *dev);
342
343void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame);
344
345/*
346 * This code performs bounds checking - use it when working with
347 * new formats, or else you may get oopses all over the place.
348 * If pixel falls out of bounds then it gets shoved back (as close
349 * to place of offence as possible) and is painted bright red.
350 *
351 * There are two important concepts: frame width, height and
352 * V4L canvas width, height. The former is the area requested by
353 * the application -for this very frame-. The latter is the largest
354 * possible frame that we can serve (we advertise that via V4L ioctl).
355 * The frame data is expected to be formatted as lines of length
356 * VIDEOSIZE_X(fr->request), total VIDEOSIZE_Y(frame->request) lines.
357 */
358static inline void RGB24_PUTPIXEL(
359 struct usbvideo_frame *fr,
360 int ix, int iy,
361 unsigned char vr,
362 unsigned char vg,
363 unsigned char vb)
364{
365 register unsigned char *pf;
366 int limiter = 0, mx, my;
367 mx = ix;
368 my = iy;
369 if (mx < 0) {
370 mx=0;
371 limiter++;
372 } else if (mx >= VIDEOSIZE_X((fr)->request)) {
373 mx= VIDEOSIZE_X((fr)->request) - 1;
374 limiter++;
375 }
376 if (my < 0) {
377 my = 0;
378 limiter++;
379 } else if (my >= VIDEOSIZE_Y((fr)->request)) {
380 my = VIDEOSIZE_Y((fr)->request) - 1;
381 limiter++;
382 }
383 pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*VIDEOSIZE_X((fr)->request) + (ix));
384 if (limiter) {
385 *pf++ = 0;
386 *pf++ = 0;
387 *pf++ = 0xFF;
388 } else {
389 *pf++ = (vb);
390 *pf++ = (vg);
391 *pf++ = (vr);
392 }
393}
394
395#endif /* usbvideo_h */
diff --git a/drivers/staging/usbvideo/vicam.c b/drivers/staging/usbvideo/vicam.c
deleted file mode 100644
index 38a373a8d077..000000000000
--- a/drivers/staging/usbvideo/vicam.c
+++ /dev/null
@@ -1,946 +0,0 @@
1/*
2 * USB ViCam WebCam driver
3 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
4 * Christopher L Cheney (ccheney@cheney.cx),
5 * Pavel Machek (pavel@ucw.cz),
6 * John Tyner (jtyner@cs.ucr.edu),
7 * Monroe Williams (monroe@pobox.com)
8 *
9 * Supports 3COM HomeConnect PC Digital WebCam
10 * Supports Compro PS39U WebCam
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * This source code is based heavily on the CPiA webcam driver which was
27 * written by Peter Pregler, Scott J. Bertin and Johannes Erdfelt
28 *
29 * Portions of this code were also copied from usbvideo.c
30 *
31 * Special thanks to the whole team at Sourceforge for help making
32 * this driver become a reality. Notably:
33 * Andy Armstrong who reverse engineered the color encoding and
34 * Pavel Machek and Chris Cheney who worked on reverse engineering the
35 * camera controls and wrote the first generation driver.
36 */
37
38#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/init.h>
41#include "videodev.h"
42#include <linux/usb.h>
43#include <linux/vmalloc.h>
44#include <linux/mm.h>
45#include <linux/slab.h>
46#include <linux/mutex.h>
47#include <linux/firmware.h>
48#include <linux/ihex.h>
49#include "usbvideo.h"
50
51/* #define VICAM_DEBUG */
52
53#ifdef VICAM_DEBUG
54#define ADBG(lineno, fmt, args...) printk(fmt, jiffies, __func__, lineno, ##args)
55#define DBG(fmt, args...) ADBG((__LINE__), KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt, ##args)
56#else
57#define DBG(fmn, args...) do {} while (0)
58#endif
59
60#define DRIVER_AUTHOR "Joe Burks, jburks@wavicle.org"
61#define DRIVER_DESC "ViCam WebCam Driver"
62
63/* Define these values to match your device */
64#define USB_VICAM_VENDOR_ID 0x04c1
65#define USB_VICAM_PRODUCT_ID 0x009d
66#define USB_COMPRO_VENDOR_ID 0x0602
67#define USB_COMPRO_PRODUCT_ID 0x1001
68
69#define VICAM_BYTES_PER_PIXEL 3
70#define VICAM_MAX_READ_SIZE (512*242+128)
71#define VICAM_MAX_FRAME_SIZE (VICAM_BYTES_PER_PIXEL*320*240)
72#define VICAM_FRAMES 2
73
74#define VICAM_HEADER_SIZE 64
75
76/* rvmalloc / rvfree copied from usbvideo.c
77 *
78 * Not sure why these are not yet non-statics which I can reference through
79 * usbvideo.h the same as it is in 2.4.20. I bet this will get fixed sometime
80 * in the future.
81 *
82*/
83static void *rvmalloc(unsigned long size)
84{
85 void *mem;
86 unsigned long adr;
87
88 size = PAGE_ALIGN(size);
89 mem = vmalloc_32(size);
90 if (!mem)
91 return NULL;
92
93 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
94 adr = (unsigned long) mem;
95 while (size > 0) {
96 SetPageReserved(vmalloc_to_page((void *)adr));
97 adr += PAGE_SIZE;
98 size -= PAGE_SIZE;
99 }
100
101 return mem;
102}
103
104static void rvfree(void *mem, unsigned long size)
105{
106 unsigned long adr;
107
108 if (!mem)
109 return;
110
111 adr = (unsigned long) mem;
112 while ((long) size > 0) {
113 ClearPageReserved(vmalloc_to_page((void *)adr));
114 adr += PAGE_SIZE;
115 size -= PAGE_SIZE;
116 }
117 vfree(mem);
118}
119
120struct vicam_camera {
121 u16 shutter_speed; /* capture shutter speed */
122 u16 gain; /* capture gain */
123
124 u8 *raw_image; /* raw data captured from the camera */
125 u8 *framebuf; /* processed data in RGB24 format */
126 u8 *cntrlbuf; /* area used to send control msgs */
127
128 struct video_device vdev; /* v4l video device */
129 struct usb_device *udev; /* usb device */
130
131 /* guard against simultaneous accesses to the camera */
132 struct mutex cam_lock;
133
134 int is_initialized;
135 u8 open_count;
136 u8 bulkEndpoint;
137 int needsDummyRead;
138};
139
140static int vicam_probe(struct usb_interface *intf, const struct usb_device_id *id);
141static void vicam_disconnect(struct usb_interface *intf);
142static void read_frame(struct vicam_camera *cam, int framenum);
143static void vicam_decode_color(const u8 *, u8 *);
144
145static int __send_control_msg(struct vicam_camera *cam,
146 u8 request,
147 u16 value,
148 u16 index,
149 unsigned char *cp,
150 u16 size)
151{
152 int status;
153
154 /* cp must be memory that has been allocated by kmalloc */
155
156 status = usb_control_msg(cam->udev,
157 usb_sndctrlpipe(cam->udev, 0),
158 request,
159 USB_DIR_OUT | USB_TYPE_VENDOR |
160 USB_RECIP_DEVICE, value, index,
161 cp, size, 1000);
162
163 status = min(status, 0);
164
165 if (status < 0) {
166 printk(KERN_INFO "Failed sending control message, error %d.\n",
167 status);
168 }
169
170 return status;
171}
172
173static int send_control_msg(struct vicam_camera *cam,
174 u8 request,
175 u16 value,
176 u16 index,
177 unsigned char *cp,
178 u16 size)
179{
180 int status = -ENODEV;
181 mutex_lock(&cam->cam_lock);
182 if (cam->udev) {
183 status = __send_control_msg(cam, request, value,
184 index, cp, size);
185 }
186 mutex_unlock(&cam->cam_lock);
187 return status;
188}
189static int
190initialize_camera(struct vicam_camera *cam)
191{
192 int err;
193 const struct ihex_binrec *rec;
194 const struct firmware *uninitialized_var(fw);
195
196 err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
197 if (err) {
198 printk(KERN_ERR "Failed to load \"vicam/firmware.fw\": %d\n",
199 err);
200 return err;
201 }
202
203 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
204 memcpy(cam->cntrlbuf, rec->data, be16_to_cpu(rec->len));
205
206 err = send_control_msg(cam, 0xff, 0, 0,
207 cam->cntrlbuf, be16_to_cpu(rec->len));
208 if (err)
209 break;
210 }
211
212 release_firmware(fw);
213
214 return err;
215}
216
217static int
218set_camera_power(struct vicam_camera *cam, int state)
219{
220 int status;
221
222 status = send_control_msg(cam, 0x50, state, 0, NULL, 0);
223 if (status < 0)
224 return status;
225
226 if (state)
227 send_control_msg(cam, 0x55, 1, 0, NULL, 0);
228
229 return 0;
230}
231
232static long
233vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg)
234{
235 void __user *user_arg = (void __user *)arg;
236 struct vicam_camera *cam = file->private_data;
237 long retval = 0;
238
239 if (!cam)
240 return -ENODEV;
241
242 switch (ioctlnr) {
243 /* query capabilities */
244 case VIDIOCGCAP:
245 {
246 struct video_capability b;
247
248 DBG("VIDIOCGCAP\n");
249 memset(&b, 0, sizeof(b));
250 strcpy(b.name, "ViCam-based Camera");
251 b.type = VID_TYPE_CAPTURE;
252 b.channels = 1;
253 b.audios = 0;
254 b.maxwidth = 320; /* VIDEOSIZE_CIF */
255 b.maxheight = 240;
256 b.minwidth = 320; /* VIDEOSIZE_48_48 */
257 b.minheight = 240;
258
259 if (copy_to_user(user_arg, &b, sizeof(b)))
260 retval = -EFAULT;
261
262 break;
263 }
264 /* get/set video source - we are a camera and nothing else */
265 case VIDIOCGCHAN:
266 {
267 struct video_channel v;
268
269 DBG("VIDIOCGCHAN\n");
270 if (copy_from_user(&v, user_arg, sizeof(v))) {
271 retval = -EFAULT;
272 break;
273 }
274 if (v.channel != 0) {
275 retval = -EINVAL;
276 break;
277 }
278
279 v.channel = 0;
280 strcpy(v.name, "Camera");
281 v.tuners = 0;
282 v.flags = 0;
283 v.type = VIDEO_TYPE_CAMERA;
284 v.norm = 0;
285
286 if (copy_to_user(user_arg, &v, sizeof(v)))
287 retval = -EFAULT;
288 break;
289 }
290
291 case VIDIOCSCHAN:
292 {
293 int v;
294
295 if (copy_from_user(&v, user_arg, sizeof(v)))
296 retval = -EFAULT;
297 DBG("VIDIOCSCHAN %d\n", v);
298
299 if (retval == 0 && v != 0)
300 retval = -EINVAL;
301
302 break;
303 }
304
305 /* image properties */
306 case VIDIOCGPICT:
307 {
308 struct video_picture vp;
309 DBG("VIDIOCGPICT\n");
310 memset(&vp, 0, sizeof(struct video_picture));
311 vp.brightness = cam->gain << 8;
312 vp.depth = 24;
313 vp.palette = VIDEO_PALETTE_RGB24;
314 if (copy_to_user(user_arg, &vp, sizeof(struct video_picture)))
315 retval = -EFAULT;
316 break;
317 }
318
319 case VIDIOCSPICT:
320 {
321 struct video_picture vp;
322
323 if (copy_from_user(&vp, user_arg, sizeof(vp))) {
324 retval = -EFAULT;
325 break;
326 }
327
328 DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,
329 vp.palette);
330
331 cam->gain = vp.brightness >> 8;
332
333 if (vp.depth != 24
334 || vp.palette != VIDEO_PALETTE_RGB24)
335 retval = -EINVAL;
336
337 break;
338 }
339
340 /* get/set capture window */
341 case VIDIOCGWIN:
342 {
343 struct video_window vw;
344 vw.x = 0;
345 vw.y = 0;
346 vw.width = 320;
347 vw.height = 240;
348 vw.chromakey = 0;
349 vw.flags = 0;
350 vw.clips = NULL;
351 vw.clipcount = 0;
352
353 DBG("VIDIOCGWIN\n");
354
355 if (copy_to_user(user_arg, (void *)&vw, sizeof(vw)))
356 retval = -EFAULT;
357
358 /* I'm not sure what the deal with a capture window is, it is very poorly described
359 * in the doc. So I won't support it now. */
360 break;
361 }
362
363 case VIDIOCSWIN:
364 {
365
366 struct video_window vw;
367
368 if (copy_from_user(&vw, user_arg, sizeof(vw))) {
369 retval = -EFAULT;
370 break;
371 }
372
373 DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height);
374
375 if (vw.width != 320 || vw.height != 240)
376 retval = -EFAULT;
377
378 break;
379 }
380
381 /* mmap interface */
382 case VIDIOCGMBUF:
383 {
384 struct video_mbuf vm;
385 int i;
386
387 DBG("VIDIOCGMBUF\n");
388 memset(&vm, 0, sizeof(vm));
389 vm.size =
390 VICAM_MAX_FRAME_SIZE * VICAM_FRAMES;
391 vm.frames = VICAM_FRAMES;
392 for (i = 0; i < VICAM_FRAMES; i++)
393 vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;
394
395 if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))
396 retval = -EFAULT;
397
398 break;
399 }
400
401 case VIDIOCMCAPTURE:
402 {
403 struct video_mmap vm;
404 /* int video_size; */
405
406 if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) {
407 retval = -EFAULT;
408 break;
409 }
410
411 DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",
412 vm.frame, vm.width, vm.height, vm.format);
413
414 if (vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24)
415 retval = -EINVAL;
416
417 /* in theory right here we'd start the image capturing
418 * (fill in a bulk urb and submit it asynchronously)
419 *
420 * Instead we're going to do a total hack job for now and
421 * retrieve the frame in VIDIOCSYNC */
422
423 break;
424 }
425
426 case VIDIOCSYNC:
427 {
428 int frame;
429
430 if (copy_from_user((void *)&frame, user_arg, sizeof(int))) {
431 retval = -EFAULT;
432 break;
433 }
434 DBG("VIDIOCSYNC: %d\n", frame);
435
436 read_frame(cam, frame);
437 vicam_decode_color(cam->raw_image,
438 cam->framebuf +
439 frame * VICAM_MAX_FRAME_SIZE);
440
441 break;
442 }
443
444 /* pointless to implement overlay with this camera */
445 case VIDIOCCAPTURE:
446 case VIDIOCGFBUF:
447 case VIDIOCSFBUF:
448 case VIDIOCKEY:
449 retval = -EINVAL;
450 break;
451
452 /* tuner interface - we have none */
453 case VIDIOCGTUNER:
454 case VIDIOCSTUNER:
455 case VIDIOCGFREQ:
456 case VIDIOCSFREQ:
457 retval = -EINVAL;
458 break;
459
460 /* audio interface - we have none */
461 case VIDIOCGAUDIO:
462 case VIDIOCSAUDIO:
463 retval = -EINVAL;
464 break;
465 default:
466 retval = -ENOIOCTLCMD;
467 break;
468 }
469
470 return retval;
471}
472
473static int
474vicam_open(struct file *file)
475{
476 struct vicam_camera *cam = video_drvdata(file);
477
478 DBG("open\n");
479
480 if (!cam) {
481 printk(KERN_ERR
482 "vicam video_device improperly initialized");
483 return -EINVAL;
484 }
485
486 /* cam_lock/open_count protects us from simultaneous opens
487 * ... for now. we probably shouldn't rely on this fact forever.
488 */
489
490 mutex_lock(&cam->cam_lock);
491 if (cam->open_count > 0) {
492 printk(KERN_INFO
493 "vicam_open called on already opened camera");
494 mutex_unlock(&cam->cam_lock);
495 return -EBUSY;
496 }
497
498 cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
499 if (!cam->raw_image) {
500 mutex_unlock(&cam->cam_lock);
501 return -ENOMEM;
502 }
503
504 cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
505 if (!cam->framebuf) {
506 kfree(cam->raw_image);
507 mutex_unlock(&cam->cam_lock);
508 return -ENOMEM;
509 }
510
511 cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
512 if (!cam->cntrlbuf) {
513 kfree(cam->raw_image);
514 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
515 mutex_unlock(&cam->cam_lock);
516 return -ENOMEM;
517 }
518
519 cam->needsDummyRead = 1;
520 cam->open_count++;
521
522 file->private_data = cam;
523 mutex_unlock(&cam->cam_lock);
524
525
526 /* First upload firmware, then turn the camera on */
527
528 if (!cam->is_initialized) {
529 initialize_camera(cam);
530
531 cam->is_initialized = 1;
532 }
533
534 set_camera_power(cam, 1);
535
536 return 0;
537}
538
539static int
540vicam_close(struct file *file)
541{
542 struct vicam_camera *cam = file->private_data;
543 int open_count;
544 struct usb_device *udev;
545
546 DBG("close\n");
547
548 /* it's not the end of the world if
549 * we fail to turn the camera off.
550 */
551
552 set_camera_power(cam, 0);
553
554 kfree(cam->raw_image);
555 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
556 kfree(cam->cntrlbuf);
557
558 mutex_lock(&cam->cam_lock);
559
560 cam->open_count--;
561 open_count = cam->open_count;
562 udev = cam->udev;
563
564 mutex_unlock(&cam->cam_lock);
565
566 if (!open_count && !udev)
567 kfree(cam);
568
569 return 0;
570}
571
572static void vicam_decode_color(const u8 *data, u8 *rgb)
573{
574 /* vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB
575 * Copyright (C) 2002 Monroe Williams (monroe@pobox.com)
576 */
577
578 int i, prevY, nextY;
579
580 prevY = 512;
581 nextY = 512;
582
583 data += VICAM_HEADER_SIZE;
584
585 for (i = 0; i < 240; i++, data += 512) {
586 const int y = (i * 242) / 240;
587
588 int j, prevX, nextX;
589 int Y, Cr, Cb;
590
591 if (y == 242 - 1)
592 nextY = -512;
593
594 prevX = 1;
595 nextX = 1;
596
597 for (j = 0; j < 320; j++, rgb += 3) {
598 const int x = (j * 512) / 320;
599 const u8 * const src = &data[x];
600
601 if (x == 512 - 1)
602 nextX = -1;
603
604 Cr = (src[prevX] - src[0]) +
605 (src[nextX] - src[0]);
606 Cr /= 2;
607
608 Cb = (src[prevY] - src[prevX + prevY]) +
609 (src[prevY] - src[nextX + prevY]) +
610 (src[nextY] - src[prevX + nextY]) +
611 (src[nextY] - src[nextX + nextY]);
612 Cb /= 4;
613
614 Y = 1160 * (src[0] + (Cr / 2) - 16);
615
616 if (i & 1) {
617 int Ct = Cr;
618 Cr = Cb;
619 Cb = Ct;
620 }
621
622 if ((x ^ i) & 1) {
623 Cr = -Cr;
624 Cb = -Cb;
625 }
626
627 rgb[0] = clamp(((Y + (2017 * Cb)) +
628 500) / 900, 0, 255);
629 rgb[1] = clamp(((Y - (392 * Cb) -
630 (813 * Cr)) +
631 500) / 1000, 0, 255);
632 rgb[2] = clamp(((Y + (1594 * Cr)) +
633 500) / 1300, 0, 255);
634
635 prevX = -1;
636 }
637
638 prevY = -512;
639 }
640}
641
642static void
643read_frame(struct vicam_camera *cam, int framenum)
644{
645 unsigned char *request = cam->cntrlbuf;
646 int realShutter;
647 int n;
648 int actual_length;
649
650 if (cam->needsDummyRead) {
651 cam->needsDummyRead = 0;
652 read_frame(cam, framenum);
653 }
654
655 memset(request, 0, 16);
656 request[0] = cam->gain; /* 0 = 0% gain, FF = 100% gain */
657
658 request[1] = 0; /* 512x242 capture */
659
660 request[2] = 0x90; /* the function of these two bytes */
661 request[3] = 0x07; /* is not yet understood */
662
663 if (cam->shutter_speed > 60) {
664 /* Short exposure */
665 realShutter =
666 ((-15631900 / cam->shutter_speed) + 260533) / 1000;
667 request[4] = realShutter & 0xFF;
668 request[5] = (realShutter >> 8) & 0xFF;
669 request[6] = 0x03;
670 request[7] = 0x01;
671 } else {
672 /* Long exposure */
673 realShutter = 15600 / cam->shutter_speed - 1;
674 request[4] = 0;
675 request[5] = 0;
676 request[6] = realShutter & 0xFF;
677 request[7] = realShutter >> 8;
678 }
679
680 /* Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0*/
681 request[8] = 0;
682 /* bytes 9-15 do not seem to affect exposure or image quality */
683
684 mutex_lock(&cam->cam_lock);
685
686 if (!cam->udev)
687 goto done;
688
689 n = __send_control_msg(cam, 0x51, 0x80, 0, request, 16);
690
691 if (n < 0) {
692 printk(KERN_ERR
693 " Problem sending frame capture control message");
694 goto done;
695 }
696
697 n = usb_bulk_msg(cam->udev,
698 usb_rcvbulkpipe(cam->udev, cam->bulkEndpoint),
699 cam->raw_image,
700 512 * 242 + 128, &actual_length, 10000);
701
702 if (n < 0) {
703 printk(KERN_ERR "Problem during bulk read of frame data: %d\n",
704 n);
705 }
706
707 done:
708 mutex_unlock(&cam->cam_lock);
709}
710
711static ssize_t
712vicam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
713{
714 struct vicam_camera *cam = file->private_data;
715
716 DBG("read %d bytes.\n", (int) count);
717
718 if (*ppos >= VICAM_MAX_FRAME_SIZE) {
719 *ppos = 0;
720 return 0;
721 }
722
723 if (*ppos == 0) {
724 read_frame(cam, 0);
725 vicam_decode_color(cam->raw_image,
726 cam->framebuf +
727 0 * VICAM_MAX_FRAME_SIZE);
728 }
729
730 count = min_t(size_t, count, VICAM_MAX_FRAME_SIZE - *ppos);
731
732 if (copy_to_user(buf, &cam->framebuf[*ppos], count))
733 count = -EFAULT;
734 else
735 *ppos += count;
736
737 if (count == VICAM_MAX_FRAME_SIZE)
738 *ppos = 0;
739
740 return count;
741}
742
743
744static int
745vicam_mmap(struct file *file, struct vm_area_struct *vma)
746{
747 /* TODO: allocate the raw frame buffer if necessary */
748 unsigned long page, pos;
749 unsigned long start = vma->vm_start;
750 unsigned long size = vma->vm_end-vma->vm_start;
751 struct vicam_camera *cam = file->private_data;
752
753 if (!cam)
754 return -ENODEV;
755
756 DBG("vicam_mmap: %ld\n", size);
757
758 /* We let mmap allocate as much as it wants because Linux was adding 2048 bytes
759 * to the size the application requested for mmap and it was screwing apps up.
760 if (size > VICAM_FRAMES*VICAM_MAX_FRAME_SIZE)
761 return -EINVAL;
762 */
763
764 pos = (unsigned long)cam->framebuf;
765 while (size > 0) {
766 page = vmalloc_to_pfn((void *)pos);
767 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
768 return -EAGAIN;
769
770 start += PAGE_SIZE;
771 pos += PAGE_SIZE;
772 if (size > PAGE_SIZE)
773 size -= PAGE_SIZE;
774 else
775 size = 0;
776 }
777
778 return 0;
779}
780
781static const struct v4l2_file_operations vicam_fops = {
782 .owner = THIS_MODULE,
783 .open = vicam_open,
784 .release = vicam_close,
785 .read = vicam_read,
786 .mmap = vicam_mmap,
787 .ioctl = vicam_ioctl,
788};
789
790static struct video_device vicam_template = {
791 .name = "ViCam-based USB Camera",
792 .fops = &vicam_fops,
793 .release = video_device_release_empty,
794};
795
796/* table of devices that work with this driver */
797static struct usb_device_id vicam_table[] = {
798 {USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)},
799 {USB_DEVICE(USB_COMPRO_VENDOR_ID, USB_COMPRO_PRODUCT_ID)},
800 {} /* Terminating entry */
801};
802
803MODULE_DEVICE_TABLE(usb, vicam_table);
804
805static struct usb_driver vicam_driver = {
806 .name = "vicam",
807 .probe = vicam_probe,
808 .disconnect = vicam_disconnect,
809 .id_table = vicam_table
810};
811
812/**
813 * vicam_probe
814 * @intf: the interface
815 * @id: the device id
816 *
817 * Called by the usb core when a new device is connected that it thinks
818 * this driver might be interested in.
819 */
820static int
821vicam_probe(struct usb_interface *intf, const struct usb_device_id *id)
822{
823 struct usb_device *dev = interface_to_usbdev(intf);
824 int bulkEndpoint = 0;
825 const struct usb_host_interface *interface;
826 const struct usb_endpoint_descriptor *endpoint;
827 struct vicam_camera *cam;
828
829 printk(KERN_INFO "ViCam based webcam connected\n");
830
831 interface = intf->cur_altsetting;
832
833 DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",
834 interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));
835 endpoint = &interface->endpoint[0].desc;
836
837 if (usb_endpoint_is_bulk_in(endpoint)) {
838 /* we found a bulk in endpoint */
839 bulkEndpoint = endpoint->bEndpointAddress;
840 } else {
841 printk(KERN_ERR
842 "No bulk in endpoint was found ?! (this is bad)\n");
843 }
844
845 cam = kzalloc(sizeof(struct vicam_camera), GFP_KERNEL);
846 if (cam == NULL) {
847 printk(KERN_WARNING
848 "could not allocate kernel memory for vicam_camera struct\n");
849 return -ENOMEM;
850 }
851
852
853 cam->shutter_speed = 15;
854
855 mutex_init(&cam->cam_lock);
856
857 memcpy(&cam->vdev, &vicam_template, sizeof(vicam_template));
858 video_set_drvdata(&cam->vdev, cam);
859
860 cam->udev = dev;
861 cam->bulkEndpoint = bulkEndpoint;
862
863 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) < 0) {
864 kfree(cam);
865 printk(KERN_WARNING "video_register_device failed\n");
866 return -EIO;
867 }
868
869 printk(KERN_INFO "ViCam webcam driver now controlling device %s\n",
870 video_device_node_name(&cam->vdev));
871
872 usb_set_intfdata(intf, cam);
873
874 return 0;
875}
876
877static void
878vicam_disconnect(struct usb_interface *intf)
879{
880 int open_count;
881 struct vicam_camera *cam = usb_get_intfdata(intf);
882 usb_set_intfdata(intf, NULL);
883
884 /* we must unregister the device before taking its
885 * cam_lock. This is because the video open call
886 * holds the same lock as video unregister. if we
887 * unregister inside of the cam_lock and open also
888 * uses the cam_lock, we get deadlock.
889 */
890
891 video_unregister_device(&cam->vdev);
892
893 /* stop the camera from being used */
894
895 mutex_lock(&cam->cam_lock);
896
897 /* mark the camera as gone */
898
899 cam->udev = NULL;
900
901 /* the only thing left to do is synchronize with
902 * our close/release function on who should release
903 * the camera memory. if there are any users using the
904 * camera, it's their job. if there are no users,
905 * it's ours.
906 */
907
908 open_count = cam->open_count;
909
910 mutex_unlock(&cam->cam_lock);
911
912 if (!open_count)
913 kfree(cam);
914
915 printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
916}
917
918/*
919 */
920static int __init
921usb_vicam_init(void)
922{
923 int retval;
924 DBG(KERN_INFO "ViCam-based WebCam driver startup\n");
925 retval = usb_register(&vicam_driver);
926 if (retval)
927 printk(KERN_WARNING "usb_register failed!\n");
928 return retval;
929}
930
931static void __exit
932usb_vicam_exit(void)
933{
934 DBG(KERN_INFO
935 "ViCam-based WebCam driver shutdown\n");
936
937 usb_deregister(&vicam_driver);
938}
939
940module_init(usb_vicam_init);
941module_exit(usb_vicam_exit);
942
943MODULE_AUTHOR(DRIVER_AUTHOR);
944MODULE_DESCRIPTION(DRIVER_DESC);
945MODULE_LICENSE("GPL");
946MODULE_FIRMWARE("vicam/firmware.fw");
diff --git a/drivers/staging/usbvideo/videodev.h b/drivers/staging/usbvideo/videodev.h
deleted file mode 100644
index f11efbef1c05..000000000000
--- a/drivers/staging/usbvideo/videodev.h
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2 * Video for Linux version 1 - OBSOLETE
3 *
4 * Header file for v4l1 drivers and applications, for
5 * Linux kernels 2.2.x or 2.4.x.
6 *
7 * Provides header for legacy drivers and applications
8 *
9 * See http://linuxtv.org for more info
10 *
11 */
12#ifndef __LINUX_VIDEODEV_H
13#define __LINUX_VIDEODEV_H
14
15#include <linux/types.h>
16#include <linux/ioctl.h>
17#include <linux/videodev2.h>
18
19#define VID_TYPE_CAPTURE 1 /* Can capture */
20#define VID_TYPE_TUNER 2 /* Can tune */
21#define VID_TYPE_TELETEXT 4 /* Does teletext */
22#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
23#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
24#define VID_TYPE_CLIPPING 32 /* Can clip */
25#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
26#define VID_TYPE_SCALES 128 /* Scalable */
27#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
28#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
29#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
30#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
31#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
32#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
33
34struct video_capability
35{
36 char name[32];
37 int type;
38 int channels; /* Num channels */
39 int audios; /* Num audio devices */
40 int maxwidth; /* Supported width */
41 int maxheight; /* And height */
42 int minwidth; /* Supported width */
43 int minheight; /* And height */
44};
45
46
47struct video_channel
48{
49 int channel;
50 char name[32];
51 int tuners;
52 __u32 flags;
53#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
54#define VIDEO_VC_AUDIO 2 /* Channel has audio */
55 __u16 type;
56#define VIDEO_TYPE_TV 1
57#define VIDEO_TYPE_CAMERA 2
58 __u16 norm; /* Norm set by channel */
59};
60
61struct video_tuner
62{
63 int tuner;
64 char name[32];
65 unsigned long rangelow, rangehigh; /* Tuner range */
66 __u32 flags;
67#define VIDEO_TUNER_PAL 1
68#define VIDEO_TUNER_NTSC 2
69#define VIDEO_TUNER_SECAM 4
70#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
71#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
72#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
73#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
74#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
75 __u16 mode; /* PAL/NTSC/SECAM/OTHER */
76#define VIDEO_MODE_PAL 0
77#define VIDEO_MODE_NTSC 1
78#define VIDEO_MODE_SECAM 2
79#define VIDEO_MODE_AUTO 3
80 __u16 signal; /* Signal strength 16bit scale */
81};
82
83struct video_picture
84{
85 __u16 brightness;
86 __u16 hue;
87 __u16 colour;
88 __u16 contrast;
89 __u16 whiteness; /* Black and white only */
90 __u16 depth; /* Capture depth */
91 __u16 palette; /* Palette in use */
92#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
93#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
94#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
95#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
96#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
97#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
98#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
99#define VIDEO_PALETTE_YUYV 8
100#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
101#define VIDEO_PALETTE_YUV420 10
102#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
103#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
104#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
105#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
106#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
107#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
108#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
109#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
110};
111
112struct video_audio
113{
114 int audio; /* Audio channel */
115 __u16 volume; /* If settable */
116 __u16 bass, treble;
117 __u32 flags;
118#define VIDEO_AUDIO_MUTE 1
119#define VIDEO_AUDIO_MUTABLE 2
120#define VIDEO_AUDIO_VOLUME 4
121#define VIDEO_AUDIO_BASS 8
122#define VIDEO_AUDIO_TREBLE 16
123#define VIDEO_AUDIO_BALANCE 32
124 char name[16];
125#define VIDEO_SOUND_MONO 1
126#define VIDEO_SOUND_STEREO 2
127#define VIDEO_SOUND_LANG1 4
128#define VIDEO_SOUND_LANG2 8
129 __u16 mode;
130 __u16 balance; /* Stereo balance */
131 __u16 step; /* Step actual volume uses */
132};
133
134struct video_clip
135{
136 __s32 x,y;
137 __s32 width, height;
138 struct video_clip *next; /* For user use/driver use only */
139};
140
141struct video_window
142{
143 __u32 x,y; /* Position of window */
144 __u32 width,height; /* Its size */
145 __u32 chromakey;
146 __u32 flags;
147 struct video_clip __user *clips; /* Set only */
148 int clipcount;
149#define VIDEO_WINDOW_INTERLACE 1
150#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
151#define VIDEO_CLIP_BITMAP -1
152/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
153#define VIDEO_CLIPMAP_SIZE (128 * 625)
154};
155
156struct video_capture
157{
158 __u32 x,y; /* Offsets into image */
159 __u32 width, height; /* Area to capture */
160 __u16 decimation; /* Decimation divider */
161 __u16 flags; /* Flags for capture */
162#define VIDEO_CAPTURE_ODD 0 /* Temporal */
163#define VIDEO_CAPTURE_EVEN 1
164};
165
166struct video_buffer
167{
168 void *base;
169 int height,width;
170 int depth;
171 int bytesperline;
172};
173
174struct video_mmap
175{
176 unsigned int frame; /* Frame (0 - n) for double buffer */
177 int height,width;
178 unsigned int format; /* should be VIDEO_PALETTE_* */
179};
180
181struct video_key
182{
183 __u8 key[8];
184 __u32 flags;
185};
186
187struct video_mbuf
188{
189 int size; /* Total memory to map */
190 int frames; /* Frames */
191 int offsets[VIDEO_MAX_FRAME];
192};
193
194#define VIDEO_NO_UNIT (-1)
195
196struct video_unit
197{
198 int video; /* Video minor */
199 int vbi; /* VBI minor */
200 int radio; /* Radio minor */
201 int audio; /* Audio minor */
202 int teletext; /* Teletext minor */
203};
204
205struct vbi_format {
206 __u32 sampling_rate; /* in Hz */
207 __u32 samples_per_line;
208 __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
209 __s32 start[2]; /* starting line for each frame */
210 __u32 count[2]; /* count of lines for each frame */
211 __u32 flags;
212#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
213#define VBI_INTERLACED 2 /* lines are interlaced */
214};
215
216/* video_info is biased towards hardware mpeg encode/decode */
217/* but it could apply generically to any hardware compressor/decompressor */
218struct video_info
219{
220 __u32 frame_count; /* frames output since decode/encode began */
221 __u32 h_size; /* current unscaled horizontal size */
222 __u32 v_size; /* current unscaled veritcal size */
223 __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */
224 __u32 picture_type; /* current picture type */
225 __u32 temporal_reference; /* current temporal reference */
226 __u8 user_data[256]; /* user data last found in compressed stream */
227 /* user_data[0] contains user data flags, user_data[1] has count */
228};
229
230/* generic structure for setting playback modes */
231struct video_play_mode
232{
233 int mode;
234 int p1;
235 int p2;
236};
237
238/* for loading microcode / fpga programming */
239struct video_code
240{
241 char loadwhat[16]; /* name or tag of file being passed */
242 int datasize;
243 __u8 *data;
244};
245
246#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
247#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
248#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
249#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
250#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
251#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
252#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
253#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
254#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
255#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
256#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
257#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
258#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
259#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
260#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
261#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
262#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
263#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
264#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
265#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
266#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */
267#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */
268#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */
269#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */
270#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */
271#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */
272#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */
273#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
274#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
275
276
277#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
278
279/* VIDIOCSWRITEMODE */
280#define VID_WRITE_MPEG_AUD 0
281#define VID_WRITE_MPEG_VID 1
282#define VID_WRITE_OSD 2
283#define VID_WRITE_TTX 3
284#define VID_WRITE_CC 4
285#define VID_WRITE_MJPEG 5
286
287/* VIDIOCSPLAYMODE */
288#define VID_PLAY_VID_OUT_MODE 0
289 /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
290#define VID_PLAY_GENLOCK 1
291 /* p1: 0 = OFF, 1 = ON */
292 /* p2: GENLOCK FINE DELAY value */
293#define VID_PLAY_NORMAL 2
294#define VID_PLAY_PAUSE 3
295#define VID_PLAY_SINGLE_FRAME 4
296#define VID_PLAY_FAST_FORWARD 5
297#define VID_PLAY_SLOW_MOTION 6
298#define VID_PLAY_IMMEDIATE_NORMAL 7
299#define VID_PLAY_SWITCH_CHANNELS 8
300#define VID_PLAY_FREEZE_FRAME 9
301#define VID_PLAY_STILL_MODE 10
302#define VID_PLAY_MASTER_MODE 11
303 /* p1: see below */
304#define VID_PLAY_MASTER_NONE 1
305#define VID_PLAY_MASTER_VIDEO 2
306#define VID_PLAY_MASTER_AUDIO 3
307#define VID_PLAY_ACTIVE_SCANLINES 12
308 /* p1 = first active; p2 = last active */
309#define VID_PLAY_RESET 13
310#define VID_PLAY_END_MARK 14
311
312#endif /* __LINUX_VIDEODEV_H */
313
314/*
315 * Local variables:
316 * c-basic-offset: 8
317 * End:
318 */
diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
index e1851f00be56..842cd9214a5e 100644
--- a/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
+++ b/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
@@ -381,10 +381,10 @@ static int cyasblkdev_blk_ioctl(
381 return -ENOTTY; 381 return -ENOTTY;
382} 382}
383 383
384/* Media_changed block_device opp 384/* check_events block_device opp
385 * this one is called by kernel to confirm if the media really changed 385 * this one is called by kernel to confirm if the media really changed
386 * as we indicated by issuing check_disk_change() call */ 386 * as we indicated by issuing check_disk_change() call */
387int cyasblkdev_media_changed(struct gendisk *gd) 387unsigned int cyasblkdev_check_events(struct gendisk *gd, unsigned int clearing)
388{ 388{
389 struct cyasblkdev_blk_data *bd; 389 struct cyasblkdev_blk_data *bd;
390 390
@@ -402,7 +402,7 @@ int cyasblkdev_media_changed(struct gendisk *gd)
402 #endif 402 #endif
403 } 403 }
404 404
405 /* return media change state "1" yes, 0 no */ 405 /* return media change state - DISK_EVENT_MEDIA_CHANGE yes, 0 no */
406 return 0; 406 return 0;
407} 407}
408 408
@@ -432,7 +432,7 @@ static struct block_device_operations cyasblkdev_bdops = {
432 .ioctl = cyasblkdev_blk_ioctl, 432 .ioctl = cyasblkdev_blk_ioctl,
433 /* .getgeo = cyasblkdev_blk_getgeo, */ 433 /* .getgeo = cyasblkdev_blk_getgeo, */
434 /* added to support media removal( real and simulated) media */ 434 /* added to support media removal( real and simulated) media */
435 .media_changed = cyasblkdev_media_changed, 435 .check_events = cyasblkdev_check_events,
436 /* added to support media removal( real and simulated) media */ 436 /* added to support media removal( real and simulated) media */
437 .revalidate_disk = cyasblkdev_revalidate_disk, 437 .revalidate_disk = cyasblkdev_revalidate_disk,
438 .owner = THIS_MODULE, 438 .owner = THIS_MODULE,
@@ -1090,6 +1090,7 @@ static int cyasblkdev_add_disks(int bus_num,
1090 bd->user_disk_0->first_minor = devidx << CYASBLKDEV_SHIFT; 1090 bd->user_disk_0->first_minor = devidx << CYASBLKDEV_SHIFT;
1091 bd->user_disk_0->minors = 8; 1091 bd->user_disk_0->minors = 8;
1092 bd->user_disk_0->fops = &cyasblkdev_bdops; 1092 bd->user_disk_0->fops = &cyasblkdev_bdops;
1093 bd->user_disk_0->events = DISK_EVENT_MEDIA_CHANGE;
1093 bd->user_disk_0->private_data = bd; 1094 bd->user_disk_0->private_data = bd;
1094 bd->user_disk_0->queue = bd->queue.queue; 1095 bd->user_disk_0->queue = bd->queue.queue;
1095 bd->dbgprn_flags = DBGPRN_RD_RQ; 1096 bd->dbgprn_flags = DBGPRN_RD_RQ;
@@ -1190,6 +1191,7 @@ static int cyasblkdev_add_disks(int bus_num,
1190 bd->user_disk_1->first_minor = (devidx + 1) << CYASBLKDEV_SHIFT; 1191 bd->user_disk_1->first_minor = (devidx + 1) << CYASBLKDEV_SHIFT;
1191 bd->user_disk_1->minors = 8; 1192 bd->user_disk_1->minors = 8;
1192 bd->user_disk_1->fops = &cyasblkdev_bdops; 1193 bd->user_disk_1->fops = &cyasblkdev_bdops;
1194 bd->user_disk_0->events = DISK_EVENT_MEDIA_CHANGE;
1193 bd->user_disk_1->private_data = bd; 1195 bd->user_disk_1->private_data = bd;
1194 bd->user_disk_1->queue = bd->queue.queue; 1196 bd->user_disk_1->queue = bd->queue.queue;
1195 bd->dbgprn_flags = DBGPRN_RD_RQ; 1197 bd->dbgprn_flags = DBGPRN_RD_RQ;
@@ -1278,6 +1280,7 @@ static int cyasblkdev_add_disks(int bus_num,
1278 (devidx + 2) << CYASBLKDEV_SHIFT; 1280 (devidx + 2) << CYASBLKDEV_SHIFT;
1279 bd->system_disk->minors = 8; 1281 bd->system_disk->minors = 8;
1280 bd->system_disk->fops = &cyasblkdev_bdops; 1282 bd->system_disk->fops = &cyasblkdev_bdops;
1283 bd->system_disk->events = DISK_EVENT_MEDIA_CHANGE;
1281 bd->system_disk->private_data = bd; 1284 bd->system_disk->private_data = bd;
1282 bd->system_disk->queue = bd->queue.queue; 1285 bd->system_disk->queue = bd->queue.queue;
1283 /* don't search for vfat 1286 /* don't search for vfat
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 3df570db0e4f..eb0afec046e1 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -391,9 +391,8 @@ static int iblock_do_task(struct se_task *task)
391{ 391{
392 struct se_device *dev = task->task_se_cmd->se_dev; 392 struct se_device *dev = task->task_se_cmd->se_dev;
393 struct iblock_req *req = IBLOCK_REQ(task); 393 struct iblock_req *req = IBLOCK_REQ(task);
394 struct iblock_dev *ibd = (struct iblock_dev *)req->ib_dev;
395 struct request_queue *q = bdev_get_queue(ibd->ibd_bd);
396 struct bio *bio = req->ib_bio, *nbio = NULL; 394 struct bio *bio = req->ib_bio, *nbio = NULL;
395 struct blk_plug plug;
397 int rw; 396 int rw;
398 397
399 if (task->task_data_direction == DMA_TO_DEVICE) { 398 if (task->task_data_direction == DMA_TO_DEVICE) {
@@ -411,6 +410,7 @@ static int iblock_do_task(struct se_task *task)
411 rw = READ; 410 rw = READ;
412 } 411 }
413 412
413 blk_start_plug(&plug);
414 while (bio) { 414 while (bio) {
415 nbio = bio->bi_next; 415 nbio = bio->bi_next;
416 bio->bi_next = NULL; 416 bio->bi_next = NULL;
@@ -420,9 +420,8 @@ static int iblock_do_task(struct se_task *task)
420 submit_bio(rw, bio); 420 submit_bio(rw, bio);
421 bio = nbio; 421 bio = nbio;
422 } 422 }
423 blk_finish_plug(&plug);
423 424
424 if (q->unplug_fn)
425 q->unplug_fn(q);
426 return PYX_TRANSPORT_SENT_TO_TRANSPORT; 425 return PYX_TRANSPORT_SENT_TO_TRANSPORT;
427} 426}
428 427
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 713b7ea4a607..fc6f2a5bde01 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -560,7 +560,8 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
560 560
561 tz->hwmon = NULL; 561 tz->hwmon = NULL;
562 device_remove_file(hwmon->device, &tz->temp_input.attr); 562 device_remove_file(hwmon->device, &tz->temp_input.attr);
563 device_remove_file(hwmon->device, &tz->temp_crit.attr); 563 if (tz->ops->get_crit_temp)
564 device_remove_file(hwmon->device, &tz->temp_crit.attr);
564 565
565 mutex_lock(&thermal_list_lock); 566 mutex_lock(&thermal_list_lock);
566 list_del(&tz->hwmon_node); 567 list_del(&tz->hwmon_node);
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 81f13958e751..43db715f1502 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -306,7 +306,7 @@ static struct sysrq_key_op sysrq_ftrace_dump_op = {
306 306
307static void sysrq_handle_showmem(int key) 307static void sysrq_handle_showmem(int key)
308{ 308{
309 show_mem(); 309 show_mem(0);
310} 310}
311static struct sysrq_key_op sysrq_showmem_op = { 311static struct sysrq_key_op sysrq_showmem_op = {
312 .handler = sysrq_handle_showmem, 312 .handler = sysrq_handle_showmem,
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 6dd3c68c13ad..d6b342b5b423 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -600,7 +600,7 @@ static void fn_scroll_back(struct vc_data *vc)
600 600
601static void fn_show_mem(struct vc_data *vc) 601static void fn_show_mem(struct vc_data *vc)
602{ 602{
603 show_mem(); 603 show_mem(0);
604} 604}
605 605
606static void fn_show_state(struct vc_data *vc) 606static void fn_show_state(struct vc_data *vc)
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index f492a7f2b6ee..e057e5381465 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -297,6 +297,8 @@ static void acm_ctrl_irq(struct urb *urb)
297 if (!ACM_READY(acm)) 297 if (!ACM_READY(acm))
298 goto exit; 298 goto exit;
299 299
300 usb_mark_last_busy(acm->dev);
301
300 data = (unsigned char *)(dr + 1); 302 data = (unsigned char *)(dr + 1);
301 switch (dr->bNotificationType) { 303 switch (dr->bNotificationType) {
302 case USB_CDC_NOTIFY_NETWORK_CONNECTION: 304 case USB_CDC_NOTIFY_NETWORK_CONNECTION:
@@ -336,7 +338,6 @@ static void acm_ctrl_irq(struct urb *urb)
336 break; 338 break;
337 } 339 }
338exit: 340exit:
339 usb_mark_last_busy(acm->dev);
340 retval = usb_submit_urb(urb, GFP_ATOMIC); 341 retval = usb_submit_urb(urb, GFP_ATOMIC);
341 if (retval) 342 if (retval)
342 dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with " 343 dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with "
@@ -533,6 +534,8 @@ static void acm_softint(struct work_struct *work)
533 if (!ACM_READY(acm)) 534 if (!ACM_READY(acm))
534 return; 535 return;
535 tty = tty_port_tty_get(&acm->port); 536 tty = tty_port_tty_get(&acm->port);
537 if (!tty)
538 return;
536 tty_wakeup(tty); 539 tty_wakeup(tty);
537 tty_kref_put(tty); 540 tty_kref_put(tty);
538} 541}
@@ -646,8 +649,10 @@ static void acm_port_down(struct acm *acm)
646 usb_kill_urb(acm->ctrlurb); 649 usb_kill_urb(acm->ctrlurb);
647 for (i = 0; i < ACM_NW; i++) 650 for (i = 0; i < ACM_NW; i++)
648 usb_kill_urb(acm->wb[i].urb); 651 usb_kill_urb(acm->wb[i].urb);
652 tasklet_disable(&acm->urb_task);
649 for (i = 0; i < nr; i++) 653 for (i = 0; i < nr; i++)
650 usb_kill_urb(acm->ru[i].urb); 654 usb_kill_urb(acm->ru[i].urb);
655 tasklet_enable(&acm->urb_task);
651 acm->control->needs_remote_wakeup = 0; 656 acm->control->needs_remote_wakeup = 0;
652 usb_autopm_put_interface(acm->control); 657 usb_autopm_put_interface(acm->control);
653 } 658 }
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 47085e5879ab..a97c018dd419 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -281,7 +281,7 @@ static void cleanup(struct wdm_device *desc)
281 desc->sbuf, 281 desc->sbuf,
282 desc->validity->transfer_dma); 282 desc->validity->transfer_dma);
283 usb_free_coherent(interface_to_usbdev(desc->intf), 283 usb_free_coherent(interface_to_usbdev(desc->intf),
284 desc->wMaxCommand, 284 desc->bMaxPacketSize0,
285 desc->inbuf, 285 desc->inbuf,
286 desc->response->transfer_dma); 286 desc->response->transfer_dma);
287 kfree(desc->orq); 287 kfree(desc->orq);
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index a7131ad630f9..37518dfdeb98 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -802,7 +802,7 @@ static int proc_control(struct dev_state *ps, void __user *arg)
802 tbuf, ctrl.wLength, tmo); 802 tbuf, ctrl.wLength, tmo);
803 usb_lock_device(dev); 803 usb_lock_device(dev);
804 snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, 804 snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE,
805 tbuf, i); 805 tbuf, max(i, 0));
806 if ((i > 0) && ctrl.wLength) { 806 if ((i > 0) && ctrl.wLength) {
807 if (copy_to_user(ctrl.data, tbuf, i)) { 807 if (copy_to_user(ctrl.data, tbuf, i)) {
808 free_page((unsigned long)tbuf); 808 free_page((unsigned long)tbuf);
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index fe99895fb098..98ded66e8d3f 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -315,7 +315,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
315 int stopped; 315 int stopped;
316 unsigned count = 0; 316 unsigned count = 0;
317 u8 state; 317 u8 state;
318 const __le32 halt = HALT_BIT(ehci);
319 struct ehci_qh_hw *hw = qh->hw; 318 struct ehci_qh_hw *hw = qh->hw;
320 319
321 if (unlikely (list_empty (&qh->qtd_list))) 320 if (unlikely (list_empty (&qh->qtd_list)))
@@ -422,7 +421,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
422 && !(qtd->hw_alt_next 421 && !(qtd->hw_alt_next
423 & EHCI_LIST_END(ehci))) { 422 & EHCI_LIST_END(ehci))) {
424 stopped = 1; 423 stopped = 1;
425 goto halt;
426 } 424 }
427 425
428 /* stop scanning when we reach qtds the hc is using */ 426 /* stop scanning when we reach qtds the hc is using */
@@ -456,16 +454,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
456 */ 454 */
457 ehci_clear_tt_buffer(ehci, qh, urb, token); 455 ehci_clear_tt_buffer(ehci, qh, urb, token);
458 } 456 }
459
460 /* force halt for unlinked or blocked qh, so we'll
461 * patch the qh later and so that completions can't
462 * activate it while we "know" it's stopped.
463 */
464 if ((halt & hw->hw_token) == 0) {
465halt:
466 hw->hw_token |= halt;
467 wmb ();
468 }
469 } 457 }
470 458
471 /* unless we already know the urb's status, collect qtd status 459 /* unless we already know the urb's status, collect qtd status
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index 8dabe8e31d8c..3558491dd87d 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -185,7 +185,7 @@ static struct platform_driver ohci_hcd_tmio_driver;
185 185
186static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev) 186static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
187{ 187{
188 struct mfd_cell *cell = dev->dev.platform_data; 188 const struct mfd_cell *cell = mfd_get_cell(dev);
189 struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0); 189 struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
190 struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1); 190 struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1);
191 struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2); 191 struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2);
@@ -274,7 +274,7 @@ static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev)
274{ 274{
275 struct usb_hcd *hcd = platform_get_drvdata(dev); 275 struct usb_hcd *hcd = platform_get_drvdata(dev);
276 struct tmio_hcd *tmio = hcd_to_tmio(hcd); 276 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
277 struct mfd_cell *cell = dev->dev.platform_data; 277 const struct mfd_cell *cell = mfd_get_cell(dev);
278 278
279 usb_remove_hcd(hcd); 279 usb_remove_hcd(hcd);
280 tmio_stop_hc(dev); 280 tmio_stop_hc(dev);
@@ -293,7 +293,7 @@ static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev)
293#ifdef CONFIG_PM 293#ifdef CONFIG_PM
294static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state) 294static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state)
295{ 295{
296 struct mfd_cell *cell = dev->dev.platform_data; 296 const struct mfd_cell *cell = mfd_get_cell(dev);
297 struct usb_hcd *hcd = platform_get_drvdata(dev); 297 struct usb_hcd *hcd = platform_get_drvdata(dev);
298 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 298 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
299 struct tmio_hcd *tmio = hcd_to_tmio(hcd); 299 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
@@ -326,7 +326,7 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s
326 326
327static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) 327static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
328{ 328{
329 struct mfd_cell *cell = dev->dev.platform_data; 329 const struct mfd_cell *cell = mfd_get_cell(dev);
330 struct usb_hcd *hcd = platform_get_drvdata(dev); 330 struct usb_hcd *hcd = platform_get_drvdata(dev);
331 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 331 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
332 struct tmio_hcd *tmio = hcd_to_tmio(hcd); 332 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index f7a205738032..8b1d94a76914 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -177,12 +177,11 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
177 spin_lock_irqsave(&priv->asynclock, flags); 177 spin_lock_irqsave(&priv->asynclock, flags);
178 list_add_tail(&rq->asynclist, &priv->asynclist); 178 list_add_tail(&rq->asynclist, &priv->asynclist);
179 spin_unlock_irqrestore(&priv->asynclock, flags); 179 spin_unlock_irqrestore(&priv->asynclock, flags);
180 kref_get(&rq->ref_count);
180 ret = usb_submit_urb(rq->urb, mem_flags); 181 ret = usb_submit_urb(rq->urb, mem_flags);
181 if (!ret) { 182 if (!ret)
182 kref_get(&rq->ref_count);
183 return rq; 183 return rq;
184 } 184 destroy_async(&rq->ref_count);
185 kref_put(&rq->ref_count, destroy_async);
186 err("submit_async_request submit_urb failed with %d", ret); 185 err("submit_async_request submit_urb failed with %d", ret);
187 return NULL; 186 return NULL;
188} 187}
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index 9d49d1cd7ce2..52312e8af213 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -322,7 +322,7 @@ static void bfin_musb_try_idle(struct musb *musb, unsigned long timeout)
322 mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); 322 mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
323} 323}
324 324
325static int bfin_musb_get_vbus_status(struct musb *musb) 325static int bfin_musb_vbus_status(struct musb *musb)
326{ 326{
327 return 0; 327 return 0;
328} 328}
@@ -540,7 +540,7 @@ static struct dev_pm_ops bfin_pm_ops = {
540 .resume = bfin_resume, 540 .resume = bfin_resume,
541}; 541};
542 542
543#define DEV_PM_OPS &bfin_pm_op, 543#define DEV_PM_OPS &bfin_pm_ops
544#else 544#else
545#define DEV_PM_OPS NULL 545#define DEV_PM_OPS NULL
546#endif 546#endif
@@ -548,7 +548,7 @@ static struct dev_pm_ops bfin_pm_ops = {
548static struct platform_driver bfin_driver = { 548static struct platform_driver bfin_driver = {
549 .remove = __exit_p(bfin_remove), 549 .remove = __exit_p(bfin_remove),
550 .driver = { 550 .driver = {
551 .name = "musb-bfin", 551 .name = "musb-blackfin",
552 .pm = DEV_PM_OPS, 552 .pm = DEV_PM_OPS,
553 }, 553 },
554}; 554};
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 5c7b321d3959..98519c5d8b5c 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1880,12 +1880,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
1880 if (retval < 0) { 1880 if (retval < 0) {
1881 DBG(1, "add_hcd failed, %d\n", retval); 1881 DBG(1, "add_hcd failed, %d\n", retval);
1882 goto err2; 1882 goto err2;
1883
1884 if ((musb->xceiv->last_event == USB_EVENT_ID)
1885 && musb->xceiv->set_vbus)
1886 otg_set_vbus(musb->xceiv, 1);
1887 } 1883 }
1888 1884
1885 if ((musb->xceiv->last_event == USB_EVENT_ID)
1886 && musb->xceiv->set_vbus)
1887 otg_set_vbus(musb->xceiv, 1);
1888
1889 hcd->self.uses_pio_for_control = 1; 1889 hcd->self.uses_pio_for_control = 1;
1890 1890
1891 if (musb->xceiv->last_event == USB_EVENT_NONE) 1891 if (musb->xceiv->last_event == USB_EVENT_NONE)
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index a65ddd543869..e4fad5e643d7 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -698,8 +698,7 @@ static void play_delayed(struct usb_serial_port *port)
698 /* we have to throw away the rest */ 698 /* we have to throw away the rest */
699 do { 699 do {
700 unbusy_queued_urb(urb, portdata); 700 unbusy_queued_urb(urb, portdata);
701 //extremely dirty 701 usb_autopm_put_interface_no_suspend(port->serial->interface);
702 atomic_dec(&port->serial->interface->dev.power.usage_count);
703 } while ((urb = usb_get_from_anchor(&portdata->delayed))); 702 } while ((urb = usb_get_from_anchor(&portdata->delayed)));
704 break; 703 break;
705 } 704 }
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 391ac939f011..8686429cbdf0 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -158,12 +158,19 @@ static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)
158 } 158 }
159} 159}
160 160
161static void arkfb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
162{
163 struct arkfb_info *par = info->par;
164
165 svga_tilecursor(par->state.vgabase, info, cursor);
166}
167
161static struct fb_tile_ops arkfb_tile_ops = { 168static struct fb_tile_ops arkfb_tile_ops = {
162 .fb_settile = arkfb_settile, 169 .fb_settile = arkfb_settile,
163 .fb_tilecopy = svga_tilecopy, 170 .fb_tilecopy = svga_tilecopy,
164 .fb_tilefill = svga_tilefill, 171 .fb_tilefill = svga_tilefill,
165 .fb_tileblit = svga_tileblit, 172 .fb_tileblit = svga_tileblit,
166 .fb_tilecursor = svga_tilecursor, 173 .fb_tilecursor = arkfb_tilecursor,
167 .fb_get_tilemax = svga_get_tilemax, 174 .fb_get_tilemax = svga_get_tilemax,
168}; 175};
169 176
@@ -466,32 +473,40 @@ static unsigned short dac_regs[4] = {0x3c8, 0x3c9, 0x3c6, 0x3c7};
466 473
467static void ark_dac_read_regs(void *data, u8 *code, int count) 474static void ark_dac_read_regs(void *data, u8 *code, int count)
468{ 475{
469 u8 regval = vga_rseq(NULL, 0x1C); 476 struct fb_info *info = data;
477 struct arkfb_info *par;
478 u8 regval;
470 479
480 par = info->par;
481 regval = vga_rseq(par->state.vgabase, 0x1C);
471 while (count != 0) 482 while (count != 0)
472 { 483 {
473 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 484 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
474 code[1] = vga_r(NULL, dac_regs[code[0] & 3]); 485 code[1] = vga_r(par->state.vgabase, dac_regs[code[0] & 3]);
475 count--; 486 count--;
476 code += 2; 487 code += 2;
477 } 488 }
478 489
479 vga_wseq(NULL, 0x1C, regval); 490 vga_wseq(par->state.vgabase, 0x1C, regval);
480} 491}
481 492
482static void ark_dac_write_regs(void *data, u8 *code, int count) 493static void ark_dac_write_regs(void *data, u8 *code, int count)
483{ 494{
484 u8 regval = vga_rseq(NULL, 0x1C); 495 struct fb_info *info = data;
496 struct arkfb_info *par;
497 u8 regval;
485 498
499 par = info->par;
500 regval = vga_rseq(par->state.vgabase, 0x1C);
486 while (count != 0) 501 while (count != 0)
487 { 502 {
488 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 503 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
489 vga_w(NULL, dac_regs[code[0] & 3], code[1]); 504 vga_w(par->state.vgabase, dac_regs[code[0] & 3], code[1]);
490 count--; 505 count--;
491 code += 2; 506 code += 2;
492 } 507 }
493 508
494 vga_wseq(NULL, 0x1C, regval); 509 vga_wseq(par->state.vgabase, 0x1C, regval);
495} 510}
496 511
497 512
@@ -507,8 +522,8 @@ static void ark_set_pixclock(struct fb_info *info, u32 pixclock)
507 } 522 }
508 523
509 /* Set VGA misc register */ 524 /* Set VGA misc register */
510 regval = vga_r(NULL, VGA_MIS_R); 525 regval = vga_r(par->state.vgabase, VGA_MIS_R);
511 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 526 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
512} 527}
513 528
514 529
@@ -520,7 +535,10 @@ static int arkfb_open(struct fb_info *info, int user)
520 535
521 mutex_lock(&(par->open_lock)); 536 mutex_lock(&(par->open_lock));
522 if (par->ref_count == 0) { 537 if (par->ref_count == 0) {
538 void __iomem *vgabase = par->state.vgabase;
539
523 memset(&(par->state), 0, sizeof(struct vgastate)); 540 memset(&(par->state), 0, sizeof(struct vgastate));
541 par->state.vgabase = vgabase;
524 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 542 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
525 par->state.num_crtc = 0x60; 543 par->state.num_crtc = 0x60;
526 par->state.num_seq = 0x30; 544 par->state.num_seq = 0x30;
@@ -646,50 +664,50 @@ static int arkfb_set_par(struct fb_info *info)
646 info->var.activate = FB_ACTIVATE_NOW; 664 info->var.activate = FB_ACTIVATE_NOW;
647 665
648 /* Unlock registers */ 666 /* Unlock registers */
649 svga_wcrt_mask(0x11, 0x00, 0x80); 667 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
650 668
651 /* Blank screen and turn off sync */ 669 /* Blank screen and turn off sync */
652 svga_wseq_mask(0x01, 0x20, 0x20); 670 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
653 svga_wcrt_mask(0x17, 0x00, 0x80); 671 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
654 672
655 /* Set default values */ 673 /* Set default values */
656 svga_set_default_gfx_regs(); 674 svga_set_default_gfx_regs(par->state.vgabase);
657 svga_set_default_atc_regs(); 675 svga_set_default_atc_regs(par->state.vgabase);
658 svga_set_default_seq_regs(); 676 svga_set_default_seq_regs(par->state.vgabase);
659 svga_set_default_crt_regs(); 677 svga_set_default_crt_regs(par->state.vgabase);
660 svga_wcrt_multi(ark_line_compare_regs, 0xFFFFFFFF); 678 svga_wcrt_multi(par->state.vgabase, ark_line_compare_regs, 0xFFFFFFFF);
661 svga_wcrt_multi(ark_start_address_regs, 0); 679 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, 0);
662 680
663 /* ARK specific initialization */ 681 /* ARK specific initialization */
664 svga_wseq_mask(0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */ 682 svga_wseq_mask(par->state.vgabase, 0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */
665 svga_wseq_mask(0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */ 683 svga_wseq_mask(par->state.vgabase, 0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */
666 684
667 vga_wseq(NULL, 0x13, info->fix.smem_start >> 16); 685 vga_wseq(par->state.vgabase, 0x13, info->fix.smem_start >> 16);
668 vga_wseq(NULL, 0x14, info->fix.smem_start >> 24); 686 vga_wseq(par->state.vgabase, 0x14, info->fix.smem_start >> 24);
669 vga_wseq(NULL, 0x15, 0); 687 vga_wseq(par->state.vgabase, 0x15, 0);
670 vga_wseq(NULL, 0x16, 0); 688 vga_wseq(par->state.vgabase, 0x16, 0);
671 689
672 /* Set the FIFO threshold register */ 690 /* Set the FIFO threshold register */
673 /* It is fascinating way to store 5-bit value in 8-bit register */ 691 /* It is fascinating way to store 5-bit value in 8-bit register */
674 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1; 692 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1;
675 vga_wseq(NULL, 0x18, regval); 693 vga_wseq(par->state.vgabase, 0x18, regval);
676 694
677 /* Set the offset register */ 695 /* Set the offset register */
678 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 696 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
679 svga_wcrt_multi(ark_offset_regs, offset_value); 697 svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);
680 698
681 /* fix for hi-res textmode */ 699 /* fix for hi-res textmode */
682 svga_wcrt_mask(0x40, 0x08, 0x08); 700 svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08);
683 701
684 if (info->var.vmode & FB_VMODE_DOUBLE) 702 if (info->var.vmode & FB_VMODE_DOUBLE)
685 svga_wcrt_mask(0x09, 0x80, 0x80); 703 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
686 else 704 else
687 svga_wcrt_mask(0x09, 0x00, 0x80); 705 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
688 706
689 if (info->var.vmode & FB_VMODE_INTERLACED) 707 if (info->var.vmode & FB_VMODE_INTERLACED)
690 svga_wcrt_mask(0x44, 0x04, 0x04); 708 svga_wcrt_mask(par->state.vgabase, 0x44, 0x04, 0x04);
691 else 709 else
692 svga_wcrt_mask(0x44, 0x00, 0x04); 710 svga_wcrt_mask(par->state.vgabase, 0x44, 0x00, 0x04);
693 711
694 hmul = 1; 712 hmul = 1;
695 hdiv = 1; 713 hdiv = 1;
@@ -699,40 +717,40 @@ static int arkfb_set_par(struct fb_info *info)
699 switch (mode) { 717 switch (mode) {
700 case 0: 718 case 0:
701 pr_debug("fb%d: text mode\n", info->node); 719 pr_debug("fb%d: text mode\n", info->node);
702 svga_set_textmode_vga_regs(); 720 svga_set_textmode_vga_regs(par->state.vgabase);
703 721
704 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 722 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
705 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 723 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
706 dac_set_mode(par->dac, DAC_PSEUDO8_8); 724 dac_set_mode(par->dac, DAC_PSEUDO8_8);
707 725
708 break; 726 break;
709 case 1: 727 case 1:
710 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 728 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
711 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 729 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
712 730
713 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 731 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
714 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 732 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
715 dac_set_mode(par->dac, DAC_PSEUDO8_8); 733 dac_set_mode(par->dac, DAC_PSEUDO8_8);
716 break; 734 break;
717 case 2: 735 case 2:
718 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 736 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
719 737
720 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 738 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
721 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 739 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
722 dac_set_mode(par->dac, DAC_PSEUDO8_8); 740 dac_set_mode(par->dac, DAC_PSEUDO8_8);
723 break; 741 break;
724 case 3: 742 case 3:
725 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 743 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
726 744
727 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode */ 745 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode */
728 746
729 if (info->var.pixclock > 20000) { 747 if (info->var.pixclock > 20000) {
730 pr_debug("fb%d: not using multiplex\n", info->node); 748 pr_debug("fb%d: not using multiplex\n", info->node);
731 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 749 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
732 dac_set_mode(par->dac, DAC_PSEUDO8_8); 750 dac_set_mode(par->dac, DAC_PSEUDO8_8);
733 } else { 751 } else {
734 pr_debug("fb%d: using multiplex\n", info->node); 752 pr_debug("fb%d: using multiplex\n", info->node);
735 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 753 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
736 dac_set_mode(par->dac, DAC_PSEUDO8_16); 754 dac_set_mode(par->dac, DAC_PSEUDO8_16);
737 hdiv = 2; 755 hdiv = 2;
738 } 756 }
@@ -740,22 +758,22 @@ static int arkfb_set_par(struct fb_info *info)
740 case 4: 758 case 4:
741 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 759 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
742 760
743 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 761 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
744 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 762 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
745 dac_set_mode(par->dac, DAC_RGB1555_16); 763 dac_set_mode(par->dac, DAC_RGB1555_16);
746 break; 764 break;
747 case 5: 765 case 5:
748 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 766 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
749 767
750 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 768 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
751 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 769 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
752 dac_set_mode(par->dac, DAC_RGB0565_16); 770 dac_set_mode(par->dac, DAC_RGB0565_16);
753 break; 771 break;
754 case 6: 772 case 6:
755 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 773 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
756 774
757 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode ??? */ 775 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode ??? */
758 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 776 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
759 dac_set_mode(par->dac, DAC_RGB0888_16); 777 dac_set_mode(par->dac, DAC_RGB0888_16);
760 hmul = 3; 778 hmul = 3;
761 hdiv = 2; 779 hdiv = 2;
@@ -763,8 +781,8 @@ static int arkfb_set_par(struct fb_info *info)
763 case 7: 781 case 7:
764 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 782 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
765 783
766 vga_wseq(NULL, 0x11, 0x1E); /* 32bpp accel mode */ 784 vga_wseq(par->state.vgabase, 0x11, 0x1E); /* 32bpp accel mode */
767 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 785 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
768 dac_set_mode(par->dac, DAC_RGB8888_16); 786 dac_set_mode(par->dac, DAC_RGB8888_16);
769 hmul = 2; 787 hmul = 2;
770 break; 788 break;
@@ -774,7 +792,7 @@ static int arkfb_set_par(struct fb_info *info)
774 } 792 }
775 793
776 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul); 794 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
777 svga_set_timings(&ark_timing_regs, &(info->var), hmul, hdiv, 795 svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
778 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 796 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
779 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 797 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
780 hmul, info->node); 798 hmul, info->node);
@@ -782,12 +800,12 @@ static int arkfb_set_par(struct fb_info *info)
782 /* Set interlaced mode start/end register */ 800 /* Set interlaced mode start/end register */
783 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 801 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
784 value = ((value * hmul / hdiv) / 8) - 5; 802 value = ((value * hmul / hdiv) / 8) - 5;
785 vga_wcrt(NULL, 0x42, (value + 1) / 2); 803 vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
786 804
787 memset_io(info->screen_base, 0x00, screen_size); 805 memset_io(info->screen_base, 0x00, screen_size);
788 /* Device and screen back on */ 806 /* Device and screen back on */
789 svga_wcrt_mask(0x17, 0x80, 0x80); 807 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
790 svga_wseq_mask(0x01, 0x00, 0x20); 808 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
791 809
792 return 0; 810 return 0;
793} 811}
@@ -857,23 +875,25 @@ static int arkfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
857 875
858static int arkfb_blank(int blank_mode, struct fb_info *info) 876static int arkfb_blank(int blank_mode, struct fb_info *info)
859{ 877{
878 struct arkfb_info *par = info->par;
879
860 switch (blank_mode) { 880 switch (blank_mode) {
861 case FB_BLANK_UNBLANK: 881 case FB_BLANK_UNBLANK:
862 pr_debug("fb%d: unblank\n", info->node); 882 pr_debug("fb%d: unblank\n", info->node);
863 svga_wseq_mask(0x01, 0x00, 0x20); 883 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
864 svga_wcrt_mask(0x17, 0x80, 0x80); 884 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
865 break; 885 break;
866 case FB_BLANK_NORMAL: 886 case FB_BLANK_NORMAL:
867 pr_debug("fb%d: blank\n", info->node); 887 pr_debug("fb%d: blank\n", info->node);
868 svga_wseq_mask(0x01, 0x20, 0x20); 888 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
869 svga_wcrt_mask(0x17, 0x80, 0x80); 889 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
870 break; 890 break;
871 case FB_BLANK_POWERDOWN: 891 case FB_BLANK_POWERDOWN:
872 case FB_BLANK_HSYNC_SUSPEND: 892 case FB_BLANK_HSYNC_SUSPEND:
873 case FB_BLANK_VSYNC_SUSPEND: 893 case FB_BLANK_VSYNC_SUSPEND:
874 pr_debug("fb%d: sync down\n", info->node); 894 pr_debug("fb%d: sync down\n", info->node);
875 svga_wseq_mask(0x01, 0x20, 0x20); 895 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
876 svga_wcrt_mask(0x17, 0x00, 0x80); 896 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
877 break; 897 break;
878 } 898 }
879 return 0; 899 return 0;
@@ -884,6 +904,7 @@ static int arkfb_blank(int blank_mode, struct fb_info *info)
884 904
885static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 905static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
886{ 906{
907 struct arkfb_info *par = info->par;
887 unsigned int offset; 908 unsigned int offset;
888 909
889 /* Calculate the offset */ 910 /* Calculate the offset */
@@ -897,7 +918,7 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
897 } 918 }
898 919
899 /* Set the offset */ 920 /* Set the offset */
900 svga_wcrt_multi(ark_start_address_regs, offset); 921 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, offset);
901 922
902 return 0; 923 return 0;
903} 924}
@@ -930,6 +951,8 @@ static struct fb_ops arkfb_ops = {
930/* PCI probe */ 951/* PCI probe */
931static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 952static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
932{ 953{
954 struct pci_bus_region bus_reg;
955 struct resource vga_res;
933 struct fb_info *info; 956 struct fb_info *info;
934 struct arkfb_info *par; 957 struct arkfb_info *par;
935 int rc; 958 int rc;
@@ -985,8 +1008,17 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_
985 goto err_iomap; 1008 goto err_iomap;
986 } 1009 }
987 1010
1011 bus_reg.start = 0;
1012 bus_reg.end = 64 * 1024;
1013
1014 vga_res.flags = IORESOURCE_IO;
1015
1016 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1017
1018 par->state.vgabase = (void __iomem *) vga_res.start;
1019
988 /* FIXME get memsize */ 1020 /* FIXME get memsize */
989 regval = vga_rseq(NULL, 0x10); 1021 regval = vga_rseq(par->state.vgabase, 0x10);
990 info->screen_size = (1 << (regval >> 6)) << 20; 1022 info->screen_size = (1 << (regval >> 6)) << 20;
991 info->fix.smem_len = info->screen_size; 1023 info->fix.smem_len = info->screen_size;
992 1024
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 4b4e8dadd6b2..ccecf9974587 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -68,7 +68,7 @@ static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
68} 68}
69#endif 69#endif
70 70
71static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 71static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
72 | ATMEL_LCDC_POL_POSITIVE 72 | ATMEL_LCDC_POL_POSITIVE
73 | ATMEL_LCDC_ENA_PWMENABLE; 73 | ATMEL_LCDC_ENA_PWMENABLE;
74 74
@@ -164,6 +164,10 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)
164 164
165static void init_contrast(struct atmel_lcdfb_info *sinfo) 165static void init_contrast(struct atmel_lcdfb_info *sinfo)
166{ 166{
167 /* contrast pwm can be 'inverted' */
168 if (sinfo->lcdcon_pol_negative)
169 contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
170
167 /* have some default contrast/backlight settings */ 171 /* have some default contrast/backlight settings */
168 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); 172 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
169 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); 173 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
@@ -711,11 +715,35 @@ static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
711 return 0; 715 return 0;
712} 716}
713 717
718static int atmel_lcdfb_blank(int blank_mode, struct fb_info *info)
719{
720 struct atmel_lcdfb_info *sinfo = info->par;
721
722 switch (blank_mode) {
723 case FB_BLANK_UNBLANK:
724 case FB_BLANK_NORMAL:
725 atmel_lcdfb_start(sinfo);
726 break;
727 case FB_BLANK_VSYNC_SUSPEND:
728 case FB_BLANK_HSYNC_SUSPEND:
729 break;
730 case FB_BLANK_POWERDOWN:
731 atmel_lcdfb_stop(sinfo);
732 break;
733 default:
734 return -EINVAL;
735 }
736
737 /* let fbcon do a soft blank for us */
738 return ((blank_mode == FB_BLANK_NORMAL) ? 1 : 0);
739}
740
714static struct fb_ops atmel_lcdfb_ops = { 741static struct fb_ops atmel_lcdfb_ops = {
715 .owner = THIS_MODULE, 742 .owner = THIS_MODULE,
716 .fb_check_var = atmel_lcdfb_check_var, 743 .fb_check_var = atmel_lcdfb_check_var,
717 .fb_set_par = atmel_lcdfb_set_par, 744 .fb_set_par = atmel_lcdfb_set_par,
718 .fb_setcolreg = atmel_lcdfb_setcolreg, 745 .fb_setcolreg = atmel_lcdfb_setcolreg,
746 .fb_blank = atmel_lcdfb_blank,
719 .fb_pan_display = atmel_lcdfb_pan_display, 747 .fb_pan_display = atmel_lcdfb_pan_display,
720 .fb_fillrect = cfb_fillrect, 748 .fb_fillrect = cfb_fillrect,
721 .fb_copyarea = cfb_copyarea, 749 .fb_copyarea = cfb_copyarea,
@@ -817,6 +845,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
817 sinfo->guard_time = pdata_sinfo->guard_time; 845 sinfo->guard_time = pdata_sinfo->guard_time;
818 sinfo->smem_len = pdata_sinfo->smem_len; 846 sinfo->smem_len = pdata_sinfo->smem_len;
819 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; 847 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
848 sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative;
820 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; 849 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
821 } else { 850 } else {
822 dev_err(dev, "cannot get default configuration\n"); 851 dev_err(dev, "cannot get default configuration\n");
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 3c1e13ed1cba..32f8cf6200a7 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1248,7 +1248,7 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1248 1248
1249 /* Workaround from XFree */ 1249 /* Workaround from XFree */
1250 if (rinfo->is_mobility) { 1250 if (rinfo->is_mobility) {
1251 /* A temporal workaround for the occational blanking on certain laptop 1251 /* A temporal workaround for the occasional blanking on certain laptop
1252 * panels. This appears to related to the PLL divider registers 1252 * panels. This appears to related to the PLL divider registers
1253 * (fail to lock?). It occurs even when all dividers are the same 1253 * (fail to lock?). It occurs even when all dividers are the same
1254 * with their old settings. In this case we really don't need to 1254 * with their old settings. In this case we really don't need to
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 78d1f4cd1fe0..ab1d0fd76316 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -100,6 +100,9 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
100{ 100{
101 rinfo->i2c[0].rinfo = rinfo; 101 rinfo->i2c[0].rinfo = rinfo;
102 rinfo->i2c[0].ddc_reg = GPIO_MONID; 102 rinfo->i2c[0].ddc_reg = GPIO_MONID;
103#ifndef CONFIG_PPC
104 rinfo->i2c[0].adapter.class = I2C_CLASS_HWMON;
105#endif
103 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid"); 106 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
104 107
105 rinfo->i2c[1].rinfo = rinfo; 108 rinfo->i2c[1].rinfo = rinfo;
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index e59623a15f3f..c8b520e9a11a 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -12,11 +12,12 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h>
15#include <linux/fb.h> 16#include <linux/fb.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/backlight.h> 18#include <linux/backlight.h>
19#include <linux/mfd/core.h>
18#include <linux/mfd/88pm860x.h> 20#include <linux/mfd/88pm860x.h>
19#include <linux/slab.h>
20 21
21#define MAX_BRIGHTNESS (0xFF) 22#define MAX_BRIGHTNESS (0xFF)
22#define MIN_BRIGHTNESS (0) 23#define MIN_BRIGHTNESS (0)
@@ -161,32 +162,13 @@ static const struct backlight_ops pm860x_backlight_ops = {
161 .get_brightness = pm860x_backlight_get_brightness, 162 .get_brightness = pm860x_backlight_get_brightness,
162}; 163};
163 164
164static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
165{
166 struct pm860x_backlight_pdata *p = pdata;
167 int ret = -EINVAL;
168
169 while (p && p->id) {
170 if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
171 break;
172
173 if (!strncmp(name, pm860x_backlight_name[p->flags],
174 MFD_NAME_SIZE)) {
175 ret = (int)p->flags;
176 break;
177 }
178 p++;
179 }
180 return ret;
181}
182
183static int pm860x_backlight_probe(struct platform_device *pdev) 165static int pm860x_backlight_probe(struct platform_device *pdev)
184{ 166{
185 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 167 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
186 struct pm860x_platform_data *pm860x_pdata;
187 struct pm860x_backlight_pdata *pdata = NULL; 168 struct pm860x_backlight_pdata *pdata = NULL;
188 struct pm860x_backlight_data *data; 169 struct pm860x_backlight_data *data;
189 struct backlight_device *bl; 170 struct backlight_device *bl;
171 struct mfd_cell *cell;
190 struct resource *res; 172 struct resource *res;
191 struct backlight_properties props; 173 struct backlight_properties props;
192 unsigned char value; 174 unsigned char value;
@@ -199,10 +181,10 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
199 return -EINVAL; 181 return -EINVAL;
200 } 182 }
201 183
202 if (pdev->dev.parent->platform_data) { 184 cell = pdev->dev.platform_data;
203 pm860x_pdata = pdev->dev.parent->platform_data; 185 if (cell == NULL)
204 pdata = pm860x_pdata->backlight; 186 return -ENODEV;
205 } 187 pdata = cell->mfd_data;
206 if (pdata == NULL) { 188 if (pdata == NULL) {
207 dev_err(&pdev->dev, "platform data isn't assigned to " 189 dev_err(&pdev->dev, "platform data isn't assigned to "
208 "backlight\n"); 190 "backlight\n");
@@ -219,7 +201,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
219 data->current_brightness = MAX_BRIGHTNESS; 201 data->current_brightness = MAX_BRIGHTNESS;
220 data->pwm = pdata->pwm; 202 data->pwm = pdata->pwm;
221 data->iset = pdata->iset; 203 data->iset = pdata->iset;
222 data->port = __check_device(pdata, name); 204 data->port = pdata->flags;
223 if (data->port < 0) { 205 if (data->port < 0) {
224 dev_err(&pdev->dev, "wrong platform data is assigned"); 206 dev_err(&pdev->dev, "wrong platform data is assigned");
225 kfree(data); 207 kfree(data);
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index e2c85b0db632..f18895006627 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -565,6 +565,7 @@ out_dealloc_cmap:
565 565
566out_unmap_regs: 566out_unmap_regs:
567 cg14_unmap_regs(op, info, par); 567 cg14_unmap_regs(op, info, par);
568 framebuffer_release(info);
568 569
569out_err: 570out_err:
570 return err; 571 return err;
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 4ffad90bde42..179e96cdb323 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -821,6 +821,7 @@ out_dealloc_cmap:
821 821
822out_unmap_regs: 822out_unmap_regs:
823 cg6_unmap_regs(op, info, par); 823 cg6_unmap_regs(op, info, par);
824 framebuffer_release(info);
824 825
825out_err: 826out_err:
826 return err; 827 return err;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 9c092b8d64e6..c58393402da2 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -823,10 +823,10 @@ static int set_con2fb_map(int unit, int newidx, int user)
823 if (oldidx == newidx) 823 if (oldidx == newidx)
824 return 0; 824 return 0;
825 825
826 if (!info || fbcon_has_exited) 826 if (!info)
827 return -EINVAL; 827 return -EINVAL;
828 828
829 if (!err && !search_for_mapped_con()) { 829 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
830 info_idx = newidx; 830 info_idx = newidx;
831 return fbcon_takeover(0); 831 return fbcon_takeover(0);
832 } 832 }
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 0056a41e5c35..15e8e1a89c45 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -83,7 +83,7 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
83 int softback_lines, int fg, int bg) 83 int softback_lines, int fg, int bg)
84{ 84{
85 struct fb_tilecursor cursor; 85 struct fb_tilecursor cursor;
86 int use_sw = (vc->vc_cursor_type & 0x01); 86 int use_sw = (vc->vc_cursor_type & 0x10);
87 87
88 cursor.sx = vc->vc_x; 88 cursor.sx = vc->vc_x;
89 cursor.sy = vc->vc_y; 89 cursor.sy = vc->vc_y;
diff --git a/drivers/video/edid.h b/drivers/video/edid.h
index bd89fb3be8c2..d03a232d90b2 100644
--- a/drivers/video/edid.h
+++ b/drivers/video/edid.h
@@ -101,8 +101,8 @@
101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO ) 101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO )
102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO ) 102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO )
103 103
104#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO ) 104#define H_SYNC_WIDTH COMBINE_HI_8LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
105#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO ) 105#define H_SYNC_OFFSET COMBINE_HI_8LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
106 106
107#define H_SIZE_LO (unsigned)block[ 12 ] 107#define H_SIZE_LO (unsigned)block[ 12 ]
108#define V_SIZE_LO (unsigned)block[ 13 ] 108#define V_SIZE_LO (unsigned)block[ 13 ]
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 910c5e6f6702..14102a3f70f5 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -1010,7 +1010,7 @@ out_dealloc_cmap:
1010 fb_dealloc_cmap(&info->cmap); 1010 fb_dealloc_cmap(&info->cmap);
1011 1011
1012out_unmap_dac: 1012out_unmap_dac:
1013 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1013 of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
1014 1014
1015out_unmap_fbc: 1015out_unmap_fbc:
1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index c77bcc6ab463..1b94643ecbcf 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -299,7 +299,7 @@ static int __devexit hecubafb_remove(struct platform_device *dev)
299 299
300static struct platform_driver hecubafb_driver = { 300static struct platform_driver hecubafb_driver = {
301 .probe = hecubafb_probe, 301 .probe = hecubafb_probe,
302 .remove = hecubafb_remove, 302 .remove = __devexit_p(hecubafb_remove),
303 .driver = { 303 .driver = {
304 .owner = THIS_MODULE, 304 .owner = THIS_MODULE,
305 .name = "hecubafb", 305 .name = "hecubafb",
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index c8e280f1bb0b..ebf8495ff198 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -321,11 +321,11 @@ static int __devinit hpfb_dio_probe(struct dio_dev * d, const struct dio_device_
321 unsigned long paddr, vaddr; 321 unsigned long paddr, vaddr;
322 322
323 paddr = d->resource.start; 323 paddr = d->resource.start;
324 if (!request_mem_region(d->resource.start, d->resource.end - d->resource.start, d->name)) 324 if (!request_mem_region(d->resource.start, resource_size(&d->resource), d->name))
325 return -EBUSY; 325 return -EBUSY;
326 326
327 if (d->scode >= DIOII_SCBASE) { 327 if (d->scode >= DIOII_SCBASE) {
328 vaddr = (unsigned long)ioremap(paddr, d->resource.end - d->resource.start); 328 vaddr = (unsigned long)ioremap(paddr, resource_size(&d->resource));
329 } else { 329 } else {
330 vaddr = paddr + DIO_VIRADDRBASE; 330 vaddr = paddr + DIO_VIRADDRBASE;
331 } 331 }
@@ -344,7 +344,7 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
344 unregister_framebuffer(&fb_info); 344 unregister_framebuffer(&fb_info);
345 if (d->scode >= DIOII_SCBASE) 345 if (d->scode >= DIOII_SCBASE)
346 iounmap((void *)fb_regs); 346 iounmap((void *)fb_regs);
347 release_mem_region(d->resource.start, d->resource.end - d->resource.start); 347 release_mem_region(d->resource.start, resource_size(&d->resource));
348} 348}
349 349
350static struct dio_device_id hpfb_dio_tbl[] = { 350static struct dio_device_id hpfb_dio_tbl[] = {
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index a74439affce9..5ce6fa6e59f0 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -101,8 +101,6 @@
101 101
102#include <linux/version.h> 102#include <linux/version.h>
103 103
104#define __OLD_VIDIOC_
105
106#include "matroxfb_base.h" 104#include "matroxfb_base.h"
107#include "matroxfb_misc.h" 105#include "matroxfb_misc.h"
108#include "matroxfb_accel.h" 106#include "matroxfb_accel.h"
@@ -1152,7 +1150,6 @@ static int matroxfb_ioctl(struct fb_info *info,
1152 return -EFAULT; 1150 return -EFAULT;
1153 return err; 1151 return err;
1154 } 1152 }
1155 case VIDIOC_S_CTRL_OLD:
1156 case VIDIOC_S_CTRL: 1153 case VIDIOC_S_CTRL:
1157 { 1154 {
1158 struct v4l2_control ctrl; 1155 struct v4l2_control ctrl;
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index 63ed3b72b01c..ed64edfd2c43 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -765,7 +765,7 @@ static int __devexit metronomefb_remove(struct platform_device *dev)
765 765
766static struct platform_driver metronomefb_driver = { 766static struct platform_driver metronomefb_driver = {
767 .probe = metronomefb_probe, 767 .probe = metronomefb_probe,
768 .remove = metronomefb_remove, 768 .remove = __devexit_p(metronomefb_remove),
769 .driver = { 769 .driver = {
770 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
771 .name = "metronomefb", 771 .name = "metronomefb",
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 083c8fe53e24..15e7f1912af9 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -5,13 +5,18 @@ config FB_OMAP
5 select FB_CFB_FILLRECT 5 select FB_CFB_FILLRECT
6 select FB_CFB_COPYAREA 6 select FB_CFB_COPYAREA
7 select FB_CFB_IMAGEBLIT 7 select FB_CFB_IMAGEBLIT
8 select TWL4030_CORE if MACH_OMAP_2430SDP
8 help 9 help
9 Frame buffer driver for OMAP based boards. 10 Frame buffer driver for OMAP based boards.
10 11
11config FB_OMAP_LCD_VGA 12config FB_OMAP_LCD_VGA
12 bool "Use LCD in VGA mode" 13 bool "Use LCD in VGA mode"
13 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP 14 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
14 15 help
16 Set LCD resolution as VGA (640 X 480).
17 Default resolution without this option is QVGA(320 X 240).
18 Please take a look at drivers/video/omap/lcd_ldp.c file
19 for lcd driver code.
15choice 20choice
16 depends on FB_OMAP && MACH_OVERO 21 depends on FB_OMAP && MACH_OVERO
17 prompt "Screen resolution" 22 prompt "Screen resolution"
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index 87785c215a52..c0504a8a5079 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -397,8 +397,7 @@ static inline void free_req(struct blizzard_request *req)
397 397
398 spin_lock_irqsave(&blizzard.req_lock, flags); 398 spin_lock_irqsave(&blizzard.req_lock, flags);
399 399
400 list_del(&req->entry); 400 list_move(&req->entry, &blizzard.free_req_list);
401 list_add(&req->entry, &blizzard.free_req_list);
402 if (!(req->flags & REQ_FROM_IRQ_POOL)) 401 if (!(req->flags & REQ_FROM_IRQ_POOL))
403 up(&blizzard.req_sema); 402 up(&blizzard.req_sema);
404 403
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 0016f77cd13f..084aa0ac562b 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -269,8 +269,7 @@ static inline void free_req(struct hwa742_request *req)
269 269
270 spin_lock_irqsave(&hwa742.req_lock, flags); 270 spin_lock_irqsave(&hwa742.req_lock, flags);
271 271
272 list_del(&req->entry); 272 list_move(&req->entry, &hwa742.free_req_list);
273 list_add(&req->entry, &hwa742.free_req_list);
274 if (!(req->flags & REQ_FROM_IRQ_POOL)) 273 if (!(req->flags & REQ_FROM_IRQ_POOL))
275 up(&hwa742.req_sema); 274 up(&hwa742.req_sema);
276 275
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 940cab394c2e..d18ad6b2372a 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -9,6 +9,12 @@ config PANEL_GENERIC_DPI
9 Supports LCD Panel used in TI SDP3430 and EVM boards, 9 Supports LCD Panel used in TI SDP3430 and EVM boards,
10 OMAP3517 EVM boards and CM-T35. 10 OMAP3517 EVM boards and CM-T35.
11 11
12config PANEL_LGPHILIPS_LB035Q02
13 tristate "LG.Philips LB035Q02 LCD Panel"
14 depends on OMAP2_DSS && SPI
15 help
16 LCD Panel used on the Gumstix Overo Palo35
17
12config PANEL_SHARP_LS037V7DW01 18config PANEL_SHARP_LS037V7DW01
13 tristate "Sharp LS037V7DW01 LCD Panel" 19 tristate "Sharp LS037V7DW01 LCD Panel"
14 depends on OMAP2_DSS 20 depends on OMAP2_DSS
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 861f0255ec6b..0f601ab3abf4 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o 1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
2obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 3obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
3obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o 4obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
4 5
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 07eb30ee59c8..4a9b9ff59467 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -156,6 +156,31 @@ static struct panel_config generic_dpi_panels[] = {
156 .power_off_delay = 0, 156 .power_off_delay = 0,
157 .name = "toppoly_tdo35s", 157 .name = "toppoly_tdo35s",
158 }, 158 },
159
160 /* Samsung LTE430WQ-F0C */
161 {
162 {
163 .x_res = 480,
164 .y_res = 272,
165
166 .pixel_clock = 9200,
167
168 .hfp = 8,
169 .hsw = 41,
170 .hbp = 45 - 41,
171
172 .vfp = 4,
173 .vsw = 10,
174 .vbp = 12 - 10,
175 },
176 .acbi = 0x0,
177 .acb = 0x0,
178 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
179 OMAP_DSS_LCD_IHS,
180 .power_on_delay = 0,
181 .power_off_delay = 0,
182 .name = "samsung_lte430wq_f0c",
183 },
159}; 184};
160 185
161struct panel_drv_data { 186struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
new file mode 100644
index 000000000000..271324db2436
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -0,0 +1,279 @@
1/*
2 * LCD panel driver for LG.Philips LB035Q02
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/spi/spi.h>
22#include <linux/mutex.h>
23
24#include <plat/display.h>
25
26struct lb035q02_data {
27 struct mutex lock;
28};
29
30static struct omap_video_timings lb035q02_timings = {
31 .x_res = 320,
32 .y_res = 240,
33
34 .pixel_clock = 6500,
35
36 .hsw = 2,
37 .hfp = 20,
38 .hbp = 68,
39
40 .vsw = 2,
41 .vfp = 4,
42 .vbp = 18,
43};
44
45static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
46{
47 int r;
48
49 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
50 return 0;
51
52 r = omapdss_dpi_display_enable(dssdev);
53 if (r)
54 goto err0;
55
56 if (dssdev->platform_enable) {
57 r = dssdev->platform_enable(dssdev);
58 if (r)
59 goto err1;
60 }
61
62 return 0;
63err1:
64 omapdss_dpi_display_disable(dssdev);
65err0:
66 return r;
67}
68
69static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
70{
71 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
72 return;
73
74 if (dssdev->platform_disable)
75 dssdev->platform_disable(dssdev);
76
77 omapdss_dpi_display_disable(dssdev);
78}
79
80static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
81{
82 struct lb035q02_data *ld;
83 int r;
84
85 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
86 OMAP_DSS_LCD_IHS;
87 dssdev->panel.timings = lb035q02_timings;
88
89 ld = kzalloc(sizeof(*ld), GFP_KERNEL);
90 if (!ld) {
91 r = -ENOMEM;
92 goto err;
93 }
94 mutex_init(&ld->lock);
95 dev_set_drvdata(&dssdev->dev, ld);
96 return 0;
97err:
98 return r;
99}
100
101static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
102{
103 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
104
105 kfree(ld);
106}
107
108static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
109{
110 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
111 int r;
112
113 mutex_lock(&ld->lock);
114
115 r = lb035q02_panel_power_on(dssdev);
116 if (r)
117 goto err;
118 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
119
120 mutex_unlock(&ld->lock);
121 return 0;
122err:
123 mutex_unlock(&ld->lock);
124 return r;
125}
126
127static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
128{
129 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
130
131 mutex_lock(&ld->lock);
132
133 lb035q02_panel_power_off(dssdev);
134 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
135
136 mutex_unlock(&ld->lock);
137}
138
139static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
140{
141 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
142
143 mutex_lock(&ld->lock);
144
145 lb035q02_panel_power_off(dssdev);
146 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
147
148 mutex_unlock(&ld->lock);
149 return 0;
150}
151
152static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
153{
154 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
155 int r;
156
157 mutex_lock(&ld->lock);
158
159 r = lb035q02_panel_power_on(dssdev);
160 if (r)
161 goto err;
162 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
163
164 mutex_unlock(&ld->lock);
165 return 0;
166err:
167 mutex_unlock(&ld->lock);
168 return r;
169}
170
171static struct omap_dss_driver lb035q02_driver = {
172 .probe = lb035q02_panel_probe,
173 .remove = lb035q02_panel_remove,
174
175 .enable = lb035q02_panel_enable,
176 .disable = lb035q02_panel_disable,
177 .suspend = lb035q02_panel_suspend,
178 .resume = lb035q02_panel_resume,
179
180 .driver = {
181 .name = "lgphilips_lb035q02_panel",
182 .owner = THIS_MODULE,
183 },
184};
185
186static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val)
187{
188 struct spi_message msg;
189 struct spi_transfer index_xfer = {
190 .len = 3,
191 .cs_change = 1,
192 };
193 struct spi_transfer value_xfer = {
194 .len = 3,
195 };
196 u8 buffer[16];
197
198 spi_message_init(&msg);
199
200 /* register index */
201 buffer[0] = 0x70;
202 buffer[1] = 0x00;
203 buffer[2] = reg & 0x7f;
204 index_xfer.tx_buf = buffer;
205 spi_message_add_tail(&index_xfer, &msg);
206
207 /* register value */
208 buffer[4] = 0x72;
209 buffer[5] = val >> 8;
210 buffer[6] = val;
211 value_xfer.tx_buf = buffer + 4;
212 spi_message_add_tail(&value_xfer, &msg);
213
214 return spi_sync(spi, &msg);
215}
216
217static void init_lb035q02_panel(struct spi_device *spi)
218{
219 /* Init sequence from page 28 of the lb035q02 spec */
220 lb035q02_write_reg(spi, 0x01, 0x6300);
221 lb035q02_write_reg(spi, 0x02, 0x0200);
222 lb035q02_write_reg(spi, 0x03, 0x0177);
223 lb035q02_write_reg(spi, 0x04, 0x04c7);
224 lb035q02_write_reg(spi, 0x05, 0xffc0);
225 lb035q02_write_reg(spi, 0x06, 0xe806);
226 lb035q02_write_reg(spi, 0x0a, 0x4008);
227 lb035q02_write_reg(spi, 0x0b, 0x0000);
228 lb035q02_write_reg(spi, 0x0d, 0x0030);
229 lb035q02_write_reg(spi, 0x0e, 0x2800);
230 lb035q02_write_reg(spi, 0x0f, 0x0000);
231 lb035q02_write_reg(spi, 0x16, 0x9f80);
232 lb035q02_write_reg(spi, 0x17, 0x0a0f);
233 lb035q02_write_reg(spi, 0x1e, 0x00c1);
234 lb035q02_write_reg(spi, 0x30, 0x0300);
235 lb035q02_write_reg(spi, 0x31, 0x0007);
236 lb035q02_write_reg(spi, 0x32, 0x0000);
237 lb035q02_write_reg(spi, 0x33, 0x0000);
238 lb035q02_write_reg(spi, 0x34, 0x0707);
239 lb035q02_write_reg(spi, 0x35, 0x0004);
240 lb035q02_write_reg(spi, 0x36, 0x0302);
241 lb035q02_write_reg(spi, 0x37, 0x0202);
242 lb035q02_write_reg(spi, 0x3a, 0x0a0d);
243 lb035q02_write_reg(spi, 0x3b, 0x0806);
244}
245
246static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi)
247{
248 init_lb035q02_panel(spi);
249 return omap_dss_register_driver(&lb035q02_driver);
250}
251
252static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi)
253{
254 omap_dss_unregister_driver(&lb035q02_driver);
255 return 0;
256}
257
258static struct spi_driver lb035q02_spi_driver = {
259 .driver = {
260 .name = "lgphilips_lb035q02_panel-spi",
261 .owner = THIS_MODULE,
262 },
263 .probe = lb035q02_panel_spi_probe,
264 .remove = __devexit_p(lb035q02_panel_spi_remove),
265};
266
267static int __init lb035q02_panel_drv_init(void)
268{
269 return spi_register_driver(&lb035q02_spi_driver);
270}
271
272static void __exit lb035q02_panel_drv_exit(void)
273{
274 spi_unregister_driver(&lb035q02_spi_driver);
275}
276
277module_init(lb035q02_panel_drv_init);
278module_exit(lb035q02_panel_drv_exit);
279MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index c74e8b778ba1..adc9900458e1 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -218,6 +218,8 @@ struct taal_data {
218 u16 w; 218 u16 w;
219 u16 h; 219 u16 h;
220 } update_region; 220 } update_region;
221 int channel;
222
221 struct delayed_work te_timeout_work; 223 struct delayed_work te_timeout_work;
222 224
223 bool use_dsi_bl; 225 bool use_dsi_bl;
@@ -257,12 +259,12 @@ static void hw_guard_wait(struct taal_data *td)
257 } 259 }
258} 260}
259 261
260static int taal_dcs_read_1(u8 dcs_cmd, u8 *data) 262static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
261{ 263{
262 int r; 264 int r;
263 u8 buf[1]; 265 u8 buf[1];
264 266
265 r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1); 267 r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
266 268
267 if (r < 0) 269 if (r < 0)
268 return r; 270 return r;
@@ -272,17 +274,17 @@ static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
272 return 0; 274 return 0;
273} 275}
274 276
275static int taal_dcs_write_0(u8 dcs_cmd) 277static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
276{ 278{
277 return dsi_vc_dcs_write(TCH, &dcs_cmd, 1); 279 return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
278} 280}
279 281
280static int taal_dcs_write_1(u8 dcs_cmd, u8 param) 282static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
281{ 283{
282 u8 buf[2]; 284 u8 buf[2];
283 buf[0] = dcs_cmd; 285 buf[0] = dcs_cmd;
284 buf[1] = param; 286 buf[1] = param;
285 return dsi_vc_dcs_write(TCH, buf, 2); 287 return dsi_vc_dcs_write(td->channel, buf, 2);
286} 288}
287 289
288static int taal_sleep_in(struct taal_data *td) 290static int taal_sleep_in(struct taal_data *td)
@@ -294,7 +296,7 @@ static int taal_sleep_in(struct taal_data *td)
294 hw_guard_wait(td); 296 hw_guard_wait(td);
295 297
296 cmd = DCS_SLEEP_IN; 298 cmd = DCS_SLEEP_IN;
297 r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1); 299 r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
298 if (r) 300 if (r)
299 return r; 301 return r;
300 302
@@ -312,7 +314,7 @@ static int taal_sleep_out(struct taal_data *td)
312 314
313 hw_guard_wait(td); 315 hw_guard_wait(td);
314 316
315 r = taal_dcs_write_0(DCS_SLEEP_OUT); 317 r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
316 if (r) 318 if (r)
317 return r; 319 return r;
318 320
@@ -324,30 +326,30 @@ static int taal_sleep_out(struct taal_data *td)
324 return 0; 326 return 0;
325} 327}
326 328
327static int taal_get_id(u8 *id1, u8 *id2, u8 *id3) 329static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
328{ 330{
329 int r; 331 int r;
330 332
331 r = taal_dcs_read_1(DCS_GET_ID1, id1); 333 r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
332 if (r) 334 if (r)
333 return r; 335 return r;
334 r = taal_dcs_read_1(DCS_GET_ID2, id2); 336 r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
335 if (r) 337 if (r)
336 return r; 338 return r;
337 r = taal_dcs_read_1(DCS_GET_ID3, id3); 339 r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
338 if (r) 340 if (r)
339 return r; 341 return r;
340 342
341 return 0; 343 return 0;
342} 344}
343 345
344static int taal_set_addr_mode(u8 rotate, bool mirror) 346static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
345{ 347{
346 int r; 348 int r;
347 u8 mode; 349 u8 mode;
348 int b5, b6, b7; 350 int b5, b6, b7;
349 351
350 r = taal_dcs_read_1(DCS_READ_MADCTL, &mode); 352 r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
351 if (r) 353 if (r)
352 return r; 354 return r;
353 355
@@ -381,10 +383,11 @@ static int taal_set_addr_mode(u8 rotate, bool mirror)
381 mode &= ~((1<<7) | (1<<6) | (1<<5)); 383 mode &= ~((1<<7) | (1<<6) | (1<<5));
382 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5); 384 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
383 385
384 return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode); 386 return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
385} 387}
386 388
387static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h) 389static int taal_set_update_window(struct taal_data *td,
390 u16 x, u16 y, u16 w, u16 h)
388{ 391{
389 int r; 392 int r;
390 u16 x1 = x; 393 u16 x1 = x;
@@ -399,7 +402,7 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
399 buf[3] = (x2 >> 8) & 0xff; 402 buf[3] = (x2 >> 8) & 0xff;
400 buf[4] = (x2 >> 0) & 0xff; 403 buf[4] = (x2 >> 0) & 0xff;
401 404
402 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 405 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
403 if (r) 406 if (r)
404 return r; 407 return r;
405 408
@@ -409,11 +412,11 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
409 buf[3] = (y2 >> 8) & 0xff; 412 buf[3] = (y2 >> 8) & 0xff;
410 buf[4] = (y2 >> 0) & 0xff; 413 buf[4] = (y2 >> 0) & 0xff;
411 414
412 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 415 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
413 if (r) 416 if (r)
414 return r; 417 return r;
415 418
416 dsi_vc_send_bta_sync(TCH); 419 dsi_vc_send_bta_sync(td->channel);
417 420
418 return r; 421 return r;
419} 422}
@@ -439,7 +442,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
439 if (td->use_dsi_bl) { 442 if (td->use_dsi_bl) {
440 if (td->enabled) { 443 if (td->enabled) {
441 dsi_bus_lock(); 444 dsi_bus_lock();
442 r = taal_dcs_write_1(DCS_BRIGHTNESS, level); 445 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
443 dsi_bus_unlock(); 446 dsi_bus_unlock();
444 } else { 447 } else {
445 r = 0; 448 r = 0;
@@ -502,7 +505,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
502 505
503 if (td->enabled) { 506 if (td->enabled) {
504 dsi_bus_lock(); 507 dsi_bus_lock();
505 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors); 508 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
506 dsi_bus_unlock(); 509 dsi_bus_unlock();
507 } else { 510 } else {
508 r = -ENODEV; 511 r = -ENODEV;
@@ -528,7 +531,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
528 531
529 if (td->enabled) { 532 if (td->enabled) {
530 dsi_bus_lock(); 533 dsi_bus_lock();
531 r = taal_get_id(&id1, &id2, &id3); 534 r = taal_get_id(td, &id1, &id2, &id3);
532 dsi_bus_unlock(); 535 dsi_bus_unlock();
533 } else { 536 } else {
534 r = -ENODEV; 537 r = -ENODEV;
@@ -590,7 +593,7 @@ static ssize_t store_cabc_mode(struct device *dev,
590 if (td->enabled) { 593 if (td->enabled) {
591 dsi_bus_lock(); 594 dsi_bus_lock();
592 if (!td->cabc_broken) 595 if (!td->cabc_broken)
593 taal_dcs_write_1(DCS_WRITE_CABC, i); 596 taal_dcs_write_1(td, DCS_WRITE_CABC, i);
594 dsi_bus_unlock(); 597 dsi_bus_unlock();
595 } 598 }
596 599
@@ -776,14 +779,29 @@ static int taal_probe(struct omap_dss_device *dssdev)
776 dev_dbg(&dssdev->dev, "Using GPIO TE\n"); 779 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
777 } 780 }
778 781
782 r = omap_dsi_request_vc(dssdev, &td->channel);
783 if (r) {
784 dev_err(&dssdev->dev, "failed to get virtual channel\n");
785 goto err_req_vc;
786 }
787
788 r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
789 if (r) {
790 dev_err(&dssdev->dev, "failed to set VC_ID\n");
791 goto err_vc_id;
792 }
793
779 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 794 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
780 if (r) { 795 if (r) {
781 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 796 dev_err(&dssdev->dev, "failed to create sysfs files\n");
782 goto err_sysfs; 797 goto err_vc_id;
783 } 798 }
784 799
785 return 0; 800 return 0;
786err_sysfs: 801
802err_vc_id:
803 omap_dsi_release_vc(dssdev, td->channel);
804err_req_vc:
787 if (panel_data->use_ext_te) 805 if (panel_data->use_ext_te)
788 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); 806 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
789err_irq: 807err_irq:
@@ -810,6 +828,7 @@ static void taal_remove(struct omap_dss_device *dssdev)
810 dev_dbg(&dssdev->dev, "remove\n"); 828 dev_dbg(&dssdev->dev, "remove\n");
811 829
812 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 830 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
831 omap_dsi_release_vc(dssdev, td->channel);
813 832
814 if (panel_data->use_ext_te) { 833 if (panel_data->use_ext_te) {
815 int gpio = panel_data->ext_te_gpio; 834 int gpio = panel_data->ext_te_gpio;
@@ -848,13 +867,13 @@ static int taal_power_on(struct omap_dss_device *dssdev)
848 867
849 taal_hw_reset(dssdev); 868 taal_hw_reset(dssdev);
850 869
851 omapdss_dsi_vc_enable_hs(TCH, false); 870 omapdss_dsi_vc_enable_hs(td->channel, false);
852 871
853 r = taal_sleep_out(td); 872 r = taal_sleep_out(td);
854 if (r) 873 if (r)
855 goto err; 874 goto err;
856 875
857 r = taal_get_id(&id1, &id2, &id3); 876 r = taal_get_id(td, &id1, &id2, &id3);
858 if (r) 877 if (r)
859 goto err; 878 goto err;
860 879
@@ -863,30 +882,30 @@ static int taal_power_on(struct omap_dss_device *dssdev)
863 (id2 == 0x00 || id2 == 0xff || id2 == 0x81)) 882 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
864 td->cabc_broken = true; 883 td->cabc_broken = true;
865 884
866 r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); 885 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
867 if (r) 886 if (r)
868 goto err; 887 goto err;
869 888
870 r = taal_dcs_write_1(DCS_CTRL_DISPLAY, 889 r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
871 (1<<2) | (1<<5)); /* BL | BCTRL */ 890 (1<<2) | (1<<5)); /* BL | BCTRL */
872 if (r) 891 if (r)
873 goto err; 892 goto err;
874 893
875 r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 894 r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
876 if (r) 895 if (r)
877 goto err; 896 goto err;
878 897
879 r = taal_set_addr_mode(td->rotate, td->mirror); 898 r = taal_set_addr_mode(td, td->rotate, td->mirror);
880 if (r) 899 if (r)
881 goto err; 900 goto err;
882 901
883 if (!td->cabc_broken) { 902 if (!td->cabc_broken) {
884 r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); 903 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
885 if (r) 904 if (r)
886 goto err; 905 goto err;
887 } 906 }
888 907
889 r = taal_dcs_write_0(DCS_DISPLAY_ON); 908 r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
890 if (r) 909 if (r)
891 goto err; 910 goto err;
892 911
@@ -905,7 +924,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
905 td->intro_printed = true; 924 td->intro_printed = true;
906 } 925 }
907 926
908 omapdss_dsi_vc_enable_hs(TCH, true); 927 omapdss_dsi_vc_enable_hs(td->channel, true);
909 928
910 return 0; 929 return 0;
911err: 930err:
@@ -923,7 +942,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
923 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 942 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
924 int r; 943 int r;
925 944
926 r = taal_dcs_write_0(DCS_DISPLAY_OFF); 945 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
927 if (!r) { 946 if (!r) {
928 r = taal_sleep_in(td); 947 r = taal_sleep_in(td);
929 /* HACK: wait a bit so that the message goes through */ 948 /* HACK: wait a bit so that the message goes through */
@@ -1091,7 +1110,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
1091 if (old) { 1110 if (old) {
1092 cancel_delayed_work(&td->te_timeout_work); 1111 cancel_delayed_work(&td->te_timeout_work);
1093 1112
1094 r = omap_dsi_update(dssdev, TCH, 1113 r = omap_dsi_update(dssdev, td->channel,
1095 td->update_region.x, 1114 td->update_region.x,
1096 td->update_region.y, 1115 td->update_region.y,
1097 td->update_region.w, 1116 td->update_region.w,
@@ -1141,7 +1160,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1141 if (r) 1160 if (r)
1142 goto err; 1161 goto err;
1143 1162
1144 r = taal_set_update_window(x, y, w, h); 1163 r = taal_set_update_window(td, x, y, w, h);
1145 if (r) 1164 if (r)
1146 goto err; 1165 goto err;
1147 1166
@@ -1155,7 +1174,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1155 msecs_to_jiffies(250)); 1174 msecs_to_jiffies(250));
1156 atomic_set(&td->do_update, 1); 1175 atomic_set(&td->do_update, 1);
1157 } else { 1176 } else {
1158 r = omap_dsi_update(dssdev, TCH, x, y, w, h, 1177 r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
1159 taal_framedone_cb, dssdev); 1178 taal_framedone_cb, dssdev);
1160 if (r) 1179 if (r)
1161 goto err; 1180 goto err;
@@ -1193,9 +1212,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1193 int r; 1212 int r;
1194 1213
1195 if (enable) 1214 if (enable)
1196 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1215 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1197 else 1216 else
1198 r = taal_dcs_write_0(DCS_TEAR_OFF); 1217 r = taal_dcs_write_0(td, DCS_TEAR_OFF);
1199 1218
1200 if (!panel_data->use_ext_te) 1219 if (!panel_data->use_ext_te)
1201 omapdss_dsi_enable_te(dssdev, enable); 1220 omapdss_dsi_enable_te(dssdev, enable);
@@ -1265,7 +1284,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1265 dsi_bus_lock(); 1284 dsi_bus_lock();
1266 1285
1267 if (td->enabled) { 1286 if (td->enabled) {
1268 r = taal_set_addr_mode(rotate, td->mirror); 1287 r = taal_set_addr_mode(td, rotate, td->mirror);
1269 if (r) 1288 if (r)
1270 goto err; 1289 goto err;
1271 } 1290 }
@@ -1308,7 +1327,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1308 1327
1309 dsi_bus_lock(); 1328 dsi_bus_lock();
1310 if (td->enabled) { 1329 if (td->enabled) {
1311 r = taal_set_addr_mode(td->rotate, enable); 1330 r = taal_set_addr_mode(td, td->rotate, enable);
1312 if (r) 1331 if (r)
1313 goto err; 1332 goto err;
1314 } 1333 }
@@ -1352,13 +1371,13 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1352 1371
1353 dsi_bus_lock(); 1372 dsi_bus_lock();
1354 1373
1355 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1374 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1356 if (r) 1375 if (r)
1357 goto err2; 1376 goto err2;
1358 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 1377 r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1359 if (r) 1378 if (r)
1360 goto err2; 1379 goto err2;
1361 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 1380 r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1362 if (r) 1381 if (r)
1363 goto err2; 1382 goto err2;
1364 1383
@@ -1406,9 +1425,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1406 else 1425 else
1407 plen = 2; 1426 plen = 2;
1408 1427
1409 taal_set_update_window(x, y, w, h); 1428 taal_set_update_window(td, x, y, w, h);
1410 1429
1411 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 1430 r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
1412 if (r) 1431 if (r)
1413 goto err2; 1432 goto err2;
1414 1433
@@ -1416,7 +1435,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1416 u8 dcs_cmd = first ? 0x2e : 0x3e; 1435 u8 dcs_cmd = first ? 0x2e : 0x3e;
1417 first = 0; 1436 first = 0;
1418 1437
1419 r = dsi_vc_dcs_read(TCH, dcs_cmd, 1438 r = dsi_vc_dcs_read(td->channel, dcs_cmd,
1420 buf + buf_used, size - buf_used); 1439 buf + buf_used, size - buf_used);
1421 1440
1422 if (r < 0) { 1441 if (r < 0) {
@@ -1442,7 +1461,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1442 r = buf_used; 1461 r = buf_used;
1443 1462
1444err3: 1463err3:
1445 dsi_vc_set_max_rx_packet_size(TCH, 1); 1464 dsi_vc_set_max_rx_packet_size(td->channel, 1);
1446err2: 1465err2:
1447 dsi_bus_unlock(); 1466 dsi_bus_unlock();
1448err1: 1467err1:
@@ -1468,7 +1487,7 @@ static void taal_esd_work(struct work_struct *work)
1468 1487
1469 dsi_bus_lock(); 1488 dsi_bus_lock();
1470 1489
1471 r = taal_dcs_read_1(DCS_RDDSDR, &state1); 1490 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
1472 if (r) { 1491 if (r) {
1473 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1492 dev_err(&dssdev->dev, "failed to read Taal status\n");
1474 goto err; 1493 goto err;
@@ -1481,7 +1500,7 @@ static void taal_esd_work(struct work_struct *work)
1481 goto err; 1500 goto err;
1482 } 1501 }
1483 1502
1484 r = taal_dcs_read_1(DCS_RDDSDR, &state2); 1503 r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
1485 if (r) { 1504 if (r) {
1486 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1505 dev_err(&dssdev->dev, "failed to read Taal status\n");
1487 goto err; 1506 goto err;
@@ -1497,7 +1516,7 @@ static void taal_esd_work(struct work_struct *work)
1497 /* Self-diagnostics result is also shown on TE GPIO line. We need 1516 /* Self-diagnostics result is also shown on TE GPIO line. We need
1498 * to re-enable TE after self diagnostics */ 1517 * to re-enable TE after self diagnostics */
1499 if (td->te_enabled && panel_data->use_ext_te) { 1518 if (td->te_enabled && panel_data->use_ext_te) {
1500 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1519 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1501 if (r) 1520 if (r)
1502 goto err; 1521 goto err;
1503 } 1522 }
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43b64403eaa4..bfc5da0e9700 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,8 +1,8 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)" 2 tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
3 depends on ARCH_OMAP2 || ARCH_OMAP3 3 depends on ARCH_OMAP2PLUS
4 help 4 help
5 OMAP2/3 Display Subsystem support. 5 OMAP2+ Display Subsystem support.
6 6
7if OMAP2_DSS 7if OMAP2_DSS
8 8
@@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
60 help 60 help
61 OMAP Video Encoder support for S-Video and composite TV-out. 61 OMAP Video Encoder support for S-Video and composite TV-out.
62 62
63config OMAP4_DSS_HDMI
64 bool "HDMI support"
65 depends on ARCH_OMAP4
66 default y
67 help
68 HDMI Interface. This adds the High Definition Multimedia Interface.
69 See http://www.hdmi.org/ for HDMI specification.
70
63config OMAP2_DSS_SDI 71config OMAP2_DSS_SDI
64 bool "SDI support" 72 bool "SDI support"
65 depends on ARCH_OMAP3 73 depends on ARCH_OMAP3
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 7db17b5e570c..10d9d3bb3e24 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -5,3 +5,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
8omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
9 hdmi_omap4_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 8e89f6049280..1aa2ed1e786e 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -34,332 +34,26 @@
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36#include <plat/display.h> 36#include <plat/display.h>
37#include <plat/clock.h>
38 37
39#include "dss.h" 38#include "dss.h"
40#include "dss_features.h" 39#include "dss_features.h"
41 40
42static struct { 41static struct {
43 struct platform_device *pdev; 42 struct platform_device *pdev;
44 int ctx_id;
45
46 struct clk *dss_ick;
47 struct clk *dss1_fck;
48 struct clk *dss2_fck;
49 struct clk *dss_54m_fck;
50 struct clk *dss_96m_fck;
51 unsigned num_clks_enabled;
52 43
53 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
54 struct regulator *vdds_sdi_reg; 45 struct regulator *vdds_sdi_reg;
55 struct regulator *vdda_dac_reg;
56} core; 46} core;
57 47
58static void dss_clk_enable_all_no_ctx(void);
59static void dss_clk_disable_all_no_ctx(void);
60static void dss_clk_enable_no_ctx(enum dss_clock clks);
61static void dss_clk_disable_no_ctx(enum dss_clock clks);
62
63static char *def_disp_name; 48static char *def_disp_name;
64module_param_named(def_disp, def_disp_name, charp, 0); 49module_param_named(def_disp, def_disp_name, charp, 0);
65MODULE_PARM_DESC(def_disp_name, "default display name"); 50MODULE_PARM_DESC(def_disp, "default display name");
66 51
67#ifdef DEBUG 52#ifdef DEBUG
68unsigned int dss_debug; 53unsigned int dss_debug;
69module_param_named(debug, dss_debug, bool, 0644); 54module_param_named(debug, dss_debug, bool, 0644);
70#endif 55#endif
71 56
72/* CONTEXT */
73static int dss_get_ctx_id(void)
74{
75 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
76 int r;
77
78 if (!pdata->get_last_off_on_transaction_id)
79 return 0;
80 r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
81 if (r < 0) {
82 dev_err(&core.pdev->dev, "getting transaction ID failed, "
83 "will force context restore\n");
84 r = -1;
85 }
86 return r;
87}
88
89int dss_need_ctx_restore(void)
90{
91 int id = dss_get_ctx_id();
92
93 if (id < 0 || id != core.ctx_id) {
94 DSSDBG("ctx id %d -> id %d\n",
95 core.ctx_id, id);
96 core.ctx_id = id;
97 return 1;
98 } else {
99 return 0;
100 }
101}
102
103static void save_all_ctx(void)
104{
105 DSSDBG("save context\n");
106
107 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
108
109 dss_save_context();
110 dispc_save_context();
111#ifdef CONFIG_OMAP2_DSS_DSI
112 dsi_save_context();
113#endif
114
115 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
116}
117
118static void restore_all_ctx(void)
119{
120 DSSDBG("restore context\n");
121
122 dss_clk_enable_all_no_ctx();
123
124 dss_restore_context();
125 dispc_restore_context();
126#ifdef CONFIG_OMAP2_DSS_DSI
127 dsi_restore_context();
128#endif
129
130 dss_clk_disable_all_no_ctx();
131}
132
133#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
134/* CLOCKS */
135static void core_dump_clocks(struct seq_file *s)
136{
137 int i;
138 struct clk *clocks[5] = {
139 core.dss_ick,
140 core.dss1_fck,
141 core.dss2_fck,
142 core.dss_54m_fck,
143 core.dss_96m_fck
144 };
145
146 seq_printf(s, "- CORE -\n");
147
148 seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
149
150 for (i = 0; i < 5; i++) {
151 if (!clocks[i])
152 continue;
153 seq_printf(s, "%-15s\t%lu\t%d\n",
154 clocks[i]->name,
155 clk_get_rate(clocks[i]),
156 clocks[i]->usecount);
157 }
158}
159#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
160
161static int dss_get_clock(struct clk **clock, const char *clk_name)
162{
163 struct clk *clk;
164
165 clk = clk_get(&core.pdev->dev, clk_name);
166
167 if (IS_ERR(clk)) {
168 DSSERR("can't get clock %s", clk_name);
169 return PTR_ERR(clk);
170 }
171
172 *clock = clk;
173
174 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
175
176 return 0;
177}
178
179static int dss_get_clocks(void)
180{
181 int r;
182
183 core.dss_ick = NULL;
184 core.dss1_fck = NULL;
185 core.dss2_fck = NULL;
186 core.dss_54m_fck = NULL;
187 core.dss_96m_fck = NULL;
188
189 r = dss_get_clock(&core.dss_ick, "ick");
190 if (r)
191 goto err;
192
193 r = dss_get_clock(&core.dss1_fck, "dss1_fck");
194 if (r)
195 goto err;
196
197 r = dss_get_clock(&core.dss2_fck, "dss2_fck");
198 if (r)
199 goto err;
200
201 r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
202 if (r)
203 goto err;
204
205 r = dss_get_clock(&core.dss_96m_fck, "video_fck");
206 if (r)
207 goto err;
208
209 return 0;
210
211err:
212 if (core.dss_ick)
213 clk_put(core.dss_ick);
214 if (core.dss1_fck)
215 clk_put(core.dss1_fck);
216 if (core.dss2_fck)
217 clk_put(core.dss2_fck);
218 if (core.dss_54m_fck)
219 clk_put(core.dss_54m_fck);
220 if (core.dss_96m_fck)
221 clk_put(core.dss_96m_fck);
222
223 return r;
224}
225
226static void dss_put_clocks(void)
227{
228 if (core.dss_96m_fck)
229 clk_put(core.dss_96m_fck);
230 clk_put(core.dss_54m_fck);
231 clk_put(core.dss1_fck);
232 clk_put(core.dss2_fck);
233 clk_put(core.dss_ick);
234}
235
236unsigned long dss_clk_get_rate(enum dss_clock clk)
237{
238 switch (clk) {
239 case DSS_CLK_ICK:
240 return clk_get_rate(core.dss_ick);
241 case DSS_CLK_FCK1:
242 return clk_get_rate(core.dss1_fck);
243 case DSS_CLK_FCK2:
244 return clk_get_rate(core.dss2_fck);
245 case DSS_CLK_54M:
246 return clk_get_rate(core.dss_54m_fck);
247 case DSS_CLK_96M:
248 return clk_get_rate(core.dss_96m_fck);
249 }
250
251 BUG();
252 return 0;
253}
254
255static unsigned count_clk_bits(enum dss_clock clks)
256{
257 unsigned num_clks = 0;
258
259 if (clks & DSS_CLK_ICK)
260 ++num_clks;
261 if (clks & DSS_CLK_FCK1)
262 ++num_clks;
263 if (clks & DSS_CLK_FCK2)
264 ++num_clks;
265 if (clks & DSS_CLK_54M)
266 ++num_clks;
267 if (clks & DSS_CLK_96M)
268 ++num_clks;
269
270 return num_clks;
271}
272
273static void dss_clk_enable_no_ctx(enum dss_clock clks)
274{
275 unsigned num_clks = count_clk_bits(clks);
276
277 if (clks & DSS_CLK_ICK)
278 clk_enable(core.dss_ick);
279 if (clks & DSS_CLK_FCK1)
280 clk_enable(core.dss1_fck);
281 if (clks & DSS_CLK_FCK2)
282 clk_enable(core.dss2_fck);
283 if (clks & DSS_CLK_54M)
284 clk_enable(core.dss_54m_fck);
285 if (clks & DSS_CLK_96M)
286 clk_enable(core.dss_96m_fck);
287
288 core.num_clks_enabled += num_clks;
289}
290
291void dss_clk_enable(enum dss_clock clks)
292{
293 bool check_ctx = core.num_clks_enabled == 0;
294
295 dss_clk_enable_no_ctx(clks);
296
297 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
298 restore_all_ctx();
299}
300
301static void dss_clk_disable_no_ctx(enum dss_clock clks)
302{
303 unsigned num_clks = count_clk_bits(clks);
304
305 if (clks & DSS_CLK_ICK)
306 clk_disable(core.dss_ick);
307 if (clks & DSS_CLK_FCK1)
308 clk_disable(core.dss1_fck);
309 if (clks & DSS_CLK_FCK2)
310 clk_disable(core.dss2_fck);
311 if (clks & DSS_CLK_54M)
312 clk_disable(core.dss_54m_fck);
313 if (clks & DSS_CLK_96M)
314 clk_disable(core.dss_96m_fck);
315
316 core.num_clks_enabled -= num_clks;
317}
318
319void dss_clk_disable(enum dss_clock clks)
320{
321 if (cpu_is_omap34xx()) {
322 unsigned num_clks = count_clk_bits(clks);
323
324 BUG_ON(core.num_clks_enabled < num_clks);
325
326 if (core.num_clks_enabled == num_clks)
327 save_all_ctx();
328 }
329
330 dss_clk_disable_no_ctx(clks);
331}
332
333static void dss_clk_enable_all_no_ctx(void)
334{
335 enum dss_clock clks;
336
337 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
338 if (cpu_is_omap34xx())
339 clks |= DSS_CLK_96M;
340 dss_clk_enable_no_ctx(clks);
341}
342
343static void dss_clk_disable_all_no_ctx(void)
344{
345 enum dss_clock clks;
346
347 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
348 if (cpu_is_omap34xx())
349 clks |= DSS_CLK_96M;
350 dss_clk_disable_no_ctx(clks);
351}
352
353static void dss_clk_disable_all(void)
354{
355 enum dss_clock clks;
356
357 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
358 if (cpu_is_omap34xx())
359 clks |= DSS_CLK_96M;
360 dss_clk_disable(clks);
361}
362
363/* REGULATORS */ 57/* REGULATORS */
364 58
365struct regulator *dss_get_vdds_dsi(void) 59struct regulator *dss_get_vdds_dsi(void)
@@ -390,32 +84,7 @@ struct regulator *dss_get_vdds_sdi(void)
390 return reg; 84 return reg;
391} 85}
392 86
393struct regulator *dss_get_vdda_dac(void)
394{
395 struct regulator *reg;
396
397 if (core.vdda_dac_reg != NULL)
398 return core.vdda_dac_reg;
399
400 reg = regulator_get(&core.pdev->dev, "vdda_dac");
401 if (!IS_ERR(reg))
402 core.vdda_dac_reg = reg;
403
404 return reg;
405}
406
407/* DEBUGFS */
408#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 87#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
409static void dss_debug_dump_clocks(struct seq_file *s)
410{
411 core_dump_clocks(s);
412 dss_dump_clocks(s);
413 dispc_dump_clocks(s);
414#ifdef CONFIG_OMAP2_DSS_DSI
415 dsi_dump_clocks(s);
416#endif
417}
418
419static int dss_debug_show(struct seq_file *s, void *unused) 88static int dss_debug_show(struct seq_file *s, void *unused)
420{ 89{
421 void (*func)(struct seq_file *) = s->private; 90 void (*func)(struct seq_file *) = s->private;
@@ -497,7 +166,6 @@ static inline void dss_uninitialize_debugfs(void)
497static int omap_dss_probe(struct platform_device *pdev) 166static int omap_dss_probe(struct platform_device *pdev)
498{ 167{
499 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 168 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
500 int skip_init = 0;
501 int r; 169 int r;
502 int i; 170 int i;
503 171
@@ -508,63 +176,43 @@ static int omap_dss_probe(struct platform_device *pdev)
508 dss_init_overlay_managers(pdev); 176 dss_init_overlay_managers(pdev);
509 dss_init_overlays(pdev); 177 dss_init_overlays(pdev);
510 178
511 r = dss_get_clocks(); 179 r = dss_init_platform_driver();
512 if (r)
513 goto err_clocks;
514
515 dss_clk_enable_all_no_ctx();
516
517 core.ctx_id = dss_get_ctx_id();
518 DSSDBG("initial ctx id %u\n", core.ctx_id);
519
520#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
521 /* DISPC_CONTROL */
522 if (omap_readl(0x48050440) & 1) /* LCD enabled? */
523 skip_init = 1;
524#endif
525
526 r = dss_init(skip_init);
527 if (r) { 180 if (r) {
528 DSSERR("Failed to initialize DSS\n"); 181 DSSERR("Failed to initialize DSS platform driver\n");
529 goto err_dss; 182 goto err_dss;
530 } 183 }
531 184
532 r = rfbi_init(); 185 /* keep clocks enabled to prevent context saves/restores during init */
533 if (r) { 186 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
534 DSSERR("Failed to initialize rfbi\n");
535 goto err_rfbi;
536 }
537 187
538 r = dpi_init(pdev); 188 r = rfbi_init_platform_driver();
539 if (r) { 189 if (r) {
540 DSSERR("Failed to initialize dpi\n"); 190 DSSERR("Failed to initialize rfbi platform driver\n");
541 goto err_dpi; 191 goto err_rfbi;
542 } 192 }
543 193
544 r = dispc_init(); 194 r = dispc_init_platform_driver();
545 if (r) { 195 if (r) {
546 DSSERR("Failed to initialize dispc\n"); 196 DSSERR("Failed to initialize dispc platform driver\n");
547 goto err_dispc; 197 goto err_dispc;
548 } 198 }
549 199
550 r = venc_init(pdev); 200 r = venc_init_platform_driver();
551 if (r) { 201 if (r) {
552 DSSERR("Failed to initialize venc\n"); 202 DSSERR("Failed to initialize venc platform driver\n");
553 goto err_venc; 203 goto err_venc;
554 } 204 }
555 205
556 if (cpu_is_omap34xx()) { 206 r = dsi_init_platform_driver();
557 r = sdi_init(skip_init); 207 if (r) {
558 if (r) { 208 DSSERR("Failed to initialize DSI platform driver\n");
559 DSSERR("Failed to initialize SDI\n"); 209 goto err_dsi;
560 goto err_sdi; 210 }
561 }
562 211
563 r = dsi_init(pdev); 212 r = hdmi_init_platform_driver();
564 if (r) { 213 if (r) {
565 DSSERR("Failed to initialize DSI\n"); 214 DSSERR("Failed to initialize hdmi\n");
566 goto err_dsi; 215 goto err_hdmi;
567 }
568 } 216 }
569 217
570 r = dss_initialize_debugfs(); 218 r = dss_initialize_debugfs();
@@ -589,32 +237,25 @@ static int omap_dss_probe(struct platform_device *pdev)
589 pdata->default_device = dssdev; 237 pdata->default_device = dssdev;
590 } 238 }
591 239
592 dss_clk_disable_all(); 240 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
593 241
594 return 0; 242 return 0;
595 243
596err_register: 244err_register:
597 dss_uninitialize_debugfs(); 245 dss_uninitialize_debugfs();
598err_debugfs: 246err_debugfs:
599 if (cpu_is_omap34xx()) 247 hdmi_uninit_platform_driver();
600 dsi_exit(); 248err_hdmi:
249 dsi_uninit_platform_driver();
601err_dsi: 250err_dsi:
602 if (cpu_is_omap34xx()) 251 venc_uninit_platform_driver();
603 sdi_exit();
604err_sdi:
605 venc_exit();
606err_venc: 252err_venc:
607 dispc_exit(); 253 dispc_uninit_platform_driver();
608err_dispc: 254err_dispc:
609 dpi_exit(); 255 rfbi_uninit_platform_driver();
610err_dpi:
611 rfbi_exit();
612err_rfbi: 256err_rfbi:
613 dss_exit(); 257 dss_uninit_platform_driver();
614err_dss: 258err_dss:
615 dss_clk_disable_all_no_ctx();
616 dss_put_clocks();
617err_clocks:
618 259
619 return r; 260 return r;
620} 261}
@@ -623,61 +264,15 @@ static int omap_dss_remove(struct platform_device *pdev)
623{ 264{
624 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 265 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
625 int i; 266 int i;
626 int c;
627 267
628 dss_uninitialize_debugfs(); 268 dss_uninitialize_debugfs();
629 269
630 venc_exit(); 270 venc_uninit_platform_driver();
631 dispc_exit(); 271 dispc_uninit_platform_driver();
632 dpi_exit(); 272 rfbi_uninit_platform_driver();
633 rfbi_exit(); 273 dsi_uninit_platform_driver();
634 if (cpu_is_omap34xx()) { 274 hdmi_uninit_platform_driver();
635 dsi_exit(); 275 dss_uninit_platform_driver();
636 sdi_exit();
637 }
638
639 dss_exit();
640
641 /* these should be removed at some point */
642 c = core.dss_ick->usecount;
643 if (c > 0) {
644 DSSERR("warning: dss_ick usecount %d, disabling\n", c);
645 while (c-- > 0)
646 clk_disable(core.dss_ick);
647 }
648
649 c = core.dss1_fck->usecount;
650 if (c > 0) {
651 DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
652 while (c-- > 0)
653 clk_disable(core.dss1_fck);
654 }
655
656 c = core.dss2_fck->usecount;
657 if (c > 0) {
658 DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
659 while (c-- > 0)
660 clk_disable(core.dss2_fck);
661 }
662
663 c = core.dss_54m_fck->usecount;
664 if (c > 0) {
665 DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
666 while (c-- > 0)
667 clk_disable(core.dss_54m_fck);
668 }
669
670 if (core.dss_96m_fck) {
671 c = core.dss_96m_fck->usecount;
672 if (c > 0) {
673 DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
674 c);
675 while (c-- > 0)
676 clk_disable(core.dss_96m_fck);
677 }
678 }
679
680 dss_put_clocks();
681 276
682 dss_uninit_overlays(pdev); 277 dss_uninit_overlays(pdev);
683 dss_uninit_overlay_managers(pdev); 278 dss_uninit_overlay_managers(pdev);
@@ -965,11 +560,6 @@ static void __exit omap_dss_exit(void)
965 core.vdds_sdi_reg = NULL; 560 core.vdds_sdi_reg = NULL;
966 } 561 }
967 562
968 if (core.vdda_dac_reg != NULL) {
969 regulator_put(core.vdda_dac_reg);
970 core.vdda_dac_reg = NULL;
971 }
972
973 platform_driver_unregister(&omap_dss_driver); 563 platform_driver_unregister(&omap_dss_driver);
974 564
975 omap_dss_bus_unregister(); 565 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 9f8c69f16e61..7804779c9da1 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/interrupt.h>
35 36
36#include <plat/sram.h> 37#include <plat/sram.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -42,8 +43,6 @@
42#include "dss_features.h" 43#include "dss_features.h"
43 44
44/* DISPC */ 45/* DISPC */
45#define DISPC_BASE 0x48050400
46
47#define DISPC_SZ_REGS SZ_4K 46#define DISPC_SZ_REGS SZ_4K
48 47
49struct dispc_reg { u16 idx; }; 48struct dispc_reg { u16 idx; };
@@ -74,7 +73,7 @@ struct dispc_reg { u16 idx; };
74#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400) 73#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
75#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404) 74#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
76#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408) 75#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
77#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C) 76#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
78#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) 77#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
79#define DISPC_SIZE_DIG DISPC_REG(0x0078) 78#define DISPC_SIZE_DIG DISPC_REG(0x0078)
80#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC) 79#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
@@ -129,6 +128,7 @@ struct dispc_reg { u16 idx; };
129 128
130#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04) 129#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
131 130
131#define DISPC_DIVISOR DISPC_REG(0x0804)
132 132
133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ 133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
134 DISPC_IRQ_OCP_ERR | \ 134 DISPC_IRQ_OCP_ERR | \
@@ -178,7 +178,9 @@ struct dispc_irq_stats {
178}; 178};
179 179
180static struct { 180static struct {
181 struct platform_device *pdev;
181 void __iomem *base; 182 void __iomem *base;
183 int irq;
182 184
183 u32 fifo_size[3]; 185 u32 fifo_size[3];
184 186
@@ -230,7 +232,7 @@ void dispc_save_context(void)
230 SR(TIMING_H(0)); 232 SR(TIMING_H(0));
231 SR(TIMING_V(0)); 233 SR(TIMING_V(0));
232 SR(POL_FREQ(0)); 234 SR(POL_FREQ(0));
233 SR(DIVISOR(0)); 235 SR(DIVISORo(0));
234 SR(GLOBAL_ALPHA); 236 SR(GLOBAL_ALPHA);
235 SR(SIZE_DIG); 237 SR(SIZE_DIG);
236 SR(SIZE_LCD(0)); 238 SR(SIZE_LCD(0));
@@ -242,7 +244,7 @@ void dispc_save_context(void)
242 SR(TIMING_H(2)); 244 SR(TIMING_H(2));
243 SR(TIMING_V(2)); 245 SR(TIMING_V(2));
244 SR(POL_FREQ(2)); 246 SR(POL_FREQ(2));
245 SR(DIVISOR(2)); 247 SR(DIVISORo(2));
246 SR(CONFIG2); 248 SR(CONFIG2);
247 } 249 }
248 250
@@ -373,6 +375,9 @@ void dispc_save_context(void)
373 SR(VID_FIR_COEF_V(1, 7)); 375 SR(VID_FIR_COEF_V(1, 7));
374 376
375 SR(VID_PRELOAD(1)); 377 SR(VID_PRELOAD(1));
378
379 if (dss_has_feature(FEAT_CORE_CLK_DIV))
380 SR(DIVISOR);
376} 381}
377 382
378void dispc_restore_context(void) 383void dispc_restore_context(void)
@@ -389,7 +394,7 @@ void dispc_restore_context(void)
389 RR(TIMING_H(0)); 394 RR(TIMING_H(0));
390 RR(TIMING_V(0)); 395 RR(TIMING_V(0));
391 RR(POL_FREQ(0)); 396 RR(POL_FREQ(0));
392 RR(DIVISOR(0)); 397 RR(DIVISORo(0));
393 RR(GLOBAL_ALPHA); 398 RR(GLOBAL_ALPHA);
394 RR(SIZE_DIG); 399 RR(SIZE_DIG);
395 RR(SIZE_LCD(0)); 400 RR(SIZE_LCD(0));
@@ -400,7 +405,7 @@ void dispc_restore_context(void)
400 RR(TIMING_H(2)); 405 RR(TIMING_H(2));
401 RR(TIMING_V(2)); 406 RR(TIMING_V(2));
402 RR(POL_FREQ(2)); 407 RR(POL_FREQ(2));
403 RR(DIVISOR(2)); 408 RR(DIVISORo(2));
404 RR(CONFIG2); 409 RR(CONFIG2);
405 } 410 }
406 411
@@ -532,6 +537,9 @@ void dispc_restore_context(void)
532 537
533 RR(VID_PRELOAD(1)); 538 RR(VID_PRELOAD(1));
534 539
540 if (dss_has_feature(FEAT_CORE_CLK_DIV))
541 RR(DIVISOR);
542
535 /* enable last, because LCD & DIGIT enable are here */ 543 /* enable last, because LCD & DIGIT enable are here */
536 RR(CONTROL); 544 RR(CONTROL);
537 if (dss_has_feature(FEAT_MGR_LCD2)) 545 if (dss_has_feature(FEAT_MGR_LCD2))
@@ -552,9 +560,9 @@ void dispc_restore_context(void)
552static inline void enable_clocks(bool enable) 560static inline void enable_clocks(bool enable)
553{ 561{
554 if (enable) 562 if (enable)
555 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 563 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
556 else 564 else
557 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 565 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
558} 566}
559 567
560bool dispc_go_busy(enum omap_channel channel) 568bool dispc_go_busy(enum omap_channel channel)
@@ -1000,6 +1008,20 @@ void dispc_set_burst_size(enum omap_plane plane,
1000 enable_clocks(0); 1008 enable_clocks(0);
1001} 1009}
1002 1010
1011void dispc_enable_gamma_table(bool enable)
1012{
1013 /*
1014 * This is partially implemented to support only disabling of
1015 * the gamma table.
1016 */
1017 if (enable) {
1018 DSSWARN("Gamma table enabling for TV not yet supported");
1019 return;
1020 }
1021
1022 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1023}
1024
1003static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) 1025static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
1004{ 1026{
1005 u32 val; 1027 u32 val;
@@ -1129,10 +1151,16 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1129 u32 val; 1151 u32 val;
1130 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0), 1152 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
1131 DISPC_VID_ACCU0(1) }; 1153 DISPC_VID_ACCU0(1) };
1154 u8 hor_start, hor_end, vert_start, vert_end;
1132 1155
1133 BUG_ON(plane == OMAP_DSS_GFX); 1156 BUG_ON(plane == OMAP_DSS_GFX);
1134 1157
1135 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1158 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1159 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1160
1161 val = FLD_VAL(vaccu, vert_start, vert_end) |
1162 FLD_VAL(haccu, hor_start, hor_end);
1163
1136 dispc_write_reg(ac0_reg[plane-1], val); 1164 dispc_write_reg(ac0_reg[plane-1], val);
1137} 1165}
1138 1166
@@ -1141,10 +1169,16 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1141 u32 val; 1169 u32 val;
1142 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0), 1170 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
1143 DISPC_VID_ACCU1(1) }; 1171 DISPC_VID_ACCU1(1) };
1172 u8 hor_start, hor_end, vert_start, vert_end;
1144 1173
1145 BUG_ON(plane == OMAP_DSS_GFX); 1174 BUG_ON(plane == OMAP_DSS_GFX);
1146 1175
1147 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1176 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1177 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1178
1179 val = FLD_VAL(vaccu, vert_start, vert_end) |
1180 FLD_VAL(haccu, hor_start, hor_end);
1181
1148 dispc_write_reg(ac1_reg[plane-1], val); 1182 dispc_write_reg(ac1_reg[plane-1], val);
1149} 1183}
1150 1184
@@ -1182,16 +1216,25 @@ static void _dispc_set_scaling(enum omap_plane plane,
1182 _dispc_set_fir(plane, fir_hinc, fir_vinc); 1216 _dispc_set_fir(plane, fir_hinc, fir_vinc);
1183 1217
1184 l = dispc_read_reg(dispc_reg_att[plane]); 1218 l = dispc_read_reg(dispc_reg_att[plane]);
1185 l &= ~((0x0f << 5) | (0x3 << 21));
1186 1219
1220 /* RESIZEENABLE and VERTICALTAPS */
1221 l &= ~((0x3 << 5) | (0x1 << 21));
1187 l |= fir_hinc ? (1 << 5) : 0; 1222 l |= fir_hinc ? (1 << 5) : 0;
1188 l |= fir_vinc ? (1 << 6) : 0; 1223 l |= fir_vinc ? (1 << 6) : 0;
1224 l |= five_taps ? (1 << 21) : 0;
1189 1225
1190 l |= hscaleup ? 0 : (1 << 7); 1226 /* VRESIZECONF and HRESIZECONF */
1191 l |= vscaleup ? 0 : (1 << 8); 1227 if (dss_has_feature(FEAT_RESIZECONF)) {
1228 l &= ~(0x3 << 7);
1229 l |= hscaleup ? 0 : (1 << 7);
1230 l |= vscaleup ? 0 : (1 << 8);
1231 }
1192 1232
1193 l |= five_taps ? (1 << 21) : 0; 1233 /* LINEBUFFERSPLIT */
1194 l |= five_taps ? (1 << 22) : 0; 1234 if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
1235 l &= ~(0x1 << 22);
1236 l |= five_taps ? (1 << 22) : 0;
1237 }
1195 1238
1196 dispc_write_reg(dispc_reg_att[plane], l); 1239 dispc_write_reg(dispc_reg_att[plane], l);
1197 1240
@@ -1215,9 +1258,11 @@ static void _dispc_set_scaling(enum omap_plane plane,
1215static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1258static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1216 bool mirroring, enum omap_color_mode color_mode) 1259 bool mirroring, enum omap_color_mode color_mode)
1217{ 1260{
1261 bool row_repeat = false;
1262 int vidrot = 0;
1263
1218 if (color_mode == OMAP_DSS_COLOR_YUV2 || 1264 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1219 color_mode == OMAP_DSS_COLOR_UYVY) { 1265 color_mode == OMAP_DSS_COLOR_UYVY) {
1220 int vidrot = 0;
1221 1266
1222 if (mirroring) { 1267 if (mirroring) {
1223 switch (rotation) { 1268 switch (rotation) {
@@ -1251,16 +1296,15 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1251 } 1296 }
1252 } 1297 }
1253 1298
1254 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1255
1256 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270) 1299 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270)
1257 REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18); 1300 row_repeat = true;
1258 else 1301 else
1259 REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18); 1302 row_repeat = false;
1260 } else {
1261 REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
1262 REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
1263 } 1303 }
1304
1305 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1306 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1307 REG_FLD_MOD(dispc_reg_att[plane], row_repeat ? 1 : 0, 18, 18);
1264} 1308}
1265 1309
1266static int color_mode_to_bpp(enum omap_color_mode color_mode) 1310static int color_mode_to_bpp(enum omap_color_mode color_mode)
@@ -2293,7 +2337,7 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2293 BUG_ON(pck_div < 2); 2337 BUG_ON(pck_div < 2);
2294 2338
2295 enable_clocks(1); 2339 enable_clocks(1);
2296 dispc_write_reg(DISPC_DIVISOR(channel), 2340 dispc_write_reg(DISPC_DIVISORo(channel),
2297 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2341 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2298 enable_clocks(0); 2342 enable_clocks(0);
2299} 2343}
@@ -2302,7 +2346,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2302 int *pck_div) 2346 int *pck_div)
2303{ 2347{
2304 u32 l; 2348 u32 l;
2305 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2349 l = dispc_read_reg(DISPC_DIVISORo(channel));
2306 *lck_div = FLD_GET(l, 23, 16); 2350 *lck_div = FLD_GET(l, 23, 16);
2307 *pck_div = FLD_GET(l, 7, 0); 2351 *pck_div = FLD_GET(l, 7, 0);
2308} 2352}
@@ -2311,14 +2355,17 @@ unsigned long dispc_fclk_rate(void)
2311{ 2355{
2312 unsigned long r = 0; 2356 unsigned long r = 0;
2313 2357
2314 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) 2358 switch (dss_get_dispc_clk_source()) {
2315 r = dss_clk_get_rate(DSS_CLK_FCK1); 2359 case DSS_CLK_SRC_FCK:
2316 else 2360 r = dss_clk_get_rate(DSS_CLK_FCK);
2317#ifdef CONFIG_OMAP2_DSS_DSI 2361 break;
2318 r = dsi_get_dsi1_pll_rate(); 2362 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2319#else 2363 r = dsi_get_pll_hsdiv_dispc_rate();
2320 BUG(); 2364 break;
2321#endif 2365 default:
2366 BUG();
2367 }
2368
2322 return r; 2369 return r;
2323} 2370}
2324 2371
@@ -2328,47 +2375,72 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2328 unsigned long r; 2375 unsigned long r;
2329 u32 l; 2376 u32 l;
2330 2377
2331 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2378 l = dispc_read_reg(DISPC_DIVISORo(channel));
2332 2379
2333 lcd = FLD_GET(l, 23, 16); 2380 lcd = FLD_GET(l, 23, 16);
2334 2381
2335 r = dispc_fclk_rate(); 2382 switch (dss_get_lcd_clk_source(channel)) {
2383 case DSS_CLK_SRC_FCK:
2384 r = dss_clk_get_rate(DSS_CLK_FCK);
2385 break;
2386 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2387 r = dsi_get_pll_hsdiv_dispc_rate();
2388 break;
2389 default:
2390 BUG();
2391 }
2336 2392
2337 return r / lcd; 2393 return r / lcd;
2338} 2394}
2339 2395
2340unsigned long dispc_pclk_rate(enum omap_channel channel) 2396unsigned long dispc_pclk_rate(enum omap_channel channel)
2341{ 2397{
2342 int lcd, pcd; 2398 int pcd;
2343 unsigned long r; 2399 unsigned long r;
2344 u32 l; 2400 u32 l;
2345 2401
2346 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2402 l = dispc_read_reg(DISPC_DIVISORo(channel));
2347 2403
2348 lcd = FLD_GET(l, 23, 16);
2349 pcd = FLD_GET(l, 7, 0); 2404 pcd = FLD_GET(l, 7, 0);
2350 2405
2351 r = dispc_fclk_rate(); 2406 r = dispc_lclk_rate(channel);
2352 2407
2353 return r / lcd / pcd; 2408 return r / pcd;
2354} 2409}
2355 2410
2356void dispc_dump_clocks(struct seq_file *s) 2411void dispc_dump_clocks(struct seq_file *s)
2357{ 2412{
2358 int lcd, pcd; 2413 int lcd, pcd;
2414 u32 l;
2415 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2416 enum dss_clk_source lcd_clk_src;
2359 2417
2360 enable_clocks(1); 2418 enable_clocks(1);
2361 2419
2362 seq_printf(s, "- DISPC -\n"); 2420 seq_printf(s, "- DISPC -\n");
2363 2421
2364 seq_printf(s, "dispc fclk source = %s\n", 2422 seq_printf(s, "dispc fclk source = %s (%s)\n",
2365 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 2423 dss_get_generic_clk_source_name(dispc_clk_src),
2366 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2424 dss_feat_get_clk_source_name(dispc_clk_src));
2367 2425
2368 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2426 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
2369 2427
2428 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
2429 seq_printf(s, "- DISPC-CORE-CLK -\n");
2430 l = dispc_read_reg(DISPC_DIVISOR);
2431 lcd = FLD_GET(l, 23, 16);
2432
2433 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2434 (dispc_fclk_rate()/lcd), lcd);
2435 }
2370 seq_printf(s, "- LCD1 -\n"); 2436 seq_printf(s, "- LCD1 -\n");
2371 2437
2438 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2439
2440 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2441 dss_get_generic_clk_source_name(lcd_clk_src),
2442 dss_feat_get_clk_source_name(lcd_clk_src));
2443
2372 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); 2444 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2373 2445
2374 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2446 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2378,6 +2450,12 @@ void dispc_dump_clocks(struct seq_file *s)
2378 if (dss_has_feature(FEAT_MGR_LCD2)) { 2450 if (dss_has_feature(FEAT_MGR_LCD2)) {
2379 seq_printf(s, "- LCD2 -\n"); 2451 seq_printf(s, "- LCD2 -\n");
2380 2452
2453 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2454
2455 seq_printf(s, "lcd2_clk source = %s (%s)\n",
2456 dss_get_generic_clk_source_name(lcd_clk_src),
2457 dss_feat_get_clk_source_name(lcd_clk_src));
2458
2381 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2459 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2382 2460
2383 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2461 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2440,7 +2518,7 @@ void dispc_dump_regs(struct seq_file *s)
2440{ 2518{
2441#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) 2519#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
2442 2520
2443 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 2521 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
2444 2522
2445 DUMPREG(DISPC_REVISION); 2523 DUMPREG(DISPC_REVISION);
2446 DUMPREG(DISPC_SYSCONFIG); 2524 DUMPREG(DISPC_SYSCONFIG);
@@ -2459,7 +2537,7 @@ void dispc_dump_regs(struct seq_file *s)
2459 DUMPREG(DISPC_TIMING_H(0)); 2537 DUMPREG(DISPC_TIMING_H(0));
2460 DUMPREG(DISPC_TIMING_V(0)); 2538 DUMPREG(DISPC_TIMING_V(0));
2461 DUMPREG(DISPC_POL_FREQ(0)); 2539 DUMPREG(DISPC_POL_FREQ(0));
2462 DUMPREG(DISPC_DIVISOR(0)); 2540 DUMPREG(DISPC_DIVISORo(0));
2463 DUMPREG(DISPC_GLOBAL_ALPHA); 2541 DUMPREG(DISPC_GLOBAL_ALPHA);
2464 DUMPREG(DISPC_SIZE_DIG); 2542 DUMPREG(DISPC_SIZE_DIG);
2465 DUMPREG(DISPC_SIZE_LCD(0)); 2543 DUMPREG(DISPC_SIZE_LCD(0));
@@ -2471,7 +2549,7 @@ void dispc_dump_regs(struct seq_file *s)
2471 DUMPREG(DISPC_TIMING_H(2)); 2549 DUMPREG(DISPC_TIMING_H(2));
2472 DUMPREG(DISPC_TIMING_V(2)); 2550 DUMPREG(DISPC_TIMING_V(2));
2473 DUMPREG(DISPC_POL_FREQ(2)); 2551 DUMPREG(DISPC_POL_FREQ(2));
2474 DUMPREG(DISPC_DIVISOR(2)); 2552 DUMPREG(DISPC_DIVISORo(2));
2475 DUMPREG(DISPC_SIZE_LCD(2)); 2553 DUMPREG(DISPC_SIZE_LCD(2));
2476 } 2554 }
2477 2555
@@ -2597,7 +2675,7 @@ void dispc_dump_regs(struct seq_file *s)
2597 DUMPREG(DISPC_VID_PRELOAD(0)); 2675 DUMPREG(DISPC_VID_PRELOAD(0));
2598 DUMPREG(DISPC_VID_PRELOAD(1)); 2676 DUMPREG(DISPC_VID_PRELOAD(1));
2599 2677
2600 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 2678 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
2601#undef DUMPREG 2679#undef DUMPREG
2602} 2680}
2603 2681
@@ -2713,8 +2791,8 @@ int dispc_get_clock_div(enum omap_channel channel,
2713 2791
2714 fck = dispc_fclk_rate(); 2792 fck = dispc_fclk_rate();
2715 2793
2716 cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16); 2794 cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
2717 cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0); 2795 cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
2718 2796
2719 cinfo->lck = fck / cinfo->lck_div; 2797 cinfo->lck = fck / cinfo->lck_div;
2720 cinfo->pck = cinfo->lck / cinfo->pck_div; 2798 cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -2791,6 +2869,9 @@ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
2791 break; 2869 break;
2792 } 2870 }
2793 2871
2872 if (ret)
2873 goto err;
2874
2794 _omap_dispc_set_irqs(); 2875 _omap_dispc_set_irqs();
2795 2876
2796 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2877 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -2866,10 +2947,10 @@ static void print_irq_status(u32 status)
2866 * but we presume they are on because we got an IRQ. However, 2947 * but we presume they are on because we got an IRQ. However,
2867 * an irq handler may turn the clocks off, so we may not have 2948 * an irq handler may turn the clocks off, so we may not have
2868 * clock later in the function. */ 2949 * clock later in the function. */
2869void dispc_irq_handler(void) 2950static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
2870{ 2951{
2871 int i; 2952 int i;
2872 u32 irqstatus; 2953 u32 irqstatus, irqenable;
2873 u32 handledirqs = 0; 2954 u32 handledirqs = 0;
2874 u32 unhandled_errors; 2955 u32 unhandled_errors;
2875 struct omap_dispc_isr_data *isr_data; 2956 struct omap_dispc_isr_data *isr_data;
@@ -2878,6 +2959,13 @@ void dispc_irq_handler(void)
2878 spin_lock(&dispc.irq_lock); 2959 spin_lock(&dispc.irq_lock);
2879 2960
2880 irqstatus = dispc_read_reg(DISPC_IRQSTATUS); 2961 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
2962 irqenable = dispc_read_reg(DISPC_IRQENABLE);
2963
2964 /* IRQ is not for us */
2965 if (!(irqstatus & irqenable)) {
2966 spin_unlock(&dispc.irq_lock);
2967 return IRQ_NONE;
2968 }
2881 2969
2882#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 2970#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2883 spin_lock(&dispc.irq_stats_lock); 2971 spin_lock(&dispc.irq_stats_lock);
@@ -2929,6 +3017,8 @@ void dispc_irq_handler(void)
2929 } 3017 }
2930 3018
2931 spin_unlock(&dispc.irq_lock); 3019 spin_unlock(&dispc.irq_lock);
3020
3021 return IRQ_HANDLED;
2932} 3022}
2933 3023
2934static void dispc_error_worker(struct work_struct *work) 3024static void dispc_error_worker(struct work_struct *work)
@@ -3253,6 +3343,15 @@ static void _omap_dispc_initial_config(void)
3253 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ 3343 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
3254 dispc_write_reg(DISPC_SYSCONFIG, l); 3344 dispc_write_reg(DISPC_SYSCONFIG, l);
3255 3345
3346 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
3347 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
3348 l = dispc_read_reg(DISPC_DIVISOR);
3349 /* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
3350 l = FLD_MOD(l, 1, 0, 0);
3351 l = FLD_MOD(l, 1, 23, 16);
3352 dispc_write_reg(DISPC_DIVISOR, l);
3353 }
3354
3256 /* FUNCGATED */ 3355 /* FUNCGATED */
3257 if (dss_has_feature(FEAT_FUNCGATED)) 3356 if (dss_has_feature(FEAT_FUNCGATED))
3258 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3357 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
@@ -3269,47 +3368,6 @@ static void _omap_dispc_initial_config(void)
3269 dispc_read_plane_fifo_sizes(); 3368 dispc_read_plane_fifo_sizes();
3270} 3369}
3271 3370
3272int dispc_init(void)
3273{
3274 u32 rev;
3275
3276 spin_lock_init(&dispc.irq_lock);
3277
3278#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3279 spin_lock_init(&dispc.irq_stats_lock);
3280 dispc.irq_stats.last_reset = jiffies;
3281#endif
3282
3283 INIT_WORK(&dispc.error_work, dispc_error_worker);
3284
3285 dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
3286 if (!dispc.base) {
3287 DSSERR("can't ioremap DISPC\n");
3288 return -ENOMEM;
3289 }
3290
3291 enable_clocks(1);
3292
3293 _omap_dispc_initial_config();
3294
3295 _omap_dispc_initialize_irq();
3296
3297 dispc_save_context();
3298
3299 rev = dispc_read_reg(DISPC_REVISION);
3300 printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
3301 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3302
3303 enable_clocks(0);
3304
3305 return 0;
3306}
3307
3308void dispc_exit(void)
3309{
3310 iounmap(dispc.base);
3311}
3312
3313int dispc_enable_plane(enum omap_plane plane, bool enable) 3371int dispc_enable_plane(enum omap_plane plane, bool enable)
3314{ 3372{
3315 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 3373 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -3359,3 +3417,94 @@ int dispc_setup_plane(enum omap_plane plane,
3359 3417
3360 return r; 3418 return r;
3361} 3419}
3420
3421/* DISPC HW IP initialisation */
3422static int omap_dispchw_probe(struct platform_device *pdev)
3423{
3424 u32 rev;
3425 int r = 0;
3426 struct resource *dispc_mem;
3427
3428 dispc.pdev = pdev;
3429
3430 spin_lock_init(&dispc.irq_lock);
3431
3432#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3433 spin_lock_init(&dispc.irq_stats_lock);
3434 dispc.irq_stats.last_reset = jiffies;
3435#endif
3436
3437 INIT_WORK(&dispc.error_work, dispc_error_worker);
3438
3439 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3440 if (!dispc_mem) {
3441 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3442 r = -EINVAL;
3443 goto fail0;
3444 }
3445 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3446 if (!dispc.base) {
3447 DSSERR("can't ioremap DISPC\n");
3448 r = -ENOMEM;
3449 goto fail0;
3450 }
3451 dispc.irq = platform_get_irq(dispc.pdev, 0);
3452 if (dispc.irq < 0) {
3453 DSSERR("platform_get_irq failed\n");
3454 r = -ENODEV;
3455 goto fail1;
3456 }
3457
3458 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3459 "OMAP DISPC", dispc.pdev);
3460 if (r < 0) {
3461 DSSERR("request_irq failed\n");
3462 goto fail1;
3463 }
3464
3465 enable_clocks(1);
3466
3467 _omap_dispc_initial_config();
3468
3469 _omap_dispc_initialize_irq();
3470
3471 dispc_save_context();
3472
3473 rev = dispc_read_reg(DISPC_REVISION);
3474 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
3475 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3476
3477 enable_clocks(0);
3478
3479 return 0;
3480fail1:
3481 iounmap(dispc.base);
3482fail0:
3483 return r;
3484}
3485
3486static int omap_dispchw_remove(struct platform_device *pdev)
3487{
3488 free_irq(dispc.irq, dispc.pdev);
3489 iounmap(dispc.base);
3490 return 0;
3491}
3492
3493static struct platform_driver omap_dispchw_driver = {
3494 .probe = omap_dispchw_probe,
3495 .remove = omap_dispchw_remove,
3496 .driver = {
3497 .name = "omapdss_dispc",
3498 .owner = THIS_MODULE,
3499 },
3500};
3501
3502int dispc_init_platform_driver(void)
3503{
3504 return platform_driver_register(&omap_dispchw_driver);
3505}
3506
3507void dispc_uninit_platform_driver(void)
3508{
3509 return platform_driver_unregister(&omap_dispchw_driver);
3510}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 22dd7a474f79..a85a6f38b40c 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -25,14 +25,11 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/list.h>
29#include <linux/platform_device.h> 28#include <linux/platform_device.h>
30 29
31#include <plat/display.h> 30#include <plat/display.h>
32#include "dss.h" 31#include "dss.h"
33 32
34static LIST_HEAD(display_list);
35
36static ssize_t display_enabled_show(struct device *dev, 33static ssize_t display_enabled_show(struct device *dev,
37 struct device_attribute *attr, char *buf) 34 struct device_attribute *attr, char *buf)
38{ 35{
@@ -345,6 +342,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
345 return 16; 342 return 16;
346 case OMAP_DISPLAY_TYPE_VENC: 343 case OMAP_DISPLAY_TYPE_VENC:
347 case OMAP_DISPLAY_TYPE_SDI: 344 case OMAP_DISPLAY_TYPE_SDI:
345 case OMAP_DISPLAY_TYPE_HDMI:
348 return 24; 346 return 24;
349 default: 347 default:
350 BUG(); 348 BUG();
@@ -371,6 +369,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
371 case OMAP_DISPLAY_TYPE_DPI: 369 case OMAP_DISPLAY_TYPE_DPI:
372 bpp = dssdev->phy.dpi.data_lines; 370 bpp = dssdev->phy.dpi.data_lines;
373 break; 371 break;
372 case OMAP_DISPLAY_TYPE_HDMI:
374 case OMAP_DISPLAY_TYPE_VENC: 373 case OMAP_DISPLAY_TYPE_VENC:
375 case OMAP_DISPLAY_TYPE_SDI: 374 case OMAP_DISPLAY_TYPE_SDI:
376 bpp = 24; 375 bpp = 24;
@@ -396,29 +395,6 @@ void dss_init_device(struct platform_device *pdev,
396 switch (dssdev->type) { 395 switch (dssdev->type) {
397#ifdef CONFIG_OMAP2_DSS_DPI 396#ifdef CONFIG_OMAP2_DSS_DPI
398 case OMAP_DISPLAY_TYPE_DPI: 397 case OMAP_DISPLAY_TYPE_DPI:
399#endif
400#ifdef CONFIG_OMAP2_DSS_RFBI
401 case OMAP_DISPLAY_TYPE_DBI:
402#endif
403#ifdef CONFIG_OMAP2_DSS_SDI
404 case OMAP_DISPLAY_TYPE_SDI:
405#endif
406#ifdef CONFIG_OMAP2_DSS_DSI
407 case OMAP_DISPLAY_TYPE_DSI:
408#endif
409#ifdef CONFIG_OMAP2_DSS_VENC
410 case OMAP_DISPLAY_TYPE_VENC:
411#endif
412 break;
413 default:
414 DSSERR("Support for display '%s' not compiled in.\n",
415 dssdev->name);
416 return;
417 }
418
419 switch (dssdev->type) {
420#ifdef CONFIG_OMAP2_DSS_DPI
421 case OMAP_DISPLAY_TYPE_DPI:
422 r = dpi_init_display(dssdev); 398 r = dpi_init_display(dssdev);
423 break; 399 break;
424#endif 400#endif
@@ -442,8 +418,13 @@ void dss_init_device(struct platform_device *pdev,
442 r = dsi_init_display(dssdev); 418 r = dsi_init_display(dssdev);
443 break; 419 break;
444#endif 420#endif
421 case OMAP_DISPLAY_TYPE_HDMI:
422 r = hdmi_init_display(dssdev);
423 break;
445 default: 424 default:
446 BUG(); 425 DSSERR("Support for display '%s' not compiled in.\n",
426 dssdev->name);
427 return;
447 } 428 }
448 429
449 if (r) { 430 if (r) {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 75fb0a515430..2d3ca4ca4a05 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -57,13 +57,13 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
57 if (r) 57 if (r)
58 return r; 58 return r;
59 59
60 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 60 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
61 61
62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
63 if (r) 63 if (r)
64 return r; 64 return r;
65 65
66 *fck = dsi_cinfo.dsi1_pll_fclk; 66 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
67 *lck_div = dispc_cinfo.lck_div; 67 *lck_div = dispc_cinfo.lck_div;
68 *pck_div = dispc_cinfo.pck_div; 68 *pck_div = dispc_cinfo.pck_div;
69 69
@@ -107,7 +107,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
107 bool is_tft; 107 bool is_tft;
108 int r = 0; 108 int r = 0;
109 109
110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
111 111
112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
113 dssdev->panel.acbi, dssdev->panel.acb); 113 dssdev->panel.acbi, dssdev->panel.acb);
@@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
137 dispc_set_lcd_timings(dssdev->manager->id, t); 137 dispc_set_lcd_timings(dssdev->manager->id, t);
138 138
139err0: 139err0:
140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
141 return r; 141 return r;
142} 142}
143 143
@@ -173,14 +173,14 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
173 goto err1; 173 goto err1;
174 } 174 }
175 175
176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
177 177
178 r = dpi_basic_init(dssdev); 178 r = dpi_basic_init(dssdev);
179 if (r) 179 if (r)
180 goto err2; 180 goto err2;
181 181
182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
183 dss_clk_enable(DSS_CLK_FCK2); 183 dss_clk_enable(DSS_CLK_SYSCK);
184 r = dsi_pll_init(dssdev, 0, 1); 184 r = dsi_pll_init(dssdev, 0, 1);
185 if (r) 185 if (r)
186 goto err3; 186 goto err3;
@@ -199,10 +199,10 @@ err4:
199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
200 dsi_pll_uninit(); 200 dsi_pll_uninit();
201err3: 201err3:
202 dss_clk_disable(DSS_CLK_FCK2); 202 dss_clk_disable(DSS_CLK_SYSCK);
203#endif 203#endif
204err2: 204err2:
205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
206 if (cpu_is_omap34xx()) 206 if (cpu_is_omap34xx())
207 regulator_disable(dpi.vdds_dsi_reg); 207 regulator_disable(dpi.vdds_dsi_reg);
208err1: 208err1:
@@ -217,12 +217,12 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
217 dssdev->manager->disable(dssdev->manager); 217 dssdev->manager->disable(dssdev->manager);
218 218
219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
220 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 220 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
221 dsi_pll_uninit(); 221 dsi_pll_uninit();
222 dss_clk_disable(DSS_CLK_FCK2); 222 dss_clk_disable(DSS_CLK_SYSCK);
223#endif 223#endif
224 224
225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
226 226
227 if (cpu_is_omap34xx()) 227 if (cpu_is_omap34xx())
228 regulator_disable(dpi.vdds_dsi_reg); 228 regulator_disable(dpi.vdds_dsi_reg);
@@ -271,7 +271,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
271 if (r) 271 if (r)
272 return r; 272 return r;
273 273
274 fck = dsi_cinfo.dsi1_pll_fclk; 274 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
275 lck_div = dispc_cinfo.lck_div; 275 lck_div = dispc_cinfo.lck_div;
276 pck_div = dispc_cinfo.pck_div; 276 pck_div = dispc_cinfo.pck_div;
277 } 277 }
@@ -303,22 +303,27 @@ int dpi_init_display(struct omap_dss_device *dssdev)
303{ 303{
304 DSSDBG("init_display\n"); 304 DSSDBG("init_display\n");
305 305
306 return 0; 306 if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
307} 307 struct regulator *vdds_dsi;
308 308
309int dpi_init(struct platform_device *pdev) 309 vdds_dsi = dss_get_vdds_dsi();
310{ 310
311 if (cpu_is_omap34xx()) { 311 if (IS_ERR(vdds_dsi)) {
312 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
313 if (IS_ERR(dpi.vdds_dsi_reg)) {
314 DSSERR("can't get VDDS_DSI regulator\n"); 312 DSSERR("can't get VDDS_DSI regulator\n");
315 return PTR_ERR(dpi.vdds_dsi_reg); 313 return PTR_ERR(vdds_dsi);
316 } 314 }
315
316 dpi.vdds_dsi_reg = vdds_dsi;
317 } 317 }
318 318
319 return 0; 319 return 0;
320} 320}
321 321
322int dpi_init(void)
323{
324 return 0;
325}
326
322void dpi_exit(void) 327void dpi_exit(void)
323{ 328{
324} 329}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ddf3a0560822..0a7f1a47f8e3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -38,12 +38,11 @@
38#include <plat/clock.h> 38#include <plat/clock.h>
39 39
40#include "dss.h" 40#include "dss.h"
41#include "dss_features.h"
41 42
42/*#define VERBOSE_IRQ*/ 43/*#define VERBOSE_IRQ*/
43#define DSI_CATCH_MISSING_TE 44#define DSI_CATCH_MISSING_TE
44 45
45#define DSI_BASE 0x4804FC00
46
47struct dsi_reg { u16 idx; }; 46struct dsi_reg { u16 idx; };
48 47
49#define DSI_REG(idx) ((const struct dsi_reg) { idx }) 48#define DSI_REG(idx) ((const struct dsi_reg) { idx })
@@ -186,13 +185,15 @@ struct dsi_reg { u16 idx; };
186#define DSI_DT_RX_SHORT_READ_1 0x21 185#define DSI_DT_RX_SHORT_READ_1 0x21
187#define DSI_DT_RX_SHORT_READ_2 0x22 186#define DSI_DT_RX_SHORT_READ_2 0x22
188 187
189#define FINT_MAX 2100000 188typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
190#define FINT_MIN 750000 189
191#define REGN_MAX (1 << 7) 190#define DSI_MAX_NR_ISRS 2
192#define REGM_MAX ((1 << 11) - 1) 191
193#define REGM3_MAX (1 << 4) 192struct dsi_isr_data {
194#define REGM4_MAX (1 << 4) 193 omap_dsi_isr_t isr;
195#define LP_DIV_MAX ((1 << 13) - 1) 194 void *arg;
195 u32 mask;
196};
196 197
197enum fifo_size { 198enum fifo_size {
198 DSI_FIFO_SIZE_0 = 0, 199 DSI_FIFO_SIZE_0 = 0,
@@ -220,9 +221,17 @@ struct dsi_irq_stats {
220 unsigned cio_irqs[32]; 221 unsigned cio_irqs[32];
221}; 222};
222 223
224struct dsi_isr_tables {
225 struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
226 struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
227 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
228};
229
223static struct 230static struct
224{ 231{
232 struct platform_device *pdev;
225 void __iomem *base; 233 void __iomem *base;
234 int irq;
226 235
227 struct dsi_clock_info current_cinfo; 236 struct dsi_clock_info current_cinfo;
228 237
@@ -232,6 +241,7 @@ static struct
232 enum dsi_vc_mode mode; 241 enum dsi_vc_mode mode;
233 struct omap_dss_device *dssdev; 242 struct omap_dss_device *dssdev;
234 enum fifo_size fifo_size; 243 enum fifo_size fifo_size;
244 int vc_id;
235 } vc[4]; 245 } vc[4];
236 246
237 struct mutex lock; 247 struct mutex lock;
@@ -239,8 +249,10 @@ static struct
239 249
240 unsigned pll_locked; 250 unsigned pll_locked;
241 251
242 struct completion bta_completion; 252 spinlock_t irq_lock;
243 void (*bta_callback)(void); 253 struct dsi_isr_tables isr_tables;
254 /* space for a copy used by the interrupt handler */
255 struct dsi_isr_tables isr_tables_copy;
244 256
245 int update_channel; 257 int update_channel;
246 struct dsi_update_region update_region; 258 struct dsi_update_region update_region;
@@ -275,6 +287,11 @@ static struct
275 spinlock_t irq_stats_lock; 287 spinlock_t irq_stats_lock;
276 struct dsi_irq_stats irq_stats; 288 struct dsi_irq_stats irq_stats;
277#endif 289#endif
290 /* DSI PLL Parameter Ranges */
291 unsigned long regm_max, regn_max;
292 unsigned long regm_dispc_max, regm_dsi_max;
293 unsigned long fint_min, fint_max;
294 unsigned long lpdiv_max;
278} dsi; 295} dsi;
279 296
280#ifdef DEBUG 297#ifdef DEBUG
@@ -318,6 +335,11 @@ static bool dsi_bus_is_locked(void)
318 return dsi.bus_lock.count == 0; 335 return dsi.bus_lock.count == 0;
319} 336}
320 337
338static void dsi_completion_handler(void *data, u32 mask)
339{
340 complete((struct completion *)data);
341}
342
321static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 343static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
322 int value) 344 int value)
323{ 345{
@@ -387,6 +409,9 @@ static void dsi_perf_show(const char *name)
387 409
388static void print_irq_status(u32 status) 410static void print_irq_status(u32 status)
389{ 411{
412 if (status == 0)
413 return;
414
390#ifndef VERBOSE_IRQ 415#ifndef VERBOSE_IRQ
391 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0) 416 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
392 return; 417 return;
@@ -422,6 +447,9 @@ static void print_irq_status(u32 status)
422 447
423static void print_irq_status_vc(int channel, u32 status) 448static void print_irq_status_vc(int channel, u32 status)
424{ 449{
450 if (status == 0)
451 return;
452
425#ifndef VERBOSE_IRQ 453#ifndef VERBOSE_IRQ
426 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0) 454 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
427 return; 455 return;
@@ -448,6 +476,9 @@ static void print_irq_status_vc(int channel, u32 status)
448 476
449static void print_irq_status_cio(u32 status) 477static void print_irq_status_cio(u32 status)
450{ 478{
479 if (status == 0)
480 return;
481
451 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); 482 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
452 483
453#define PIS(x) \ 484#define PIS(x) \
@@ -478,22 +509,33 @@ static void print_irq_status_cio(u32 status)
478 printk("\n"); 509 printk("\n");
479} 510}
480 511
481static int debug_irq; 512#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
482 513static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
483/* called from dss */
484void dsi_irq_handler(void)
485{ 514{
486 u32 irqstatus, vcstatus, ciostatus;
487 int i; 515 int i;
488 516
489 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
490
491#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
492 spin_lock(&dsi.irq_stats_lock); 517 spin_lock(&dsi.irq_stats_lock);
518
493 dsi.irq_stats.irq_count++; 519 dsi.irq_stats.irq_count++;
494 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); 520 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs);
521
522 for (i = 0; i < 4; ++i)
523 dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]);
524
525 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
526
527 spin_unlock(&dsi.irq_stats_lock);
528}
529#else
530#define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus)
495#endif 531#endif
496 532
533static int debug_irq;
534
535static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
536{
537 int i;
538
497 if (irqstatus & DSI_IRQ_ERROR_MASK) { 539 if (irqstatus & DSI_IRQ_ERROR_MASK) {
498 DSSERR("DSI error, irqstatus %x\n", irqstatus); 540 DSSERR("DSI error, irqstatus %x\n", irqstatus);
499 print_irq_status(irqstatus); 541 print_irq_status(irqstatus);
@@ -504,37 +546,88 @@ void dsi_irq_handler(void)
504 print_irq_status(irqstatus); 546 print_irq_status(irqstatus);
505 } 547 }
506 548
507#ifdef DSI_CATCH_MISSING_TE 549 for (i = 0; i < 4; ++i) {
508 if (irqstatus & DSI_IRQ_TE_TRIGGER) 550 if (vcstatus[i] & DSI_VC_IRQ_ERROR_MASK) {
509 del_timer(&dsi.te_timer); 551 DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
510#endif 552 i, vcstatus[i]);
553 print_irq_status_vc(i, vcstatus[i]);
554 } else if (debug_irq) {
555 print_irq_status_vc(i, vcstatus[i]);
556 }
557 }
558
559 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) {
560 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
561 print_irq_status_cio(ciostatus);
562 } else if (debug_irq) {
563 print_irq_status_cio(ciostatus);
564 }
565}
566
567static void dsi_call_isrs(struct dsi_isr_data *isr_array,
568 unsigned isr_array_size, u32 irqstatus)
569{
570 struct dsi_isr_data *isr_data;
571 int i;
572
573 for (i = 0; i < isr_array_size; i++) {
574 isr_data = &isr_array[i];
575 if (isr_data->isr && isr_data->mask & irqstatus)
576 isr_data->isr(isr_data->arg, irqstatus);
577 }
578}
579
580static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
581 u32 irqstatus, u32 *vcstatus, u32 ciostatus)
582{
583 int i;
584
585 dsi_call_isrs(isr_tables->isr_table,
586 ARRAY_SIZE(isr_tables->isr_table),
587 irqstatus);
511 588
512 for (i = 0; i < 4; ++i) { 589 for (i = 0; i < 4; ++i) {
513 if ((irqstatus & (1<<i)) == 0) 590 if (vcstatus[i] == 0)
514 continue; 591 continue;
592 dsi_call_isrs(isr_tables->isr_table_vc[i],
593 ARRAY_SIZE(isr_tables->isr_table_vc[i]),
594 vcstatus[i]);
595 }
515 596
516 vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 597 if (ciostatus != 0)
598 dsi_call_isrs(isr_tables->isr_table_cio,
599 ARRAY_SIZE(isr_tables->isr_table_cio),
600 ciostatus);
601}
517 602
518#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 603static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
519 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); 604{
520#endif 605 u32 irqstatus, vcstatus[4], ciostatus;
606 int i;
521 607
522 if (vcstatus & DSI_VC_IRQ_BTA) { 608 spin_lock(&dsi.irq_lock);
523 complete(&dsi.bta_completion);
524 609
525 if (dsi.bta_callback) 610 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
526 dsi.bta_callback();
527 }
528 611
529 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { 612 /* IRQ is not for us */
530 DSSERR("DSI VC(%d) error, vc irqstatus %x\n", 613 if (!irqstatus) {
531 i, vcstatus); 614 spin_unlock(&dsi.irq_lock);
532 print_irq_status_vc(i, vcstatus); 615 return IRQ_NONE;
533 } else if (debug_irq) { 616 }
534 print_irq_status_vc(i, vcstatus); 617
618 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
619 /* flush posted write */
620 dsi_read_reg(DSI_IRQSTATUS);
621
622 for (i = 0; i < 4; ++i) {
623 if ((irqstatus & (1 << i)) == 0) {
624 vcstatus[i] = 0;
625 continue;
535 } 626 }
536 627
537 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus); 628 vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i));
629
630 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]);
538 /* flush posted write */ 631 /* flush posted write */
539 dsi_read_reg(DSI_VC_IRQSTATUS(i)); 632 dsi_read_reg(DSI_VC_IRQSTATUS(i));
540 } 633 }
@@ -542,117 +635,307 @@ void dsi_irq_handler(void)
542 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { 635 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
543 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 636 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
544 637
545#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
546 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
547#endif
548
549 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); 638 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
550 /* flush posted write */ 639 /* flush posted write */
551 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 640 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
641 } else {
642 ciostatus = 0;
643 }
552 644
553 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) { 645#ifdef DSI_CATCH_MISSING_TE
554 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); 646 if (irqstatus & DSI_IRQ_TE_TRIGGER)
555 print_irq_status_cio(ciostatus); 647 del_timer(&dsi.te_timer);
556 } else if (debug_irq) { 648#endif
557 print_irq_status_cio(ciostatus); 649
558 } 650 /* make a copy and unlock, so that isrs can unregister
651 * themselves */
652 memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables));
653
654 spin_unlock(&dsi.irq_lock);
655
656 dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus);
657
658 dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus);
659
660 dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus);
661
662 return IRQ_HANDLED;
663}
664
665/* dsi.irq_lock has to be locked by the caller */
666static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array,
667 unsigned isr_array_size, u32 default_mask,
668 const struct dsi_reg enable_reg,
669 const struct dsi_reg status_reg)
670{
671 struct dsi_isr_data *isr_data;
672 u32 mask;
673 u32 old_mask;
674 int i;
675
676 mask = default_mask;
677
678 for (i = 0; i < isr_array_size; i++) {
679 isr_data = &isr_array[i];
680
681 if (isr_data->isr == NULL)
682 continue;
683
684 mask |= isr_data->mask;
559 } 685 }
560 686
561 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 687 old_mask = dsi_read_reg(enable_reg);
562 /* flush posted write */ 688 /* clear the irqstatus for newly enabled irqs */
563 dsi_read_reg(DSI_IRQSTATUS); 689 dsi_write_reg(status_reg, (mask ^ old_mask) & mask);
690 dsi_write_reg(enable_reg, mask);
564 691
565#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 692 /* flush posted writes */
566 spin_unlock(&dsi.irq_stats_lock); 693 dsi_read_reg(enable_reg);
694 dsi_read_reg(status_reg);
695}
696
697/* dsi.irq_lock has to be locked by the caller */
698static void _omap_dsi_set_irqs(void)
699{
700 u32 mask = DSI_IRQ_ERROR_MASK;
701#ifdef DSI_CATCH_MISSING_TE
702 mask |= DSI_IRQ_TE_TRIGGER;
567#endif 703#endif
704 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table,
705 ARRAY_SIZE(dsi.isr_tables.isr_table), mask,
706 DSI_IRQENABLE, DSI_IRQSTATUS);
707}
708
709/* dsi.irq_lock has to be locked by the caller */
710static void _omap_dsi_set_irqs_vc(int vc)
711{
712 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc],
713 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]),
714 DSI_VC_IRQ_ERROR_MASK,
715 DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
568} 716}
569 717
718/* dsi.irq_lock has to be locked by the caller */
719static void _omap_dsi_set_irqs_cio(void)
720{
721 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio,
722 ARRAY_SIZE(dsi.isr_tables.isr_table_cio),
723 DSI_CIO_IRQ_ERROR_MASK,
724 DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
725}
570 726
571static void _dsi_initialize_irq(void) 727static void _dsi_initialize_irq(void)
572{ 728{
573 u32 l; 729 unsigned long flags;
730 int vc;
731
732 spin_lock_irqsave(&dsi.irq_lock, flags);
733
734 memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables));
735
736 _omap_dsi_set_irqs();
737 for (vc = 0; vc < 4; ++vc)
738 _omap_dsi_set_irqs_vc(vc);
739 _omap_dsi_set_irqs_cio();
740
741 spin_unlock_irqrestore(&dsi.irq_lock, flags);
742}
743
744static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
745 struct dsi_isr_data *isr_array, unsigned isr_array_size)
746{
747 struct dsi_isr_data *isr_data;
748 int free_idx;
574 int i; 749 int i;
575 750
576 /* disable all interrupts */ 751 BUG_ON(isr == NULL);
577 dsi_write_reg(DSI_IRQENABLE, 0);
578 for (i = 0; i < 4; ++i)
579 dsi_write_reg(DSI_VC_IRQENABLE(i), 0);
580 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0);
581 752
582 /* clear interrupt status */ 753 /* check for duplicate entry and find a free slot */
583 l = dsi_read_reg(DSI_IRQSTATUS); 754 free_idx = -1;
584 dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK); 755 for (i = 0; i < isr_array_size; i++) {
756 isr_data = &isr_array[i];
585 757
586 for (i = 0; i < 4; ++i) { 758 if (isr_data->isr == isr && isr_data->arg == arg &&
587 l = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 759 isr_data->mask == mask) {
588 dsi_write_reg(DSI_VC_IRQSTATUS(i), l); 760 return -EINVAL;
761 }
762
763 if (isr_data->isr == NULL && free_idx == -1)
764 free_idx = i;
589 } 765 }
590 766
591 l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 767 if (free_idx == -1)
592 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l); 768 return -EBUSY;
593 769
594 /* enable error irqs */ 770 isr_data = &isr_array[free_idx];
595 l = DSI_IRQ_ERROR_MASK; 771 isr_data->isr = isr;
596#ifdef DSI_CATCH_MISSING_TE 772 isr_data->arg = arg;
597 l |= DSI_IRQ_TE_TRIGGER; 773 isr_data->mask = mask;
598#endif
599 dsi_write_reg(DSI_IRQENABLE, l);
600 774
601 l = DSI_VC_IRQ_ERROR_MASK; 775 return 0;
602 for (i = 0; i < 4; ++i) 776}
603 dsi_write_reg(DSI_VC_IRQENABLE(i), l); 777
778static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
779 struct dsi_isr_data *isr_array, unsigned isr_array_size)
780{
781 struct dsi_isr_data *isr_data;
782 int i;
783
784 for (i = 0; i < isr_array_size; i++) {
785 isr_data = &isr_array[i];
786 if (isr_data->isr != isr || isr_data->arg != arg ||
787 isr_data->mask != mask)
788 continue;
789
790 isr_data->isr = NULL;
791 isr_data->arg = NULL;
792 isr_data->mask = 0;
793
794 return 0;
795 }
604 796
605 l = DSI_CIO_IRQ_ERROR_MASK; 797 return -EINVAL;
606 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, l);
607} 798}
608 799
609static u32 dsi_get_errors(void) 800static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
610{ 801{
611 unsigned long flags; 802 unsigned long flags;
612 u32 e; 803 int r;
613 spin_lock_irqsave(&dsi.errors_lock, flags); 804
614 e = dsi.errors; 805 spin_lock_irqsave(&dsi.irq_lock, flags);
615 dsi.errors = 0; 806
616 spin_unlock_irqrestore(&dsi.errors_lock, flags); 807 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table,
617 return e; 808 ARRAY_SIZE(dsi.isr_tables.isr_table));
809
810 if (r == 0)
811 _omap_dsi_set_irqs();
812
813 spin_unlock_irqrestore(&dsi.irq_lock, flags);
814
815 return r;
618} 816}
619 817
620static void dsi_vc_enable_bta_irq(int channel) 818static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
621{ 819{
622 u32 l; 820 unsigned long flags;
821 int r;
822
823 spin_lock_irqsave(&dsi.irq_lock, flags);
824
825 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table,
826 ARRAY_SIZE(dsi.isr_tables.isr_table));
827
828 if (r == 0)
829 _omap_dsi_set_irqs();
623 830
624 dsi_write_reg(DSI_VC_IRQSTATUS(channel), DSI_VC_IRQ_BTA); 831 spin_unlock_irqrestore(&dsi.irq_lock, flags);
625 832
626 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 833 return r;
627 l |= DSI_VC_IRQ_BTA;
628 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
629} 834}
630 835
631static void dsi_vc_disable_bta_irq(int channel) 836static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
837 u32 mask)
632{ 838{
633 u32 l; 839 unsigned long flags;
840 int r;
841
842 spin_lock_irqsave(&dsi.irq_lock, flags);
843
844 r = _dsi_register_isr(isr, arg, mask,
845 dsi.isr_tables.isr_table_vc[channel],
846 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
847
848 if (r == 0)
849 _omap_dsi_set_irqs_vc(channel);
850
851 spin_unlock_irqrestore(&dsi.irq_lock, flags);
852
853 return r;
854}
855
856static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
857 u32 mask)
858{
859 unsigned long flags;
860 int r;
861
862 spin_lock_irqsave(&dsi.irq_lock, flags);
863
864 r = _dsi_unregister_isr(isr, arg, mask,
865 dsi.isr_tables.isr_table_vc[channel],
866 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
867
868 if (r == 0)
869 _omap_dsi_set_irqs_vc(channel);
870
871 spin_unlock_irqrestore(&dsi.irq_lock, flags);
872
873 return r;
874}
875
876static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
877{
878 unsigned long flags;
879 int r;
880
881 spin_lock_irqsave(&dsi.irq_lock, flags);
882
883 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
884 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
885
886 if (r == 0)
887 _omap_dsi_set_irqs_cio();
888
889 spin_unlock_irqrestore(&dsi.irq_lock, flags);
890
891 return r;
892}
893
894static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
895{
896 unsigned long flags;
897 int r;
898
899 spin_lock_irqsave(&dsi.irq_lock, flags);
900
901 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
902 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
903
904 if (r == 0)
905 _omap_dsi_set_irqs_cio();
906
907 spin_unlock_irqrestore(&dsi.irq_lock, flags);
634 908
635 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 909 return r;
636 l &= ~DSI_VC_IRQ_BTA;
637 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
638} 910}
639 911
640/* DSI func clock. this could also be DSI2_PLL_FCLK */ 912static u32 dsi_get_errors(void)
913{
914 unsigned long flags;
915 u32 e;
916 spin_lock_irqsave(&dsi.errors_lock, flags);
917 e = dsi.errors;
918 dsi.errors = 0;
919 spin_unlock_irqrestore(&dsi.errors_lock, flags);
920 return e;
921}
922
923/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */
641static inline void enable_clocks(bool enable) 924static inline void enable_clocks(bool enable)
642{ 925{
643 if (enable) 926 if (enable)
644 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 927 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
645 else 928 else
646 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 929 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
647} 930}
648 931
649/* source clock for DSI PLL. this could also be PCLKFREE */ 932/* source clock for DSI PLL. this could also be PCLKFREE */
650static inline void dsi_enable_pll_clock(bool enable) 933static inline void dsi_enable_pll_clock(bool enable)
651{ 934{
652 if (enable) 935 if (enable)
653 dss_clk_enable(DSS_CLK_FCK2); 936 dss_clk_enable(DSS_CLK_SYSCK);
654 else 937 else
655 dss_clk_disable(DSS_CLK_FCK2); 938 dss_clk_disable(DSS_CLK_SYSCK);
656 939
657 if (enable && dsi.pll_locked) { 940 if (enable && dsi.pll_locked) {
658 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) 941 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
@@ -707,14 +990,14 @@ static inline int dsi_if_enable(bool enable)
707 return 0; 990 return 0;
708} 991}
709 992
710unsigned long dsi_get_dsi1_pll_rate(void) 993unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
711{ 994{
712 return dsi.current_cinfo.dsi1_pll_fclk; 995 return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk;
713} 996}
714 997
715static unsigned long dsi_get_dsi2_pll_rate(void) 998static unsigned long dsi_get_pll_hsdiv_dsi_rate(void)
716{ 999{
717 return dsi.current_cinfo.dsi2_pll_fclk; 1000 return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk;
718} 1001}
719 1002
720static unsigned long dsi_get_txbyteclkhs(void) 1003static unsigned long dsi_get_txbyteclkhs(void)
@@ -726,12 +1009,12 @@ static unsigned long dsi_fclk_rate(void)
726{ 1009{
727 unsigned long r; 1010 unsigned long r;
728 1011
729 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { 1012 if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) {
730 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 1013 /* DSI FCLK source is DSS_CLK_FCK */
731 r = dss_clk_get_rate(DSS_CLK_FCK1); 1014 r = dss_clk_get_rate(DSS_CLK_FCK);
732 } else { 1015 } else {
733 /* DSI FCLK source is DSI2_PLL_FCLK */ 1016 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
734 r = dsi_get_dsi2_pll_rate(); 1017 r = dsi_get_pll_hsdiv_dsi_rate();
735 } 1018 }
736 1019
737 return r; 1020 return r;
@@ -745,7 +1028,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
745 1028
746 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; 1029 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div;
747 1030
748 if (lp_clk_div == 0 || lp_clk_div > LP_DIV_MAX) 1031 if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max)
749 return -EINVAL; 1032 return -EINVAL;
750 1033
751 dsi_fclk = dsi_fclk_rate(); 1034 dsi_fclk = dsi_fclk_rate();
@@ -795,22 +1078,22 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
795static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, 1078static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
796 struct dsi_clock_info *cinfo) 1079 struct dsi_clock_info *cinfo)
797{ 1080{
798 if (cinfo->regn == 0 || cinfo->regn > REGN_MAX) 1081 if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max)
799 return -EINVAL; 1082 return -EINVAL;
800 1083
801 if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) 1084 if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max)
802 return -EINVAL; 1085 return -EINVAL;
803 1086
804 if (cinfo->regm3 > REGM3_MAX) 1087 if (cinfo->regm_dispc > dsi.regm_dispc_max)
805 return -EINVAL; 1088 return -EINVAL;
806 1089
807 if (cinfo->regm4 > REGM4_MAX) 1090 if (cinfo->regm_dsi > dsi.regm_dsi_max)
808 return -EINVAL; 1091 return -EINVAL;
809 1092
810 if (cinfo->use_dss2_fck) { 1093 if (cinfo->use_sys_clk) {
811 cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2); 1094 cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK);
812 /* XXX it is unclear if highfreq should be used 1095 /* XXX it is unclear if highfreq should be used
813 * with DSS2_FCK source also */ 1096 * with DSS_SYS_CLK source also */
814 cinfo->highfreq = 0; 1097 cinfo->highfreq = 0;
815 } else { 1098 } else {
816 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id); 1099 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id);
@@ -823,7 +1106,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
823 1106
824 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); 1107 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
825 1108
826 if (cinfo->fint > FINT_MAX || cinfo->fint < FINT_MIN) 1109 if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min)
827 return -EINVAL; 1110 return -EINVAL;
828 1111
829 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; 1112 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
@@ -831,15 +1114,17 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
831 if (cinfo->clkin4ddr > 1800 * 1000 * 1000) 1114 if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
832 return -EINVAL; 1115 return -EINVAL;
833 1116
834 if (cinfo->regm3 > 0) 1117 if (cinfo->regm_dispc > 0)
835 cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3; 1118 cinfo->dsi_pll_hsdiv_dispc_clk =
1119 cinfo->clkin4ddr / cinfo->regm_dispc;
836 else 1120 else
837 cinfo->dsi1_pll_fclk = 0; 1121 cinfo->dsi_pll_hsdiv_dispc_clk = 0;
838 1122
839 if (cinfo->regm4 > 0) 1123 if (cinfo->regm_dsi > 0)
840 cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4; 1124 cinfo->dsi_pll_hsdiv_dsi_clk =
1125 cinfo->clkin4ddr / cinfo->regm_dsi;
841 else 1126 else
842 cinfo->dsi2_pll_fclk = 0; 1127 cinfo->dsi_pll_hsdiv_dsi_clk = 0;
843 1128
844 return 0; 1129 return 0;
845} 1130}
@@ -852,23 +1137,25 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
852 struct dispc_clock_info best_dispc; 1137 struct dispc_clock_info best_dispc;
853 int min_fck_per_pck; 1138 int min_fck_per_pck;
854 int match = 0; 1139 int match = 0;
855 unsigned long dss_clk_fck2; 1140 unsigned long dss_sys_clk, max_dss_fck;
1141
1142 dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK);
856 1143
857 dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); 1144 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
858 1145
859 if (req_pck == dsi.cache_req_pck && 1146 if (req_pck == dsi.cache_req_pck &&
860 dsi.cache_cinfo.clkin == dss_clk_fck2) { 1147 dsi.cache_cinfo.clkin == dss_sys_clk) {
861 DSSDBG("DSI clock info found from cache\n"); 1148 DSSDBG("DSI clock info found from cache\n");
862 *dsi_cinfo = dsi.cache_cinfo; 1149 *dsi_cinfo = dsi.cache_cinfo;
863 dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk, 1150 dispc_find_clk_divs(is_tft, req_pck,
864 dispc_cinfo); 1151 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo);
865 return 0; 1152 return 0;
866 } 1153 }
867 1154
868 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 1155 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
869 1156
870 if (min_fck_per_pck && 1157 if (min_fck_per_pck &&
871 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 1158 req_pck * min_fck_per_pck > max_dss_fck) {
872 DSSERR("Requested pixel clock not possible with the current " 1159 DSSERR("Requested pixel clock not possible with the current "
873 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 1160 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
874 "the constraint off.\n"); 1161 "the constraint off.\n");
@@ -882,24 +1169,24 @@ retry:
882 memset(&best_dispc, 0, sizeof(best_dispc)); 1169 memset(&best_dispc, 0, sizeof(best_dispc));
883 1170
884 memset(&cur, 0, sizeof(cur)); 1171 memset(&cur, 0, sizeof(cur));
885 cur.clkin = dss_clk_fck2; 1172 cur.clkin = dss_sys_clk;
886 cur.use_dss2_fck = 1; 1173 cur.use_sys_clk = 1;
887 cur.highfreq = 0; 1174 cur.highfreq = 0;
888 1175
889 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1176 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
890 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ 1177 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
891 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1178 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
892 for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { 1179 for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) {
893 if (cur.highfreq == 0) 1180 if (cur.highfreq == 0)
894 cur.fint = cur.clkin / cur.regn; 1181 cur.fint = cur.clkin / cur.regn;
895 else 1182 else
896 cur.fint = cur.clkin / (2 * cur.regn); 1183 cur.fint = cur.clkin / (2 * cur.regn);
897 1184
898 if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) 1185 if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min)
899 continue; 1186 continue;
900 1187
901 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ 1188 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
902 for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { 1189 for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) {
903 unsigned long a, b; 1190 unsigned long a, b;
904 1191
905 a = 2 * cur.regm * (cur.clkin/1000); 1192 a = 2 * cur.regm * (cur.clkin/1000);
@@ -909,30 +1196,32 @@ retry:
909 if (cur.clkin4ddr > 1800 * 1000 * 1000) 1196 if (cur.clkin4ddr > 1800 * 1000 * 1000)
910 break; 1197 break;
911 1198
912 /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ 1199 /* dsi_pll_hsdiv_dispc_clk(MHz) =
913 for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; 1200 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
914 ++cur.regm3) { 1201 for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max;
1202 ++cur.regm_dispc) {
915 struct dispc_clock_info cur_dispc; 1203 struct dispc_clock_info cur_dispc;
916 cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3; 1204 cur.dsi_pll_hsdiv_dispc_clk =
1205 cur.clkin4ddr / cur.regm_dispc;
917 1206
918 /* this will narrow down the search a bit, 1207 /* this will narrow down the search a bit,
919 * but still give pixclocks below what was 1208 * but still give pixclocks below what was
920 * requested */ 1209 * requested */
921 if (cur.dsi1_pll_fclk < req_pck) 1210 if (cur.dsi_pll_hsdiv_dispc_clk < req_pck)
922 break; 1211 break;
923 1212
924 if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) 1213 if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck)
925 continue; 1214 continue;
926 1215
927 if (min_fck_per_pck && 1216 if (min_fck_per_pck &&
928 cur.dsi1_pll_fclk < 1217 cur.dsi_pll_hsdiv_dispc_clk <
929 req_pck * min_fck_per_pck) 1218 req_pck * min_fck_per_pck)
930 continue; 1219 continue;
931 1220
932 match = 1; 1221 match = 1;
933 1222
934 dispc_find_clk_divs(is_tft, req_pck, 1223 dispc_find_clk_divs(is_tft, req_pck,
935 cur.dsi1_pll_fclk, 1224 cur.dsi_pll_hsdiv_dispc_clk,
936 &cur_dispc); 1225 &cur_dispc);
937 1226
938 if (abs(cur_dispc.pck - req_pck) < 1227 if (abs(cur_dispc.pck - req_pck) <
@@ -961,9 +1250,9 @@ found:
961 return -EINVAL; 1250 return -EINVAL;
962 } 1251 }
963 1252
964 /* DSI2_PLL_FCLK (regm4) is not used */ 1253 /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */
965 best.regm4 = 0; 1254 best.regm_dsi = 0;
966 best.dsi2_pll_fclk = 0; 1255 best.dsi_pll_hsdiv_dsi_clk = 0;
967 1256
968 if (dsi_cinfo) 1257 if (dsi_cinfo)
969 *dsi_cinfo = best; 1258 *dsi_cinfo = best;
@@ -982,23 +1271,27 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
982 int r = 0; 1271 int r = 0;
983 u32 l; 1272 u32 l;
984 int f; 1273 int f;
1274 u8 regn_start, regn_end, regm_start, regm_end;
1275 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
985 1276
986 DSSDBGF(); 1277 DSSDBGF();
987 1278
988 dsi.current_cinfo.fint = cinfo->fint; 1279 dsi.current_cinfo.fint = cinfo->fint;
989 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; 1280 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr;
990 dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk; 1281 dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk =
991 dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk; 1282 cinfo->dsi_pll_hsdiv_dispc_clk;
1283 dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk =
1284 cinfo->dsi_pll_hsdiv_dsi_clk;
992 1285
993 dsi.current_cinfo.regn = cinfo->regn; 1286 dsi.current_cinfo.regn = cinfo->regn;
994 dsi.current_cinfo.regm = cinfo->regm; 1287 dsi.current_cinfo.regm = cinfo->regm;
995 dsi.current_cinfo.regm3 = cinfo->regm3; 1288 dsi.current_cinfo.regm_dispc = cinfo->regm_dispc;
996 dsi.current_cinfo.regm4 = cinfo->regm4; 1289 dsi.current_cinfo.regm_dsi = cinfo->regm_dsi;
997 1290
998 DSSDBG("DSI Fint %ld\n", cinfo->fint); 1291 DSSDBG("DSI Fint %ld\n", cinfo->fint);
999 1292
1000 DSSDBG("clkin (%s) rate %ld, highfreq %d\n", 1293 DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
1001 cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", 1294 cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree",
1002 cinfo->clkin, 1295 cinfo->clkin,
1003 cinfo->highfreq); 1296 cinfo->highfreq);
1004 1297
@@ -1015,24 +1308,39 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1015 1308
1016 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); 1309 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
1017 1310
1018 DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", 1311 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
1019 cinfo->regm3, cinfo->dsi1_pll_fclk); 1312 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1020 DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", 1313 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1021 cinfo->regm4, cinfo->dsi2_pll_fclk); 1314 cinfo->dsi_pll_hsdiv_dispc_clk);
1315 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
1316 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1317 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1318 cinfo->dsi_pll_hsdiv_dsi_clk);
1319
1320 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
1321 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, &regm_start, &regm_end);
1322 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, &regm_dispc_start,
1323 &regm_dispc_end);
1324 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
1325 &regm_dsi_end);
1022 1326
1023 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ 1327 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
1024 1328
1025 l = dsi_read_reg(DSI_PLL_CONFIGURATION1); 1329 l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
1026 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ 1330 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
1027 l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ 1331 /* DSI_PLL_REGN */
1028 l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ 1332 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
1029 l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0, 1333 /* DSI_PLL_REGM */
1030 22, 19); /* DSI_CLOCK_DIV */ 1334 l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
1031 l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0, 1335 /* DSI_CLOCK_DIV */
1032 26, 23); /* DSIPROTO_CLOCK_DIV */ 1336 l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
1337 regm_dispc_start, regm_dispc_end);
1338 /* DSIPROTO_CLOCK_DIV */
1339 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
1340 regm_dsi_start, regm_dsi_end);
1033 dsi_write_reg(DSI_PLL_CONFIGURATION1, l); 1341 dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
1034 1342
1035 BUG_ON(cinfo->fint < 750000 || cinfo->fint > 2100000); 1343 BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
1036 if (cinfo->fint < 1000000) 1344 if (cinfo->fint < 1000000)
1037 f = 0x3; 1345 f = 0x3;
1038 else if (cinfo->fint < 1250000) 1346 else if (cinfo->fint < 1250000)
@@ -1046,7 +1354,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1046 1354
1047 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1355 l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
1048 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ 1356 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
1049 l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, 1357 l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
1050 11, 11); /* DSI_PLL_CLKSEL */ 1358 11, 11); /* DSI_PLL_CLKSEL */
1051 l = FLD_MOD(l, cinfo->highfreq, 1359 l = FLD_MOD(l, cinfo->highfreq,
1052 12, 12); /* DSI_PLL_HIGHFREQ */ 1360 12, 12); /* DSI_PLL_HIGHFREQ */
@@ -1101,6 +1409,26 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1101 1409
1102 DSSDBG("PLL init\n"); 1410 DSSDBG("PLL init\n");
1103 1411
1412#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
1413 /*
1414 * HACK: this is just a quick hack to get the USE_DSI_PLL
1415 * option working. USE_DSI_PLL is itself a big hack, and
1416 * should be removed.
1417 */
1418 if (dsi.vdds_dsi_reg == NULL) {
1419 struct regulator *vdds_dsi;
1420
1421 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
1422
1423 if (IS_ERR(vdds_dsi)) {
1424 DSSERR("can't get VDDS_DSI regulator\n");
1425 return PTR_ERR(vdds_dsi);
1426 }
1427
1428 dsi.vdds_dsi_reg = vdds_dsi;
1429 }
1430#endif
1431
1104 enable_clocks(1); 1432 enable_clocks(1);
1105 dsi_enable_pll_clock(1); 1433 dsi_enable_pll_clock(1);
1106 1434
@@ -1162,6 +1490,10 @@ void dsi_dump_clocks(struct seq_file *s)
1162{ 1490{
1163 int clksel; 1491 int clksel;
1164 struct dsi_clock_info *cinfo = &dsi.current_cinfo; 1492 struct dsi_clock_info *cinfo = &dsi.current_cinfo;
1493 enum dss_clk_source dispc_clk_src, dsi_clk_src;
1494
1495 dispc_clk_src = dss_get_dispc_clk_source();
1496 dsi_clk_src = dss_get_dsi_clk_source();
1165 1497
1166 enable_clocks(1); 1498 enable_clocks(1);
1167 1499
@@ -1171,30 +1503,34 @@ void dsi_dump_clocks(struct seq_file *s)
1171 1503
1172 seq_printf(s, "dsi pll source = %s\n", 1504 seq_printf(s, "dsi pll source = %s\n",
1173 clksel == 0 ? 1505 clksel == 0 ?
1174 "dss2_alwon_fclk" : "pclkfree"); 1506 "dss_sys_clk" : "pclkfree");
1175 1507
1176 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1508 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
1177 1509
1178 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", 1510 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
1179 cinfo->clkin4ddr, cinfo->regm); 1511 cinfo->clkin4ddr, cinfo->regm);
1180 1512
1181 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1513 seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n",
1182 cinfo->dsi1_pll_fclk, 1514 dss_get_generic_clk_source_name(dispc_clk_src),
1183 cinfo->regm3, 1515 dss_feat_get_clk_source_name(dispc_clk_src),
1184 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1516 cinfo->dsi_pll_hsdiv_dispc_clk,
1517 cinfo->regm_dispc,
1518 dispc_clk_src == DSS_CLK_SRC_FCK ?
1185 "off" : "on"); 1519 "off" : "on");
1186 1520
1187 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1521 seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
1188 cinfo->dsi2_pll_fclk, 1522 dss_get_generic_clk_source_name(dsi_clk_src),
1189 cinfo->regm4, 1523 dss_feat_get_clk_source_name(dsi_clk_src),
1190 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1524 cinfo->dsi_pll_hsdiv_dsi_clk,
1525 cinfo->regm_dsi,
1526 dsi_clk_src == DSS_CLK_SRC_FCK ?
1191 "off" : "on"); 1527 "off" : "on");
1192 1528
1193 seq_printf(s, "- DSI -\n"); 1529 seq_printf(s, "- DSI -\n");
1194 1530
1195 seq_printf(s, "dsi fclk source = %s\n", 1531 seq_printf(s, "dsi fclk source = %s (%s)\n",
1196 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1532 dss_get_generic_clk_source_name(dsi_clk_src),
1197 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1533 dss_feat_get_clk_source_name(dsi_clk_src));
1198 1534
1199 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1535 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate());
1200 1536
@@ -1306,7 +1642,7 @@ void dsi_dump_regs(struct seq_file *s)
1306{ 1642{
1307#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) 1643#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
1308 1644
1309 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1645 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1310 1646
1311 DUMPREG(DSI_REVISION); 1647 DUMPREG(DSI_REVISION);
1312 DUMPREG(DSI_SYSCONFIG); 1648 DUMPREG(DSI_SYSCONFIG);
@@ -1378,7 +1714,7 @@ void dsi_dump_regs(struct seq_file *s)
1378 DUMPREG(DSI_PLL_CONFIGURATION1); 1714 DUMPREG(DSI_PLL_CONFIGURATION1);
1379 DUMPREG(DSI_PLL_CONFIGURATION2); 1715 DUMPREG(DSI_PLL_CONFIGURATION2);
1380 1716
1381 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1717 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1382#undef DUMPREG 1718#undef DUMPREG
1383} 1719}
1384 1720
@@ -1622,20 +1958,6 @@ static int _dsi_reset(void)
1622 return _dsi_wait_reset(); 1958 return _dsi_wait_reset();
1623} 1959}
1624 1960
1625static void dsi_reset_tx_fifo(int channel)
1626{
1627 u32 mask;
1628 u32 l;
1629
1630 /* set fifosize of the channel to 0, then return the old size */
1631 l = dsi_read_reg(DSI_TX_FIFO_VC_SIZE);
1632
1633 mask = FLD_MASK((8 * channel) + 7, (8 * channel) + 4);
1634 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l & ~mask);
1635
1636 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l);
1637}
1638
1639static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, 1961static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
1640 enum fifo_size size3, enum fifo_size size4) 1962 enum fifo_size size3, enum fifo_size size4)
1641{ 1963{
@@ -1753,8 +2075,6 @@ static void dsi_vc_initial_config(int channel)
1753 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2075 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
1754 2076
1755 dsi_write_reg(DSI_VC_CTRL(channel), r); 2077 dsi_write_reg(DSI_VC_CTRL(channel), r);
1756
1757 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1758} 2078}
1759 2079
1760static int dsi_vc_config_l4(int channel) 2080static int dsi_vc_config_l4(int channel)
@@ -1922,33 +2242,44 @@ static int dsi_vc_send_bta(int channel)
1922 2242
1923int dsi_vc_send_bta_sync(int channel) 2243int dsi_vc_send_bta_sync(int channel)
1924{ 2244{
2245 DECLARE_COMPLETION_ONSTACK(completion);
1925 int r = 0; 2246 int r = 0;
1926 u32 err; 2247 u32 err;
1927 2248
1928 INIT_COMPLETION(dsi.bta_completion); 2249 r = dsi_register_isr_vc(channel, dsi_completion_handler,
2250 &completion, DSI_VC_IRQ_BTA);
2251 if (r)
2252 goto err0;
1929 2253
1930 dsi_vc_enable_bta_irq(channel); 2254 r = dsi_register_isr(dsi_completion_handler, &completion,
2255 DSI_IRQ_ERROR_MASK);
2256 if (r)
2257 goto err1;
1931 2258
1932 r = dsi_vc_send_bta(channel); 2259 r = dsi_vc_send_bta(channel);
1933 if (r) 2260 if (r)
1934 goto err; 2261 goto err2;
1935 2262
1936 if (wait_for_completion_timeout(&dsi.bta_completion, 2263 if (wait_for_completion_timeout(&completion,
1937 msecs_to_jiffies(500)) == 0) { 2264 msecs_to_jiffies(500)) == 0) {
1938 DSSERR("Failed to receive BTA\n"); 2265 DSSERR("Failed to receive BTA\n");
1939 r = -EIO; 2266 r = -EIO;
1940 goto err; 2267 goto err2;
1941 } 2268 }
1942 2269
1943 err = dsi_get_errors(); 2270 err = dsi_get_errors();
1944 if (err) { 2271 if (err) {
1945 DSSERR("Error while sending BTA: %x\n", err); 2272 DSSERR("Error while sending BTA: %x\n", err);
1946 r = -EIO; 2273 r = -EIO;
1947 goto err; 2274 goto err2;
1948 } 2275 }
1949err: 2276err2:
1950 dsi_vc_disable_bta_irq(channel); 2277 dsi_unregister_isr(dsi_completion_handler, &completion,
1951 2278 DSI_IRQ_ERROR_MASK);
2279err1:
2280 dsi_unregister_isr_vc(channel, dsi_completion_handler,
2281 &completion, DSI_VC_IRQ_BTA);
2282err0:
1952 return r; 2283 return r;
1953} 2284}
1954EXPORT_SYMBOL(dsi_vc_send_bta_sync); 2285EXPORT_SYMBOL(dsi_vc_send_bta_sync);
@@ -1961,7 +2292,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type,
1961 2292
1962 WARN_ON(!dsi_bus_is_locked()); 2293 WARN_ON(!dsi_bus_is_locked());
1963 2294
1964 data_id = data_type | channel << 6; 2295 data_id = data_type | dsi.vc[channel].vc_id << 6;
1965 2296
1966 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 2297 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
1967 FLD_VAL(ecc, 31, 24); 2298 FLD_VAL(ecc, 31, 24);
@@ -2064,7 +2395,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2064 return -EINVAL; 2395 return -EINVAL;
2065 } 2396 }
2066 2397
2067 data_id = data_type | channel << 6; 2398 data_id = data_type | dsi.vc[channel].vc_id << 6;
2068 2399
2069 r = (data_id << 0) | (data << 8) | (ecc << 24); 2400 r = (data_id << 0) | (data << 8) | (ecc << 24);
2070 2401
@@ -2762,19 +3093,20 @@ static void dsi_te_timeout(unsigned long arg)
2762} 3093}
2763#endif 3094#endif
2764 3095
3096static void dsi_framedone_bta_callback(void *data, u32 mask);
3097
2765static void dsi_handle_framedone(int error) 3098static void dsi_handle_framedone(int error)
2766{ 3099{
2767 const int channel = dsi.update_channel; 3100 const int channel = dsi.update_channel;
2768 3101
2769 cancel_delayed_work(&dsi.framedone_timeout_work); 3102 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3103 NULL, DSI_VC_IRQ_BTA);
2770 3104
2771 dsi_vc_disable_bta_irq(channel); 3105 cancel_delayed_work(&dsi.framedone_timeout_work);
2772 3106
2773 /* SIDLEMODE back to smart-idle */ 3107 /* SIDLEMODE back to smart-idle */
2774 dispc_enable_sidle(); 3108 dispc_enable_sidle();
2775 3109
2776 dsi.bta_callback = NULL;
2777
2778 if (dsi.te_enabled) { 3110 if (dsi.te_enabled) {
2779 /* enable LP_RX_TO again after the TE */ 3111 /* enable LP_RX_TO again after the TE */
2780 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 3112 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
@@ -2808,7 +3140,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2808 dsi_handle_framedone(-ETIMEDOUT); 3140 dsi_handle_framedone(-ETIMEDOUT);
2809} 3141}
2810 3142
2811static void dsi_framedone_bta_callback(void) 3143static void dsi_framedone_bta_callback(void *data, u32 mask)
2812{ 3144{
2813 dsi_handle_framedone(0); 3145 dsi_handle_framedone(0);
2814 3146
@@ -2848,15 +3180,19 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
2848 * asynchronously. 3180 * asynchronously.
2849 * */ 3181 * */
2850 3182
2851 dsi.bta_callback = dsi_framedone_bta_callback; 3183 r = dsi_register_isr_vc(channel, dsi_framedone_bta_callback,
2852 3184 NULL, DSI_VC_IRQ_BTA);
2853 barrier(); 3185 if (r) {
2854 3186 DSSERR("Failed to register BTA ISR\n");
2855 dsi_vc_enable_bta_irq(channel); 3187 dsi_handle_framedone(-EIO);
3188 return;
3189 }
2856 3190
2857 r = dsi_vc_send_bta(channel); 3191 r = dsi_vc_send_bta(channel);
2858 if (r) { 3192 if (r) {
2859 DSSERR("BTA after framedone failed\n"); 3193 DSSERR("BTA after framedone failed\n");
3194 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3195 NULL, DSI_VC_IRQ_BTA);
2860 dsi_handle_framedone(-EIO); 3196 dsi_handle_framedone(-EIO);
2861 } 3197 }
2862} 3198}
@@ -2984,12 +3320,12 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
2984 struct dsi_clock_info cinfo; 3320 struct dsi_clock_info cinfo;
2985 int r; 3321 int r;
2986 3322
2987 /* we always use DSS2_FCK as input clock */ 3323 /* we always use DSS_CLK_SYSCK as input clock */
2988 cinfo.use_dss2_fck = true; 3324 cinfo.use_sys_clk = true;
2989 cinfo.regn = dssdev->phy.dsi.div.regn; 3325 cinfo.regn = dssdev->phy.dsi.div.regn;
2990 cinfo.regm = dssdev->phy.dsi.div.regm; 3326 cinfo.regm = dssdev->phy.dsi.div.regm;
2991 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 3327 cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc;
2992 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 3328 cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi;
2993 r = dsi_calc_clock_rates(dssdev, &cinfo); 3329 r = dsi_calc_clock_rates(dssdev, &cinfo);
2994 if (r) { 3330 if (r) {
2995 DSSERR("Failed to calc dsi clocks\n"); 3331 DSSERR("Failed to calc dsi clocks\n");
@@ -3011,7 +3347,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3011 int r; 3347 int r;
3012 unsigned long long fck; 3348 unsigned long long fck;
3013 3349
3014 fck = dsi_get_dsi1_pll_rate(); 3350 fck = dsi_get_pll_hsdiv_dispc_rate();
3015 3351
3016 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; 3352 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div;
3017 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; 3353 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div;
@@ -3045,8 +3381,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3045 if (r) 3381 if (r)
3046 goto err1; 3382 goto err1;
3047 3383
3048 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 3384 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
3049 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); 3385 dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI);
3050 3386
3051 DSSDBG("PLL OK\n"); 3387 DSSDBG("PLL OK\n");
3052 3388
@@ -3082,8 +3418,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3082err3: 3418err3:
3083 dsi_complexio_uninit(); 3419 dsi_complexio_uninit();
3084err2: 3420err2:
3085 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3421 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3086 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3422 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3087err1: 3423err1:
3088 dsi_pll_uninit(); 3424 dsi_pll_uninit();
3089err0: 3425err0:
@@ -3099,8 +3435,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3099 dsi_vc_enable(2, 0); 3435 dsi_vc_enable(2, 0);
3100 dsi_vc_enable(3, 0); 3436 dsi_vc_enable(3, 0);
3101 3437
3102 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3438 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3103 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3439 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3104 dsi_complexio_uninit(); 3440 dsi_complexio_uninit();
3105 dsi_pll_uninit(); 3441 dsi_pll_uninit();
3106} 3442}
@@ -3220,29 +3556,107 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3220 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 3556 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3221 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 3557 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
3222 3558
3223 dsi.vc[0].dssdev = dssdev; 3559 if (dsi.vdds_dsi_reg == NULL) {
3224 dsi.vc[1].dssdev = dssdev; 3560 struct regulator *vdds_dsi;
3561
3562 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
3563
3564 if (IS_ERR(vdds_dsi)) {
3565 DSSERR("can't get VDDS_DSI regulator\n");
3566 return PTR_ERR(vdds_dsi);
3567 }
3568
3569 dsi.vdds_dsi_reg = vdds_dsi;
3570 }
3225 3571
3226 return 0; 3572 return 0;
3227} 3573}
3228 3574
3229void dsi_wait_dsi1_pll_active(void) 3575int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
3576{
3577 int i;
3578
3579 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3580 if (!dsi.vc[i].dssdev) {
3581 dsi.vc[i].dssdev = dssdev;
3582 *channel = i;
3583 return 0;
3584 }
3585 }
3586
3587 DSSERR("cannot get VC for display %s", dssdev->name);
3588 return -ENOSPC;
3589}
3590EXPORT_SYMBOL(omap_dsi_request_vc);
3591
3592int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
3593{
3594 if (vc_id < 0 || vc_id > 3) {
3595 DSSERR("VC ID out of range\n");
3596 return -EINVAL;
3597 }
3598
3599 if (channel < 0 || channel > 3) {
3600 DSSERR("Virtual Channel out of range\n");
3601 return -EINVAL;
3602 }
3603
3604 if (dsi.vc[channel].dssdev != dssdev) {
3605 DSSERR("Virtual Channel not allocated to display %s\n",
3606 dssdev->name);
3607 return -EINVAL;
3608 }
3609
3610 dsi.vc[channel].vc_id = vc_id;
3611
3612 return 0;
3613}
3614EXPORT_SYMBOL(omap_dsi_set_vc_id);
3615
3616void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
3617{
3618 if ((channel >= 0 && channel <= 3) &&
3619 dsi.vc[channel].dssdev == dssdev) {
3620 dsi.vc[channel].dssdev = NULL;
3621 dsi.vc[channel].vc_id = 0;
3622 }
3623}
3624EXPORT_SYMBOL(omap_dsi_release_vc);
3625
3626void dsi_wait_pll_hsdiv_dispc_active(void)
3230{ 3627{
3231 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) 3628 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1)
3232 DSSERR("DSI1 PLL clock not active\n"); 3629 DSSERR("%s (%s) not active\n",
3630 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
3631 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
3233} 3632}
3234 3633
3235void dsi_wait_dsi2_pll_active(void) 3634void dsi_wait_pll_hsdiv_dsi_active(void)
3236{ 3635{
3237 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) 3636 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1)
3238 DSSERR("DSI2 PLL clock not active\n"); 3637 DSSERR("%s (%s) not active\n",
3638 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
3639 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
3640}
3641
3642static void dsi_calc_clock_param_ranges(void)
3643{
3644 dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
3645 dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
3646 dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
3647 dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
3648 dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
3649 dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
3650 dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
3239} 3651}
3240 3652
3241int dsi_init(struct platform_device *pdev) 3653static int dsi_init(struct platform_device *pdev)
3242{ 3654{
3243 u32 rev; 3655 u32 rev;
3244 int r; 3656 int r, i;
3657 struct resource *dsi_mem;
3245 3658
3659 spin_lock_init(&dsi.irq_lock);
3246 spin_lock_init(&dsi.errors_lock); 3660 spin_lock_init(&dsi.errors_lock);
3247 dsi.errors = 0; 3661 dsi.errors = 0;
3248 3662
@@ -3251,8 +3665,6 @@ int dsi_init(struct platform_device *pdev)
3251 dsi.irq_stats.last_reset = jiffies; 3665 dsi.irq_stats.last_reset = jiffies;
3252#endif 3666#endif
3253 3667
3254 init_completion(&dsi.bta_completion);
3255
3256 mutex_init(&dsi.lock); 3668 mutex_init(&dsi.lock);
3257 sema_init(&dsi.bus_lock, 1); 3669 sema_init(&dsi.bus_lock, 1);
3258 3670
@@ -3268,24 +3680,45 @@ int dsi_init(struct platform_device *pdev)
3268 dsi.te_timer.function = dsi_te_timeout; 3680 dsi.te_timer.function = dsi_te_timeout;
3269 dsi.te_timer.data = 0; 3681 dsi.te_timer.data = 0;
3270#endif 3682#endif
3271 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 3683 dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0);
3684 if (!dsi_mem) {
3685 DSSERR("can't get IORESOURCE_MEM DSI\n");
3686 r = -EINVAL;
3687 goto err1;
3688 }
3689 dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem));
3272 if (!dsi.base) { 3690 if (!dsi.base) {
3273 DSSERR("can't ioremap DSI\n"); 3691 DSSERR("can't ioremap DSI\n");
3274 r = -ENOMEM; 3692 r = -ENOMEM;
3275 goto err1; 3693 goto err1;
3276 } 3694 }
3695 dsi.irq = platform_get_irq(dsi.pdev, 0);
3696 if (dsi.irq < 0) {
3697 DSSERR("platform_get_irq failed\n");
3698 r = -ENODEV;
3699 goto err2;
3700 }
3277 3701
3278 dsi.vdds_dsi_reg = dss_get_vdds_dsi(); 3702 r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED,
3279 if (IS_ERR(dsi.vdds_dsi_reg)) { 3703 "OMAP DSI1", dsi.pdev);
3280 DSSERR("can't get VDDS_DSI regulator\n"); 3704 if (r < 0) {
3281 r = PTR_ERR(dsi.vdds_dsi_reg); 3705 DSSERR("request_irq failed\n");
3282 goto err2; 3706 goto err2;
3283 } 3707 }
3284 3708
3709 /* DSI VCs initialization */
3710 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3711 dsi.vc[i].mode = DSI_VC_MODE_L4;
3712 dsi.vc[i].dssdev = NULL;
3713 dsi.vc[i].vc_id = 0;
3714 }
3715
3716 dsi_calc_clock_param_ranges();
3717
3285 enable_clocks(1); 3718 enable_clocks(1);
3286 3719
3287 rev = dsi_read_reg(DSI_REVISION); 3720 rev = dsi_read_reg(DSI_REVISION);
3288 printk(KERN_INFO "OMAP DSI rev %d.%d\n", 3721 dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n",
3289 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 3722 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3290 3723
3291 enable_clocks(0); 3724 enable_clocks(0);
@@ -3298,8 +3731,14 @@ err1:
3298 return r; 3731 return r;
3299} 3732}
3300 3733
3301void dsi_exit(void) 3734static void dsi_exit(void)
3302{ 3735{
3736 if (dsi.vdds_dsi_reg != NULL) {
3737 regulator_put(dsi.vdds_dsi_reg);
3738 dsi.vdds_dsi_reg = NULL;
3739 }
3740
3741 free_irq(dsi.irq, dsi.pdev);
3303 iounmap(dsi.base); 3742 iounmap(dsi.base);
3304 3743
3305 destroy_workqueue(dsi.workqueue); 3744 destroy_workqueue(dsi.workqueue);
@@ -3307,3 +3746,41 @@ void dsi_exit(void)
3307 DSSDBG("omap_dsi_exit\n"); 3746 DSSDBG("omap_dsi_exit\n");
3308} 3747}
3309 3748
3749/* DSI1 HW IP initialisation */
3750static int omap_dsi1hw_probe(struct platform_device *pdev)
3751{
3752 int r;
3753 dsi.pdev = pdev;
3754 r = dsi_init(pdev);
3755 if (r) {
3756 DSSERR("Failed to initialize DSI\n");
3757 goto err_dsi;
3758 }
3759err_dsi:
3760 return r;
3761}
3762
3763static int omap_dsi1hw_remove(struct platform_device *pdev)
3764{
3765 dsi_exit();
3766 return 0;
3767}
3768
3769static struct platform_driver omap_dsi1hw_driver = {
3770 .probe = omap_dsi1hw_probe,
3771 .remove = omap_dsi1hw_remove,
3772 .driver = {
3773 .name = "omapdss_dsi1",
3774 .owner = THIS_MODULE,
3775 },
3776};
3777
3778int dsi_init_platform_driver(void)
3779{
3780 return platform_driver_register(&omap_dsi1hw_driver);
3781}
3782
3783void dsi_uninit_platform_driver(void)
3784{
3785 return platform_driver_unregister(&omap_dsi1hw_driver);
3786}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c3621c9171..3f1fee63c678 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -26,14 +26,13 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/seq_file.h> 29#include <linux/seq_file.h>
31#include <linux/clk.h> 30#include <linux/clk.h>
32 31
33#include <plat/display.h> 32#include <plat/display.h>
33#include <plat/clock.h>
34#include "dss.h" 34#include "dss.h"
35 35#include "dss_features.h"
36#define DSS_BASE 0x48050000
37 36
38#define DSS_SZ_REGS SZ_512 37#define DSS_SZ_REGS SZ_512
39 38
@@ -59,9 +58,17 @@ struct dss_reg {
59 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 58 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
60 59
61static struct { 60static struct {
61 struct platform_device *pdev;
62 void __iomem *base; 62 void __iomem *base;
63 int ctx_id;
63 64
64 struct clk *dpll4_m4_ck; 65 struct clk *dpll4_m4_ck;
66 struct clk *dss_ick;
67 struct clk *dss_fck;
68 struct clk *dss_sys_clk;
69 struct clk *dss_tv_fck;
70 struct clk *dss_video_fck;
71 unsigned num_clks_enabled;
65 72
66 unsigned long cache_req_pck; 73 unsigned long cache_req_pck;
67 unsigned long cache_prate; 74 unsigned long cache_prate;
@@ -70,10 +77,22 @@ static struct {
70 77
71 enum dss_clk_source dsi_clk_source; 78 enum dss_clk_source dsi_clk_source;
72 enum dss_clk_source dispc_clk_source; 79 enum dss_clk_source dispc_clk_source;
80 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
73 81
74 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 82 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
75} dss; 83} dss;
76 84
85static const char * const dss_generic_clk_source_names[] = {
86 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
87 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
88 [DSS_CLK_SRC_FCK] = "DSS_FCK",
89};
90
91static void dss_clk_enable_all_no_ctx(void);
92static void dss_clk_disable_all_no_ctx(void);
93static void dss_clk_enable_no_ctx(enum dss_clock clks);
94static void dss_clk_disable_no_ctx(enum dss_clock clks);
95
77static int _omap_dss_wait_reset(void); 96static int _omap_dss_wait_reset(void);
78 97
79static inline void dss_write_reg(const struct dss_reg idx, u32 val) 98static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -99,10 +118,11 @@ void dss_save_context(void)
99 SR(SYSCONFIG); 118 SR(SYSCONFIG);
100 SR(CONTROL); 119 SR(CONTROL);
101 120
102#ifdef CONFIG_OMAP2_DSS_SDI 121 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
103 SR(SDI_CONTROL); 122 OMAP_DISPLAY_TYPE_SDI) {
104 SR(PLL_CONTROL); 123 SR(SDI_CONTROL);
105#endif 124 SR(PLL_CONTROL);
125 }
106} 126}
107 127
108void dss_restore_context(void) 128void dss_restore_context(void)
@@ -113,10 +133,11 @@ void dss_restore_context(void)
113 RR(SYSCONFIG); 133 RR(SYSCONFIG);
114 RR(CONTROL); 134 RR(CONTROL);
115 135
116#ifdef CONFIG_OMAP2_DSS_SDI 136 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
117 RR(SDI_CONTROL); 137 OMAP_DISPLAY_TYPE_SDI) {
118 RR(PLL_CONTROL); 138 RR(SDI_CONTROL);
119#endif 139 RR(PLL_CONTROL);
140 }
120} 141}
121 142
122#undef SR 143#undef SR
@@ -209,66 +230,96 @@ void dss_sdi_disable(void)
209 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 230 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
210} 231}
211 232
233const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src)
234{
235 return dss_generic_clk_source_names[clk_src];
236}
237
212void dss_dump_clocks(struct seq_file *s) 238void dss_dump_clocks(struct seq_file *s)
213{ 239{
214 unsigned long dpll4_ck_rate; 240 unsigned long dpll4_ck_rate;
215 unsigned long dpll4_m4_ck_rate; 241 unsigned long dpll4_m4_ck_rate;
242 const char *fclk_name, *fclk_real_name;
243 unsigned long fclk_rate;
216 244
217 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 245 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
218
219 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
220 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
221 246
222 seq_printf(s, "- DSS -\n"); 247 seq_printf(s, "- DSS -\n");
223 248
224 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); 249 fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK);
250 fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK);
251 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
225 252
226 if (cpu_is_omap3630()) 253 if (dss.dpll4_m4_ck) {
227 seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", 254 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
228 dpll4_ck_rate, 255 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
229 dpll4_ck_rate / dpll4_m4_ck_rate, 256
230 dss_clk_get_rate(DSS_CLK_FCK1)); 257 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
231 else
232 seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
233 dpll4_ck_rate,
234 dpll4_ck_rate / dpll4_m4_ck_rate,
235 dss_clk_get_rate(DSS_CLK_FCK1));
236 258
237 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 259 if (cpu_is_omap3630() || cpu_is_omap44xx())
260 seq_printf(s, "%s (%s) = %lu / %lu = %lu\n",
261 fclk_name, fclk_real_name,
262 dpll4_ck_rate,
263 dpll4_ck_rate / dpll4_m4_ck_rate,
264 fclk_rate);
265 else
266 seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
267 fclk_name, fclk_real_name,
268 dpll4_ck_rate,
269 dpll4_ck_rate / dpll4_m4_ck_rate,
270 fclk_rate);
271 } else {
272 seq_printf(s, "%s (%s) = %lu\n",
273 fclk_name, fclk_real_name,
274 fclk_rate);
275 }
276
277 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
238} 278}
239 279
240void dss_dump_regs(struct seq_file *s) 280void dss_dump_regs(struct seq_file *s)
241{ 281{
242#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 282#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
243 283
244 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 284 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
245 285
246 DUMPREG(DSS_REVISION); 286 DUMPREG(DSS_REVISION);
247 DUMPREG(DSS_SYSCONFIG); 287 DUMPREG(DSS_SYSCONFIG);
248 DUMPREG(DSS_SYSSTATUS); 288 DUMPREG(DSS_SYSSTATUS);
249 DUMPREG(DSS_IRQSTATUS); 289 DUMPREG(DSS_IRQSTATUS);
250 DUMPREG(DSS_CONTROL); 290 DUMPREG(DSS_CONTROL);
251 DUMPREG(DSS_SDI_CONTROL);
252 DUMPREG(DSS_PLL_CONTROL);
253 DUMPREG(DSS_SDI_STATUS);
254 291
255 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 292 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
293 OMAP_DISPLAY_TYPE_SDI) {
294 DUMPREG(DSS_SDI_CONTROL);
295 DUMPREG(DSS_PLL_CONTROL);
296 DUMPREG(DSS_SDI_STATUS);
297 }
298
299 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
256#undef DUMPREG 300#undef DUMPREG
257} 301}
258 302
259void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 303void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
260{ 304{
261 int b; 305 int b;
306 u8 start, end;
307
308 switch (clk_src) {
309 case DSS_CLK_SRC_FCK:
310 b = 0;
311 break;
312 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
313 b = 1;
314 dsi_wait_pll_hsdiv_dispc_active();
315 break;
316 default:
317 BUG();
318 }
262 319
263 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && 320 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
264 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
265
266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
267
268 if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
269 dsi_wait_dsi1_pll_active();
270 321
271 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 322 REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
272 323
273 dss.dispc_clk_source = clk_src; 324 dss.dispc_clk_source = clk_src;
274} 325}
@@ -277,19 +328,51 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
277{ 328{
278 int b; 329 int b;
279 330
280 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && 331 switch (clk_src) {
281 clk_src != DSS_SRC_DSS1_ALWON_FCLK); 332 case DSS_CLK_SRC_FCK:
282 333 b = 0;
283 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 334 break;
284 335 case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
285 if (clk_src == DSS_SRC_DSI2_PLL_FCLK) 336 b = 1;
286 dsi_wait_dsi2_pll_active(); 337 dsi_wait_pll_hsdiv_dsi_active();
338 break;
339 default:
340 BUG();
341 }
287 342
288 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 343 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
289 344
290 dss.dsi_clk_source = clk_src; 345 dss.dsi_clk_source = clk_src;
291} 346}
292 347
348void dss_select_lcd_clk_source(enum omap_channel channel,
349 enum dss_clk_source clk_src)
350{
351 int b, ix, pos;
352
353 if (!dss_has_feature(FEAT_LCD_CLK_SRC))
354 return;
355
356 switch (clk_src) {
357 case DSS_CLK_SRC_FCK:
358 b = 0;
359 break;
360 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
361 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
362 b = 1;
363 dsi_wait_pll_hsdiv_dispc_active();
364 break;
365 default:
366 BUG();
367 }
368
369 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
370 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
371
372 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
373 dss.lcd_clk_source[ix] = clk_src;
374}
375
293enum dss_clk_source dss_get_dispc_clk_source(void) 376enum dss_clk_source dss_get_dispc_clk_source(void)
294{ 377{
295 return dss.dispc_clk_source; 378 return dss.dispc_clk_source;
@@ -300,34 +383,52 @@ enum dss_clk_source dss_get_dsi_clk_source(void)
300 return dss.dsi_clk_source; 383 return dss.dsi_clk_source;
301} 384}
302 385
386enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
387{
388 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
389 return dss.lcd_clk_source[ix];
390}
391
303/* calculate clock rates using dividers in cinfo */ 392/* calculate clock rates using dividers in cinfo */
304int dss_calc_clock_rates(struct dss_clock_info *cinfo) 393int dss_calc_clock_rates(struct dss_clock_info *cinfo)
305{ 394{
306 unsigned long prate; 395 if (dss.dpll4_m4_ck) {
396 unsigned long prate;
397 u16 fck_div_max = 16;
307 398
308 if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) || 399 if (cpu_is_omap3630() || cpu_is_omap44xx())
309 cinfo->fck_div == 0) 400 fck_div_max = 32;
310 return -EINVAL; 401
402 if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
403 return -EINVAL;
311 404
312 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 405 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
313 406
314 cinfo->fck = prate / cinfo->fck_div; 407 cinfo->fck = prate / cinfo->fck_div;
408 } else {
409 if (cinfo->fck_div != 0)
410 return -EINVAL;
411 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
412 }
315 413
316 return 0; 414 return 0;
317} 415}
318 416
319int dss_set_clock_div(struct dss_clock_info *cinfo) 417int dss_set_clock_div(struct dss_clock_info *cinfo)
320{ 418{
321 unsigned long prate; 419 if (dss.dpll4_m4_ck) {
322 int r; 420 unsigned long prate;
421 int r;
323 422
324 if (cpu_is_omap34xx()) {
325 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 423 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
326 DSSDBG("dpll4_m4 = %ld\n", prate); 424 DSSDBG("dpll4_m4 = %ld\n", prate);
327 425
328 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div); 426 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
329 if (r) 427 if (r)
330 return r; 428 return r;
429 } else {
430 if (cinfo->fck_div != 0)
431 return -EINVAL;
331 } 432 }
332 433
333 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 434 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
@@ -337,12 +438,14 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
337 438
338int dss_get_clock_div(struct dss_clock_info *cinfo) 439int dss_get_clock_div(struct dss_clock_info *cinfo)
339{ 440{
340 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); 441 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
341 442
342 if (cpu_is_omap34xx()) { 443 if (dss.dpll4_m4_ck) {
343 unsigned long prate; 444 unsigned long prate;
445
344 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 446 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
345 if (cpu_is_omap3630()) 447
448 if (cpu_is_omap3630() || cpu_is_omap44xx())
346 cinfo->fck_div = prate / (cinfo->fck); 449 cinfo->fck_div = prate / (cinfo->fck);
347 else 450 else
348 cinfo->fck_div = prate / (cinfo->fck / 2); 451 cinfo->fck_div = prate / (cinfo->fck / 2);
@@ -355,7 +458,7 @@ int dss_get_clock_div(struct dss_clock_info *cinfo)
355 458
356unsigned long dss_get_dpll4_rate(void) 459unsigned long dss_get_dpll4_rate(void)
357{ 460{
358 if (cpu_is_omap34xx()) 461 if (dss.dpll4_m4_ck)
359 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 462 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
360 else 463 else
361 return 0; 464 return 0;
@@ -369,16 +472,18 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
369 struct dss_clock_info best_dss; 472 struct dss_clock_info best_dss;
370 struct dispc_clock_info best_dispc; 473 struct dispc_clock_info best_dispc;
371 474
372 unsigned long fck; 475 unsigned long fck, max_dss_fck;
373 476
374 u16 fck_div; 477 u16 fck_div, fck_div_max = 16;
375 478
376 int match = 0; 479 int match = 0;
377 int min_fck_per_pck; 480 int min_fck_per_pck;
378 481
379 prate = dss_get_dpll4_rate(); 482 prate = dss_get_dpll4_rate();
380 483
381 fck = dss_clk_get_rate(DSS_CLK_FCK1); 484 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
485
486 fck = dss_clk_get_rate(DSS_CLK_FCK);
382 if (req_pck == dss.cache_req_pck && 487 if (req_pck == dss.cache_req_pck &&
383 ((cpu_is_omap34xx() && prate == dss.cache_prate) || 488 ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
384 dss.cache_dss_cinfo.fck == fck)) { 489 dss.cache_dss_cinfo.fck == fck)) {
@@ -391,7 +496,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
391 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 496 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
392 497
393 if (min_fck_per_pck && 498 if (min_fck_per_pck &&
394 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 499 req_pck * min_fck_per_pck > max_dss_fck) {
395 DSSERR("Requested pixel clock not possible with the current " 500 DSSERR("Requested pixel clock not possible with the current "
396 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 501 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
397 "the constraint off.\n"); 502 "the constraint off.\n");
@@ -402,10 +507,10 @@ retry:
402 memset(&best_dss, 0, sizeof(best_dss)); 507 memset(&best_dss, 0, sizeof(best_dss));
403 memset(&best_dispc, 0, sizeof(best_dispc)); 508 memset(&best_dispc, 0, sizeof(best_dispc));
404 509
405 if (cpu_is_omap24xx()) { 510 if (dss.dpll4_m4_ck == NULL) {
406 struct dispc_clock_info cur_dispc; 511 struct dispc_clock_info cur_dispc;
407 /* XXX can we change the clock on omap2? */ 512 /* XXX can we change the clock on omap2? */
408 fck = dss_clk_get_rate(DSS_CLK_FCK1); 513 fck = dss_clk_get_rate(DSS_CLK_FCK);
409 fck_div = 1; 514 fck_div = 1;
410 515
411 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 516 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
@@ -417,17 +522,19 @@ retry:
417 best_dispc = cur_dispc; 522 best_dispc = cur_dispc;
418 523
419 goto found; 524 goto found;
420 } else if (cpu_is_omap34xx()) { 525 } else {
421 for (fck_div = (cpu_is_omap3630() ? 32 : 16); 526 if (cpu_is_omap3630() || cpu_is_omap44xx())
422 fck_div > 0; --fck_div) { 527 fck_div_max = 32;
528
529 for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
423 struct dispc_clock_info cur_dispc; 530 struct dispc_clock_info cur_dispc;
424 531
425 if (cpu_is_omap3630()) 532 if (fck_div_max == 32)
426 fck = prate / fck_div; 533 fck = prate / fck_div;
427 else 534 else
428 fck = prate / fck_div * 2; 535 fck = prate / fck_div * 2;
429 536
430 if (fck > DISPC_MAX_FCK) 537 if (fck > max_dss_fck)
431 continue; 538 continue;
432 539
433 if (min_fck_per_pck && 540 if (min_fck_per_pck &&
@@ -450,8 +557,6 @@ retry:
450 goto found; 557 goto found;
451 } 558 }
452 } 559 }
453 } else {
454 BUG();
455 } 560 }
456 561
457found: 562found:
@@ -482,31 +587,6 @@ found:
482 return 0; 587 return 0;
483} 588}
484 589
485
486
487static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
488{
489 dispc_irq_handler();
490
491 return IRQ_HANDLED;
492}
493
494static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
495{
496 u32 irqstatus;
497
498 irqstatus = dss_read_reg(DSS_IRQSTATUS);
499
500 if (irqstatus & (1<<0)) /* DISPC_IRQ */
501 dispc_irq_handler();
502#ifdef CONFIG_OMAP2_DSS_DSI
503 if (irqstatus & (1<<1)) /* DSI_IRQ */
504 dsi_irq_handler();
505#endif
506
507 return IRQ_HANDLED;
508}
509
510static int _omap_dss_wait_reset(void) 590static int _omap_dss_wait_reset(void)
511{ 591{
512 int t = 0; 592 int t = 0;
@@ -549,34 +629,45 @@ void dss_set_dac_pwrdn_bgz(bool enable)
549 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ 629 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
550} 630}
551 631
552int dss_init(bool skip_init) 632void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
633{
634 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
635}
636
637static int dss_init(void)
553{ 638{
554 int r; 639 int r;
555 u32 rev; 640 u32 rev;
641 struct resource *dss_mem;
642 struct clk *dpll4_m4_ck;
556 643
557 dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); 644 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
645 if (!dss_mem) {
646 DSSERR("can't get IORESOURCE_MEM DSS\n");
647 r = -EINVAL;
648 goto fail0;
649 }
650 dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
558 if (!dss.base) { 651 if (!dss.base) {
559 DSSERR("can't ioremap DSS\n"); 652 DSSERR("can't ioremap DSS\n");
560 r = -ENOMEM; 653 r = -ENOMEM;
561 goto fail0; 654 goto fail0;
562 } 655 }
563 656
564 if (!skip_init) { 657 /* disable LCD and DIGIT output. This seems to fix the synclost
565 /* disable LCD and DIGIT output. This seems to fix the synclost 658 * problem that we get, if the bootloader starts the DSS and
566 * problem that we get, if the bootloader starts the DSS and 659 * the kernel resets it */
567 * the kernel resets it */ 660 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
568 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
569 661
570 /* We need to wait here a bit, otherwise we sometimes start to 662 /* We need to wait here a bit, otherwise we sometimes start to
571 * get synclost errors, and after that only power cycle will 663 * get synclost errors, and after that only power cycle will
572 * restore DSS functionality. I have no idea why this happens. 664 * restore DSS functionality. I have no idea why this happens.
573 * And we have to wait _before_ resetting the DSS, but after 665 * And we have to wait _before_ resetting the DSS, but after
574 * enabling clocks. 666 * enabling clocks.
575 */ 667 */
576 msleep(50); 668 msleep(50);
577 669
578 _omap_dss_reset(); 670 _omap_dss_reset();
579 }
580 671
581 /* autoidle */ 672 /* autoidle */
582 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); 673 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
@@ -589,29 +680,30 @@ int dss_init(bool skip_init)
589 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 680 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
590 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 681 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
591#endif 682#endif
592
593 r = request_irq(INT_24XX_DSS_IRQ,
594 cpu_is_omap24xx()
595 ? dss_irq_handler_omap2
596 : dss_irq_handler_omap3,
597 0, "OMAP DSS", NULL);
598
599 if (r < 0) {
600 DSSERR("omap2 dss: request_irq failed\n");
601 goto fail1;
602 }
603
604 if (cpu_is_omap34xx()) { 683 if (cpu_is_omap34xx()) {
605 dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 684 dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
606 if (IS_ERR(dss.dpll4_m4_ck)) { 685 if (IS_ERR(dpll4_m4_ck)) {
607 DSSERR("Failed to get dpll4_m4_ck\n"); 686 DSSERR("Failed to get dpll4_m4_ck\n");
608 r = PTR_ERR(dss.dpll4_m4_ck); 687 r = PTR_ERR(dpll4_m4_ck);
609 goto fail2; 688 goto fail1;
610 } 689 }
690 } else if (cpu_is_omap44xx()) {
691 dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
692 if (IS_ERR(dpll4_m4_ck)) {
693 DSSERR("Failed to get dpll4_m4_ck\n");
694 r = PTR_ERR(dpll4_m4_ck);
695 goto fail1;
696 }
697 } else { /* omap24xx */
698 dpll4_m4_ck = NULL;
611 } 699 }
612 700
613 dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 701 dss.dpll4_m4_ck = dpll4_m4_ck;
614 dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 702
703 dss.dsi_clk_source = DSS_CLK_SRC_FCK;
704 dss.dispc_clk_source = DSS_CLK_SRC_FCK;
705 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
706 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
615 707
616 dss_save_context(); 708 dss_save_context();
617 709
@@ -621,21 +713,416 @@ int dss_init(bool skip_init)
621 713
622 return 0; 714 return 0;
623 715
624fail2:
625 free_irq(INT_24XX_DSS_IRQ, NULL);
626fail1: 716fail1:
627 iounmap(dss.base); 717 iounmap(dss.base);
628fail0: 718fail0:
629 return r; 719 return r;
630} 720}
631 721
632void dss_exit(void) 722static void dss_exit(void)
633{ 723{
634 if (cpu_is_omap34xx()) 724 if (dss.dpll4_m4_ck)
635 clk_put(dss.dpll4_m4_ck); 725 clk_put(dss.dpll4_m4_ck);
636 726
637 free_irq(INT_24XX_DSS_IRQ, NULL);
638
639 iounmap(dss.base); 727 iounmap(dss.base);
640} 728}
641 729
730/* CONTEXT */
731static int dss_get_ctx_id(void)
732{
733 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
734 int r;
735
736 if (!pdata->board_data->get_last_off_on_transaction_id)
737 return 0;
738 r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
739 if (r < 0) {
740 dev_err(&dss.pdev->dev, "getting transaction ID failed, "
741 "will force context restore\n");
742 r = -1;
743 }
744 return r;
745}
746
747int dss_need_ctx_restore(void)
748{
749 int id = dss_get_ctx_id();
750
751 if (id < 0 || id != dss.ctx_id) {
752 DSSDBG("ctx id %d -> id %d\n",
753 dss.ctx_id, id);
754 dss.ctx_id = id;
755 return 1;
756 } else {
757 return 0;
758 }
759}
760
761static void save_all_ctx(void)
762{
763 DSSDBG("save context\n");
764
765 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
766
767 dss_save_context();
768 dispc_save_context();
769#ifdef CONFIG_OMAP2_DSS_DSI
770 dsi_save_context();
771#endif
772
773 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
774}
775
776static void restore_all_ctx(void)
777{
778 DSSDBG("restore context\n");
779
780 dss_clk_enable_all_no_ctx();
781
782 dss_restore_context();
783 dispc_restore_context();
784#ifdef CONFIG_OMAP2_DSS_DSI
785 dsi_restore_context();
786#endif
787
788 dss_clk_disable_all_no_ctx();
789}
790
791static int dss_get_clock(struct clk **clock, const char *clk_name)
792{
793 struct clk *clk;
794
795 clk = clk_get(&dss.pdev->dev, clk_name);
796
797 if (IS_ERR(clk)) {
798 DSSERR("can't get clock %s", clk_name);
799 return PTR_ERR(clk);
800 }
801
802 *clock = clk;
803
804 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
805
806 return 0;
807}
808
809static int dss_get_clocks(void)
810{
811 int r;
812 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
813
814 dss.dss_ick = NULL;
815 dss.dss_fck = NULL;
816 dss.dss_sys_clk = NULL;
817 dss.dss_tv_fck = NULL;
818 dss.dss_video_fck = NULL;
819
820 r = dss_get_clock(&dss.dss_ick, "ick");
821 if (r)
822 goto err;
823
824 r = dss_get_clock(&dss.dss_fck, "fck");
825 if (r)
826 goto err;
827
828 if (!pdata->opt_clock_available) {
829 r = -ENODEV;
830 goto err;
831 }
832
833 if (pdata->opt_clock_available("sys_clk")) {
834 r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
835 if (r)
836 goto err;
837 }
838
839 if (pdata->opt_clock_available("tv_clk")) {
840 r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
841 if (r)
842 goto err;
843 }
844
845 if (pdata->opt_clock_available("video_clk")) {
846 r = dss_get_clock(&dss.dss_video_fck, "video_clk");
847 if (r)
848 goto err;
849 }
850
851 return 0;
852
853err:
854 if (dss.dss_ick)
855 clk_put(dss.dss_ick);
856 if (dss.dss_fck)
857 clk_put(dss.dss_fck);
858 if (dss.dss_sys_clk)
859 clk_put(dss.dss_sys_clk);
860 if (dss.dss_tv_fck)
861 clk_put(dss.dss_tv_fck);
862 if (dss.dss_video_fck)
863 clk_put(dss.dss_video_fck);
864
865 return r;
866}
867
868static void dss_put_clocks(void)
869{
870 if (dss.dss_video_fck)
871 clk_put(dss.dss_video_fck);
872 if (dss.dss_tv_fck)
873 clk_put(dss.dss_tv_fck);
874 if (dss.dss_sys_clk)
875 clk_put(dss.dss_sys_clk);
876 clk_put(dss.dss_fck);
877 clk_put(dss.dss_ick);
878}
879
880unsigned long dss_clk_get_rate(enum dss_clock clk)
881{
882 switch (clk) {
883 case DSS_CLK_ICK:
884 return clk_get_rate(dss.dss_ick);
885 case DSS_CLK_FCK:
886 return clk_get_rate(dss.dss_fck);
887 case DSS_CLK_SYSCK:
888 return clk_get_rate(dss.dss_sys_clk);
889 case DSS_CLK_TVFCK:
890 return clk_get_rate(dss.dss_tv_fck);
891 case DSS_CLK_VIDFCK:
892 return clk_get_rate(dss.dss_video_fck);
893 }
894
895 BUG();
896 return 0;
897}
898
899static unsigned count_clk_bits(enum dss_clock clks)
900{
901 unsigned num_clks = 0;
902
903 if (clks & DSS_CLK_ICK)
904 ++num_clks;
905 if (clks & DSS_CLK_FCK)
906 ++num_clks;
907 if (clks & DSS_CLK_SYSCK)
908 ++num_clks;
909 if (clks & DSS_CLK_TVFCK)
910 ++num_clks;
911 if (clks & DSS_CLK_VIDFCK)
912 ++num_clks;
913
914 return num_clks;
915}
916
917static void dss_clk_enable_no_ctx(enum dss_clock clks)
918{
919 unsigned num_clks = count_clk_bits(clks);
920
921 if (clks & DSS_CLK_ICK)
922 clk_enable(dss.dss_ick);
923 if (clks & DSS_CLK_FCK)
924 clk_enable(dss.dss_fck);
925 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
926 clk_enable(dss.dss_sys_clk);
927 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
928 clk_enable(dss.dss_tv_fck);
929 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
930 clk_enable(dss.dss_video_fck);
931
932 dss.num_clks_enabled += num_clks;
933}
934
935void dss_clk_enable(enum dss_clock clks)
936{
937 bool check_ctx = dss.num_clks_enabled == 0;
938
939 dss_clk_enable_no_ctx(clks);
940
941 /*
942 * HACK: On omap4 the registers may not be accessible right after
943 * enabling the clocks. At some point this will be handled by
944 * pm_runtime, but for the time begin this should make things work.
945 */
946 if (cpu_is_omap44xx() && check_ctx)
947 udelay(10);
948
949 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
950 restore_all_ctx();
951}
952
953static void dss_clk_disable_no_ctx(enum dss_clock clks)
954{
955 unsigned num_clks = count_clk_bits(clks);
956
957 if (clks & DSS_CLK_ICK)
958 clk_disable(dss.dss_ick);
959 if (clks & DSS_CLK_FCK)
960 clk_disable(dss.dss_fck);
961 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
962 clk_disable(dss.dss_sys_clk);
963 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
964 clk_disable(dss.dss_tv_fck);
965 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
966 clk_disable(dss.dss_video_fck);
967
968 dss.num_clks_enabled -= num_clks;
969}
970
971void dss_clk_disable(enum dss_clock clks)
972{
973 if (cpu_is_omap34xx()) {
974 unsigned num_clks = count_clk_bits(clks);
975
976 BUG_ON(dss.num_clks_enabled < num_clks);
977
978 if (dss.num_clks_enabled == num_clks)
979 save_all_ctx();
980 }
981
982 dss_clk_disable_no_ctx(clks);
983}
984
985static void dss_clk_enable_all_no_ctx(void)
986{
987 enum dss_clock clks;
988
989 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
990 if (cpu_is_omap34xx())
991 clks |= DSS_CLK_VIDFCK;
992 dss_clk_enable_no_ctx(clks);
993}
994
995static void dss_clk_disable_all_no_ctx(void)
996{
997 enum dss_clock clks;
998
999 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
1000 if (cpu_is_omap34xx())
1001 clks |= DSS_CLK_VIDFCK;
1002 dss_clk_disable_no_ctx(clks);
1003}
1004
1005#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1006/* CLOCKS */
1007static void core_dump_clocks(struct seq_file *s)
1008{
1009 int i;
1010 struct clk *clocks[5] = {
1011 dss.dss_ick,
1012 dss.dss_fck,
1013 dss.dss_sys_clk,
1014 dss.dss_tv_fck,
1015 dss.dss_video_fck
1016 };
1017
1018 seq_printf(s, "- CORE -\n");
1019
1020 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
1021
1022 for (i = 0; i < 5; i++) {
1023 if (!clocks[i])
1024 continue;
1025 seq_printf(s, "%-15s\t%lu\t%d\n",
1026 clocks[i]->name,
1027 clk_get_rate(clocks[i]),
1028 clocks[i]->usecount);
1029 }
1030}
1031#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
1032
1033/* DEBUGFS */
1034#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1035void dss_debug_dump_clocks(struct seq_file *s)
1036{
1037 core_dump_clocks(s);
1038 dss_dump_clocks(s);
1039 dispc_dump_clocks(s);
1040#ifdef CONFIG_OMAP2_DSS_DSI
1041 dsi_dump_clocks(s);
1042#endif
1043}
1044#endif
1045
1046
1047/* DSS HW IP initialisation */
1048static int omap_dsshw_probe(struct platform_device *pdev)
1049{
1050 int r;
1051
1052 dss.pdev = pdev;
1053
1054 r = dss_get_clocks();
1055 if (r)
1056 goto err_clocks;
1057
1058 dss_clk_enable_all_no_ctx();
1059
1060 dss.ctx_id = dss_get_ctx_id();
1061 DSSDBG("initial ctx id %u\n", dss.ctx_id);
1062
1063 r = dss_init();
1064 if (r) {
1065 DSSERR("Failed to initialize DSS\n");
1066 goto err_dss;
1067 }
1068
1069 r = dpi_init();
1070 if (r) {
1071 DSSERR("Failed to initialize DPI\n");
1072 goto err_dpi;
1073 }
1074
1075 r = sdi_init();
1076 if (r) {
1077 DSSERR("Failed to initialize SDI\n");
1078 goto err_sdi;
1079 }
1080
1081 dss_clk_disable_all_no_ctx();
1082 return 0;
1083err_sdi:
1084 dpi_exit();
1085err_dpi:
1086 dss_exit();
1087err_dss:
1088 dss_clk_disable_all_no_ctx();
1089 dss_put_clocks();
1090err_clocks:
1091 return r;
1092}
1093
1094static int omap_dsshw_remove(struct platform_device *pdev)
1095{
1096
1097 dss_exit();
1098
1099 /*
1100 * As part of hwmod changes, DSS is not the only controller of dss
1101 * clocks; hwmod framework itself will also enable clocks during hwmod
1102 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
1103 * need to disable clocks if their usecounts > 1.
1104 */
1105 WARN_ON(dss.num_clks_enabled > 0);
1106
1107 dss_put_clocks();
1108 return 0;
1109}
1110
1111static struct platform_driver omap_dsshw_driver = {
1112 .probe = omap_dsshw_probe,
1113 .remove = omap_dsshw_remove,
1114 .driver = {
1115 .name = "omapdss_dss",
1116 .owner = THIS_MODULE,
1117 },
1118};
1119
1120int dss_init_platform_driver(void)
1121{
1122 return platform_driver_register(&omap_dsshw_driver);
1123}
1124
1125void dss_uninit_platform_driver(void)
1126{
1127 return platform_driver_unregister(&omap_dsshw_driver);
1128}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b394951120ac..c2f582bb19c0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,8 +97,6 @@ extern unsigned int dss_debug;
97#define FLD_MOD(orig, val, start, end) \ 97#define FLD_MOD(orig, val, start, end) \
98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
99 99
100#define DISPC_MAX_FCK 173000000
101
102enum omap_burst_size { 100enum omap_burst_size {
103 OMAP_DSS_BURST_4x32 = 0, 101 OMAP_DSS_BURST_4x32 = 0,
104 OMAP_DSS_BURST_8x32 = 1, 102 OMAP_DSS_BURST_8x32 = 1,
@@ -112,17 +110,25 @@ enum omap_parallel_interface_mode {
112}; 110};
113 111
114enum dss_clock { 112enum dss_clock {
115 DSS_CLK_ICK = 1 << 0, 113 DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
116 DSS_CLK_FCK1 = 1 << 1, 114 DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
117 DSS_CLK_FCK2 = 1 << 2, 115 DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
118 DSS_CLK_54M = 1 << 3, 116 DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
119 DSS_CLK_96M = 1 << 4, 117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
120}; 118};
121 119
122enum dss_clk_source { 120enum dss_clk_source {
123 DSS_SRC_DSI1_PLL_FCLK, 121 DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
124 DSS_SRC_DSI2_PLL_FCLK, 122 * OMAP4: PLL1_CLK1 */
125 DSS_SRC_DSS1_ALWON_FCLK, 123 DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
124 * OMAP4: PLL1_CLK2 */
125 DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
126 * OMAP4: DSS_FCLK */
127};
128
129enum dss_hdmi_venc_clk_source_select {
130 DSS_VENC_TV_CLK = 0,
131 DSS_HDMI_M_PCLK = 1,
126}; 132};
127 133
128struct dss_clock_info { 134struct dss_clock_info {
@@ -148,36 +154,42 @@ struct dsi_clock_info {
148 unsigned long fint; 154 unsigned long fint;
149 unsigned long clkin4ddr; 155 unsigned long clkin4ddr;
150 unsigned long clkin; 156 unsigned long clkin;
151 unsigned long dsi1_pll_fclk; 157 unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
152 unsigned long dsi2_pll_fclk; 158 * OMAP4: PLLx_CLK1 */
153 159 unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
160 * OMAP4: PLLx_CLK2 */
154 unsigned long lp_clk; 161 unsigned long lp_clk;
155 162
156 /* dividers */ 163 /* dividers */
157 u16 regn; 164 u16 regn;
158 u16 regm; 165 u16 regm;
159 u16 regm3; 166 u16 regm_dispc; /* OMAP3: REGM3
160 u16 regm4; 167 * OMAP4: REGM4 */
161 168 u16 regm_dsi; /* OMAP3: REGM4
169 * OMAP4: REGM5 */
162 u16 lp_clk_div; 170 u16 lp_clk_div;
163 171
164 u8 highfreq; 172 u8 highfreq;
165 bool use_dss2_fck; 173 bool use_sys_clk;
174};
175
176/* HDMI PLL structure */
177struct hdmi_pll_info {
178 u16 regn;
179 u16 regm;
180 u32 regmf;
181 u16 regm2;
182 u16 regsd;
183 u16 dcofreq;
166}; 184};
167 185
168struct seq_file; 186struct seq_file;
169struct platform_device; 187struct platform_device;
170 188
171/* core */ 189/* core */
172void dss_clk_enable(enum dss_clock clks);
173void dss_clk_disable(enum dss_clock clks);
174unsigned long dss_clk_get_rate(enum dss_clock clk);
175int dss_need_ctx_restore(void);
176void dss_dump_clocks(struct seq_file *s);
177struct bus_type *dss_get_bus(void); 190struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void); 191struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void); 192struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
181 193
182/* display */ 194/* display */
183int dss_suspend_all_devices(void); 195int dss_suspend_all_devices(void);
@@ -214,13 +226,23 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
214void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 226void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
215 227
216/* DSS */ 228/* DSS */
217int dss_init(bool skip_init); 229int dss_init_platform_driver(void);
218void dss_exit(void); 230void dss_uninit_platform_driver(void);
219 231
232void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
220void dss_save_context(void); 233void dss_save_context(void);
221void dss_restore_context(void); 234void dss_restore_context(void);
235void dss_clk_enable(enum dss_clock clks);
236void dss_clk_disable(enum dss_clock clks);
237unsigned long dss_clk_get_rate(enum dss_clock clk);
238int dss_need_ctx_restore(void);
239const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src);
240void dss_dump_clocks(struct seq_file *s);
222 241
223void dss_dump_regs(struct seq_file *s); 242void dss_dump_regs(struct seq_file *s);
243#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
244void dss_debug_dump_clocks(struct seq_file *s);
245#endif
224 246
225void dss_sdi_init(u8 datapairs); 247void dss_sdi_init(u8 datapairs);
226int dss_sdi_enable(void); 248int dss_sdi_enable(void);
@@ -228,8 +250,11 @@ void dss_sdi_disable(void);
228 250
229void dss_select_dispc_clk_source(enum dss_clk_source clk_src); 251void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
230void dss_select_dsi_clk_source(enum dss_clk_source clk_src); 252void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
253void dss_select_lcd_clk_source(enum omap_channel channel,
254 enum dss_clk_source clk_src);
231enum dss_clk_source dss_get_dispc_clk_source(void); 255enum dss_clk_source dss_get_dispc_clk_source(void);
232enum dss_clk_source dss_get_dsi_clk_source(void); 256enum dss_clk_source dss_get_dsi_clk_source(void);
257enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
233 258
234void dss_set_venc_output(enum omap_dss_venc_type type); 259void dss_set_venc_output(enum omap_dss_venc_type type);
235void dss_set_dac_pwrdn_bgz(bool enable); 260void dss_set_dac_pwrdn_bgz(bool enable);
@@ -244,11 +269,11 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
244 269
245/* SDI */ 270/* SDI */
246#ifdef CONFIG_OMAP2_DSS_SDI 271#ifdef CONFIG_OMAP2_DSS_SDI
247int sdi_init(bool skip_init); 272int sdi_init(void);
248void sdi_exit(void); 273void sdi_exit(void);
249int sdi_init_display(struct omap_dss_device *display); 274int sdi_init_display(struct omap_dss_device *display);
250#else 275#else
251static inline int sdi_init(bool skip_init) 276static inline int sdi_init(void)
252{ 277{
253 return 0; 278 return 0;
254} 279}
@@ -259,8 +284,8 @@ static inline void sdi_exit(void)
259 284
260/* DSI */ 285/* DSI */
261#ifdef CONFIG_OMAP2_DSS_DSI 286#ifdef CONFIG_OMAP2_DSS_DSI
262int dsi_init(struct platform_device *pdev); 287int dsi_init_platform_driver(void);
263void dsi_exit(void); 288void dsi_uninit_platform_driver(void);
264 289
265void dsi_dump_clocks(struct seq_file *s); 290void dsi_dump_clocks(struct seq_file *s);
266void dsi_dump_irqs(struct seq_file *s); 291void dsi_dump_irqs(struct seq_file *s);
@@ -271,7 +296,7 @@ void dsi_restore_context(void);
271 296
272int dsi_init_display(struct omap_dss_device *display); 297int dsi_init_display(struct omap_dss_device *display);
273void dsi_irq_handler(void); 298void dsi_irq_handler(void);
274unsigned long dsi_get_dsi1_pll_rate(void); 299unsigned long dsi_get_pll_hsdiv_dispc_rate(void);
275int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); 300int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
276int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 301int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
277 struct dsi_clock_info *cinfo, 302 struct dsi_clock_info *cinfo,
@@ -282,31 +307,36 @@ void dsi_pll_uninit(void);
282void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 307void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
283 u32 fifo_size, enum omap_burst_size *burst_size, 308 u32 fifo_size, enum omap_burst_size *burst_size,
284 u32 *fifo_low, u32 *fifo_high); 309 u32 *fifo_low, u32 *fifo_high);
285void dsi_wait_dsi1_pll_active(void); 310void dsi_wait_pll_hsdiv_dispc_active(void);
286void dsi_wait_dsi2_pll_active(void); 311void dsi_wait_pll_hsdiv_dsi_active(void);
287#else 312#else
288static inline int dsi_init(struct platform_device *pdev) 313static inline int dsi_init_platform_driver(void)
289{ 314{
290 return 0; 315 return 0;
291} 316}
292static inline void dsi_exit(void) 317static inline void dsi_uninit_platform_driver(void)
293{ 318{
294} 319}
295static inline void dsi_wait_dsi1_pll_active(void) 320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
296{ 321{
322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
323 return 0;
297} 324}
298static inline void dsi_wait_dsi2_pll_active(void) 325static inline void dsi_wait_pll_hsdiv_dispc_active(void)
326{
327}
328static inline void dsi_wait_pll_hsdiv_dsi_active(void)
299{ 329{
300} 330}
301#endif 331#endif
302 332
303/* DPI */ 333/* DPI */
304#ifdef CONFIG_OMAP2_DSS_DPI 334#ifdef CONFIG_OMAP2_DSS_DPI
305int dpi_init(struct platform_device *pdev); 335int dpi_init(void);
306void dpi_exit(void); 336void dpi_exit(void);
307int dpi_init_display(struct omap_dss_device *dssdev); 337int dpi_init_display(struct omap_dss_device *dssdev);
308#else 338#else
309static inline int dpi_init(struct platform_device *pdev) 339static inline int dpi_init(void)
310{ 340{
311 return 0; 341 return 0;
312} 342}
@@ -316,8 +346,8 @@ static inline void dpi_exit(void)
316#endif 346#endif
317 347
318/* DISPC */ 348/* DISPC */
319int dispc_init(void); 349int dispc_init_platform_driver(void);
320void dispc_exit(void); 350void dispc_uninit_platform_driver(void);
321void dispc_dump_clocks(struct seq_file *s); 351void dispc_dump_clocks(struct seq_file *s);
322void dispc_dump_irqs(struct seq_file *s); 352void dispc_dump_irqs(struct seq_file *s);
323void dispc_dump_regs(struct seq_file *s); 353void dispc_dump_regs(struct seq_file *s);
@@ -350,6 +380,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
350void dispc_set_channel_out(enum omap_plane plane, 380void dispc_set_channel_out(enum omap_plane plane,
351 enum omap_channel channel_out); 381 enum omap_channel channel_out);
352 382
383void dispc_enable_gamma_table(bool enable);
353int dispc_setup_plane(enum omap_plane plane, 384int dispc_setup_plane(enum omap_plane plane,
354 u32 paddr, u16 screen_width, 385 u32 paddr, u16 screen_width,
355 u16 pos_x, u16 pos_y, 386 u16 pos_x, u16 pos_y,
@@ -409,24 +440,50 @@ int dispc_get_clock_div(enum omap_channel channel,
409 440
410/* VENC */ 441/* VENC */
411#ifdef CONFIG_OMAP2_DSS_VENC 442#ifdef CONFIG_OMAP2_DSS_VENC
412int venc_init(struct platform_device *pdev); 443int venc_init_platform_driver(void);
413void venc_exit(void); 444void venc_uninit_platform_driver(void);
414void venc_dump_regs(struct seq_file *s); 445void venc_dump_regs(struct seq_file *s);
415int venc_init_display(struct omap_dss_device *display); 446int venc_init_display(struct omap_dss_device *display);
416#else 447#else
417static inline int venc_init(struct platform_device *pdev) 448static inline int venc_init_platform_driver(void)
449{
450 return 0;
451}
452static inline void venc_uninit_platform_driver(void)
453{
454}
455#endif
456
457/* HDMI */
458#ifdef CONFIG_OMAP4_DSS_HDMI
459int hdmi_init_platform_driver(void);
460void hdmi_uninit_platform_driver(void);
461int hdmi_init_display(struct omap_dss_device *dssdev);
462#else
463static inline int hdmi_init_display(struct omap_dss_device *dssdev)
464{
465 return 0;
466}
467static inline int hdmi_init_platform_driver(void)
418{ 468{
419 return 0; 469 return 0;
420} 470}
421static inline void venc_exit(void) 471static inline void hdmi_uninit_platform_driver(void)
422{ 472{
423} 473}
424#endif 474#endif
475int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
476void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
477void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
478int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
479 struct omap_video_timings *timings);
480int hdmi_panel_init(void);
481void hdmi_panel_exit(void);
425 482
426/* RFBI */ 483/* RFBI */
427#ifdef CONFIG_OMAP2_DSS_RFBI 484#ifdef CONFIG_OMAP2_DSS_RFBI
428int rfbi_init(void); 485int rfbi_init_platform_driver(void);
429void rfbi_exit(void); 486void rfbi_uninit_platform_driver(void);
430void rfbi_dump_regs(struct seq_file *s); 487void rfbi_dump_regs(struct seq_file *s);
431 488
432int rfbi_configure(int rfbi_module, int bpp, int lines); 489int rfbi_configure(int rfbi_module, int bpp, int lines);
@@ -437,11 +494,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
437unsigned long rfbi_get_max_tx_rate(void); 494unsigned long rfbi_get_max_tx_rate(void);
438int rfbi_init_display(struct omap_dss_device *display); 495int rfbi_init_display(struct omap_dss_device *display);
439#else 496#else
440static inline int rfbi_init(void) 497static inline int rfbi_init_platform_driver(void)
441{ 498{
442 return 0; 499 return 0;
443} 500}
444static inline void rfbi_exit(void) 501static inline void rfbi_uninit_platform_driver(void)
445{ 502{
446} 503}
447#endif 504#endif
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index cf3ef696e141..aa1622241d0d 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -25,14 +25,18 @@
25#include <plat/display.h> 25#include <plat/display.h>
26#include <plat/cpu.h> 26#include <plat/cpu.h>
27 27
28#include "dss.h"
28#include "dss_features.h" 29#include "dss_features.h"
29 30
30/* Defines a generic omap register field */ 31/* Defines a generic omap register field */
31struct dss_reg_field { 32struct dss_reg_field {
32 enum dss_feat_reg_field id;
33 u8 start, end; 33 u8 start, end;
34}; 34};
35 35
36struct dss_param_range {
37 int min, max;
38};
39
36struct omap_dss_features { 40struct omap_dss_features {
37 const struct dss_reg_field *reg_fields; 41 const struct dss_reg_field *reg_fields;
38 const int num_reg_fields; 42 const int num_reg_fields;
@@ -43,29 +47,68 @@ struct omap_dss_features {
43 const int num_ovls; 47 const int num_ovls;
44 const enum omap_display_type *supported_displays; 48 const enum omap_display_type *supported_displays;
45 const enum omap_color_mode *supported_color_modes; 49 const enum omap_color_mode *supported_color_modes;
50 const char * const *clksrc_names;
51 const struct dss_param_range *dss_params;
46}; 52};
47 53
48/* This struct is assigned to one of the below during initialization */ 54/* This struct is assigned to one of the below during initialization */
49static struct omap_dss_features *omap_current_dss_features; 55static struct omap_dss_features *omap_current_dss_features;
50 56
51static const struct dss_reg_field omap2_dss_reg_fields[] = { 57static const struct dss_reg_field omap2_dss_reg_fields[] = {
52 { FEAT_REG_FIRHINC, 11, 0 }, 58 [FEAT_REG_FIRHINC] = { 11, 0 },
53 { FEAT_REG_FIRVINC, 27, 16 }, 59 [FEAT_REG_FIRVINC] = { 27, 16 },
54 { FEAT_REG_FIFOLOWTHRESHOLD, 8, 0 }, 60 [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
55 { FEAT_REG_FIFOHIGHTHRESHOLD, 24, 16 }, 61 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
56 { FEAT_REG_FIFOSIZE, 8, 0 }, 62 [FEAT_REG_FIFOSIZE] = { 8, 0 },
63 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
64 [FEAT_REG_VERTICALACCU] = { 25, 16 },
65 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
66 [FEAT_REG_DSIPLL_REGN] = { 0, 0 },
67 [FEAT_REG_DSIPLL_REGM] = { 0, 0 },
68 [FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
69 [FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
57}; 70};
58 71
59static const struct dss_reg_field omap3_dss_reg_fields[] = { 72static const struct dss_reg_field omap3_dss_reg_fields[] = {
60 { FEAT_REG_FIRHINC, 12, 0 }, 73 [FEAT_REG_FIRHINC] = { 12, 0 },
61 { FEAT_REG_FIRVINC, 28, 16 }, 74 [FEAT_REG_FIRVINC] = { 28, 16 },
62 { FEAT_REG_FIFOLOWTHRESHOLD, 11, 0 }, 75 [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
63 { FEAT_REG_FIFOHIGHTHRESHOLD, 27, 16 }, 76 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
64 { FEAT_REG_FIFOSIZE, 10, 0 }, 77 [FEAT_REG_FIFOSIZE] = { 10, 0 },
78 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
79 [FEAT_REG_VERTICALACCU] = { 25, 16 },
80 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
81 [FEAT_REG_DSIPLL_REGN] = { 7, 1 },
82 [FEAT_REG_DSIPLL_REGM] = { 18, 8 },
83 [FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
84 [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
85};
86
87static const struct dss_reg_field omap4_dss_reg_fields[] = {
88 [FEAT_REG_FIRHINC] = { 12, 0 },
89 [FEAT_REG_FIRVINC] = { 28, 16 },
90 [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
91 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
92 [FEAT_REG_FIFOSIZE] = { 15, 0 },
93 [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
94 [FEAT_REG_VERTICALACCU] = { 26, 16 },
95 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
96 [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
97 [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
98 [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
99 [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
65}; 100};
66 101
67static const enum omap_display_type omap2_dss_supported_displays[] = { 102static const enum omap_display_type omap2_dss_supported_displays[] = {
68 /* OMAP_DSS_CHANNEL_LCD */ 103 /* OMAP_DSS_CHANNEL_LCD */
104 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
105
106 /* OMAP_DSS_CHANNEL_DIGIT */
107 OMAP_DISPLAY_TYPE_VENC,
108};
109
110static const enum omap_display_type omap3430_dss_supported_displays[] = {
111 /* OMAP_DSS_CHANNEL_LCD */
69 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 112 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
70 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 113 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
71 114
@@ -73,10 +116,10 @@ static const enum omap_display_type omap2_dss_supported_displays[] = {
73 OMAP_DISPLAY_TYPE_VENC, 116 OMAP_DISPLAY_TYPE_VENC,
74}; 117};
75 118
76static const enum omap_display_type omap3_dss_supported_displays[] = { 119static const enum omap_display_type omap3630_dss_supported_displays[] = {
77 /* OMAP_DSS_CHANNEL_LCD */ 120 /* OMAP_DSS_CHANNEL_LCD */
78 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 121 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
79 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 122 OMAP_DISPLAY_TYPE_DSI,
80 123
81 /* OMAP_DSS_CHANNEL_DIGIT */ 124 /* OMAP_DSS_CHANNEL_DIGIT */
82 OMAP_DISPLAY_TYPE_VENC, 125 OMAP_DISPLAY_TYPE_VENC,
@@ -87,7 +130,7 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
87 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, 130 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
88 131
89 /* OMAP_DSS_CHANNEL_DIGIT */ 132 /* OMAP_DSS_CHANNEL_DIGIT */
90 OMAP_DISPLAY_TYPE_VENC, 133 OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
91 134
92 /* OMAP_DSS_CHANNEL_LCD2 */ 135 /* OMAP_DSS_CHANNEL_LCD2 */
93 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 136 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
@@ -134,6 +177,54 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
134 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, 177 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
135}; 178};
136 179
180static const char * const omap2_dss_clk_source_names[] = {
181 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
182 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
183 [DSS_CLK_SRC_FCK] = "DSS_FCLK1",
184};
185
186static const char * const omap3_dss_clk_source_names[] = {
187 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
188 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
189 [DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
190};
191
192static const char * const omap4_dss_clk_source_names[] = {
193 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
194 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
195 [DSS_CLK_SRC_FCK] = "DSS_FCLK",
196};
197
198static const struct dss_param_range omap2_dss_param_range[] = {
199 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
200 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
201 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
202 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
203 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
204 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
205 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
206};
207
208static const struct dss_param_range omap3_dss_param_range[] = {
209 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
210 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
211 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
212 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
213 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
214 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
215 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
216};
217
218static const struct dss_param_range omap4_dss_param_range[] = {
219 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
220 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
221 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
222 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
223 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
224 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
225 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
226};
227
137/* OMAP2 DSS Features */ 228/* OMAP2 DSS Features */
138static struct omap_dss_features omap2_dss_features = { 229static struct omap_dss_features omap2_dss_features = {
139 .reg_fields = omap2_dss_reg_fields, 230 .reg_fields = omap2_dss_reg_fields,
@@ -141,12 +232,15 @@ static struct omap_dss_features omap2_dss_features = {
141 232
142 .has_feature = 233 .has_feature =
143 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | 234 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL |
144 FEAT_PCKFREEENABLE | FEAT_FUNCGATED, 235 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
236 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
145 237
146 .num_mgrs = 2, 238 .num_mgrs = 2,
147 .num_ovls = 3, 239 .num_ovls = 3,
148 .supported_displays = omap2_dss_supported_displays, 240 .supported_displays = omap2_dss_supported_displays,
149 .supported_color_modes = omap2_dss_supported_color_modes, 241 .supported_color_modes = omap2_dss_supported_color_modes,
242 .clksrc_names = omap2_dss_clk_source_names,
243 .dss_params = omap2_dss_param_range,
150}; 244};
151 245
152/* OMAP3 DSS Features */ 246/* OMAP3 DSS Features */
@@ -157,12 +251,15 @@ static struct omap_dss_features omap3430_dss_features = {
157 .has_feature = 251 .has_feature =
158 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 252 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
159 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 253 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
160 FEAT_FUNCGATED, 254 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
255 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF,
161 256
162 .num_mgrs = 2, 257 .num_mgrs = 2,
163 .num_ovls = 3, 258 .num_ovls = 3,
164 .supported_displays = omap3_dss_supported_displays, 259 .supported_displays = omap3430_dss_supported_displays,
165 .supported_color_modes = omap3_dss_supported_color_modes, 260 .supported_color_modes = omap3_dss_supported_color_modes,
261 .clksrc_names = omap3_dss_clk_source_names,
262 .dss_params = omap3_dss_param_range,
166}; 263};
167 264
168static struct omap_dss_features omap3630_dss_features = { 265static struct omap_dss_features omap3630_dss_features = {
@@ -172,27 +269,34 @@ static struct omap_dss_features omap3630_dss_features = {
172 .has_feature = 269 .has_feature =
173 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 270 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
174 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 271 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
175 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED, 272 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
273 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
274 FEAT_RESIZECONF,
176 275
177 .num_mgrs = 2, 276 .num_mgrs = 2,
178 .num_ovls = 3, 277 .num_ovls = 3,
179 .supported_displays = omap3_dss_supported_displays, 278 .supported_displays = omap3630_dss_supported_displays,
180 .supported_color_modes = omap3_dss_supported_color_modes, 279 .supported_color_modes = omap3_dss_supported_color_modes,
280 .clksrc_names = omap3_dss_clk_source_names,
281 .dss_params = omap3_dss_param_range,
181}; 282};
182 283
183/* OMAP4 DSS Features */ 284/* OMAP4 DSS Features */
184static struct omap_dss_features omap4_dss_features = { 285static struct omap_dss_features omap4_dss_features = {
185 .reg_fields = omap3_dss_reg_fields, 286 .reg_fields = omap4_dss_reg_fields,
186 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 287 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
187 288
188 .has_feature = 289 .has_feature =
189 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 290 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
190 FEAT_MGR_LCD2, 291 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
292 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
191 293
192 .num_mgrs = 3, 294 .num_mgrs = 3,
193 .num_ovls = 3, 295 .num_ovls = 3,
194 .supported_displays = omap4_dss_supported_displays, 296 .supported_displays = omap4_dss_supported_displays,
195 .supported_color_modes = omap3_dss_supported_color_modes, 297 .supported_color_modes = omap3_dss_supported_color_modes,
298 .clksrc_names = omap4_dss_clk_source_names,
299 .dss_params = omap4_dss_param_range,
196}; 300};
197 301
198/* Functions returning values related to a DSS feature */ 302/* Functions returning values related to a DSS feature */
@@ -206,6 +310,16 @@ int dss_feat_get_num_ovls(void)
206 return omap_current_dss_features->num_ovls; 310 return omap_current_dss_features->num_ovls;
207} 311}
208 312
313unsigned long dss_feat_get_param_min(enum dss_range_param param)
314{
315 return omap_current_dss_features->dss_params[param].min;
316}
317
318unsigned long dss_feat_get_param_max(enum dss_range_param param)
319{
320 return omap_current_dss_features->dss_params[param].max;
321}
322
209enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) 323enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
210{ 324{
211 return omap_current_dss_features->supported_displays[channel]; 325 return omap_current_dss_features->supported_displays[channel];
@@ -223,6 +337,11 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
223 color_mode; 337 color_mode;
224} 338}
225 339
340const char *dss_feat_get_clk_source_name(enum dss_clk_source id)
341{
342 return omap_current_dss_features->clksrc_names[id];
343}
344
226/* DSS has_feature check */ 345/* DSS has_feature check */
227bool dss_has_feature(enum dss_feat_id id) 346bool dss_has_feature(enum dss_feat_id id)
228{ 347{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index b9c70be92588..12e9c4ef0dec 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -22,6 +22,7 @@
22 22
23#define MAX_DSS_MANAGERS 3 23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 24#define MAX_DSS_OVERLAYS 3
25#define MAX_DSS_LCD_MANAGERS 2
25 26
26/* DSS has feature id */ 27/* DSS has feature id */
27enum dss_feat_id { 28enum dss_feat_id {
@@ -33,6 +34,12 @@ enum dss_feat_id {
33 FEAT_PCKFREEENABLE = 1 << 5, 34 FEAT_PCKFREEENABLE = 1 << 5,
34 FEAT_FUNCGATED = 1 << 6, 35 FEAT_FUNCGATED = 1 << 6,
35 FEAT_MGR_LCD2 = 1 << 7, 36 FEAT_MGR_LCD2 = 1 << 7,
37 FEAT_LINEBUFFERSPLIT = 1 << 8,
38 FEAT_ROWREPEATENABLE = 1 << 9,
39 FEAT_RESIZECONF = 1 << 10,
40 /* Independent core clk divider */
41 FEAT_CORE_CLK_DIV = 1 << 11,
42 FEAT_LCD_CLK_SRC = 1 << 12,
36}; 43};
37 44
38/* DSS register field id */ 45/* DSS register field id */
@@ -42,15 +49,35 @@ enum dss_feat_reg_field {
42 FEAT_REG_FIFOHIGHTHRESHOLD, 49 FEAT_REG_FIFOHIGHTHRESHOLD,
43 FEAT_REG_FIFOLOWTHRESHOLD, 50 FEAT_REG_FIFOLOWTHRESHOLD,
44 FEAT_REG_FIFOSIZE, 51 FEAT_REG_FIFOSIZE,
52 FEAT_REG_HORIZONTALACCU,
53 FEAT_REG_VERTICALACCU,
54 FEAT_REG_DISPC_CLK_SWITCH,
55 FEAT_REG_DSIPLL_REGN,
56 FEAT_REG_DSIPLL_REGM,
57 FEAT_REG_DSIPLL_REGM_DISPC,
58 FEAT_REG_DSIPLL_REGM_DSI,
59};
60
61enum dss_range_param {
62 FEAT_PARAM_DSS_FCK,
63 FEAT_PARAM_DSIPLL_REGN,
64 FEAT_PARAM_DSIPLL_REGM,
65 FEAT_PARAM_DSIPLL_REGM_DISPC,
66 FEAT_PARAM_DSIPLL_REGM_DSI,
67 FEAT_PARAM_DSIPLL_FINT,
68 FEAT_PARAM_DSIPLL_LPDIV,
45}; 69};
46 70
47/* DSS Feature Functions */ 71/* DSS Feature Functions */
48int dss_feat_get_num_mgrs(void); 72int dss_feat_get_num_mgrs(void);
49int dss_feat_get_num_ovls(void); 73int dss_feat_get_num_ovls(void);
74unsigned long dss_feat_get_param_min(enum dss_range_param param);
75unsigned long dss_feat_get_param_max(enum dss_range_param param);
50enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 76enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
51enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 77enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
52bool dss_feat_color_mode_supported(enum omap_plane plane, 78bool dss_feat_color_mode_supported(enum omap_plane plane,
53 enum omap_color_mode color_mode); 79 enum omap_color_mode color_mode);
80const char *dss_feat_get_clk_source_name(enum dss_clk_source id);
54 81
55bool dss_has_feature(enum dss_feat_id id); 82bool dss_has_feature(enum dss_feat_id id);
56void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 83void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
new file mode 100644
index 000000000000..0d44f070ef36
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -0,0 +1,1332 @@
1/*
2 * hdmi.c
3 *
4 * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6 * Authors: Yong Zhi
7 * Mythri pk <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#define DSS_SUBSYS_NAME "HDMI"
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/mutex.h>
30#include <linux/delay.h>
31#include <linux/string.h>
32#include <plat/display.h>
33
34#include "dss.h"
35#include "hdmi.h"
36
37static struct {
38 struct mutex lock;
39 struct omap_display_platform_data *pdata;
40 struct platform_device *pdev;
41 void __iomem *base_wp; /* HDMI wrapper */
42 int code;
43 int mode;
44 u8 edid[HDMI_EDID_MAX_LENGTH];
45 u8 edid_set;
46 bool custom_set;
47 struct hdmi_config cfg;
48} hdmi;
49
50/*
51 * Logic for the below structure :
52 * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
53 * There is a correspondence between CEA/VESA timing and code, please
54 * refer to section 6.3 in HDMI 1.3 specification for timing code.
55 *
56 * In the below structure, cea_vesa_timings corresponds to all OMAP4
57 * supported CEA and VESA timing values.code_cea corresponds to the CEA
58 * code, It is used to get the timing from cea_vesa_timing array.Similarly
59 * with code_vesa. Code_index is used for back mapping, that is once EDID
60 * is read from the TV, EDID is parsed to find the timing values and then
61 * map it to corresponding CEA or VESA index.
62 */
63
64static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
65 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
66 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
67 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
68 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
69 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
70 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
71 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
72 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
73 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
74 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
75 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
76 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
77 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
78 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
79 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
80 /* VESA From Here */
81 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
82 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
83 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
84 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
85 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
86 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
87 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
88 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
89 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
90 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
91 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
92 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
93 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
94 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
95 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
96 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
97 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
98 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
99 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
100};
101
102/*
103 * This is a static mapping array which maps the timing values
104 * with corresponding CEA / VESA code
105 */
106static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
107 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
108 /* <--15 CEA 17--> vesa*/
109 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
110 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
111};
112
113/*
114 * This is reverse static mapping which maps the CEA / VESA code
115 * to the corresponding timing values
116 */
117static const int code_cea[39] = {
118 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
119 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
120 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
121 11, 12, 14, -1, -1, 13, 13, 4, 4
122};
123
124static const int code_vesa[85] = {
125 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
126 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
127 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
128 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
129 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
130 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
131 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
132 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
133 -1, 27, 28, -1, 33};
134
135static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
136
137static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
138{
139 __raw_writel(val, hdmi.base_wp + idx.idx);
140}
141
142static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
143{
144 return __raw_readl(hdmi.base_wp + idx.idx);
145}
146
147static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
148 int b2, int b1, u32 val)
149{
150 u32 t = 0;
151 while (val != REG_GET(idx, b2, b1)) {
152 udelay(1);
153 if (t++ > 10000)
154 return !val;
155 }
156 return val;
157}
158
159int hdmi_init_display(struct omap_dss_device *dssdev)
160{
161 DSSDBG("init_display\n");
162
163 return 0;
164}
165
166static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
167 struct hdmi_pll_info *fmt, u16 sd)
168{
169 u32 r;
170
171 /* PLL start always use manual mode */
172 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
173
174 r = hdmi_read_reg(PLLCTRL_CFG1);
175 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
176 r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
177
178 hdmi_write_reg(PLLCTRL_CFG1, r);
179
180 r = hdmi_read_reg(PLLCTRL_CFG2);
181
182 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
183 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
184 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
185
186 if (dcofreq) {
187 /* divider programming for frequency beyond 1000Mhz */
188 REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
189 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
190 } else {
191 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
192 }
193
194 hdmi_write_reg(PLLCTRL_CFG2, r);
195
196 r = hdmi_read_reg(PLLCTRL_CFG4);
197 r = FLD_MOD(r, fmt->regm2, 24, 18);
198 r = FLD_MOD(r, fmt->regmf, 17, 0);
199
200 hdmi_write_reg(PLLCTRL_CFG4, r);
201
202 /* go now */
203 REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
204
205 /* wait for bit change */
206 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
207 DSSERR("PLL GO bit not set\n");
208 return -ETIMEDOUT;
209 }
210
211 /* Wait till the lock bit is set in PLL status */
212 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
213 DSSWARN("cannot lock PLL\n");
214 DSSWARN("CFG1 0x%x\n",
215 hdmi_read_reg(PLLCTRL_CFG1));
216 DSSWARN("CFG2 0x%x\n",
217 hdmi_read_reg(PLLCTRL_CFG2));
218 DSSWARN("CFG4 0x%x\n",
219 hdmi_read_reg(PLLCTRL_CFG4));
220 return -ETIMEDOUT;
221 }
222
223 DSSDBG("PLL locked!\n");
224
225 return 0;
226}
227
228/* PHY_PWR_CMD */
229static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
230{
231 /* Command for power control of HDMI PHY */
232 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
233
234 /* Status of the power control of HDMI PHY */
235 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
236 DSSERR("Failed to set PHY power mode to %d\n", val);
237 return -ETIMEDOUT;
238 }
239
240 return 0;
241}
242
243/* PLL_PWR_CMD */
244static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
245{
246 /* Command for power control of HDMI PLL */
247 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
248
249 /* wait till PHY_PWR_STATUS is set */
250 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
251 DSSERR("Failed to set PHY_PWR_STATUS\n");
252 return -ETIMEDOUT;
253 }
254
255 return 0;
256}
257
258static int hdmi_pll_reset(void)
259{
260 /* SYSRESET controlled by power FSM */
261 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
262
263 /* READ 0x0 reset is in progress */
264 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
265 DSSERR("Failed to sysreset PLL\n");
266 return -ETIMEDOUT;
267 }
268
269 return 0;
270}
271
272static int hdmi_phy_init(void)
273{
274 u16 r = 0;
275
276 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
277 if (r)
278 return r;
279
280 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
281 if (r)
282 return r;
283
284 /*
285 * Read address 0 in order to get the SCP reset done completed
286 * Dummy access performed to make sure reset is done
287 */
288 hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
289
290 /*
291 * Write to phy address 0 to configure the clock
292 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
293 */
294 REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
295
296 /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
297 hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
298
299 /* Setup max LDO voltage */
300 REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
301
302 /* Write to phy address 3 to change the polarity control */
303 REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
304
305 return 0;
306}
307
308static int hdmi_wait_softreset(void)
309{
310 /* reset W1 */
311 REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
312
313 /* wait till SOFTRESET == 0 */
314 if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
315 DSSERR("sysconfig reset failed\n");
316 return -ETIMEDOUT;
317 }
318
319 return 0;
320}
321
322static int hdmi_pll_program(struct hdmi_pll_info *fmt)
323{
324 u16 r = 0;
325 enum hdmi_clk_refsel refsel;
326
327 /* wait for wrapper reset */
328 r = hdmi_wait_softreset();
329 if (r)
330 return r;
331
332 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
333 if (r)
334 return r;
335
336 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
337 if (r)
338 return r;
339
340 r = hdmi_pll_reset();
341 if (r)
342 return r;
343
344 refsel = HDMI_REFSEL_SYSCLK;
345
346 r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
347 if (r)
348 return r;
349
350 return 0;
351}
352
353static void hdmi_phy_off(void)
354{
355 hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
356}
357
358static int hdmi_core_ddc_edid(u8 *pedid, int ext)
359{
360 u32 i, j;
361 char checksum = 0;
362 u32 offset = 0;
363
364 /* Turn on CLK for DDC */
365 REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
366
367 /*
368 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
369 * right shifted values( The behavior is not consistent and seen only
370 * with some TV's)
371 */
372 usleep_range(800, 1000);
373
374 if (!ext) {
375 /* Clk SCL Devices */
376 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
377
378 /* HDMI_CORE_DDC_STATUS_IN_PROG */
379 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
380 4, 4, 0) != 0) {
381 DSSERR("Failed to program DDC\n");
382 return -ETIMEDOUT;
383 }
384
385 /* Clear FIFO */
386 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
387
388 /* HDMI_CORE_DDC_STATUS_IN_PROG */
389 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
390 4, 4, 0) != 0) {
391 DSSERR("Failed to program DDC\n");
392 return -ETIMEDOUT;
393 }
394
395 } else {
396 if (ext % 2 != 0)
397 offset = 0x80;
398 }
399
400 /* Load Segment Address Register */
401 REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
402
403 /* Load Slave Address Register */
404 REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
405
406 /* Load Offset Address Register */
407 REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
408
409 /* Load Byte Count */
410 REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
411 REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
412
413 /* Set DDC_CMD */
414 if (ext)
415 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
416 else
417 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
418
419 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
420 if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
421 DSSWARN("I2C Bus Low?\n");
422 return -EIO;
423 }
424 /* HDMI_CORE_DDC_STATUS_NO_ACK */
425 if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
426 DSSWARN("I2C No Ack\n");
427 return -EIO;
428 }
429
430 i = ext * 128;
431 j = 0;
432 while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
433 (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
434 j < 128) {
435
436 if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
437 /* FIFO not empty */
438 pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
439 j++;
440 }
441 }
442
443 for (j = 0; j < 128; j++)
444 checksum += pedid[j];
445
446 if (checksum != 0) {
447 DSSERR("E-EDID checksum failed!!\n");
448 return -EIO;
449 }
450
451 return 0;
452}
453
454static int read_edid(u8 *pedid, u16 max_length)
455{
456 int r = 0, n = 0, i = 0;
457 int max_ext_blocks = (max_length / 128) - 1;
458
459 r = hdmi_core_ddc_edid(pedid, 0);
460 if (r) {
461 return r;
462 } else {
463 n = pedid[0x7e];
464
465 /*
466 * README: need to comply with max_length set by the caller.
467 * Better implementation should be to allocate necessary
468 * memory to store EDID according to nb_block field found
469 * in first block
470 */
471 if (n > max_ext_blocks)
472 n = max_ext_blocks;
473
474 for (i = 1; i <= n; i++) {
475 r = hdmi_core_ddc_edid(pedid, i);
476 if (r)
477 return r;
478 }
479 }
480 return 0;
481}
482
483static int get_timings_index(void)
484{
485 int code;
486
487 if (hdmi.mode == 0)
488 code = code_vesa[hdmi.code];
489 else
490 code = code_cea[hdmi.code];
491
492 if (code == -1) {
493 /* HDMI code 4 corresponds to 640 * 480 VGA */
494 hdmi.code = 4;
495 /* DVI mode 1 corresponds to HDMI 0 to DVI */
496 hdmi.mode = HDMI_DVI;
497
498 code = code_vesa[hdmi.code];
499 }
500 return code;
501}
502
503static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
504{
505 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
506 int timing_vsync = 0, timing_hsync = 0;
507 struct omap_video_timings temp;
508 struct hdmi_cm cm = {-1};
509 DSSDBG("hdmi_get_code\n");
510
511 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
512 temp = cea_vesa_timings[i].timings;
513 if ((temp.pixel_clock == timing->pixel_clock) &&
514 (temp.x_res == timing->x_res) &&
515 (temp.y_res == timing->y_res)) {
516
517 temp_hsync = temp.hfp + temp.hsw + temp.hbp;
518 timing_hsync = timing->hfp + timing->hsw + timing->hbp;
519 temp_vsync = temp.vfp + temp.vsw + temp.vbp;
520 timing_vsync = timing->vfp + timing->vsw + timing->vbp;
521
522 DSSDBG("temp_hsync = %d , temp_vsync = %d"
523 "timing_hsync = %d, timing_vsync = %d\n",
524 temp_hsync, temp_hsync,
525 timing_hsync, timing_vsync);
526
527 if ((temp_hsync == timing_hsync) &&
528 (temp_vsync == timing_vsync)) {
529 code = i;
530 cm.code = code_index[i];
531 if (code < 14)
532 cm.mode = HDMI_HDMI;
533 else
534 cm.mode = HDMI_DVI;
535 DSSDBG("Hdmi_code = %d mode = %d\n",
536 cm.code, cm.mode);
537 break;
538 }
539 }
540 }
541
542 return cm;
543}
544
545static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
546 struct omap_video_timings *timings)
547{
548 /* X and Y resolution */
549 timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
550 edid[current_descriptor_addrs + 2]);
551 timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
552 edid[current_descriptor_addrs + 5]);
553
554 timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
555 edid[current_descriptor_addrs]);
556
557 timings->pixel_clock = 10 * timings->pixel_clock;
558
559 /* HORIZONTAL FRONT PORCH */
560 timings->hfp = edid[current_descriptor_addrs + 8] |
561 ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
562 /* HORIZONTAL SYNC WIDTH */
563 timings->hsw = edid[current_descriptor_addrs + 9] |
564 ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
565 /* HORIZONTAL BACK PORCH */
566 timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
567 edid[current_descriptor_addrs + 3]) -
568 (timings->hfp + timings->hsw);
569 /* VERTICAL FRONT PORCH */
570 timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
571 ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
572 /* VERTICAL SYNC WIDTH */
573 timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
574 ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
575 /* VERTICAL BACK PORCH */
576 timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
577 edid[current_descriptor_addrs + 6]) -
578 (timings->vfp + timings->vsw);
579
580}
581
582/* Description : This function gets the resolution information from EDID */
583static void get_edid_timing_data(u8 *edid)
584{
585 u8 count;
586 u16 current_descriptor_addrs;
587 struct hdmi_cm cm;
588 struct omap_video_timings edid_timings;
589
590 /* seach block 0, there are 4 DTDs arranged in priority order */
591 for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
592 current_descriptor_addrs =
593 EDID_DESCRIPTOR_BLOCK0_ADDRESS +
594 count * EDID_TIMING_DESCRIPTOR_SIZE;
595 get_horz_vert_timing_info(current_descriptor_addrs,
596 edid, &edid_timings);
597 cm = hdmi_get_code(&edid_timings);
598 DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
599 count, cm.code, cm.mode);
600 if (cm.code == -1) {
601 continue;
602 } else {
603 hdmi.code = cm.code;
604 hdmi.mode = cm.mode;
605 DSSDBG("code = %d , mode = %d\n",
606 hdmi.code, hdmi.mode);
607 return;
608 }
609 }
610 if (edid[0x7e] != 0x00) {
611 for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
612 count++) {
613 current_descriptor_addrs =
614 EDID_DESCRIPTOR_BLOCK1_ADDRESS +
615 count * EDID_TIMING_DESCRIPTOR_SIZE;
616 get_horz_vert_timing_info(current_descriptor_addrs,
617 edid, &edid_timings);
618 cm = hdmi_get_code(&edid_timings);
619 DSSDBG("Block1[%d] value matches code = %d, mode = %d",
620 count, cm.code, cm.mode);
621 if (cm.code == -1) {
622 continue;
623 } else {
624 hdmi.code = cm.code;
625 hdmi.mode = cm.mode;
626 DSSDBG("code = %d , mode = %d\n",
627 hdmi.code, hdmi.mode);
628 return;
629 }
630 }
631 }
632
633 DSSINFO("no valid timing found , falling back to VGA\n");
634 hdmi.code = 4; /* setting default value of 640 480 VGA */
635 hdmi.mode = HDMI_DVI;
636}
637
638static void hdmi_read_edid(struct omap_video_timings *dp)
639{
640 int ret = 0, code;
641
642 memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
643
644 if (!hdmi.edid_set)
645 ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
646
647 if (!ret) {
648 if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
649 /* search for timings of default resolution */
650 get_edid_timing_data(hdmi.edid);
651 hdmi.edid_set = true;
652 }
653 } else {
654 DSSWARN("failed to read E-EDID\n");
655 }
656
657 if (!hdmi.edid_set) {
658 DSSINFO("fallback to VGA\n");
659 hdmi.code = 4; /* setting default value of 640 480 VGA */
660 hdmi.mode = HDMI_DVI;
661 }
662
663 code = get_timings_index();
664
665 *dp = cea_vesa_timings[code].timings;
666}
667
668static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
669 struct hdmi_core_infoframe_avi *avi_cfg,
670 struct hdmi_core_packet_enable_repeat *repeat_cfg)
671{
672 DSSDBG("Enter hdmi_core_init\n");
673
674 /* video core */
675 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
676 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
677 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
678 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
679 video_cfg->hdmi_dvi = HDMI_DVI;
680 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
681
682 /* info frame */
683 avi_cfg->db1_format = 0;
684 avi_cfg->db1_active_info = 0;
685 avi_cfg->db1_bar_info_dv = 0;
686 avi_cfg->db1_scan_info = 0;
687 avi_cfg->db2_colorimetry = 0;
688 avi_cfg->db2_aspect_ratio = 0;
689 avi_cfg->db2_active_fmt_ar = 0;
690 avi_cfg->db3_itc = 0;
691 avi_cfg->db3_ec = 0;
692 avi_cfg->db3_q_range = 0;
693 avi_cfg->db3_nup_scaling = 0;
694 avi_cfg->db4_videocode = 0;
695 avi_cfg->db5_pixel_repeat = 0;
696 avi_cfg->db6_7_line_eoftop = 0 ;
697 avi_cfg->db8_9_line_sofbottom = 0;
698 avi_cfg->db10_11_pixel_eofleft = 0;
699 avi_cfg->db12_13_pixel_sofright = 0;
700
701 /* packet enable and repeat */
702 repeat_cfg->audio_pkt = 0;
703 repeat_cfg->audio_pkt_repeat = 0;
704 repeat_cfg->avi_infoframe = 0;
705 repeat_cfg->avi_infoframe_repeat = 0;
706 repeat_cfg->gen_cntrl_pkt = 0;
707 repeat_cfg->gen_cntrl_pkt_repeat = 0;
708 repeat_cfg->generic_pkt = 0;
709 repeat_cfg->generic_pkt_repeat = 0;
710}
711
712static void hdmi_core_powerdown_disable(void)
713{
714 DSSDBG("Enter hdmi_core_powerdown_disable\n");
715 REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
716}
717
718static void hdmi_core_swreset_release(void)
719{
720 DSSDBG("Enter hdmi_core_swreset_release\n");
721 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
722}
723
724static void hdmi_core_swreset_assert(void)
725{
726 DSSDBG("Enter hdmi_core_swreset_assert\n");
727 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
728}
729
730/* DSS_HDMI_CORE_VIDEO_CONFIG */
731static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
732{
733 u32 r = 0;
734
735 /* sys_ctrl1 default configuration not tunable */
736 r = hdmi_read_reg(HDMI_CORE_CTRL1);
737 r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
738 r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
739 r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
740 r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
741 hdmi_write_reg(HDMI_CORE_CTRL1, r);
742
743 REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
744
745 /* Vid_Mode */
746 r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
747
748 /* dither truncation configuration */
749 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
750 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
751 r = FLD_MOD(r, 1, 5, 5);
752 } else {
753 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
754 r = FLD_MOD(r, 0, 5, 5);
755 }
756 hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
757
758 /* HDMI_Ctrl */
759 r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
760 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
761 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
762 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
763 hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
764
765 /* TMDS_CTRL */
766 REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
767 cfg->tclk_sel_clkmult, 6, 5);
768}
769
770static void hdmi_core_aux_infoframe_avi_config(
771 struct hdmi_core_infoframe_avi info_avi)
772{
773 u32 val;
774 char sum = 0, checksum = 0;
775
776 sum += 0x82 + 0x002 + 0x00D;
777 hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
778 hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
779 hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
780
781 val = (info_avi.db1_format << 5) |
782 (info_avi.db1_active_info << 4) |
783 (info_avi.db1_bar_info_dv << 2) |
784 (info_avi.db1_scan_info);
785 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
786 sum += val;
787
788 val = (info_avi.db2_colorimetry << 6) |
789 (info_avi.db2_aspect_ratio << 4) |
790 (info_avi.db2_active_fmt_ar);
791 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
792 sum += val;
793
794 val = (info_avi.db3_itc << 7) |
795 (info_avi.db3_ec << 4) |
796 (info_avi.db3_q_range << 2) |
797 (info_avi.db3_nup_scaling);
798 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
799 sum += val;
800
801 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
802 sum += info_avi.db4_videocode;
803
804 val = info_avi.db5_pixel_repeat;
805 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
806 sum += val;
807
808 val = info_avi.db6_7_line_eoftop & 0x00FF;
809 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
810 sum += val;
811
812 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
813 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
814 sum += val;
815
816 val = info_avi.db8_9_line_sofbottom & 0x00FF;
817 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
818 sum += val;
819
820 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
821 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
822 sum += val;
823
824 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
825 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
826 sum += val;
827
828 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
829 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
830 sum += val;
831
832 val = info_avi.db12_13_pixel_sofright & 0x00FF;
833 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
834 sum += val;
835
836 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
837 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
838 sum += val;
839
840 checksum = 0x100 - sum;
841 hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
842}
843
844static void hdmi_core_av_packet_config(
845 struct hdmi_core_packet_enable_repeat repeat_cfg)
846{
847 /* enable/repeat the infoframe */
848 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
849 (repeat_cfg.audio_pkt << 5) |
850 (repeat_cfg.audio_pkt_repeat << 4) |
851 (repeat_cfg.avi_infoframe << 1) |
852 (repeat_cfg.avi_infoframe_repeat));
853
854 /* enable/repeat the packet */
855 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
856 (repeat_cfg.gen_cntrl_pkt << 3) |
857 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
858 (repeat_cfg.generic_pkt << 1) |
859 (repeat_cfg.generic_pkt_repeat));
860}
861
862static void hdmi_wp_init(struct omap_video_timings *timings,
863 struct hdmi_video_format *video_fmt,
864 struct hdmi_video_interface *video_int)
865{
866 DSSDBG("Enter hdmi_wp_init\n");
867
868 timings->hbp = 0;
869 timings->hfp = 0;
870 timings->hsw = 0;
871 timings->vbp = 0;
872 timings->vfp = 0;
873 timings->vsw = 0;
874
875 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
876 video_fmt->y_res = 0;
877 video_fmt->x_res = 0;
878
879 video_int->vsp = 0;
880 video_int->hsp = 0;
881
882 video_int->interlacing = 0;
883 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
884
885}
886
887static void hdmi_wp_video_start(bool start)
888{
889 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
890}
891
892static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
893 struct omap_video_timings *timings, struct hdmi_config *param)
894{
895 DSSDBG("Enter hdmi_wp_video_init_format\n");
896
897 video_fmt->y_res = param->timings.timings.y_res;
898 video_fmt->x_res = param->timings.timings.x_res;
899
900 timings->hbp = param->timings.timings.hbp;
901 timings->hfp = param->timings.timings.hfp;
902 timings->hsw = param->timings.timings.hsw;
903 timings->vbp = param->timings.timings.vbp;
904 timings->vfp = param->timings.timings.vfp;
905 timings->vsw = param->timings.timings.vsw;
906}
907
908static void hdmi_wp_video_config_format(
909 struct hdmi_video_format *video_fmt)
910{
911 u32 l = 0;
912
913 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
914
915 l |= FLD_VAL(video_fmt->y_res, 31, 16);
916 l |= FLD_VAL(video_fmt->x_res, 15, 0);
917 hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
918}
919
920static void hdmi_wp_video_config_interface(
921 struct hdmi_video_interface *video_int)
922{
923 u32 r;
924 DSSDBG("Enter hdmi_wp_video_config_interface\n");
925
926 r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
927 r = FLD_MOD(r, video_int->vsp, 7, 7);
928 r = FLD_MOD(r, video_int->hsp, 6, 6);
929 r = FLD_MOD(r, video_int->interlacing, 3, 3);
930 r = FLD_MOD(r, video_int->tm, 1, 0);
931 hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
932}
933
934static void hdmi_wp_video_config_timing(
935 struct omap_video_timings *timings)
936{
937 u32 timing_h = 0;
938 u32 timing_v = 0;
939
940 DSSDBG("Enter hdmi_wp_video_config_timing\n");
941
942 timing_h |= FLD_VAL(timings->hbp, 31, 20);
943 timing_h |= FLD_VAL(timings->hfp, 19, 8);
944 timing_h |= FLD_VAL(timings->hsw, 7, 0);
945 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
946
947 timing_v |= FLD_VAL(timings->vbp, 31, 20);
948 timing_v |= FLD_VAL(timings->vfp, 19, 8);
949 timing_v |= FLD_VAL(timings->vsw, 7, 0);
950 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
951}
952
953static void hdmi_basic_configure(struct hdmi_config *cfg)
954{
955 /* HDMI */
956 struct omap_video_timings video_timing;
957 struct hdmi_video_format video_format;
958 struct hdmi_video_interface video_interface;
959 /* HDMI core */
960 struct hdmi_core_infoframe_avi avi_cfg;
961 struct hdmi_core_video_config v_core_cfg;
962 struct hdmi_core_packet_enable_repeat repeat_cfg;
963
964 hdmi_wp_init(&video_timing, &video_format,
965 &video_interface);
966
967 hdmi_core_init(&v_core_cfg,
968 &avi_cfg,
969 &repeat_cfg);
970
971 hdmi_wp_video_init_format(&video_format,
972 &video_timing, cfg);
973
974 hdmi_wp_video_config_timing(&video_timing);
975
976 /* video config */
977 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
978
979 hdmi_wp_video_config_format(&video_format);
980
981 video_interface.vsp = cfg->timings.vsync_pol;
982 video_interface.hsp = cfg->timings.hsync_pol;
983 video_interface.interlacing = cfg->interlace;
984 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
985
986 hdmi_wp_video_config_interface(&video_interface);
987
988 /*
989 * configure core video part
990 * set software reset in the core
991 */
992 hdmi_core_swreset_assert();
993
994 /* power down off */
995 hdmi_core_powerdown_disable();
996
997 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
998 v_core_cfg.hdmi_dvi = cfg->cm.mode;
999
1000 hdmi_core_video_config(&v_core_cfg);
1001
1002 /* release software reset in the core */
1003 hdmi_core_swreset_release();
1004
1005 /*
1006 * configure packet
1007 * info frame video see doc CEA861-D page 65
1008 */
1009 avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
1010 avi_cfg.db1_active_info =
1011 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
1012 avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
1013 avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
1014 avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
1015 avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
1016 avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
1017 avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
1018 avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
1019 avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
1020 avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
1021 avi_cfg.db4_videocode = cfg->cm.code;
1022 avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
1023 avi_cfg.db6_7_line_eoftop = 0;
1024 avi_cfg.db8_9_line_sofbottom = 0;
1025 avi_cfg.db10_11_pixel_eofleft = 0;
1026 avi_cfg.db12_13_pixel_sofright = 0;
1027
1028 hdmi_core_aux_infoframe_avi_config(avi_cfg);
1029
1030 /* enable/repeat the infoframe */
1031 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
1032 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
1033 /* wakeup */
1034 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
1035 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
1036 hdmi_core_av_packet_config(repeat_cfg);
1037}
1038
1039static void update_hdmi_timings(struct hdmi_config *cfg,
1040 struct omap_video_timings *timings, int code)
1041{
1042 cfg->timings.timings.x_res = timings->x_res;
1043 cfg->timings.timings.y_res = timings->y_res;
1044 cfg->timings.timings.hbp = timings->hbp;
1045 cfg->timings.timings.hfp = timings->hfp;
1046 cfg->timings.timings.hsw = timings->hsw;
1047 cfg->timings.timings.vbp = timings->vbp;
1048 cfg->timings.timings.vfp = timings->vfp;
1049 cfg->timings.timings.vsw = timings->vsw;
1050 cfg->timings.timings.pixel_clock = timings->pixel_clock;
1051 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
1052 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
1053}
1054
1055static void hdmi_compute_pll(unsigned long clkin, int phy,
1056 int n, struct hdmi_pll_info *pi)
1057{
1058 unsigned long refclk;
1059 u32 mf;
1060
1061 /*
1062 * Input clock is predivided by N + 1
1063 * out put of which is reference clk
1064 */
1065 refclk = clkin / (n + 1);
1066 pi->regn = n;
1067
1068 /*
1069 * multiplier is pixel_clk/ref_clk
1070 * Multiplying by 100 to avoid fractional part removal
1071 */
1072 pi->regm = (phy * 100/(refclk))/100;
1073 pi->regm2 = 1;
1074
1075 /*
1076 * fractional multiplier is remainder of the difference between
1077 * multiplier and actual phy(required pixel clock thus should be
1078 * multiplied by 2^18(262144) divided by the reference clock
1079 */
1080 mf = (phy - pi->regm * refclk) * 262144;
1081 pi->regmf = mf/(refclk);
1082
1083 /*
1084 * Dcofreq should be set to 1 if required pixel clock
1085 * is greater than 1000MHz
1086 */
1087 pi->dcofreq = phy > 1000 * 100;
1088 pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
1089
1090 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1091 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
1092}
1093
1094static void hdmi_enable_clocks(int enable)
1095{
1096 if (enable)
1097 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
1098 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1099 else
1100 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
1101 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1102}
1103
1104static int hdmi_power_on(struct omap_dss_device *dssdev)
1105{
1106 int r, code = 0;
1107 struct hdmi_pll_info pll_data;
1108 struct omap_video_timings *p;
1109 int clkin, n, phy;
1110
1111 hdmi_enable_clocks(1);
1112
1113 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1114
1115 p = &dssdev->panel.timings;
1116
1117 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
1118 dssdev->panel.timings.x_res,
1119 dssdev->panel.timings.y_res);
1120
1121 if (!hdmi.custom_set) {
1122 DSSDBG("Read EDID as no EDID is not set on poweron\n");
1123 hdmi_read_edid(p);
1124 }
1125 code = get_timings_index();
1126 dssdev->panel.timings = cea_vesa_timings[code].timings;
1127 update_hdmi_timings(&hdmi.cfg, p, code);
1128
1129 clkin = 3840; /* 38.4 MHz */
1130 n = 15; /* this is a constant for our math */
1131 phy = p->pixel_clock;
1132
1133 hdmi_compute_pll(clkin, phy, n, &pll_data);
1134
1135 hdmi_wp_video_start(0);
1136
1137 /* config the PLL and PHY first */
1138 r = hdmi_pll_program(&pll_data);
1139 if (r) {
1140 DSSDBG("Failed to lock PLL\n");
1141 goto err;
1142 }
1143
1144 r = hdmi_phy_init();
1145 if (r) {
1146 DSSDBG("Failed to start PHY\n");
1147 goto err;
1148 }
1149
1150 hdmi.cfg.cm.mode = hdmi.mode;
1151 hdmi.cfg.cm.code = hdmi.code;
1152 hdmi_basic_configure(&hdmi.cfg);
1153
1154 /* Make selection of HDMI in DSS */
1155 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
1156
1157 /* Select the dispc clock source as PRCM clock, to ensure that it is not
1158 * DSI PLL source as the clock selected by DSI PLL might not be
1159 * sufficient for the resolution selected / that can be changed
1160 * dynamically by user. This can be moved to single location , say
1161 * Boardfile.
1162 */
1163 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
1164
1165 /* bypass TV gamma table */
1166 dispc_enable_gamma_table(0);
1167
1168 /* tv size */
1169 dispc_set_digit_size(dssdev->panel.timings.x_res,
1170 dssdev->panel.timings.y_res);
1171
1172 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
1173
1174 hdmi_wp_video_start(1);
1175
1176 return 0;
1177err:
1178 hdmi_enable_clocks(0);
1179 return -EIO;
1180}
1181
1182static void hdmi_power_off(struct omap_dss_device *dssdev)
1183{
1184 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1185
1186 hdmi_wp_video_start(0);
1187 hdmi_phy_off();
1188 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
1189 hdmi_enable_clocks(0);
1190
1191 hdmi.edid_set = 0;
1192}
1193
1194int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
1195 struct omap_video_timings *timings)
1196{
1197 struct hdmi_cm cm;
1198
1199 cm = hdmi_get_code(timings);
1200 if (cm.code == -1) {
1201 DSSERR("Invalid timing entered\n");
1202 return -EINVAL;
1203 }
1204
1205 return 0;
1206
1207}
1208
1209void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
1210{
1211 struct hdmi_cm cm;
1212
1213 hdmi.custom_set = 1;
1214 cm = hdmi_get_code(&dssdev->panel.timings);
1215 hdmi.code = cm.code;
1216 hdmi.mode = cm.mode;
1217 omapdss_hdmi_display_enable(dssdev);
1218 hdmi.custom_set = 0;
1219}
1220
1221int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
1222{
1223 int r = 0;
1224
1225 DSSDBG("ENTER hdmi_display_enable\n");
1226
1227 mutex_lock(&hdmi.lock);
1228
1229 r = omap_dss_start_device(dssdev);
1230 if (r) {
1231 DSSERR("failed to start device\n");
1232 goto err0;
1233 }
1234
1235 if (dssdev->platform_enable) {
1236 r = dssdev->platform_enable(dssdev);
1237 if (r) {
1238 DSSERR("failed to enable GPIO's\n");
1239 goto err1;
1240 }
1241 }
1242
1243 r = hdmi_power_on(dssdev);
1244 if (r) {
1245 DSSERR("failed to power on device\n");
1246 goto err2;
1247 }
1248
1249 mutex_unlock(&hdmi.lock);
1250 return 0;
1251
1252err2:
1253 if (dssdev->platform_disable)
1254 dssdev->platform_disable(dssdev);
1255err1:
1256 omap_dss_stop_device(dssdev);
1257err0:
1258 mutex_unlock(&hdmi.lock);
1259 return r;
1260}
1261
1262void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1263{
1264 DSSDBG("Enter hdmi_display_disable\n");
1265
1266 mutex_lock(&hdmi.lock);
1267
1268 hdmi_power_off(dssdev);
1269
1270 if (dssdev->platform_disable)
1271 dssdev->platform_disable(dssdev);
1272
1273 omap_dss_stop_device(dssdev);
1274
1275 mutex_unlock(&hdmi.lock);
1276}
1277
1278/* HDMI HW IP initialisation */
1279static int omapdss_hdmihw_probe(struct platform_device *pdev)
1280{
1281 struct resource *hdmi_mem;
1282
1283 hdmi.pdata = pdev->dev.platform_data;
1284 hdmi.pdev = pdev;
1285
1286 mutex_init(&hdmi.lock);
1287
1288 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1289 if (!hdmi_mem) {
1290 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1291 return -EINVAL;
1292 }
1293
1294 /* Base address taken from platform */
1295 hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
1296 if (!hdmi.base_wp) {
1297 DSSERR("can't ioremap WP\n");
1298 return -ENOMEM;
1299 }
1300
1301 hdmi_panel_init();
1302
1303 return 0;
1304}
1305
1306static int omapdss_hdmihw_remove(struct platform_device *pdev)
1307{
1308 hdmi_panel_exit();
1309
1310 iounmap(hdmi.base_wp);
1311
1312 return 0;
1313}
1314
1315static struct platform_driver omapdss_hdmihw_driver = {
1316 .probe = omapdss_hdmihw_probe,
1317 .remove = omapdss_hdmihw_remove,
1318 .driver = {
1319 .name = "omapdss_hdmi",
1320 .owner = THIS_MODULE,
1321 },
1322};
1323
1324int hdmi_init_platform_driver(void)
1325{
1326 return platform_driver_register(&omapdss_hdmihw_driver);
1327}
1328
1329void hdmi_uninit_platform_driver(void)
1330{
1331 return platform_driver_unregister(&omapdss_hdmihw_driver);
1332}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
new file mode 100644
index 000000000000..9887ab96da3c
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -0,0 +1,415 @@
1/*
2 * hdmi.h
3 *
4 * HDMI driver definition for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef _OMAP4_DSS_HDMI_H_
22#define _OMAP4_DSS_HDMI_H_
23
24#include <linux/string.h>
25#include <plat/display.h>
26
27#define HDMI_WP 0x0
28#define HDMI_CORE_SYS 0x400
29#define HDMI_CORE_AV 0x900
30#define HDMI_PLLCTRL 0x200
31#define HDMI_PHY 0x300
32
33struct hdmi_reg { u16 idx; };
34
35#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
36
37/* HDMI Wrapper */
38#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
39
40#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
41#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
42#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
43#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
44#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
45#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
46#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
47#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
51
52/* HDMI IP Core System */
53#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
54
55#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
56#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
57#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
58#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
59#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
60#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
61#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
62#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
63#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
64#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
65#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
66#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
67#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
68#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
69#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
70#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
71#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
72#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
73#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
74#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
75#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
76#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
77#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
78#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
79#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
80#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
81#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
82
83/* HDMI DDC E-DID */
84#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
85#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
86#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
87#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
88#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
89#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
90#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
91#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
92
93/* HDMI IP Core Audio Video */
94#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
95
96#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
97#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
98#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
99#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
100#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
101#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
102#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
103#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
104#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
105#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
106#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
107#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
108#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
109#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
110#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
111#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
112#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
113#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
114#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
115#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
116#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
117#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
118#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
119#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
120#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
121#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
122#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
123#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
124#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
125#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
126#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
127#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
128#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
129#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
130#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
131#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
132#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
133#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
134#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
135#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
136#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
137#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
138#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
139#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
140#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
141#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
142#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
143#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
144#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
145#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
146#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
147#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
148#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
149#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
150#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
151#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
152#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
153#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
154#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
155#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
156#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
157#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
158#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
159#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
160#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
161#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
162#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
163#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
164#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
165#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
166
167/* PLL */
168#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
169
170#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
171#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
172#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
173#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
174#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
175#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
176#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
177
178/* HDMI PHY */
179#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
180
181#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
182#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
183#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
184#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
185
186/* HDMI EDID Length */
187#define HDMI_EDID_MAX_LENGTH 256
188#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
189#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
190#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
191#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
192#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
193
194#define OMAP_HDMI_TIMINGS_NB 34
195
196#define REG_FLD_MOD(idx, val, start, end) \
197 hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
198#define REG_GET(idx, start, end) \
199 FLD_GET(hdmi_read_reg(idx), start, end)
200
201/* HDMI timing structure */
202struct hdmi_timings {
203 struct omap_video_timings timings;
204 int vsync_pol;
205 int hsync_pol;
206};
207
208enum hdmi_phy_pwr {
209 HDMI_PHYPWRCMD_OFF = 0,
210 HDMI_PHYPWRCMD_LDOON = 1,
211 HDMI_PHYPWRCMD_TXON = 2
212};
213
214enum hdmi_pll_pwr {
215 HDMI_PLLPWRCMD_ALLOFF = 0,
216 HDMI_PLLPWRCMD_PLLONLY = 1,
217 HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
218 HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
219};
220
221enum hdmi_clk_refsel {
222 HDMI_REFSEL_PCLK = 0,
223 HDMI_REFSEL_REF1 = 1,
224 HDMI_REFSEL_REF2 = 2,
225 HDMI_REFSEL_SYSCLK = 3
226};
227
228enum hdmi_core_inputbus_width {
229 HDMI_INPUT_8BIT = 0,
230 HDMI_INPUT_10BIT = 1,
231 HDMI_INPUT_12BIT = 2
232};
233
234enum hdmi_core_dither_trunc {
235 HDMI_OUTPUTTRUNCATION_8BIT = 0,
236 HDMI_OUTPUTTRUNCATION_10BIT = 1,
237 HDMI_OUTPUTTRUNCATION_12BIT = 2,
238 HDMI_OUTPUTDITHER_8BIT = 3,
239 HDMI_OUTPUTDITHER_10BIT = 4,
240 HDMI_OUTPUTDITHER_12BIT = 5
241};
242
243enum hdmi_core_deepcolor_ed {
244 HDMI_DEEPCOLORPACKECTDISABLE = 0,
245 HDMI_DEEPCOLORPACKECTENABLE = 1
246};
247
248enum hdmi_core_packet_mode {
249 HDMI_PACKETMODERESERVEDVALUE = 0,
250 HDMI_PACKETMODE24BITPERPIXEL = 4,
251 HDMI_PACKETMODE30BITPERPIXEL = 5,
252 HDMI_PACKETMODE36BITPERPIXEL = 6,
253 HDMI_PACKETMODE48BITPERPIXEL = 7
254};
255
256enum hdmi_core_hdmi_dvi {
257 HDMI_DVI = 0,
258 HDMI_HDMI = 1
259};
260
261enum hdmi_core_tclkselclkmult {
262 HDMI_FPLL05IDCK = 0,
263 HDMI_FPLL10IDCK = 1,
264 HDMI_FPLL20IDCK = 2,
265 HDMI_FPLL40IDCK = 3
266};
267
268enum hdmi_core_packet_ctrl {
269 HDMI_PACKETENABLE = 1,
270 HDMI_PACKETDISABLE = 0,
271 HDMI_PACKETREPEATON = 1,
272 HDMI_PACKETREPEATOFF = 0
273};
274
275/* INFOFRAME_AVI_ definitions */
276enum hdmi_core_infoframe {
277 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
278 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
279 HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
280 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
281 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
282 HDMI_INFOFRAME_AVI_DB1B_NO = 0,
283 HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
284 HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
285 HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
286 HDMI_INFOFRAME_AVI_DB1S_0 = 0,
287 HDMI_INFOFRAME_AVI_DB1S_1 = 1,
288 HDMI_INFOFRAME_AVI_DB1S_2 = 2,
289 HDMI_INFOFRAME_AVI_DB2C_NO = 0,
290 HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
291 HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
292 HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
293 HDMI_INFOFRAME_AVI_DB2M_NO = 0,
294 HDMI_INFOFRAME_AVI_DB2M_43 = 1,
295 HDMI_INFOFRAME_AVI_DB2M_169 = 2,
296 HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
297 HDMI_INFOFRAME_AVI_DB2R_43 = 9,
298 HDMI_INFOFRAME_AVI_DB2R_169 = 10,
299 HDMI_INFOFRAME_AVI_DB2R_149 = 11,
300 HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
301 HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
302 HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
303 HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
304 HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
305 HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
306 HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
307 HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
308 HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
309 HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
310 HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
311 HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
312 HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
313 HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
314 HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
315 HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
316 HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
317 HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
318 HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
319 HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
320 HDMI_INFOFRAME_AVI_DB5PR_10 = 9
321};
322
323enum hdmi_packing_mode {
324 HDMI_PACK_10b_RGB_YUV444 = 0,
325 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
326 HDMI_PACK_20b_YUV422 = 2,
327 HDMI_PACK_ALREADYPACKED = 7
328};
329
330struct hdmi_core_video_config {
331 enum hdmi_core_inputbus_width ip_bus_width;
332 enum hdmi_core_dither_trunc op_dither_truc;
333 enum hdmi_core_deepcolor_ed deep_color_pkt;
334 enum hdmi_core_packet_mode pkt_mode;
335 enum hdmi_core_hdmi_dvi hdmi_dvi;
336 enum hdmi_core_tclkselclkmult tclk_sel_clkmult;
337};
338
339/*
340 * Refer to section 8.2 in HDMI 1.3 specification for
341 * details about infoframe databytes
342 */
343struct hdmi_core_infoframe_avi {
344 u8 db1_format;
345 /* Y0, Y1 rgb,yCbCr */
346 u8 db1_active_info;
347 /* A0 Active information Present */
348 u8 db1_bar_info_dv;
349 /* B0, B1 Bar info data valid */
350 u8 db1_scan_info;
351 /* S0, S1 scan information */
352 u8 db2_colorimetry;
353 /* C0, C1 colorimetry */
354 u8 db2_aspect_ratio;
355 /* M0, M1 Aspect ratio (4:3, 16:9) */
356 u8 db2_active_fmt_ar;
357 /* R0...R3 Active format aspect ratio */
358 u8 db3_itc;
359 /* ITC IT content. */
360 u8 db3_ec;
361 /* EC0, EC1, EC2 Extended colorimetry */
362 u8 db3_q_range;
363 /* Q1, Q0 Quantization range */
364 u8 db3_nup_scaling;
365 /* SC1, SC0 Non-uniform picture scaling */
366 u8 db4_videocode;
367 /* VIC0..6 Video format identification */
368 u8 db5_pixel_repeat;
369 /* PR0..PR3 Pixel repetition factor */
370 u16 db6_7_line_eoftop;
371 /* Line number end of top bar */
372 u16 db8_9_line_sofbottom;
373 /* Line number start of bottom bar */
374 u16 db10_11_pixel_eofleft;
375 /* Pixel number end of left bar */
376 u16 db12_13_pixel_sofright;
377 /* Pixel number start of right bar */
378};
379
380struct hdmi_core_packet_enable_repeat {
381 u32 audio_pkt;
382 u32 audio_pkt_repeat;
383 u32 avi_infoframe;
384 u32 avi_infoframe_repeat;
385 u32 gen_cntrl_pkt;
386 u32 gen_cntrl_pkt_repeat;
387 u32 generic_pkt;
388 u32 generic_pkt_repeat;
389};
390
391struct hdmi_video_format {
392 enum hdmi_packing_mode packing_mode;
393 u32 y_res; /* Line per panel */
394 u32 x_res; /* pixel per line */
395};
396
397struct hdmi_video_interface {
398 int vsp; /* Vsync polarity */
399 int hsp; /* Hsync polarity */
400 int interlacing;
401 int tm; /* Timing mode */
402};
403
404struct hdmi_cm {
405 int code;
406 int mode;
407};
408
409struct hdmi_config {
410 struct hdmi_timings timings;
411 u16 interlace;
412 struct hdmi_cm cm;
413};
414
415#endif
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
new file mode 100644
index 000000000000..ffb5de94131f
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
@@ -0,0 +1,222 @@
1/*
2 * hdmi_omap4_panel.c
3 *
4 * HDMI library support functions for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 * Authors: Mythri P k <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/mutex.h>
26#include <linux/module.h>
27#include <plat/display.h>
28
29#include "dss.h"
30
31static struct {
32 struct mutex hdmi_lock;
33} hdmi;
34
35
36static int hdmi_panel_probe(struct omap_dss_device *dssdev)
37{
38 DSSDBG("ENTER hdmi_panel_probe\n");
39
40 dssdev->panel.config = OMAP_DSS_LCD_TFT |
41 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
42
43 /*
44 * Initialize the timings to 640 * 480
45 * This is only for framebuffer update not for TV timing setting
46 * Setting TV timing will be done only on enable
47 */
48 dssdev->panel.timings.x_res = 640;
49 dssdev->panel.timings.y_res = 480;
50
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res,
53 dssdev->panel.timings.y_res);
54 return 0;
55}
56
57static void hdmi_panel_remove(struct omap_dss_device *dssdev)
58{
59
60}
61
62static int hdmi_panel_enable(struct omap_dss_device *dssdev)
63{
64 int r = 0;
65 DSSDBG("ENTER hdmi_panel_enable\n");
66
67 mutex_lock(&hdmi.hdmi_lock);
68
69 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
70 r = -EINVAL;
71 goto err;
72 }
73
74 r = omapdss_hdmi_display_enable(dssdev);
75 if (r) {
76 DSSERR("failed to power on\n");
77 goto err;
78 }
79
80 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
81
82err:
83 mutex_unlock(&hdmi.hdmi_lock);
84
85 return r;
86}
87
88static void hdmi_panel_disable(struct omap_dss_device *dssdev)
89{
90 mutex_lock(&hdmi.hdmi_lock);
91
92 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
93 omapdss_hdmi_display_disable(dssdev);
94
95 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
96
97 mutex_unlock(&hdmi.hdmi_lock);
98}
99
100static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
101{
102 int r = 0;
103
104 mutex_lock(&hdmi.hdmi_lock);
105
106 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
107 r = -EINVAL;
108 goto err;
109 }
110
111 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
112
113 omapdss_hdmi_display_disable(dssdev);
114
115err:
116 mutex_unlock(&hdmi.hdmi_lock);
117
118 return r;
119}
120
121static int hdmi_panel_resume(struct omap_dss_device *dssdev)
122{
123 int r = 0;
124
125 mutex_lock(&hdmi.hdmi_lock);
126
127 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
128 r = -EINVAL;
129 goto err;
130 }
131
132 r = omapdss_hdmi_display_enable(dssdev);
133 if (r) {
134 DSSERR("failed to power on\n");
135 goto err;
136 }
137
138 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
139
140err:
141 mutex_unlock(&hdmi.hdmi_lock);
142
143 return r;
144}
145
146static void hdmi_get_timings(struct omap_dss_device *dssdev,
147 struct omap_video_timings *timings)
148{
149 mutex_lock(&hdmi.hdmi_lock);
150
151 *timings = dssdev->panel.timings;
152
153 mutex_unlock(&hdmi.hdmi_lock);
154}
155
156static void hdmi_set_timings(struct omap_dss_device *dssdev,
157 struct omap_video_timings *timings)
158{
159 DSSDBG("hdmi_set_timings\n");
160
161 mutex_lock(&hdmi.hdmi_lock);
162
163 dssdev->panel.timings = *timings;
164
165 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
166 /* turn the hdmi off and on to get new timings to use */
167 omapdss_hdmi_display_disable(dssdev);
168 omapdss_hdmi_display_set_timing(dssdev);
169 }
170
171 mutex_unlock(&hdmi.hdmi_lock);
172}
173
174static int hdmi_check_timings(struct omap_dss_device *dssdev,
175 struct omap_video_timings *timings)
176{
177 int r = 0;
178
179 DSSDBG("hdmi_check_timings\n");
180
181 mutex_lock(&hdmi.hdmi_lock);
182
183 r = omapdss_hdmi_display_check_timing(dssdev, timings);
184 if (r) {
185 DSSERR("Timing cannot be applied\n");
186 goto err;
187 }
188err:
189 mutex_unlock(&hdmi.hdmi_lock);
190 return r;
191}
192
193static struct omap_dss_driver hdmi_driver = {
194 .probe = hdmi_panel_probe,
195 .remove = hdmi_panel_remove,
196 .enable = hdmi_panel_enable,
197 .disable = hdmi_panel_disable,
198 .suspend = hdmi_panel_suspend,
199 .resume = hdmi_panel_resume,
200 .get_timings = hdmi_get_timings,
201 .set_timings = hdmi_set_timings,
202 .check_timings = hdmi_check_timings,
203 .driver = {
204 .name = "hdmi_panel",
205 .owner = THIS_MODULE,
206 },
207};
208
209int hdmi_panel_init(void)
210{
211 mutex_init(&hdmi.hdmi_lock);
212
213 omap_dss_register_driver(&hdmi_driver);
214
215 return 0;
216}
217
218void hdmi_panel_exit(void)
219{
220 omap_dss_unregister_driver(&hdmi_driver);
221
222}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 172d4e697309..bcd37ec86952 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -515,6 +515,8 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
515 515
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD; 517 irq = DISPC_IRQ_EVSYNC_ODD;
518 } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) {
519 irq = DISPC_IRQ_EVSYNC_EVEN;
518 } else { 520 } else {
519 if (mgr->id == OMAP_DSS_CHANNEL_LCD) 521 if (mgr->id == OMAP_DSS_CHANNEL_LCD)
520 irq = DISPC_IRQ_VSYNC; 522 irq = DISPC_IRQ_VSYNC;
@@ -536,7 +538,8 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
536 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 538 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
537 return 0; 539 return 0;
538 540
539 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 541 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
542 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
540 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 543 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
541 } else { 544 } else {
542 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 545 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -613,7 +616,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
613 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 616 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
614 return 0; 617 return 0;
615 618
616 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 619 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
620 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
617 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 621 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
618 } else { 622 } else {
619 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 623 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -1377,6 +1381,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1377 case OMAP_DISPLAY_TYPE_DBI: 1381 case OMAP_DISPLAY_TYPE_DBI:
1378 case OMAP_DISPLAY_TYPE_SDI: 1382 case OMAP_DISPLAY_TYPE_SDI:
1379 case OMAP_DISPLAY_TYPE_VENC: 1383 case OMAP_DISPLAY_TYPE_VENC:
1384 case OMAP_DISPLAY_TYPE_HDMI:
1380 default_get_overlay_fifo_thresholds(ovl->id, size, 1385 default_get_overlay_fifo_thresholds(ovl->id, size,
1381 &oc->burst_size, &oc->fifo_low, 1386 &oc->burst_size, &oc->fifo_low,
1382 &oc->fifo_high); 1387 &oc->fifo_high);
@@ -1394,7 +1399,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1394 } 1399 }
1395 1400
1396 r = 0; 1401 r = 0;
1397 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1402 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1398 if (!dss_cache.irq_enabled) { 1403 if (!dss_cache.irq_enabled) {
1399 u32 mask; 1404 u32 mask;
1400 1405
@@ -1407,7 +1412,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1407 dss_cache.irq_enabled = true; 1412 dss_cache.irq_enabled = true;
1408 } 1413 }
1409 configure_dispc(); 1414 configure_dispc();
1410 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1415 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1411 1416
1412 spin_unlock_irqrestore(&dss_cache.lock, flags); 1417 spin_unlock_irqrestore(&dss_cache.lock, flags);
1413 1418
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 456efef03c20..f1aca6d04011 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -490,7 +490,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
490 490
491 ovl->manager = mgr; 491 ovl->manager = mgr;
492 492
493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
494 /* XXX: on manual update display, in auto update mode, a bug happens 494 /* XXX: on manual update display, in auto update mode, a bug happens
495 * here. When an overlay is first enabled on LCD, then it's disabled, 495 * here. When an overlay is first enabled on LCD, then it's disabled,
496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT 496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
@@ -499,7 +499,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
499 * but I don't understand how or why. */ 499 * but I don't understand how or why. */
500 msleep(40); 500 msleep(40);
501 dispc_set_channel_out(ovl->id, mgr->id); 501 dispc_set_channel_out(ovl->id, mgr->id);
502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
503 503
504 return 0; 504 return 0;
505} 505}
@@ -679,7 +679,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
679 lcd2_mgr->set_device(lcd2_mgr, dssdev); 679 lcd2_mgr->set_device(lcd2_mgr, dssdev);
680 mgr = lcd2_mgr; 680 mgr = lcd2_mgr;
681 } 681 }
682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
683 && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
683 if (!lcd_mgr->device || force) { 684 if (!lcd_mgr->device || force) {
684 if (lcd_mgr->device) 685 if (lcd_mgr->device)
685 lcd_mgr->unset_device(lcd_mgr); 686 lcd_mgr->unset_device(lcd_mgr);
@@ -688,7 +689,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
688 } 689 }
689 } 690 }
690 691
691 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 692 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
693 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
692 if (!tv_mgr->device || force) { 694 if (!tv_mgr->device || force) {
693 if (tv_mgr->device) 695 if (tv_mgr->device)
694 tv_mgr->unset_device(tv_mgr); 696 tv_mgr->unset_device(tv_mgr);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 10a2ffe02882..5ea17f49c611 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
36#include <plat/display.h> 36#include <plat/display.h>
37#include "dss.h" 37#include "dss.h"
38 38
39#define RFBI_BASE 0x48050800
40
41struct rfbi_reg { u16 idx; }; 39struct rfbi_reg { u16 idx; };
42 40
43#define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) 41#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
@@ -100,6 +98,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t);
100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 98static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
101 99
102static struct { 100static struct {
101 struct platform_device *pdev;
103 void __iomem *base; 102 void __iomem *base;
104 103
105 unsigned long l4_khz; 104 unsigned long l4_khz;
@@ -142,9 +141,9 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
142static void rfbi_enable_clocks(bool enable) 141static void rfbi_enable_clocks(bool enable)
143{ 142{
144 if (enable) 143 if (enable)
145 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 144 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
146 else 145 else
147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 146 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
148} 147}
149 148
150void omap_rfbi_write_command(const void *buf, u32 len) 149void omap_rfbi_write_command(const void *buf, u32 len)
@@ -497,7 +496,7 @@ unsigned long rfbi_get_max_tx_rate(void)
497 }; 496 };
498 497
499 l4_rate = rfbi.l4_khz / 1000; 498 l4_rate = rfbi.l4_khz / 1000;
500 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000; 499 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
501 500
502 for (i = 0; i < ARRAY_SIZE(ftab); i++) { 501 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
503 /* Use a window instead of an exact match, to account 502 /* Use a window instead of an exact match, to account
@@ -922,7 +921,7 @@ void rfbi_dump_regs(struct seq_file *s)
922{ 921{
923#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 922#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
924 923
925 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 924 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
926 925
927 DUMPREG(RFBI_REVISION); 926 DUMPREG(RFBI_REVISION);
928 DUMPREG(RFBI_SYSCONFIG); 927 DUMPREG(RFBI_SYSCONFIG);
@@ -953,54 +952,10 @@ void rfbi_dump_regs(struct seq_file *s)
953 DUMPREG(RFBI_VSYNC_WIDTH); 952 DUMPREG(RFBI_VSYNC_WIDTH);
954 DUMPREG(RFBI_HSYNC_WIDTH); 953 DUMPREG(RFBI_HSYNC_WIDTH);
955 954
956 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 955 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
957#undef DUMPREG 956#undef DUMPREG
958} 957}
959 958
960int rfbi_init(void)
961{
962 u32 rev;
963 u32 l;
964
965 spin_lock_init(&rfbi.cmd_lock);
966
967 init_completion(&rfbi.cmd_done);
968 atomic_set(&rfbi.cmd_fifo_full, 0);
969 atomic_set(&rfbi.cmd_pending, 0);
970
971 rfbi.base = ioremap(RFBI_BASE, SZ_256);
972 if (!rfbi.base) {
973 DSSERR("can't ioremap RFBI\n");
974 return -ENOMEM;
975 }
976
977 rfbi_enable_clocks(1);
978
979 msleep(10);
980
981 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
982
983 /* Enable autoidle and smart-idle */
984 l = rfbi_read_reg(RFBI_SYSCONFIG);
985 l |= (1 << 0) | (2 << 3);
986 rfbi_write_reg(RFBI_SYSCONFIG, l);
987
988 rev = rfbi_read_reg(RFBI_REVISION);
989 printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
990 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
991
992 rfbi_enable_clocks(0);
993
994 return 0;
995}
996
997void rfbi_exit(void)
998{
999 DSSDBG("rfbi_exit\n");
1000
1001 iounmap(rfbi.base);
1002}
1003
1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 959int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1005{ 960{
1006 int r; 961 int r;
@@ -1056,3 +1011,74 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
1056 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1011 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1057 return 0; 1012 return 0;
1058} 1013}
1014
1015/* RFBI HW IP initialisation */
1016static int omap_rfbihw_probe(struct platform_device *pdev)
1017{
1018 u32 rev;
1019 u32 l;
1020 struct resource *rfbi_mem;
1021
1022 rfbi.pdev = pdev;
1023
1024 spin_lock_init(&rfbi.cmd_lock);
1025
1026 init_completion(&rfbi.cmd_done);
1027 atomic_set(&rfbi.cmd_fifo_full, 0);
1028 atomic_set(&rfbi.cmd_pending, 0);
1029
1030 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
1031 if (!rfbi_mem) {
1032 DSSERR("can't get IORESOURCE_MEM RFBI\n");
1033 return -EINVAL;
1034 }
1035 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
1036 if (!rfbi.base) {
1037 DSSERR("can't ioremap RFBI\n");
1038 return -ENOMEM;
1039 }
1040
1041 rfbi_enable_clocks(1);
1042
1043 msleep(10);
1044
1045 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
1046
1047 /* Enable autoidle and smart-idle */
1048 l = rfbi_read_reg(RFBI_SYSCONFIG);
1049 l |= (1 << 0) | (2 << 3);
1050 rfbi_write_reg(RFBI_SYSCONFIG, l);
1051
1052 rev = rfbi_read_reg(RFBI_REVISION);
1053 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
1054 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1055
1056 rfbi_enable_clocks(0);
1057
1058 return 0;
1059}
1060
1061static int omap_rfbihw_remove(struct platform_device *pdev)
1062{
1063 iounmap(rfbi.base);
1064 return 0;
1065}
1066
1067static struct platform_driver omap_rfbihw_driver = {
1068 .probe = omap_rfbihw_probe,
1069 .remove = omap_rfbihw_remove,
1070 .driver = {
1071 .name = "omapdss_rfbi",
1072 .owner = THIS_MODULE,
1073 },
1074};
1075
1076int rfbi_init_platform_driver(void)
1077{
1078 return platform_driver_register(&omap_rfbihw_driver);
1079}
1080
1081void rfbi_uninit_platform_driver(void)
1082{
1083 return platform_driver_unregister(&omap_rfbihw_driver);
1084}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index b64adf7dfc88..54a53e648180 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -30,7 +30,6 @@
30#include "dss.h" 30#include "dss.h"
31 31
32static struct { 32static struct {
33 bool skip_init;
34 bool update_enabled; 33 bool update_enabled;
35 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
36} sdi; 35} sdi;
@@ -68,9 +67,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
68 if (r) 67 if (r)
69 goto err1; 68 goto err1;
70 69
71 /* In case of skip_init sdi_init has already enabled the clocks */ 70 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
72 if (!sdi.skip_init)
73 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
74 71
75 sdi_basic_init(dssdev); 72 sdi_basic_init(dssdev);
76 73
@@ -80,14 +77,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
80 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 77 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
81 dssdev->panel.acbi, dssdev->panel.acb); 78 dssdev->panel.acbi, dssdev->panel.acb);
82 79
83 if (!sdi.skip_init) { 80 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
84 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 81 &dss_cinfo, &dispc_cinfo);
85 &dss_cinfo, &dispc_cinfo);
86 } else {
87 r = dss_get_clock_div(&dss_cinfo);
88 r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo);
89 }
90
91 if (r) 82 if (r)
92 goto err2; 83 goto err2;
93 84
@@ -116,21 +107,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
116 if (r) 107 if (r)
117 goto err2; 108 goto err2;
118 109
119 if (!sdi.skip_init) { 110 dss_sdi_init(dssdev->phy.sdi.datapairs);
120 dss_sdi_init(dssdev->phy.sdi.datapairs); 111 r = dss_sdi_enable();
121 r = dss_sdi_enable(); 112 if (r)
122 if (r) 113 goto err1;
123 goto err1; 114 mdelay(2);
124 mdelay(2);
125 }
126 115
127 dssdev->manager->enable(dssdev->manager); 116 dssdev->manager->enable(dssdev->manager);
128 117
129 sdi.skip_init = 0;
130
131 return 0; 118 return 0;
132err2: 119err2:
133 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 120 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
134 regulator_disable(sdi.vdds_sdi_reg); 121 regulator_disable(sdi.vdds_sdi_reg);
135err1: 122err1:
136 omap_dss_stop_device(dssdev); 123 omap_dss_stop_device(dssdev);
@@ -145,7 +132,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
145 132
146 dss_sdi_disable(); 133 dss_sdi_disable();
147 134
148 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 135 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
149 136
150 regulator_disable(sdi.vdds_sdi_reg); 137 regulator_disable(sdi.vdds_sdi_reg);
151 138
@@ -157,25 +144,24 @@ int sdi_init_display(struct omap_dss_device *dssdev)
157{ 144{
158 DSSDBG("SDI init\n"); 145 DSSDBG("SDI init\n");
159 146
147 if (sdi.vdds_sdi_reg == NULL) {
148 struct regulator *vdds_sdi;
149
150 vdds_sdi = dss_get_vdds_sdi();
151
152 if (IS_ERR(vdds_sdi)) {
153 DSSERR("can't get VDDS_SDI regulator\n");
154 return PTR_ERR(vdds_sdi);
155 }
156
157 sdi.vdds_sdi_reg = vdds_sdi;
158 }
159
160 return 0; 160 return 0;
161} 161}
162 162
163int sdi_init(bool skip_init) 163int sdi_init(void)
164{ 164{
165 /* we store this for first display enable, then clear it */
166 sdi.skip_init = skip_init;
167
168 sdi.vdds_sdi_reg = dss_get_vdds_sdi();
169 if (IS_ERR(sdi.vdds_sdi_reg)) {
170 DSSERR("can't get VDDS_SDI regulator\n");
171 return PTR_ERR(sdi.vdds_sdi_reg);
172 }
173 /*
174 * Enable clocks already here, otherwise there would be a toggle
175 * of them until sdi_display_enable is called.
176 */
177 if (skip_init)
178 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
179 return 0; 165 return 0;
180} 166}
181 167
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index eff35050e28a..8e35a5bae429 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -39,8 +39,6 @@
39 39
40#include "dss.h" 40#include "dss.h"
41 41
42#define VENC_BASE 0x48050C00
43
44/* Venc registers */ 42/* Venc registers */
45#define VENC_REV_ID 0x00 43#define VENC_REV_ID 0x00
46#define VENC_STATUS 0x04 44#define VENC_STATUS 0x04
@@ -289,6 +287,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
289EXPORT_SYMBOL(omap_dss_ntsc_timings); 287EXPORT_SYMBOL(omap_dss_ntsc_timings);
290 288
291static struct { 289static struct {
290 struct platform_device *pdev;
292 void __iomem *base; 291 void __iomem *base;
293 struct mutex venc_lock; 292 struct mutex venc_lock;
294 u32 wss_data; 293 u32 wss_data;
@@ -381,11 +380,11 @@ static void venc_reset(void)
381static void venc_enable_clocks(int enable) 380static void venc_enable_clocks(int enable)
382{ 381{
383 if (enable) 382 if (enable)
384 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 383 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
385 DSS_CLK_96M); 384 DSS_CLK_VIDFCK);
386 else 385 else
387 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 386 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
388 DSS_CLK_96M); 387 DSS_CLK_VIDFCK);
389} 388}
390 389
391static const struct venc_config *venc_timings_to_config( 390static const struct venc_config *venc_timings_to_config(
@@ -641,50 +640,23 @@ static struct omap_dss_driver venc_driver = {
641}; 640};
642/* driver end */ 641/* driver end */
643 642
644 643int venc_init_display(struct omap_dss_device *dssdev)
645
646int venc_init(struct platform_device *pdev)
647{ 644{
648 u8 rev_id; 645 DSSDBG("init_display\n");
649 646
650 mutex_init(&venc.venc_lock); 647 if (venc.vdda_dac_reg == NULL) {
648 struct regulator *vdda_dac;
651 649
652 venc.wss_data = 0; 650 vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac");
653 651
654 venc.base = ioremap(VENC_BASE, SZ_1K); 652 if (IS_ERR(vdda_dac)) {
655 if (!venc.base) { 653 DSSERR("can't get VDDA_DAC regulator\n");
656 DSSERR("can't ioremap VENC\n"); 654 return PTR_ERR(vdda_dac);
657 return -ENOMEM; 655 }
658 }
659 656
660 venc.vdda_dac_reg = dss_get_vdda_dac(); 657 venc.vdda_dac_reg = vdda_dac;
661 if (IS_ERR(venc.vdda_dac_reg)) {
662 iounmap(venc.base);
663 DSSERR("can't get VDDA_DAC regulator\n");
664 return PTR_ERR(venc.vdda_dac_reg);
665 } 658 }
666 659
667 venc_enable_clocks(1);
668
669 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
670 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
671
672 venc_enable_clocks(0);
673
674 return omap_dss_register_driver(&venc_driver);
675}
676
677void venc_exit(void)
678{
679 omap_dss_unregister_driver(&venc_driver);
680
681 iounmap(venc.base);
682}
683
684int venc_init_display(struct omap_dss_device *dssdev)
685{
686 DSSDBG("init_display\n");
687
688 return 0; 660 return 0;
689} 661}
690 662
@@ -740,3 +712,73 @@ void venc_dump_regs(struct seq_file *s)
740 712
741#undef DUMPREG 713#undef DUMPREG
742} 714}
715
716/* VENC HW IP initialisation */
717static int omap_venchw_probe(struct platform_device *pdev)
718{
719 u8 rev_id;
720 struct resource *venc_mem;
721
722 venc.pdev = pdev;
723
724 mutex_init(&venc.venc_lock);
725
726 venc.wss_data = 0;
727
728 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
729 if (!venc_mem) {
730 DSSERR("can't get IORESOURCE_MEM VENC\n");
731 return -EINVAL;
732 }
733 venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
734 if (!venc.base) {
735 DSSERR("can't ioremap VENC\n");
736 return -ENOMEM;
737 }
738
739 venc_enable_clocks(1);
740
741 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
742 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
743
744 venc_enable_clocks(0);
745
746 return omap_dss_register_driver(&venc_driver);
747}
748
749static int omap_venchw_remove(struct platform_device *pdev)
750{
751 if (venc.vdda_dac_reg != NULL) {
752 regulator_put(venc.vdda_dac_reg);
753 venc.vdda_dac_reg = NULL;
754 }
755 omap_dss_unregister_driver(&venc_driver);
756
757 iounmap(venc.base);
758 return 0;
759}
760
761static struct platform_driver omap_venchw_driver = {
762 .probe = omap_venchw_probe,
763 .remove = omap_venchw_remove,
764 .driver = {
765 .name = "omapdss_venc",
766 .owner = THIS_MODULE,
767 },
768};
769
770int venc_init_platform_driver(void)
771{
772 if (cpu_is_omap44xx())
773 return 0;
774
775 return platform_driver_register(&omap_venchw_driver);
776}
777
778void venc_uninit_platform_driver(void)
779{
780 if (cpu_is_omap44xx())
781 return;
782
783 return platform_driver_unregister(&omap_venchw_driver);
784}
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 65149b22cf37..aa33386c81ff 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -1,5 +1,5 @@
1menuconfig FB_OMAP2 1menuconfig FB_OMAP2
2 tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)" 2 tristate "OMAP2+ frame buffer support (EXPERIMENTAL)"
3 depends on FB && OMAP2_DSS 3 depends on FB && OMAP2_DSS
4 4
5 select OMAP2_VRAM 5 select OMAP2_VRAM
@@ -8,10 +8,10 @@ menuconfig FB_OMAP2
8 select FB_CFB_COPYAREA 8 select FB_CFB_COPYAREA
9 select FB_CFB_IMAGEBLIT 9 select FB_CFB_IMAGEBLIT
10 help 10 help
11 Frame buffer driver for OMAP2/3 based boards. 11 Frame buffer driver for OMAP2+ based boards.
12 12
13config FB_OMAP2_DEBUG_SUPPORT 13config FB_OMAP2_DEBUG_SUPPORT
14 bool "Debug support for OMAP2/3 FB" 14 bool "Debug support for OMAP2+ FB"
15 default y 15 default y
16 depends on FB_OMAP2 16 depends on FB_OMAP2
17 help 17 help
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4fdab8e9c496..505ec6672049 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2090,7 +2090,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2090{ 2090{
2091 int r; 2091 int r;
2092 u8 bpp; 2092 u8 bpp;
2093 struct omap_video_timings timings; 2093 struct omap_video_timings timings, temp_timings;
2094 2094
2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
2096 if (r) 2096 if (r)
@@ -2100,14 +2100,23 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; 2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
2101 ++fbdev->num_bpp_overrides; 2101 ++fbdev->num_bpp_overrides;
2102 2102
2103 if (!display->driver->check_timings || !display->driver->set_timings) 2103 if (display->driver->check_timings) {
2104 return -EINVAL; 2104 r = display->driver->check_timings(display, &timings);
2105 if (r)
2106 return r;
2107 } else {
2108 /* If check_timings is not present compare xres and yres */
2109 if (display->driver->get_timings) {
2110 display->driver->get_timings(display, &temp_timings);
2105 2111
2106 r = display->driver->check_timings(display, &timings); 2112 if (temp_timings.x_res != timings.x_res ||
2107 if (r) 2113 temp_timings.y_res != timings.y_res)
2108 return r; 2114 return -EINVAL;
2115 }
2116 }
2109 2117
2110 display->driver->set_timings(display, &timings); 2118 if (display->driver->set_timings)
2119 display->driver->set_timings(display, &timings);
2111 2120
2112 return 0; 2121 return 0;
2113} 2122}
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 83ce9a04d872..6817d187d46e 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1340,6 +1340,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1340 sfb->bus_clk = clk_get(dev, "lcd"); 1340 sfb->bus_clk = clk_get(dev, "lcd");
1341 if (IS_ERR(sfb->bus_clk)) { 1341 if (IS_ERR(sfb->bus_clk)) {
1342 dev_err(dev, "failed to get bus clock\n"); 1342 dev_err(dev, "failed to get bus clock\n");
1343 ret = PTR_ERR(sfb->bus_clk);
1343 goto err_sfb; 1344 goto err_sfb;
1344 } 1345 }
1345 1346
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 75738a928610..ddedad9cd069 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -64,6 +64,8 @@ static const struct svga_fb_format s3fb_formats[] = {
64 64
65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, 65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
66 35000, 240000, 14318}; 66 35000, 240000, 14318};
67static const struct svga_pll s3_trio3d_pll = {3, 129, 3, 31, 0, 4,
68 230000, 460000, 14318};
67 69
68static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; 70static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
69 71
@@ -72,7 +74,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
72 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", 74 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge",
73 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
74 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P", 76 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P",
75 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X"}; 77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
78 "S3 Trio3D"};
76 79
77#define CHIP_UNKNOWN 0x00 80#define CHIP_UNKNOWN 0x00
78#define CHIP_732_TRIO32 0x01 81#define CHIP_732_TRIO32 0x01
@@ -93,6 +96,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
93#define CHIP_360_TRIO3D_1X 0x10 96#define CHIP_360_TRIO3D_1X 0x10
94#define CHIP_362_TRIO3D_2X 0x11 97#define CHIP_362_TRIO3D_2X 0x11
95#define CHIP_368_TRIO3D_2X 0x12 98#define CHIP_368_TRIO3D_2X 0x12
99#define CHIP_365_TRIO3D 0x13
96 100
97#define CHIP_XXX_TRIO 0x80 101#define CHIP_XXX_TRIO 0x80
98#define CHIP_XXX_TRIO64V2_DXGX 0x81 102#define CHIP_XXX_TRIO64V2_DXGX 0x81
@@ -119,9 +123,11 @@ static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07,
119static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; 123static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END};
120 124
121static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END}; 125static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END};
122static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; 126static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x69, 0, 4}, VGA_REGSET_END};
123static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ 127static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */
124 128
129static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END};
130
125static const struct svga_timing_regs s3_timing_regs = { 131static const struct svga_timing_regs s3_timing_regs = {
126 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs, 132 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs,
127 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs, 133 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs,
@@ -188,12 +194,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
188 } 194 }
189} 195}
190 196
197static void s3fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
198{
199 struct s3fb_info *par = info->par;
200
201 svga_tilecursor(par->state.vgabase, info, cursor);
202}
203
191static struct fb_tile_ops s3fb_tile_ops = { 204static struct fb_tile_ops s3fb_tile_ops = {
192 .fb_settile = svga_settile, 205 .fb_settile = svga_settile,
193 .fb_tilecopy = svga_tilecopy, 206 .fb_tilecopy = svga_tilecopy,
194 .fb_tilefill = svga_tilefill, 207 .fb_tilefill = svga_tilefill,
195 .fb_tileblit = svga_tileblit, 208 .fb_tileblit = svga_tileblit,
196 .fb_tilecursor = svga_tilecursor, 209 .fb_tilecursor = s3fb_tilecursor,
197 .fb_get_tilemax = svga_get_tilemax, 210 .fb_get_tilemax = svga_get_tilemax,
198}; 211};
199 212
@@ -202,7 +215,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = {
202 .fb_tilecopy = svga_tilecopy, 215 .fb_tilecopy = svga_tilecopy,
203 .fb_tilefill = svga_tilefill, 216 .fb_tilefill = svga_tilefill,
204 .fb_tileblit = svga_tileblit, 217 .fb_tileblit = svga_tileblit,
205 .fb_tilecursor = svga_tilecursor, 218 .fb_tilecursor = s3fb_tilecursor,
206 .fb_get_tilemax = svga_get_tilemax, 219 .fb_get_tilemax = svga_get_tilemax,
207}; 220};
208 221
@@ -334,33 +347,34 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
334 u8 regval; 347 u8 regval;
335 int rv; 348 int rv;
336 349
337 rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); 350 rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll,
351 1000000000 / pixclock, &m, &n, &r, info->node);
338 if (rv < 0) { 352 if (rv < 0) {
339 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); 353 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
340 return; 354 return;
341 } 355 }
342 356
343 /* Set VGA misc register */ 357 /* Set VGA misc register */
344 regval = vga_r(NULL, VGA_MIS_R); 358 regval = vga_r(par->state.vgabase, VGA_MIS_R);
345 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 359 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
346 360
347 /* Set S3 clock registers */ 361 /* Set S3 clock registers */
348 if (par->chip == CHIP_360_TRIO3D_1X || 362 if (par->chip == CHIP_360_TRIO3D_1X ||
349 par->chip == CHIP_362_TRIO3D_2X || 363 par->chip == CHIP_362_TRIO3D_2X ||
350 par->chip == CHIP_368_TRIO3D_2X) { 364 par->chip == CHIP_368_TRIO3D_2X) {
351 vga_wseq(NULL, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 365 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
352 vga_wseq(NULL, 0x29, r >> 2); /* remaining highest bit of r */ 366 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */
353 } else 367 } else
354 vga_wseq(NULL, 0x12, (n - 2) | (r << 5)); 368 vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5));
355 vga_wseq(NULL, 0x13, m - 2); 369 vga_wseq(par->state.vgabase, 0x13, m - 2);
356 370
357 udelay(1000); 371 udelay(1000);
358 372
359 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ 373 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */
360 regval = vga_rseq (NULL, 0x15); /* | 0x80; */ 374 regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */
361 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 375 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
362 vga_wseq(NULL, 0x15, regval | (1<<5)); 376 vga_wseq(par->state.vgabase, 0x15, regval | (1<<5));
363 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 377 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
364} 378}
365 379
366 380
@@ -372,7 +386,10 @@ static int s3fb_open(struct fb_info *info, int user)
372 386
373 mutex_lock(&(par->open_lock)); 387 mutex_lock(&(par->open_lock));
374 if (par->ref_count == 0) { 388 if (par->ref_count == 0) {
389 void __iomem *vgabase = par->state.vgabase;
390
375 memset(&(par->state), 0, sizeof(struct vgastate)); 391 memset(&(par->state), 0, sizeof(struct vgastate));
392 par->state.vgabase = vgabase;
376 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 393 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
377 par->state.num_crtc = 0x70; 394 par->state.num_crtc = 0x70;
378 par->state.num_seq = 0x20; 395 par->state.num_seq = 0x20;
@@ -470,6 +487,7 @@ static int s3fb_set_par(struct fb_info *info)
470 struct s3fb_info *par = info->par; 487 struct s3fb_info *par = info->par;
471 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; 488 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes;
472 u32 bpp = info->var.bits_per_pixel; 489 u32 bpp = info->var.bits_per_pixel;
490 u32 htotal, hsstart;
473 491
474 if (bpp != 0) { 492 if (bpp != 0) {
475 info->fix.ypanstep = 1; 493 info->fix.ypanstep = 1;
@@ -504,99 +522,112 @@ static int s3fb_set_par(struct fb_info *info)
504 info->var.activate = FB_ACTIVATE_NOW; 522 info->var.activate = FB_ACTIVATE_NOW;
505 523
506 /* Unlock registers */ 524 /* Unlock registers */
507 vga_wcrt(NULL, 0x38, 0x48); 525 vga_wcrt(par->state.vgabase, 0x38, 0x48);
508 vga_wcrt(NULL, 0x39, 0xA5); 526 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
509 vga_wseq(NULL, 0x08, 0x06); 527 vga_wseq(par->state.vgabase, 0x08, 0x06);
510 svga_wcrt_mask(0x11, 0x00, 0x80); 528 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
511 529
512 /* Blank screen and turn off sync */ 530 /* Blank screen and turn off sync */
513 svga_wseq_mask(0x01, 0x20, 0x20); 531 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
514 svga_wcrt_mask(0x17, 0x00, 0x80); 532 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
515 533
516 /* Set default values */ 534 /* Set default values */
517 svga_set_default_gfx_regs(); 535 svga_set_default_gfx_regs(par->state.vgabase);
518 svga_set_default_atc_regs(); 536 svga_set_default_atc_regs(par->state.vgabase);
519 svga_set_default_seq_regs(); 537 svga_set_default_seq_regs(par->state.vgabase);
520 svga_set_default_crt_regs(); 538 svga_set_default_crt_regs(par->state.vgabase);
521 svga_wcrt_multi(s3_line_compare_regs, 0xFFFFFFFF); 539 svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF);
522 svga_wcrt_multi(s3_start_address_regs, 0); 540 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0);
523 541
524 /* S3 specific initialization */ 542 /* S3 specific initialization */
525 svga_wcrt_mask(0x58, 0x10, 0x10); /* enable linear framebuffer */ 543 svga_wcrt_mask(par->state.vgabase, 0x58, 0x10, 0x10); /* enable linear framebuffer */
526 svga_wcrt_mask(0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */ 544 svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */
527 545
528/* svga_wcrt_mask(0x33, 0x08, 0x08); */ /* DDR ? */ 546/* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */
529/* svga_wcrt_mask(0x43, 0x01, 0x01); */ /* DDR ? */ 547/* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */
530 svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */ 548 svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */
531 svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */ 549 svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */
532 550
533 svga_wcrt_mask(0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ 551 svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */
534 552
535/* svga_wcrt_mask(0x58, 0x03, 0x03); */ 553/* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */
536 554
537/* svga_wcrt_mask(0x53, 0x12, 0x13); */ /* enable MMIO */ 555/* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */
538/* svga_wcrt_mask(0x40, 0x08, 0x08); */ /* enable write buffer */ 556/* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */
539 557
540 558
541 /* Set the offset register */ 559 /* Set the offset register */
542 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 560 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
543 svga_wcrt_multi(s3_offset_regs, offset_value); 561 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);
544 562
545 if (par->chip != CHIP_360_TRIO3D_1X && 563 if (par->chip != CHIP_360_TRIO3D_1X &&
546 par->chip != CHIP_362_TRIO3D_2X && 564 par->chip != CHIP_362_TRIO3D_2X &&
547 par->chip != CHIP_368_TRIO3D_2X) { 565 par->chip != CHIP_368_TRIO3D_2X) {
548 vga_wcrt(NULL, 0x54, 0x18); /* M parameter */ 566 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
549 vga_wcrt(NULL, 0x60, 0xff); /* N parameter */ 567 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */
550 vga_wcrt(NULL, 0x61, 0xff); /* L parameter */ 568 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */
551 vga_wcrt(NULL, 0x62, 0xff); /* L parameter */ 569 vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */
552 } 570 }
553 571
554 vga_wcrt(NULL, 0x3A, 0x35); 572 vga_wcrt(par->state.vgabase, 0x3A, 0x35);
555 svga_wattr(0x33, 0x00); 573 svga_wattr(par->state.vgabase, 0x33, 0x00);
556 574
557 if (info->var.vmode & FB_VMODE_DOUBLE) 575 if (info->var.vmode & FB_VMODE_DOUBLE)
558 svga_wcrt_mask(0x09, 0x80, 0x80); 576 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
559 else 577 else
560 svga_wcrt_mask(0x09, 0x00, 0x80); 578 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
561 579
562 if (info->var.vmode & FB_VMODE_INTERLACED) 580 if (info->var.vmode & FB_VMODE_INTERLACED)
563 svga_wcrt_mask(0x42, 0x20, 0x20); 581 svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20);
564 else 582 else
565 svga_wcrt_mask(0x42, 0x00, 0x20); 583 svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20);
566 584
567 /* Disable hardware graphics cursor */ 585 /* Disable hardware graphics cursor */
568 svga_wcrt_mask(0x45, 0x00, 0x01); 586 svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01);
569 /* Disable Streams engine */ 587 /* Disable Streams engine */
570 svga_wcrt_mask(0x67, 0x00, 0x0C); 588 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C);
571 589
572 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); 590 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix));
573 591
574 /* S3 virge DX hack */ 592 /* S3 virge DX hack */
575 if (par->chip == CHIP_375_VIRGE_DX) { 593 if (par->chip == CHIP_375_VIRGE_DX) {
576 vga_wcrt(NULL, 0x86, 0x80); 594 vga_wcrt(par->state.vgabase, 0x86, 0x80);
577 vga_wcrt(NULL, 0x90, 0x00); 595 vga_wcrt(par->state.vgabase, 0x90, 0x00);
578 } 596 }
579 597
580 /* S3 virge VX hack */ 598 /* S3 virge VX hack */
581 if (par->chip == CHIP_988_VIRGE_VX) { 599 if (par->chip == CHIP_988_VIRGE_VX) {
582 vga_wcrt(NULL, 0x50, 0x00); 600 vga_wcrt(par->state.vgabase, 0x50, 0x00);
583 vga_wcrt(NULL, 0x67, 0x50); 601 vga_wcrt(par->state.vgabase, 0x67, 0x50);
584 602
585 vga_wcrt(NULL, 0x63, (mode <= 2) ? 0x90 : 0x09); 603 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
586 vga_wcrt(NULL, 0x66, 0x90); 604 vga_wcrt(par->state.vgabase, 0x66, 0x90);
587 } 605 }
588 606
589 if (par->chip == CHIP_360_TRIO3D_1X || 607 if (par->chip == CHIP_360_TRIO3D_1X ||
590 par->chip == CHIP_362_TRIO3D_2X || 608 par->chip == CHIP_362_TRIO3D_2X ||
591 par->chip == CHIP_368_TRIO3D_2X) { 609 par->chip == CHIP_368_TRIO3D_2X ||
610 par->chip == CHIP_365_TRIO3D ||
611 par->chip == CHIP_375_VIRGE_DX ||
612 par->chip == CHIP_385_VIRGE_GX) {
592 dbytes = info->var.xres * ((bpp+7)/8); 613 dbytes = info->var.xres * ((bpp+7)/8);
593 vga_wcrt(NULL, 0x91, (dbytes + 7) / 8); 614 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8);
594 vga_wcrt(NULL, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); 615 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
595 616
596 vga_wcrt(NULL, 0x66, 0x81); 617 vga_wcrt(par->state.vgabase, 0x66, 0x81);
597 } 618 }
598 619
599 svga_wcrt_mask(0x31, 0x00, 0x40); 620 if (par->chip == CHIP_356_VIRGE_GX2 ||
621 par->chip == CHIP_357_VIRGE_GX2P ||
622 par->chip == CHIP_359_VIRGE_GX2P ||
623 par->chip == CHIP_360_TRIO3D_1X ||
624 par->chip == CHIP_362_TRIO3D_2X ||
625 par->chip == CHIP_368_TRIO3D_2X)
626 vga_wcrt(par->state.vgabase, 0x34, 0x00);
627 else /* enable Data Transfer Position Control (DTPC) */
628 vga_wcrt(par->state.vgabase, 0x34, 0x10);
629
630 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40);
600 multiplex = 0; 631 multiplex = 0;
601 hmul = 1; 632 hmul = 1;
602 633
@@ -604,51 +635,51 @@ static int s3fb_set_par(struct fb_info *info)
604 switch (mode) { 635 switch (mode) {
605 case 0: 636 case 0:
606 pr_debug("fb%d: text mode\n", info->node); 637 pr_debug("fb%d: text mode\n", info->node);
607 svga_set_textmode_vga_regs(); 638 svga_set_textmode_vga_regs(par->state.vgabase);
608 639
609 /* Set additional registers like in 8-bit mode */ 640 /* Set additional registers like in 8-bit mode */
610 svga_wcrt_mask(0x50, 0x00, 0x30); 641 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
611 svga_wcrt_mask(0x67, 0x00, 0xF0); 642 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
612 643
613 /* Disable enhanced mode */ 644 /* Disable enhanced mode */
614 svga_wcrt_mask(0x3A, 0x00, 0x30); 645 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
615 646
616 if (fasttext) { 647 if (fasttext) {
617 pr_debug("fb%d: high speed text mode set\n", info->node); 648 pr_debug("fb%d: high speed text mode set\n", info->node);
618 svga_wcrt_mask(0x31, 0x40, 0x40); 649 svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40);
619 } 650 }
620 break; 651 break;
621 case 1: 652 case 1:
622 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 653 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
623 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 654 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
624 655
625 /* Set additional registers like in 8-bit mode */ 656 /* Set additional registers like in 8-bit mode */
626 svga_wcrt_mask(0x50, 0x00, 0x30); 657 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
627 svga_wcrt_mask(0x67, 0x00, 0xF0); 658 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
628 659
629 /* disable enhanced mode */ 660 /* disable enhanced mode */
630 svga_wcrt_mask(0x3A, 0x00, 0x30); 661 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
631 break; 662 break;
632 case 2: 663 case 2:
633 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 664 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
634 665
635 /* Set additional registers like in 8-bit mode */ 666 /* Set additional registers like in 8-bit mode */
636 svga_wcrt_mask(0x50, 0x00, 0x30); 667 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
637 svga_wcrt_mask(0x67, 0x00, 0xF0); 668 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
638 669
639 /* disable enhanced mode */ 670 /* disable enhanced mode */
640 svga_wcrt_mask(0x3A, 0x00, 0x30); 671 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
641 break; 672 break;
642 case 3: 673 case 3:
643 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 674 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
644 svga_wcrt_mask(0x50, 0x00, 0x30); 675 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
645 if (info->var.pixclock > 20000 || 676 if (info->var.pixclock > 20000 ||
646 par->chip == CHIP_360_TRIO3D_1X || 677 par->chip == CHIP_360_TRIO3D_1X ||
647 par->chip == CHIP_362_TRIO3D_2X || 678 par->chip == CHIP_362_TRIO3D_2X ||
648 par->chip == CHIP_368_TRIO3D_2X) 679 par->chip == CHIP_368_TRIO3D_2X)
649 svga_wcrt_mask(0x67, 0x00, 0xF0); 680 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
650 else { 681 else {
651 svga_wcrt_mask(0x67, 0x10, 0xF0); 682 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0);
652 multiplex = 1; 683 multiplex = 1;
653 } 684 }
654 break; 685 break;
@@ -656,12 +687,21 @@ static int s3fb_set_par(struct fb_info *info)
656 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 687 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
657 if (par->chip == CHIP_988_VIRGE_VX) { 688 if (par->chip == CHIP_988_VIRGE_VX) {
658 if (info->var.pixclock > 20000) 689 if (info->var.pixclock > 20000)
659 svga_wcrt_mask(0x67, 0x20, 0xF0); 690 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
660 else 691 else
661 svga_wcrt_mask(0x67, 0x30, 0xF0); 692 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
693 } else if (par->chip == CHIP_365_TRIO3D) {
694 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
695 if (info->var.pixclock > 8695) {
696 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
697 hmul = 2;
698 } else {
699 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
700 multiplex = 1;
701 }
662 } else { 702 } else {
663 svga_wcrt_mask(0x50, 0x10, 0x30); 703 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
664 svga_wcrt_mask(0x67, 0x30, 0xF0); 704 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
665 if (par->chip != CHIP_360_TRIO3D_1X && 705 if (par->chip != CHIP_360_TRIO3D_1X &&
666 par->chip != CHIP_362_TRIO3D_2X && 706 par->chip != CHIP_362_TRIO3D_2X &&
667 par->chip != CHIP_368_TRIO3D_2X) 707 par->chip != CHIP_368_TRIO3D_2X)
@@ -672,12 +712,21 @@ static int s3fb_set_par(struct fb_info *info)
672 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 712 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
673 if (par->chip == CHIP_988_VIRGE_VX) { 713 if (par->chip == CHIP_988_VIRGE_VX) {
674 if (info->var.pixclock > 20000) 714 if (info->var.pixclock > 20000)
675 svga_wcrt_mask(0x67, 0x40, 0xF0); 715 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
676 else 716 else
677 svga_wcrt_mask(0x67, 0x50, 0xF0); 717 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
718 } else if (par->chip == CHIP_365_TRIO3D) {
719 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
720 if (info->var.pixclock > 8695) {
721 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
722 hmul = 2;
723 } else {
724 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
725 multiplex = 1;
726 }
678 } else { 727 } else {
679 svga_wcrt_mask(0x50, 0x10, 0x30); 728 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
680 svga_wcrt_mask(0x67, 0x50, 0xF0); 729 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
681 if (par->chip != CHIP_360_TRIO3D_1X && 730 if (par->chip != CHIP_360_TRIO3D_1X &&
682 par->chip != CHIP_362_TRIO3D_2X && 731 par->chip != CHIP_362_TRIO3D_2X &&
683 par->chip != CHIP_368_TRIO3D_2X) 732 par->chip != CHIP_368_TRIO3D_2X)
@@ -687,12 +736,12 @@ static int s3fb_set_par(struct fb_info *info)
687 case 6: 736 case 6:
688 /* VIRGE VX case */ 737 /* VIRGE VX case */
689 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 738 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
690 svga_wcrt_mask(0x67, 0xD0, 0xF0); 739 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
691 break; 740 break;
692 case 7: 741 case 7:
693 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 742 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
694 svga_wcrt_mask(0x50, 0x30, 0x30); 743 svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30);
695 svga_wcrt_mask(0x67, 0xD0, 0xF0); 744 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
696 break; 745 break;
697 default: 746 default:
698 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); 747 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node);
@@ -700,25 +749,30 @@ static int s3fb_set_par(struct fb_info *info)
700 } 749 }
701 750
702 if (par->chip != CHIP_988_VIRGE_VX) { 751 if (par->chip != CHIP_988_VIRGE_VX) {
703 svga_wseq_mask(0x15, multiplex ? 0x10 : 0x00, 0x10); 752 svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10);
704 svga_wseq_mask(0x18, multiplex ? 0x80 : 0x00, 0x80); 753 svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80);
705 } 754 }
706 755
707 s3_set_pixclock(info, info->var.pixclock); 756 s3_set_pixclock(info, info->var.pixclock);
708 svga_set_timings(&s3_timing_regs, &(info->var), hmul, 1, 757 svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1,
709 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 758 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
710 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 759 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
711 hmul, info->node); 760 hmul, info->node);
712 761
713 /* Set interlaced mode start/end register */ 762 /* Set interlaced mode start/end register */
714 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 763 htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
715 value = ((value * hmul) / 8) - 5; 764 htotal = ((htotal * hmul) / 8) - 5;
716 vga_wcrt(NULL, 0x3C, (value + 1) / 2); 765 vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2);
766
767 /* Set Data Transfer Position */
768 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
769 value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
770 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
717 771
718 memset_io(info->screen_base, 0x00, screen_size); 772 memset_io(info->screen_base, 0x00, screen_size);
719 /* Device and screen back on */ 773 /* Device and screen back on */
720 svga_wcrt_mask(0x17, 0x80, 0x80); 774 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
721 svga_wseq_mask(0x01, 0x00, 0x20); 775 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
722 776
723 return 0; 777 return 0;
724} 778}
@@ -788,31 +842,33 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
788 842
789static int s3fb_blank(int blank_mode, struct fb_info *info) 843static int s3fb_blank(int blank_mode, struct fb_info *info)
790{ 844{
845 struct s3fb_info *par = info->par;
846
791 switch (blank_mode) { 847 switch (blank_mode) {
792 case FB_BLANK_UNBLANK: 848 case FB_BLANK_UNBLANK:
793 pr_debug("fb%d: unblank\n", info->node); 849 pr_debug("fb%d: unblank\n", info->node);
794 svga_wcrt_mask(0x56, 0x00, 0x06); 850 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
795 svga_wseq_mask(0x01, 0x00, 0x20); 851 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
796 break; 852 break;
797 case FB_BLANK_NORMAL: 853 case FB_BLANK_NORMAL:
798 pr_debug("fb%d: blank\n", info->node); 854 pr_debug("fb%d: blank\n", info->node);
799 svga_wcrt_mask(0x56, 0x00, 0x06); 855 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
800 svga_wseq_mask(0x01, 0x20, 0x20); 856 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
801 break; 857 break;
802 case FB_BLANK_HSYNC_SUSPEND: 858 case FB_BLANK_HSYNC_SUSPEND:
803 pr_debug("fb%d: hsync\n", info->node); 859 pr_debug("fb%d: hsync\n", info->node);
804 svga_wcrt_mask(0x56, 0x02, 0x06); 860 svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);
805 svga_wseq_mask(0x01, 0x20, 0x20); 861 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
806 break; 862 break;
807 case FB_BLANK_VSYNC_SUSPEND: 863 case FB_BLANK_VSYNC_SUSPEND:
808 pr_debug("fb%d: vsync\n", info->node); 864 pr_debug("fb%d: vsync\n", info->node);
809 svga_wcrt_mask(0x56, 0x04, 0x06); 865 svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);
810 svga_wseq_mask(0x01, 0x20, 0x20); 866 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
811 break; 867 break;
812 case FB_BLANK_POWERDOWN: 868 case FB_BLANK_POWERDOWN:
813 pr_debug("fb%d: sync down\n", info->node); 869 pr_debug("fb%d: sync down\n", info->node);
814 svga_wcrt_mask(0x56, 0x06, 0x06); 870 svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);
815 svga_wseq_mask(0x01, 0x20, 0x20); 871 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
816 break; 872 break;
817 } 873 }
818 874
@@ -822,8 +878,9 @@ static int s3fb_blank(int blank_mode, struct fb_info *info)
822 878
823/* Pan the display */ 879/* Pan the display */
824 880
825static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { 881static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
826 882{
883 struct s3fb_info *par = info->par;
827 unsigned int offset; 884 unsigned int offset;
828 885
829 /* Calculate the offset */ 886 /* Calculate the offset */
@@ -837,7 +894,7 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
837 } 894 }
838 895
839 /* Set the offset */ 896 /* Set the offset */
840 svga_wcrt_multi(s3_start_address_regs, offset); 897 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset);
841 898
842 return 0; 899 return 0;
843} 900}
@@ -863,12 +920,14 @@ static struct fb_ops s3fb_ops = {
863 920
864/* ------------------------------------------------------------------------- */ 921/* ------------------------------------------------------------------------- */
865 922
866static int __devinit s3_identification(int chip) 923static int __devinit s3_identification(struct s3fb_info *par)
867{ 924{
925 int chip = par->chip;
926
868 if (chip == CHIP_XXX_TRIO) { 927 if (chip == CHIP_XXX_TRIO) {
869 u8 cr30 = vga_rcrt(NULL, 0x30); 928 u8 cr30 = vga_rcrt(par->state.vgabase, 0x30);
870 u8 cr2e = vga_rcrt(NULL, 0x2e); 929 u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e);
871 u8 cr2f = vga_rcrt(NULL, 0x2f); 930 u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f);
872 931
873 if ((cr30 == 0xE0) || (cr30 == 0xE1)) { 932 if ((cr30 == 0xE0) || (cr30 == 0xE1)) {
874 if (cr2e == 0x10) 933 if (cr2e == 0x10)
@@ -883,7 +942,7 @@ static int __devinit s3_identification(int chip)
883 } 942 }
884 943
885 if (chip == CHIP_XXX_TRIO64V2_DXGX) { 944 if (chip == CHIP_XXX_TRIO64V2_DXGX) {
886 u8 cr6f = vga_rcrt(NULL, 0x6f); 945 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
887 946
888 if (! (cr6f & 0x01)) 947 if (! (cr6f & 0x01))
889 return CHIP_775_TRIO64V2_DX; 948 return CHIP_775_TRIO64V2_DX;
@@ -892,7 +951,7 @@ static int __devinit s3_identification(int chip)
892 } 951 }
893 952
894 if (chip == CHIP_XXX_VIRGE_DXGX) { 953 if (chip == CHIP_XXX_VIRGE_DXGX) {
895 u8 cr6f = vga_rcrt(NULL, 0x6f); 954 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
896 955
897 if (! (cr6f & 0x01)) 956 if (! (cr6f & 0x01))
898 return CHIP_375_VIRGE_DX; 957 return CHIP_375_VIRGE_DX;
@@ -901,7 +960,7 @@ static int __devinit s3_identification(int chip)
901 } 960 }
902 961
903 if (chip == CHIP_36X_TRIO3D_1X_2X) { 962 if (chip == CHIP_36X_TRIO3D_1X_2X) {
904 switch (vga_rcrt(NULL, 0x2f)) { 963 switch (vga_rcrt(par->state.vgabase, 0x2f)) {
905 case 0x00: 964 case 0x00:
906 return CHIP_360_TRIO3D_1X; 965 return CHIP_360_TRIO3D_1X;
907 case 0x01: 966 case 0x01:
@@ -919,6 +978,8 @@ static int __devinit s3_identification(int chip)
919 978
920static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 979static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
921{ 980{
981 struct pci_bus_region bus_reg;
982 struct resource vga_res;
922 struct fb_info *info; 983 struct fb_info *info;
923 struct s3fb_info *par; 984 struct s3fb_info *par;
924 int rc; 985 int rc;
@@ -968,31 +1029,42 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
968 goto err_iomap; 1029 goto err_iomap;
969 } 1030 }
970 1031
1032 bus_reg.start = 0;
1033 bus_reg.end = 64 * 1024;
1034
1035 vga_res.flags = IORESOURCE_IO;
1036
1037 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1038
1039 par->state.vgabase = (void __iomem *) vga_res.start;
1040
971 /* Unlock regs */ 1041 /* Unlock regs */
972 cr38 = vga_rcrt(NULL, 0x38); 1042 cr38 = vga_rcrt(par->state.vgabase, 0x38);
973 cr39 = vga_rcrt(NULL, 0x39); 1043 cr39 = vga_rcrt(par->state.vgabase, 0x39);
974 vga_wseq(NULL, 0x08, 0x06); 1044 vga_wseq(par->state.vgabase, 0x08, 0x06);
975 vga_wcrt(NULL, 0x38, 0x48); 1045 vga_wcrt(par->state.vgabase, 0x38, 0x48);
976 vga_wcrt(NULL, 0x39, 0xA5); 1046 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
977 1047
978 /* Identify chip type */ 1048 /* Identify chip type */
979 par->chip = id->driver_data & CHIP_MASK; 1049 par->chip = id->driver_data & CHIP_MASK;
980 par->rev = vga_rcrt(NULL, 0x2f); 1050 par->rev = vga_rcrt(par->state.vgabase, 0x2f);
981 if (par->chip & CHIP_UNDECIDED_FLAG) 1051 if (par->chip & CHIP_UNDECIDED_FLAG)
982 par->chip = s3_identification(par->chip); 1052 par->chip = s3_identification(par);
983 1053
984 /* Find how many physical memory there is on card */ 1054 /* Find how many physical memory there is on card */
985 /* 0x36 register is accessible even if other registers are locked */ 1055 /* 0x36 register is accessible even if other registers are locked */
986 regval = vga_rcrt(NULL, 0x36); 1056 regval = vga_rcrt(par->state.vgabase, 0x36);
987 if (par->chip == CHIP_360_TRIO3D_1X || 1057 if (par->chip == CHIP_360_TRIO3D_1X ||
988 par->chip == CHIP_362_TRIO3D_2X || 1058 par->chip == CHIP_362_TRIO3D_2X ||
989 par->chip == CHIP_368_TRIO3D_2X) { 1059 par->chip == CHIP_368_TRIO3D_2X ||
1060 par->chip == CHIP_365_TRIO3D) {
990 switch ((regval & 0xE0) >> 5) { 1061 switch ((regval & 0xE0) >> 5) {
991 case 0: /* 8MB -- only 4MB usable for display */ 1062 case 0: /* 8MB -- only 4MB usable for display */
992 case 1: /* 4MB with 32-bit bus */ 1063 case 1: /* 4MB with 32-bit bus */
993 case 2: /* 4MB */ 1064 case 2: /* 4MB */
994 info->screen_size = 4 << 20; 1065 info->screen_size = 4 << 20;
995 break; 1066 break;
1067 case 4: /* 2MB on 365 Trio3D */
996 case 6: /* 2MB */ 1068 case 6: /* 2MB */
997 info->screen_size = 2 << 20; 1069 info->screen_size = 2 << 20;
998 break; 1070 break;
@@ -1002,13 +1074,13 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1002 info->fix.smem_len = info->screen_size; 1074 info->fix.smem_len = info->screen_size;
1003 1075
1004 /* Find MCLK frequency */ 1076 /* Find MCLK frequency */
1005 regval = vga_rseq(NULL, 0x10); 1077 regval = vga_rseq(par->state.vgabase, 0x10);
1006 par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); 1078 par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2);
1007 par->mclk_freq = par->mclk_freq >> (regval >> 5); 1079 par->mclk_freq = par->mclk_freq >> (regval >> 5);
1008 1080
1009 /* Restore locks */ 1081 /* Restore locks */
1010 vga_wcrt(NULL, 0x38, cr38); 1082 vga_wcrt(par->state.vgabase, 0x38, cr38);
1011 vga_wcrt(NULL, 0x39, cr39); 1083 vga_wcrt(par->state.vgabase, 0x39, cr39);
1012 1084
1013 strcpy(info->fix.id, s3_names [par->chip]); 1085 strcpy(info->fix.id, s3_names [par->chip]);
1014 info->fix.mmio_start = 0; 1086 info->fix.mmio_start = 0;
@@ -1027,6 +1099,14 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1027 goto err_find_mode; 1099 goto err_find_mode;
1028 } 1100 }
1029 1101
1102 /* maximize virtual vertical size for fast scrolling */
1103 info->var.yres_virtual = info->fix.smem_len * 8 /
1104 (info->var.bits_per_pixel * info->var.xres_virtual);
1105 if (info->var.yres_virtual < info->var.yres) {
1106 dev_err(info->device, "virtual vertical size smaller than real\n");
1107 goto err_find_mode;
1108 }
1109
1030 rc = fb_alloc_cmap(&info->cmap, 256, 0); 1110 rc = fb_alloc_cmap(&info->cmap, 256, 0);
1031 if (rc < 0) { 1111 if (rc < 0) {
1032 dev_err(info->device, "cannot allocate colormap\n"); 1112 dev_err(info->device, "cannot allocate colormap\n");
@@ -1044,8 +1124,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1044 1124
1045 if (par->chip == CHIP_UNKNOWN) 1125 if (par->chip == CHIP_UNKNOWN)
1046 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", 1126 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n",
1047 info->node, vga_rcrt(NULL, 0x2d), vga_rcrt(NULL, 0x2e), 1127 info->node, vga_rcrt(par->state.vgabase, 0x2d), vga_rcrt(par->state.vgabase, 0x2e),
1048 vga_rcrt(NULL, 0x2f), vga_rcrt(NULL, 0x30)); 1128 vga_rcrt(par->state.vgabase, 0x2f), vga_rcrt(par->state.vgabase, 0x30));
1049 1129
1050 /* Record a reference to the driver data */ 1130 /* Record a reference to the driver data */
1051 pci_set_drvdata(dev, info); 1131 pci_set_drvdata(dev, info);
@@ -1192,6 +1272,7 @@ static struct pci_device_id s3_devices[] __devinitdata = {
1192 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, 1272 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P},
1193 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1273 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
1194 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1274 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
1275 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
1195 1276
1196 {0, 0, 0, 0, 0, 0, 0} 1277 {0, 0, 0, 0, 0, 0, 0}
1197}; 1278};
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index bea38fce2470..8fe19582c460 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -459,14 +459,14 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev)
459 } 459 }
460 460
461 par->ioarea = request_mem_region(res->start, 461 par->ioarea = request_mem_region(res->start,
462 (res->end - res->start), pdev->name); 462 resource_size(res), pdev->name);
463 if (!par->ioarea) { 463 if (!par->ioarea) {
464 dev_err(&pdev->dev, "mmio area busy\n"); 464 dev_err(&pdev->dev, "mmio area busy\n");
465 ret = -EBUSY; 465 ret = -EBUSY;
466 goto out_fb; 466 goto out_fb;
467 } 467 }
468 468
469 par->base = ioremap_nocache(res->start, res->end - res->start + 1); 469 par->base = ioremap_nocache(res->start, resource_size(res));
470 if (!par->base) { 470 if (!par->base) {
471 dev_err(&pdev->dev, "cannot remap\n"); 471 dev_err(&pdev->dev, "cannot remap\n");
472 ret = -ENODEV; 472 ret = -ENODEV;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index bf2629f83f40..757665bc500f 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1088,8 +1088,9 @@ static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1088 1088
1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch, 1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
1090 &sh_mobile_lcdc_bl_ops, NULL); 1090 &sh_mobile_lcdc_bl_ops, NULL);
1091 if (!bl) { 1091 if (IS_ERR(bl)) {
1092 dev_err(parent, "unable to register backlight device\n"); 1092 dev_err(parent, "unable to register backlight device: %ld\n",
1093 PTR_ERR(bl));
1093 return NULL; 1094 return NULL;
1094 } 1095 }
1095 1096
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index eac7a01925f3..1987f1b7212f 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -495,6 +495,7 @@ struct sis_video_info {
495 unsigned int refresh_rate; 495 unsigned int refresh_rate;
496 496
497 unsigned int chip; 497 unsigned int chip;
498 unsigned int chip_real_id;
498 u8 revision_id; 499 u8 revision_id;
499 int sisvga_enabled; /* PCI device was enabled */ 500 int sisvga_enabled; /* PCI device was enabled */
500 501
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a660fb..75259845933d 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4563,6 +4563,11 @@ sisfb_post_sis315330(struct pci_dev *pdev)
4563} 4563}
4564#endif 4564#endif
4565 4565
4566static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
4567{
4568 return ivideo->chip_real_id == XGI_21;
4569}
4570
4566static void __devinit 4571static void __devinit
4567sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) 4572sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
4568{ 4573{
@@ -4627,11 +4632,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
4627 return 1; 4632 return 1;
4628} 4633}
4629 4634
4630static void __devinit 4635static int __devinit
4631sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) 4636sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4632{ 4637{
4633 unsigned int buswidth, ranksize, channelab, mapsize; 4638 unsigned int buswidth, ranksize, channelab, mapsize;
4634 int i, j, k, l; 4639 int i, j, k, l, status;
4635 u8 reg, sr14; 4640 u8 reg, sr14;
4636 static const u8 dramsr13[12 * 5] = { 4641 static const u8 dramsr13[12 * 5] = {
4637 0x02, 0x0e, 0x0b, 0x80, 0x5d, 4642 0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4678,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4673 SiS_SetReg(SISSR, 0x13, 0x35); 4678 SiS_SetReg(SISSR, 0x13, 0x35);
4674 SiS_SetReg(SISSR, 0x14, 0x41); 4679 SiS_SetReg(SISSR, 0x14, 0x41);
4675 /* TODO */ 4680 /* TODO */
4676 return; 4681 return -ENOMEM;
4677 } 4682 }
4678 4683
4679 /* Non-interleaving */ 4684 /* Non-interleaving */
@@ -4835,6 +4840,7 @@ bail_out:
4835 4840
4836 j = (ivideo->chip == XGI_20) ? 5 : 9; 4841 j = (ivideo->chip == XGI_20) ? 5 : 9;
4837 k = (ivideo->chip == XGI_20) ? 12 : 4; 4842 k = (ivideo->chip == XGI_20) ? 12 : 4;
4843 status = -EIO;
4838 4844
4839 for(i = 0; i < k; i++) { 4845 for(i = 0; i < k; i++) {
4840 4846
@@ -4868,11 +4874,15 @@ bail_out:
4868 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0)); 4874 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
4869 sisfb_post_xgi_delay(ivideo, 1); 4875 sisfb_post_xgi_delay(ivideo, 1);
4870 4876
4871 if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) 4877 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
4878 status = 0;
4872 break; 4879 break;
4880 }
4873 } 4881 }
4874 4882
4875 iounmap(ivideo->video_vbase); 4883 iounmap(ivideo->video_vbase);
4884
4885 return status;
4876} 4886}
4877 4887
4878static void __devinit 4888static void __devinit
@@ -4931,6 +4941,175 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
4931 sisfb_post_xgi_delay(ivideo, 0x43); 4941 sisfb_post_xgi_delay(ivideo, 0x43);
4932} 4942}
4933 4943
4944static void __devinit
4945sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
4946{
4947 unsigned char *bios = ivideo->bios_abase;
4948 u8 v1;
4949
4950 SiS_SetReg(SISSR, 0x28, 0x64);
4951 SiS_SetReg(SISSR, 0x29, 0x63);
4952 sisfb_post_xgi_delay(ivideo, 15);
4953 SiS_SetReg(SISSR, 0x18, 0x00);
4954 SiS_SetReg(SISSR, 0x19, 0x20);
4955 SiS_SetReg(SISSR, 0x16, 0x00);
4956 SiS_SetReg(SISSR, 0x16, 0x80);
4957 SiS_SetReg(SISSR, 0x18, 0xc5);
4958 SiS_SetReg(SISSR, 0x19, 0x23);
4959 SiS_SetReg(SISSR, 0x16, 0x00);
4960 SiS_SetReg(SISSR, 0x16, 0x80);
4961 sisfb_post_xgi_delay(ivideo, 1);
4962 SiS_SetReg(SISCR, 0x97, 0x11);
4963 sisfb_post_xgi_setclocks(ivideo, regb);
4964 sisfb_post_xgi_delay(ivideo, 0x46);
4965 SiS_SetReg(SISSR, 0x18, 0xc5);
4966 SiS_SetReg(SISSR, 0x19, 0x23);
4967 SiS_SetReg(SISSR, 0x16, 0x00);
4968 SiS_SetReg(SISSR, 0x16, 0x80);
4969 sisfb_post_xgi_delay(ivideo, 1);
4970 SiS_SetReg(SISSR, 0x1b, 0x04);
4971 sisfb_post_xgi_delay(ivideo, 1);
4972 SiS_SetReg(SISSR, 0x1b, 0x00);
4973 sisfb_post_xgi_delay(ivideo, 1);
4974 v1 = 0x31;
4975 if (ivideo->haveXGIROM) {
4976 v1 = bios[0xf0];
4977 }
4978 SiS_SetReg(SISSR, 0x18, v1);
4979 SiS_SetReg(SISSR, 0x19, 0x06);
4980 SiS_SetReg(SISSR, 0x16, 0x04);
4981 SiS_SetReg(SISSR, 0x16, 0x84);
4982 sisfb_post_xgi_delay(ivideo, 1);
4983}
4984
4985static void __devinit
4986sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
4987{
4988 sisfb_post_xgi_setclocks(ivideo, 1);
4989
4990 SiS_SetReg(SISCR, 0x97, 0x11);
4991 sisfb_post_xgi_delay(ivideo, 0x46);
4992
4993 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */
4994 SiS_SetReg(SISSR, 0x19, 0x80);
4995 SiS_SetReg(SISSR, 0x16, 0x05);
4996 SiS_SetReg(SISSR, 0x16, 0x85);
4997
4998 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */
4999 SiS_SetReg(SISSR, 0x19, 0xc0);
5000 SiS_SetReg(SISSR, 0x16, 0x05);
5001 SiS_SetReg(SISSR, 0x16, 0x85);
5002
5003 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */
5004 SiS_SetReg(SISSR, 0x19, 0x40);
5005 SiS_SetReg(SISSR, 0x16, 0x05);
5006 SiS_SetReg(SISSR, 0x16, 0x85);
5007
5008 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5009 SiS_SetReg(SISSR, 0x19, 0x02);
5010 SiS_SetReg(SISSR, 0x16, 0x05);
5011 SiS_SetReg(SISSR, 0x16, 0x85);
5012 sisfb_post_xgi_delay(ivideo, 1);
5013
5014 SiS_SetReg(SISSR, 0x1b, 0x04);
5015 sisfb_post_xgi_delay(ivideo, 1);
5016
5017 SiS_SetReg(SISSR, 0x1b, 0x00);
5018 sisfb_post_xgi_delay(ivideo, 1);
5019
5020 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5021 SiS_SetReg(SISSR, 0x19, 0x00);
5022 SiS_SetReg(SISSR, 0x16, 0x05);
5023 SiS_SetReg(SISSR, 0x16, 0x85);
5024 sisfb_post_xgi_delay(ivideo, 1);
5025}
5026
5027static void __devinit
5028sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
5029{
5030 unsigned char *bios = ivideo->bios_abase;
5031 static const u8 cs158[8] = {
5032 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5033 };
5034 static const u8 cs160[8] = {
5035 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5036 };
5037 static const u8 cs168[8] = {
5038 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5039 };
5040 u8 reg;
5041 u8 v1;
5042 u8 v2;
5043 u8 v3;
5044
5045 SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
5046 SiS_SetReg(SISCR, 0x82, 0x77);
5047 SiS_SetReg(SISCR, 0x86, 0x00);
5048 reg = SiS_GetReg(SISCR, 0x86);
5049 SiS_SetReg(SISCR, 0x86, 0x88);
5050 reg = SiS_GetReg(SISCR, 0x86);
5051 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5052 if (ivideo->haveXGIROM) {
5053 v1 = bios[regb + 0x168];
5054 v2 = bios[regb + 0x160];
5055 v3 = bios[regb + 0x158];
5056 }
5057 SiS_SetReg(SISCR, 0x86, v1);
5058 SiS_SetReg(SISCR, 0x82, 0x77);
5059 SiS_SetReg(SISCR, 0x85, 0x00);
5060 reg = SiS_GetReg(SISCR, 0x85);
5061 SiS_SetReg(SISCR, 0x85, 0x88);
5062 reg = SiS_GetReg(SISCR, 0x85);
5063 SiS_SetReg(SISCR, 0x85, v2);
5064 SiS_SetReg(SISCR, 0x82, v3);
5065 SiS_SetReg(SISCR, 0x98, 0x01);
5066 SiS_SetReg(SISCR, 0x9a, 0x02);
5067 if (sisfb_xgi_is21(ivideo))
5068 sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
5069 else
5070 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
5071}
5072
5073static u8 __devinit
5074sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
5075{
5076 unsigned char *bios = ivideo->bios_abase;
5077 u8 ramtype;
5078 u8 reg;
5079 u8 v1;
5080
5081 ramtype = 0x00; v1 = 0x10;
5082 if (ivideo->haveXGIROM) {
5083 ramtype = bios[0x62];
5084 v1 = bios[0x1d2];
5085 }
5086 if (!(ramtype & 0x80)) {
5087 if (sisfb_xgi_is21(ivideo)) {
5088 SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
5089 SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */
5090 reg = SiS_GetReg(SISCR, 0x48);
5091 SiS_SetRegOR(SISCR, 0xb4, 0x02);
5092 ramtype = reg & 0x01; /* GPIOH */
5093 } else if (ivideo->chip == XGI_20) {
5094 SiS_SetReg(SISCR, 0x97, v1);
5095 reg = SiS_GetReg(SISCR, 0x97);
5096 if (reg & 0x10) {
5097 ramtype = (reg & 0x01) << 1;
5098 }
5099 } else {
5100 reg = SiS_GetReg(SISSR, 0x39);
5101 ramtype = reg & 0x02;
5102 if (!(ramtype)) {
5103 reg = SiS_GetReg(SISSR, 0x3a);
5104 ramtype = (reg >> 1) & 0x01;
5105 }
5106 }
5107 }
5108 ramtype &= 0x07;
5109
5110 return ramtype;
5111}
5112
4934static int __devinit 5113static int __devinit
4935sisfb_post_xgi(struct pci_dev *pdev) 5114sisfb_post_xgi(struct pci_dev *pdev)
4936{ 5115{
@@ -5213,9 +5392,23 @@ sisfb_post_xgi(struct pci_dev *pdev)
5213 SiS_SetReg(SISCR, 0x77, v1); 5392 SiS_SetReg(SISCR, 0x77, v1);
5214 } 5393 }
5215 5394
5216 /* RAM type */ 5395 /* RAM type:
5217 5396 *
5218 regb = 0; /* ! */ 5397 * 0 == DDR1, 1 == DDR2, 2..7 == reserved?
5398 *
5399 * The code seems to written so that regb should equal ramtype,
5400 * however, so far it has been hardcoded to 0. Enable other values only
5401 * on XGI Z9, as it passes the POST, and add a warning for others.
5402 */
5403 ramtype = sisfb_post_xgi_ramtype(ivideo);
5404 if (!sisfb_xgi_is21(ivideo) && ramtype) {
5405 dev_warn(&pdev->dev,
5406 "RAM type something else than expected: %d\n",
5407 ramtype);
5408 regb = 0;
5409 } else {
5410 regb = ramtype;
5411 }
5219 5412
5220 v1 = 0xff; 5413 v1 = 0xff;
5221 if(ivideo->haveXGIROM) { 5414 if(ivideo->haveXGIROM) {
@@ -5367,7 +5560,10 @@ sisfb_post_xgi(struct pci_dev *pdev)
5367 } 5560 }
5368 } 5561 }
5369 5562
5370 SiS_SetReg(SISSR, 0x17, 0x00); 5563 if (regb == 1)
5564 SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */
5565 else
5566 SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */
5371 SiS_SetReg(SISSR, 0x1a, 0x87); 5567 SiS_SetReg(SISSR, 0x1a, 0x87);
5372 5568
5373 if(ivideo->chip == XGI_20) { 5569 if(ivideo->chip == XGI_20) {
@@ -5375,31 +5571,6 @@ sisfb_post_xgi(struct pci_dev *pdev)
5375 SiS_SetReg(SISSR, 0x1c, 0x00); 5571 SiS_SetReg(SISSR, 0x1c, 0x00);
5376 } 5572 }
5377 5573
5378 ramtype = 0x00; v1 = 0x10;
5379 if(ivideo->haveXGIROM) {
5380 ramtype = bios[0x62];
5381 v1 = bios[0x1d2];
5382 }
5383 if(!(ramtype & 0x80)) {
5384 if(ivideo->chip == XGI_20) {
5385 SiS_SetReg(SISCR, 0x97, v1);
5386 reg = SiS_GetReg(SISCR, 0x97);
5387 if(reg & 0x10) {
5388 ramtype = (reg & 0x01) << 1;
5389 }
5390 } else {
5391 reg = SiS_GetReg(SISSR, 0x39);
5392 ramtype = reg & 0x02;
5393 if(!(ramtype)) {
5394 reg = SiS_GetReg(SISSR, 0x3a);
5395 ramtype = (reg >> 1) & 0x01;
5396 }
5397 }
5398 }
5399 ramtype &= 0x07;
5400
5401 regb = 0; /* ! */
5402
5403 switch(ramtype) { 5574 switch(ramtype) {
5404 case 0: 5575 case 0:
5405 sisfb_post_xgi_setclocks(ivideo, regb); 5576 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5485,61 +5656,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5485 SiS_SetReg(SISSR, 0x1b, 0x00); 5656 SiS_SetReg(SISSR, 0x1b, 0x00);
5486 break; 5657 break;
5487 case 1: 5658 case 1:
5488 SiS_SetReg(SISCR, 0x82, 0x77); 5659 sisfb_post_xgi_ddr2(ivideo, regb);
5489 SiS_SetReg(SISCR, 0x86, 0x00);
5490 reg = SiS_GetReg(SISCR, 0x86);
5491 SiS_SetReg(SISCR, 0x86, 0x88);
5492 reg = SiS_GetReg(SISCR, 0x86);
5493 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5494 if(ivideo->haveXGIROM) {
5495 v1 = bios[regb + 0x168];
5496 v2 = bios[regb + 0x160];
5497 v3 = bios[regb + 0x158];
5498 }
5499 SiS_SetReg(SISCR, 0x86, v1);
5500 SiS_SetReg(SISCR, 0x82, 0x77);
5501 SiS_SetReg(SISCR, 0x85, 0x00);
5502 reg = SiS_GetReg(SISCR, 0x85);
5503 SiS_SetReg(SISCR, 0x85, 0x88);
5504 reg = SiS_GetReg(SISCR, 0x85);
5505 SiS_SetReg(SISCR, 0x85, v2);
5506 SiS_SetReg(SISCR, 0x82, v3);
5507 SiS_SetReg(SISCR, 0x98, 0x01);
5508 SiS_SetReg(SISCR, 0x9a, 0x02);
5509
5510 SiS_SetReg(SISSR, 0x28, 0x64);
5511 SiS_SetReg(SISSR, 0x29, 0x63);
5512 sisfb_post_xgi_delay(ivideo, 15);
5513 SiS_SetReg(SISSR, 0x18, 0x00);
5514 SiS_SetReg(SISSR, 0x19, 0x20);
5515 SiS_SetReg(SISSR, 0x16, 0x00);
5516 SiS_SetReg(SISSR, 0x16, 0x80);
5517 SiS_SetReg(SISSR, 0x18, 0xc5);
5518 SiS_SetReg(SISSR, 0x19, 0x23);
5519 SiS_SetReg(SISSR, 0x16, 0x00);
5520 SiS_SetReg(SISSR, 0x16, 0x80);
5521 sisfb_post_xgi_delay(ivideo, 1);
5522 SiS_SetReg(SISCR, 0x97, 0x11);
5523 sisfb_post_xgi_setclocks(ivideo, regb);
5524 sisfb_post_xgi_delay(ivideo, 0x46);
5525 SiS_SetReg(SISSR, 0x18, 0xc5);
5526 SiS_SetReg(SISSR, 0x19, 0x23);
5527 SiS_SetReg(SISSR, 0x16, 0x00);
5528 SiS_SetReg(SISSR, 0x16, 0x80);
5529 sisfb_post_xgi_delay(ivideo, 1);
5530 SiS_SetReg(SISSR, 0x1b, 0x04);
5531 sisfb_post_xgi_delay(ivideo, 1);
5532 SiS_SetReg(SISSR, 0x1b, 0x00);
5533 sisfb_post_xgi_delay(ivideo, 1);
5534 v1 = 0x31;
5535 if(ivideo->haveXGIROM) {
5536 v1 = bios[0xf0];
5537 }
5538 SiS_SetReg(SISSR, 0x18, v1);
5539 SiS_SetReg(SISSR, 0x19, 0x06);
5540 SiS_SetReg(SISSR, 0x16, 0x04);
5541 SiS_SetReg(SISSR, 0x16, 0x84);
5542 sisfb_post_xgi_delay(ivideo, 1);
5543 break; 5660 break;
5544 default: 5661 default:
5545 sisfb_post_xgi_setclocks(ivideo, regb); 5662 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5648,6 +5765,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5648 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]); 5765 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
5649 5766
5650 } else { 5767 } else {
5768 int err;
5651 5769
5652 /* Set default mode, don't clear screen */ 5770 /* Set default mode, don't clear screen */
5653 ivideo->SiS_Pr.SiS_UseOEM = false; 5771 ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5779,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
5661 5779
5662 /* Disable read-cache */ 5780 /* Disable read-cache */
5663 SiS_SetRegAND(SISSR, 0x21, 0xdf); 5781 SiS_SetRegAND(SISSR, 0x21, 0xdf);
5664 sisfb_post_xgi_ramsize(ivideo); 5782 err = sisfb_post_xgi_ramsize(ivideo);
5665 /* Enable read-cache */ 5783 /* Enable read-cache */
5666 SiS_SetRegOR(SISSR, 0x21, 0x20); 5784 SiS_SetRegOR(SISSR, 0x21, 0x20);
5667 5785
5786 if (err) {
5787 dev_err(&pdev->dev,
5788 "%s: RAM size detection failed: %d\n",
5789 __func__, err);
5790 return 0;
5791 }
5668 } 5792 }
5669 5793
5670#if 0 5794#if 0
@@ -5777,6 +5901,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5777#endif 5901#endif
5778 5902
5779 ivideo->chip = chipinfo->chip; 5903 ivideo->chip = chipinfo->chip;
5904 ivideo->chip_real_id = chipinfo->chip;
5780 ivideo->sisvga_engine = chipinfo->vgaengine; 5905 ivideo->sisvga_engine = chipinfo->vgaengine;
5781 ivideo->hwcursor_size = chipinfo->hwcursor_size; 5906 ivideo->hwcursor_size = chipinfo->hwcursor_size;
5782 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable; 5907 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
@@ -6010,6 +6135,18 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
6010 sisfb_detect_custom_timing(ivideo); 6135 sisfb_detect_custom_timing(ivideo);
6011 } 6136 }
6012 6137
6138#ifdef CONFIG_FB_SIS_315
6139 if (ivideo->chip == XGI_20) {
6140 /* Check if our Z7 chip is actually Z9 */
6141 SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */
6142 reg = SiS_GetReg(SISCR, 0x48);
6143 if (reg & 0x02) { /* GPIOG */
6144 ivideo->chip_real_id = XGI_21;
6145 dev_info(&pdev->dev, "Z9 detected\n");
6146 }
6147 }
6148#endif
6149
6013 /* POST card in case this has not been done by the BIOS */ 6150 /* POST card in case this has not been done by the BIOS */
6014 if( (!ivideo->sisvga_enabled) 6151 if( (!ivideo->sisvga_enabled)
6015#if !defined(__i386__) && !defined(__x86_64__) 6152#if !defined(__i386__) && !defined(__x86_64__)
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 12c0dfaf2518..e3f9976cfef0 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -87,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
87 SIS_341, 87 SIS_341,
88 SIS_342, 88 SIS_342,
89 XGI_20 = 75, 89 XGI_20 = 75,
90 XGI_21,
90 XGI_40, 91 XGI_40,
91 MAX_SIS_CHIP 92 MAX_SIS_CHIP
92} SIS_CHIP_TYPE; 93} SIS_CHIP_TYPE;
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index bcb44a594ebc..46d1a64fe80d 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -41,6 +41,26 @@
41#include <linux/sm501.h> 41#include <linux/sm501.h>
42#include <linux/sm501-regs.h> 42#include <linux/sm501-regs.h>
43 43
44#include "edid.h"
45
46static char *fb_mode = "640x480-16@60";
47static unsigned long default_bpp = 16;
48
49static struct fb_videomode __devinitdata sm501_default_mode = {
50 .refresh = 60,
51 .xres = 640,
52 .yres = 480,
53 .pixclock = 20833,
54 .left_margin = 142,
55 .right_margin = 13,
56 .upper_margin = 21,
57 .lower_margin = 1,
58 .hsync_len = 69,
59 .vsync_len = 3,
60 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
61 .vmode = FB_VMODE_NONINTERLACED
62};
63
44#define NR_PALETTE 256 64#define NR_PALETTE 256
45 65
46enum sm501_controller { 66enum sm501_controller {
@@ -77,6 +97,7 @@ struct sm501fb_info {
77 void __iomem *regs2d; /* 2d remapped registers */ 97 void __iomem *regs2d; /* 2d remapped registers */
78 void __iomem *fbmem; /* remapped framebuffer */ 98 void __iomem *fbmem; /* remapped framebuffer */
79 size_t fbmem_len; /* length of remapped region */ 99 size_t fbmem_len; /* length of remapped region */
100 u8 *edid_data;
80}; 101};
81 102
82/* per-framebuffer private data */ 103/* per-framebuffer private data */
@@ -117,7 +138,7 @@ static inline int v_total(struct fb_var_screeninfo *var)
117 138
118static inline void sm501fb_sync_regs(struct sm501fb_info *info) 139static inline void sm501fb_sync_regs(struct sm501fb_info *info)
119{ 140{
120 readl(info->regs); 141 smc501_readl(info->regs);
121} 142}
122 143
123/* sm501_alloc_mem 144/* sm501_alloc_mem
@@ -262,7 +283,7 @@ static void sm501fb_setup_gamma(struct sm501fb_info *fbi,
262 283
263 /* set gamma values */ 284 /* set gamma values */
264 for (offset = 0; offset < 256 * 4; offset += 4) { 285 for (offset = 0; offset < 256 * 4; offset += 4) {
265 writel(value, fbi->regs + palette + offset); 286 smc501_writel(value, fbi->regs + palette + offset);
266 value += 0x010101; /* Advance RGB by 1,1,1.*/ 287 value += 0x010101; /* Advance RGB by 1,1,1.*/
267 } 288 }
268} 289}
@@ -476,7 +497,8 @@ static int sm501fb_set_par_common(struct fb_info *info,
476 497
477 /* set start of framebuffer to the screen */ 498 /* set start of framebuffer to the screen */
478 499
479 writel(par->screen.sm_addr | SM501_ADDR_FLIP, fbi->regs + head_addr); 500 smc501_writel(par->screen.sm_addr | SM501_ADDR_FLIP,
501 fbi->regs + head_addr);
480 502
481 /* program CRT clock */ 503 /* program CRT clock */
482 504
@@ -519,7 +541,7 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
519 reg = info->fix.line_length; 541 reg = info->fix.line_length;
520 reg |= ((var->xres * var->bits_per_pixel)/8) << 16; 542 reg |= ((var->xres * var->bits_per_pixel)/8) << 16;
521 543
522 writel(reg, fbi->regs + (par->head == HEAD_CRT ? 544 smc501_writel(reg, fbi->regs + (par->head == HEAD_CRT ?
523 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET)); 545 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET));
524 546
525 /* program horizontal total */ 547 /* program horizontal total */
@@ -527,27 +549,27 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
527 reg = (h_total(var) - 1) << 16; 549 reg = (h_total(var) - 1) << 16;
528 reg |= (var->xres - 1); 550 reg |= (var->xres - 1);
529 551
530 writel(reg, base + SM501_OFF_DC_H_TOT); 552 smc501_writel(reg, base + SM501_OFF_DC_H_TOT);
531 553
532 /* program horizontal sync */ 554 /* program horizontal sync */
533 555
534 reg = var->hsync_len << 16; 556 reg = var->hsync_len << 16;
535 reg |= var->xres + var->right_margin - 1; 557 reg |= var->xres + var->right_margin - 1;
536 558
537 writel(reg, base + SM501_OFF_DC_H_SYNC); 559 smc501_writel(reg, base + SM501_OFF_DC_H_SYNC);
538 560
539 /* program vertical total */ 561 /* program vertical total */
540 562
541 reg = (v_total(var) - 1) << 16; 563 reg = (v_total(var) - 1) << 16;
542 reg |= (var->yres - 1); 564 reg |= (var->yres - 1);
543 565
544 writel(reg, base + SM501_OFF_DC_V_TOT); 566 smc501_writel(reg, base + SM501_OFF_DC_V_TOT);
545 567
546 /* program vertical sync */ 568 /* program vertical sync */
547 reg = var->vsync_len << 16; 569 reg = var->vsync_len << 16;
548 reg |= var->yres + var->lower_margin - 1; 570 reg |= var->yres + var->lower_margin - 1;
549 571
550 writel(reg, base + SM501_OFF_DC_V_SYNC); 572 smc501_writel(reg, base + SM501_OFF_DC_V_SYNC);
551} 573}
552 574
553/* sm501fb_pan_crt 575/* sm501fb_pan_crt
@@ -566,15 +588,15 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
566 588
567 xoffs = var->xoffset * bytes_pixel; 589 xoffs = var->xoffset * bytes_pixel;
568 590
569 reg = readl(fbi->regs + SM501_DC_CRT_CONTROL); 591 reg = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
570 592
571 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK; 593 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK;
572 reg |= ((xoffs & 15) / bytes_pixel) << 4; 594 reg |= ((xoffs & 15) / bytes_pixel) << 4;
573 writel(reg, fbi->regs + SM501_DC_CRT_CONTROL); 595 smc501_writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
574 596
575 reg = (par->screen.sm_addr + xoffs + 597 reg = (par->screen.sm_addr + xoffs +
576 var->yoffset * info->fix.line_length); 598 var->yoffset * info->fix.line_length);
577 writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR); 599 smc501_writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
578 600
579 sm501fb_sync_regs(fbi); 601 sm501fb_sync_regs(fbi);
580 return 0; 602 return 0;
@@ -593,10 +615,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
593 unsigned long reg; 615 unsigned long reg;
594 616
595 reg = var->xoffset | (var->xres_virtual << 16); 617 reg = var->xoffset | (var->xres_virtual << 16);
596 writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH); 618 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
597 619
598 reg = var->yoffset | (var->yres_virtual << 16); 620 reg = var->yoffset | (var->yres_virtual << 16);
599 writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT); 621 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
600 622
601 sm501fb_sync_regs(fbi); 623 sm501fb_sync_regs(fbi);
602 return 0; 624 return 0;
@@ -622,7 +644,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
622 /* enable CRT DAC - note 0 is on!*/ 644 /* enable CRT DAC - note 0 is on!*/
623 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER); 645 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER);
624 646
625 control = readl(fbi->regs + SM501_DC_CRT_CONTROL); 647 control = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
626 648
627 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK | 649 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK |
628 SM501_DC_CRT_CONTROL_GAMMA | 650 SM501_DC_CRT_CONTROL_GAMMA |
@@ -684,7 +706,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
684 out_update: 706 out_update:
685 dev_dbg(fbi->dev, "new control is %08lx\n", control); 707 dev_dbg(fbi->dev, "new control is %08lx\n", control);
686 708
687 writel(control, fbi->regs + SM501_DC_CRT_CONTROL); 709 smc501_writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
688 sm501fb_sync_regs(fbi); 710 sm501fb_sync_regs(fbi);
689 711
690 return 0; 712 return 0;
@@ -696,18 +718,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
696 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; 718 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
697 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl; 719 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
698 720
699 control = readl(ctrl_reg); 721 control = smc501_readl(ctrl_reg);
700 722
701 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) { 723 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) {
702 /* enable panel power */ 724 /* enable panel power */
703 725
704 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */ 726 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */
705 writel(control, ctrl_reg); 727 smc501_writel(control, ctrl_reg);
706 sm501fb_sync_regs(fbi); 728 sm501fb_sync_regs(fbi);
707 mdelay(10); 729 mdelay(10);
708 730
709 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */ 731 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */
710 writel(control, ctrl_reg); 732 smc501_writel(control, ctrl_reg);
711 sm501fb_sync_regs(fbi); 733 sm501fb_sync_regs(fbi);
712 mdelay(10); 734 mdelay(10);
713 735
@@ -719,7 +741,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
719 else 741 else
720 control |= SM501_DC_PANEL_CONTROL_BIAS; 742 control |= SM501_DC_PANEL_CONTROL_BIAS;
721 743
722 writel(control, ctrl_reg); 744 smc501_writel(control, ctrl_reg);
723 sm501fb_sync_regs(fbi); 745 sm501fb_sync_regs(fbi);
724 mdelay(10); 746 mdelay(10);
725 } 747 }
@@ -730,7 +752,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
730 else 752 else
731 control |= SM501_DC_PANEL_CONTROL_FPEN; 753 control |= SM501_DC_PANEL_CONTROL_FPEN;
732 754
733 writel(control, ctrl_reg); 755 smc501_writel(control, ctrl_reg);
734 sm501fb_sync_regs(fbi); 756 sm501fb_sync_regs(fbi);
735 mdelay(10); 757 mdelay(10);
736 } 758 }
@@ -742,7 +764,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
742 else 764 else
743 control &= ~SM501_DC_PANEL_CONTROL_FPEN; 765 control &= ~SM501_DC_PANEL_CONTROL_FPEN;
744 766
745 writel(control, ctrl_reg); 767 smc501_writel(control, ctrl_reg);
746 sm501fb_sync_regs(fbi); 768 sm501fb_sync_regs(fbi);
747 mdelay(10); 769 mdelay(10);
748 } 770 }
@@ -753,18 +775,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
753 else 775 else
754 control &= ~SM501_DC_PANEL_CONTROL_BIAS; 776 control &= ~SM501_DC_PANEL_CONTROL_BIAS;
755 777
756 writel(control, ctrl_reg); 778 smc501_writel(control, ctrl_reg);
757 sm501fb_sync_regs(fbi); 779 sm501fb_sync_regs(fbi);
758 mdelay(10); 780 mdelay(10);
759 } 781 }
760 782
761 control &= ~SM501_DC_PANEL_CONTROL_DATA; 783 control &= ~SM501_DC_PANEL_CONTROL_DATA;
762 writel(control, ctrl_reg); 784 smc501_writel(control, ctrl_reg);
763 sm501fb_sync_regs(fbi); 785 sm501fb_sync_regs(fbi);
764 mdelay(10); 786 mdelay(10);
765 787
766 control &= ~SM501_DC_PANEL_CONTROL_VDD; 788 control &= ~SM501_DC_PANEL_CONTROL_VDD;
767 writel(control, ctrl_reg); 789 smc501_writel(control, ctrl_reg);
768 sm501fb_sync_regs(fbi); 790 sm501fb_sync_regs(fbi);
769 mdelay(10); 791 mdelay(10);
770 } 792 }
@@ -799,7 +821,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
799 821
800 /* update control register */ 822 /* update control register */
801 823
802 control = readl(fbi->regs + SM501_DC_PANEL_CONTROL); 824 control = smc501_readl(fbi->regs + SM501_DC_PANEL_CONTROL);
803 control &= (SM501_DC_PANEL_CONTROL_GAMMA | 825 control &= (SM501_DC_PANEL_CONTROL_GAMMA |
804 SM501_DC_PANEL_CONTROL_VDD | 826 SM501_DC_PANEL_CONTROL_VDD |
805 SM501_DC_PANEL_CONTROL_DATA | 827 SM501_DC_PANEL_CONTROL_DATA |
@@ -833,16 +855,16 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
833 BUG(); 855 BUG();
834 } 856 }
835 857
836 writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL); 858 smc501_writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
837 859
838 /* panel plane top left and bottom right location */ 860 /* panel plane top left and bottom right location */
839 861
840 writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC); 862 smc501_writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
841 863
842 reg = var->xres - 1; 864 reg = var->xres - 1;
843 reg |= (var->yres - 1) << 16; 865 reg |= (var->yres - 1) << 16;
844 866
845 writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC); 867 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
846 868
847 /* program panel control register */ 869 /* program panel control register */
848 870
@@ -855,7 +877,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
855 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0) 877 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
856 control |= SM501_DC_PANEL_CONTROL_VSP; 878 control |= SM501_DC_PANEL_CONTROL_VSP;
857 879
858 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL); 880 smc501_writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
859 sm501fb_sync_regs(fbi); 881 sm501fb_sync_regs(fbi);
860 882
861 /* ensure the panel interface is not tristated at this point */ 883 /* ensure the panel interface is not tristated at this point */
@@ -924,7 +946,7 @@ static int sm501fb_setcolreg(unsigned regno,
924 val |= (green >> 8) << 8; 946 val |= (green >> 8) << 8;
925 val |= blue >> 8; 947 val |= blue >> 8;
926 948
927 writel(val, base + (regno * 4)); 949 smc501_writel(val, base + (regno * 4));
928 } 950 }
929 951
930 break; 952 break;
@@ -980,7 +1002,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
980 1002
981 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info); 1003 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info);
982 1004
983 ctrl = readl(fbi->regs + SM501_DC_CRT_CONTROL); 1005 ctrl = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
984 1006
985 switch (blank_mode) { 1007 switch (blank_mode) {
986 case FB_BLANK_POWERDOWN: 1008 case FB_BLANK_POWERDOWN:
@@ -1004,7 +1026,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
1004 1026
1005 } 1027 }
1006 1028
1007 writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL); 1029 smc501_writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
1008 sm501fb_sync_regs(fbi); 1030 sm501fb_sync_regs(fbi);
1009 1031
1010 return 0; 1032 return 0;
@@ -1041,12 +1063,14 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1041 if (cursor->image.depth > 1) 1063 if (cursor->image.depth > 1)
1042 return -EINVAL; 1064 return -EINVAL;
1043 1065
1044 hwc_addr = readl(base + SM501_OFF_HWC_ADDR); 1066 hwc_addr = smc501_readl(base + SM501_OFF_HWC_ADDR);
1045 1067
1046 if (cursor->enable) 1068 if (cursor->enable)
1047 writel(hwc_addr | SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1069 smc501_writel(hwc_addr | SM501_HWC_EN,
1070 base + SM501_OFF_HWC_ADDR);
1048 else 1071 else
1049 writel(hwc_addr & ~SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1072 smc501_writel(hwc_addr & ~SM501_HWC_EN,
1073 base + SM501_OFF_HWC_ADDR);
1050 1074
1051 /* set data */ 1075 /* set data */
1052 if (cursor->set & FB_CUR_SETPOS) { 1076 if (cursor->set & FB_CUR_SETPOS) {
@@ -1060,7 +1084,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1060 1084
1061 //y += cursor->image.height; 1085 //y += cursor->image.height;
1062 1086
1063 writel(x | (y << 16), base + SM501_OFF_HWC_LOC); 1087 smc501_writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
1064 } 1088 }
1065 1089
1066 if (cursor->set & FB_CUR_SETCMAP) { 1090 if (cursor->set & FB_CUR_SETCMAP) {
@@ -1080,8 +1104,8 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1080 1104
1081 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg); 1105 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
1082 1106
1083 writel(bg, base + SM501_OFF_HWC_COLOR_1_2); 1107 smc501_writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
1084 writel(fg, base + SM501_OFF_HWC_COLOR_3); 1108 smc501_writel(fg, base + SM501_OFF_HWC_COLOR_3);
1085 } 1109 }
1086 1110
1087 if (cursor->set & FB_CUR_SETSIZE || 1111 if (cursor->set & FB_CUR_SETSIZE ||
@@ -1102,7 +1126,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1102 __func__, cursor->image.width, cursor->image.height); 1126 __func__, cursor->image.width, cursor->image.height);
1103 1127
1104 for (op = 0; op < (64*64*2)/8; op+=4) 1128 for (op = 0; op < (64*64*2)/8; op+=4)
1105 writel(0x0, dst + op); 1129 smc501_writel(0x0, dst + op);
1106 1130
1107 for (y = 0; y < cursor->image.height; y++) { 1131 for (y = 0; y < cursor->image.height; y++) {
1108 for (x = 0; x < cursor->image.width; x++) { 1132 for (x = 0; x < cursor->image.width; x++) {
@@ -1141,7 +1165,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
1141 struct sm501fb_info *info = dev_get_drvdata(dev); 1165 struct sm501fb_info *info = dev_get_drvdata(dev);
1142 unsigned long ctrl; 1166 unsigned long ctrl;
1143 1167
1144 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1168 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1145 ctrl &= SM501_DC_CRT_CONTROL_SEL; 1169 ctrl &= SM501_DC_CRT_CONTROL_SEL;
1146 1170
1147 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel"); 1171 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
@@ -1172,7 +1196,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1172 1196
1173 dev_info(dev, "setting crt source to head %d\n", head); 1197 dev_info(dev, "setting crt source to head %d\n", head);
1174 1198
1175 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1199 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1176 1200
1177 if (head == HEAD_CRT) { 1201 if (head == HEAD_CRT) {
1178 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1202 ctrl |= SM501_DC_CRT_CONTROL_SEL;
@@ -1184,7 +1208,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1184 ctrl &= ~SM501_DC_CRT_CONTROL_TE; 1208 ctrl &= ~SM501_DC_CRT_CONTROL_TE;
1185 } 1209 }
1186 1210
1187 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1211 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1188 sm501fb_sync_regs(info); 1212 sm501fb_sync_regs(info);
1189 1213
1190 return len; 1214 return len;
@@ -1205,7 +1229,8 @@ static int sm501fb_show_regs(struct sm501fb_info *info, char *ptr,
1205 unsigned int reg; 1229 unsigned int reg;
1206 1230
1207 for (reg = start; reg < (len + start); reg += 4) 1231 for (reg = start; reg < (len + start); reg += 4)
1208 ptr += sprintf(ptr, "%08x = %08x\n", reg, readl(mem + reg)); 1232 ptr += sprintf(ptr, "%08x = %08x\n", reg,
1233 smc501_readl(mem + reg));
1209 1234
1210 return ptr - buf; 1235 return ptr - buf;
1211} 1236}
@@ -1257,7 +1282,7 @@ static int sm501fb_sync(struct fb_info *info)
1257 1282
1258 /* wait for the 2d engine to be ready */ 1283 /* wait for the 2d engine to be ready */
1259 while ((count > 0) && 1284 while ((count > 0) &&
1260 (readl(fbi->regs + SM501_SYSTEM_CONTROL) & 1285 (smc501_readl(fbi->regs + SM501_SYSTEM_CONTROL) &
1261 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0) 1286 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0)
1262 count--; 1287 count--;
1263 1288
@@ -1312,45 +1337,46 @@ static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
1312 return; 1337 return;
1313 1338
1314 /* set the base addresses */ 1339 /* set the base addresses */
1315 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1340 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1316 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1341 smc501_writel(par->screen.sm_addr,
1342 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1317 1343
1318 /* set the window width */ 1344 /* set the window width */
1319 writel((info->var.xres << 16) | info->var.xres, 1345 smc501_writel((info->var.xres << 16) | info->var.xres,
1320 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1346 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1321 1347
1322 /* set window stride */ 1348 /* set window stride */
1323 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1349 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1324 fbi->regs2d + SM501_2D_PITCH); 1350 fbi->regs2d + SM501_2D_PITCH);
1325 1351
1326 /* set data format */ 1352 /* set data format */
1327 switch (info->var.bits_per_pixel) { 1353 switch (info->var.bits_per_pixel) {
1328 case 8: 1354 case 8:
1329 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1355 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1330 break; 1356 break;
1331 case 16: 1357 case 16:
1332 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1358 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1333 break; 1359 break;
1334 case 32: 1360 case 32:
1335 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1361 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1336 break; 1362 break;
1337 } 1363 }
1338 1364
1339 /* 2d compare mask */ 1365 /* 2d compare mask */
1340 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1366 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1341 1367
1342 /* 2d mask */ 1368 /* 2d mask */
1343 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1369 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1344 1370
1345 /* source and destination x y */ 1371 /* source and destination x y */
1346 writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE); 1372 smc501_writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
1347 writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION); 1373 smc501_writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
1348 1374
1349 /* w/h */ 1375 /* w/h */
1350 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1376 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1351 1377
1352 /* do area move */ 1378 /* do area move */
1353 writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL); 1379 smc501_writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
1354} 1380}
1355 1381
1356static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 1382static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
@@ -1372,47 +1398,49 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
1372 return; 1398 return;
1373 1399
1374 /* set the base addresses */ 1400 /* set the base addresses */
1375 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1401 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1376 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1402 smc501_writel(par->screen.sm_addr,
1403 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1377 1404
1378 /* set the window width */ 1405 /* set the window width */
1379 writel((info->var.xres << 16) | info->var.xres, 1406 smc501_writel((info->var.xres << 16) | info->var.xres,
1380 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1407 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1381 1408
1382 /* set window stride */ 1409 /* set window stride */
1383 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1410 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1384 fbi->regs2d + SM501_2D_PITCH); 1411 fbi->regs2d + SM501_2D_PITCH);
1385 1412
1386 /* set data format */ 1413 /* set data format */
1387 switch (info->var.bits_per_pixel) { 1414 switch (info->var.bits_per_pixel) {
1388 case 8: 1415 case 8:
1389 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1416 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1390 break; 1417 break;
1391 case 16: 1418 case 16:
1392 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1419 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1393 break; 1420 break;
1394 case 32: 1421 case 32:
1395 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1422 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1396 break; 1423 break;
1397 } 1424 }
1398 1425
1399 /* 2d compare mask */ 1426 /* 2d compare mask */
1400 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1427 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1401 1428
1402 /* 2d mask */ 1429 /* 2d mask */
1403 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1430 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1404 1431
1405 /* colour */ 1432 /* colour */
1406 writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND); 1433 smc501_writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
1407 1434
1408 /* x y */ 1435 /* x y */
1409 writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION); 1436 smc501_writel((rect->dx << 16) | rect->dy,
1437 fbi->regs2d + SM501_2D_DESTINATION);
1410 1438
1411 /* w/h */ 1439 /* w/h */
1412 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1440 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1413 1441
1414 /* do rectangle fill */ 1442 /* do rectangle fill */
1415 writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL); 1443 smc501_writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
1416} 1444}
1417 1445
1418 1446
@@ -1470,11 +1498,12 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
1470 1498
1471 /* initialise the colour registers */ 1499 /* initialise the colour registers */
1472 1500
1473 writel(par->cursor.sm_addr, par->cursor_regs + SM501_OFF_HWC_ADDR); 1501 smc501_writel(par->cursor.sm_addr,
1502 par->cursor_regs + SM501_OFF_HWC_ADDR);
1474 1503
1475 writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC); 1504 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
1476 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2); 1505 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
1477 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3); 1506 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
1478 sm501fb_sync_regs(info); 1507 sm501fb_sync_regs(info);
1479 1508
1480 return 0; 1509 return 0;
@@ -1581,7 +1610,7 @@ static int sm501fb_start(struct sm501fb_info *info,
1581 1610
1582 /* clear palette ram - undefined at power on */ 1611 /* clear palette ram - undefined at power on */
1583 for (k = 0; k < (256 * 3); k++) 1612 for (k = 0; k < (256 * 3); k++)
1584 writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4)); 1613 smc501_writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
1585 1614
1586 /* enable display controller */ 1615 /* enable display controller */
1587 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); 1616 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
@@ -1649,20 +1678,20 @@ static int sm501fb_init_fb(struct fb_info *fb,
1649 switch (head) { 1678 switch (head) {
1650 case HEAD_CRT: 1679 case HEAD_CRT:
1651 pd = info->pdata->fb_crt; 1680 pd = info->pdata->fb_crt;
1652 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1681 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1653 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0; 1682 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0;
1654 1683
1655 /* ensure we set the correct source register */ 1684 /* ensure we set the correct source register */
1656 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) { 1685 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) {
1657 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1686 ctrl |= SM501_DC_CRT_CONTROL_SEL;
1658 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1687 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1659 } 1688 }
1660 1689
1661 break; 1690 break;
1662 1691
1663 case HEAD_PANEL: 1692 case HEAD_PANEL:
1664 pd = info->pdata->fb_pnl; 1693 pd = info->pdata->fb_pnl;
1665 ctrl = readl(info->regs + SM501_DC_PANEL_CONTROL); 1694 ctrl = smc501_readl(info->regs + SM501_DC_PANEL_CONTROL);
1666 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0; 1695 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0;
1667 break; 1696 break;
1668 1697
@@ -1680,7 +1709,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
1680 1709
1681 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) { 1710 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) {
1682 ctrl &= ~SM501_DC_CRT_CONTROL_SEL; 1711 ctrl &= ~SM501_DC_CRT_CONTROL_SEL;
1683 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1712 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1684 enable = 0; 1713 enable = 0;
1685 } 1714 }
1686 1715
@@ -1700,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
1700 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1729 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1701 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; 1730 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
1702 1731
1732#if defined(CONFIG_OF)
1733#ifdef __BIG_ENDIAN
1734 if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
1735 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1736#else
1737 if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
1738 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1739#endif
1740#endif
1703 /* fixed data */ 1741 /* fixed data */
1704 1742
1705 fb->fix.type = FB_TYPE_PACKED_PIXELS; 1743 fb->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1717,9 +1755,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
1717 fb->var.vmode = FB_VMODE_NONINTERLACED; 1755 fb->var.vmode = FB_VMODE_NONINTERLACED;
1718 fb->var.bits_per_pixel = 16; 1756 fb->var.bits_per_pixel = 16;
1719 1757
1758 if (info->edid_data) {
1759 /* Now build modedb from EDID */
1760 fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
1761 fb_videomode_to_modelist(fb->monspecs.modedb,
1762 fb->monspecs.modedb_len,
1763 &fb->modelist);
1764 }
1765
1720 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { 1766 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
1721 /* TODO read the mode from the current display */ 1767 /* TODO read the mode from the current display */
1722
1723 } else { 1768 } else {
1724 if (pd->def_mode) { 1769 if (pd->def_mode) {
1725 dev_info(info->dev, "using supplied mode\n"); 1770 dev_info(info->dev, "using supplied mode\n");
@@ -1729,12 +1774,37 @@ static int sm501fb_init_fb(struct fb_info *fb,
1729 fb->var.xres_virtual = fb->var.xres; 1774 fb->var.xres_virtual = fb->var.xres;
1730 fb->var.yres_virtual = fb->var.yres; 1775 fb->var.yres_virtual = fb->var.yres;
1731 } else { 1776 } else {
1732 ret = fb_find_mode(&fb->var, fb, 1777 if (info->edid_data) {
1778 ret = fb_find_mode(&fb->var, fb, fb_mode,
1779 fb->monspecs.modedb,
1780 fb->monspecs.modedb_len,
1781 &sm501_default_mode, default_bpp);
1782 /* edid_data is no longer needed, free it */
1783 kfree(info->edid_data);
1784 } else {
1785 ret = fb_find_mode(&fb->var, fb,
1733 NULL, NULL, 0, NULL, 8); 1786 NULL, NULL, 0, NULL, 8);
1787 }
1734 1788
1735 if (ret == 0 || ret == 4) { 1789 switch (ret) {
1736 dev_err(info->dev, 1790 case 1:
1737 "failed to get initial mode\n"); 1791 dev_info(info->dev, "using mode specified in "
1792 "@mode\n");
1793 break;
1794 case 2:
1795 dev_info(info->dev, "using mode specified in "
1796 "@mode with ignored refresh rate\n");
1797 break;
1798 case 3:
1799 dev_info(info->dev, "using mode default "
1800 "mode\n");
1801 break;
1802 case 4:
1803 dev_info(info->dev, "using mode from list\n");
1804 break;
1805 default:
1806 dev_info(info->dev, "ret = %d\n", ret);
1807 dev_info(info->dev, "failed to find mode\n");
1738 return -EINVAL; 1808 return -EINVAL;
1739 } 1809 }
1740 } 1810 }
@@ -1875,8 +1945,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
1875 } 1945 }
1876 1946
1877 if (info->pdata == NULL) { 1947 if (info->pdata == NULL) {
1878 dev_info(dev, "using default configuration data\n"); 1948 int found = 0;
1949#if defined(CONFIG_OF)
1950 struct device_node *np = pdev->dev.parent->of_node;
1951 const u8 *prop;
1952 const char *cp;
1953 int len;
1954
1879 info->pdata = &sm501fb_def_pdata; 1955 info->pdata = &sm501fb_def_pdata;
1956 if (np) {
1957 /* Get EDID */
1958 cp = of_get_property(np, "mode", &len);
1959 if (cp)
1960 strcpy(fb_mode, cp);
1961 prop = of_get_property(np, "edid", &len);
1962 if (prop && len == EDID_LENGTH) {
1963 info->edid_data = kmemdup(prop, EDID_LENGTH,
1964 GFP_KERNEL);
1965 if (info->edid_data)
1966 found = 1;
1967 }
1968 }
1969#endif
1970 if (!found) {
1971 dev_info(dev, "using default configuration data\n");
1972 info->pdata = &sm501fb_def_pdata;
1973 }
1880 } 1974 }
1881 1975
1882 /* probe for the presence of each panel */ 1976 /* probe for the presence of each panel */
@@ -2085,7 +2179,7 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
2085 struct sm501fb_info *info = platform_get_drvdata(pdev); 2179 struct sm501fb_info *info = platform_get_drvdata(pdev);
2086 2180
2087 /* store crt control to resume with */ 2181 /* store crt control to resume with */
2088 info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2182 info->pm_crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2089 2183
2090 sm501fb_suspend_fb(info, HEAD_CRT); 2184 sm501fb_suspend_fb(info, HEAD_CRT);
2091 sm501fb_suspend_fb(info, HEAD_PANEL); 2185 sm501fb_suspend_fb(info, HEAD_PANEL);
@@ -2109,10 +2203,10 @@ static int sm501fb_resume(struct platform_device *pdev)
2109 2203
2110 /* restore the items we want to be saved for crt control */ 2204 /* restore the items we want to be saved for crt control */
2111 2205
2112 crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2206 crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2113 crt_ctrl &= ~SM501_CRT_CTRL_SAVE; 2207 crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
2114 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE; 2208 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
2115 writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL); 2209 smc501_writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
2116 2210
2117 sm501fb_resume_fb(info, HEAD_CRT); 2211 sm501fb_resume_fb(info, HEAD_CRT);
2118 sm501fb_resume_fb(info, HEAD_PANEL); 2212 sm501fb_resume_fb(info, HEAD_PANEL);
@@ -2149,6 +2243,11 @@ static void __exit sm501fb_cleanup(void)
2149module_init(sm501fb_init); 2243module_init(sm501fb_init);
2150module_exit(sm501fb_cleanup); 2244module_exit(sm501fb_cleanup);
2151 2245
2246module_param_named(mode, fb_mode, charp, 0);
2247MODULE_PARM_DESC(mode,
2248 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
2249module_param_named(bpp, default_bpp, ulong, 0);
2250MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
2152MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); 2251MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
2153MODULE_DESCRIPTION("SM501 Framebuffer driver"); 2252MODULE_DESCRIPTION("SM501 Framebuffer driver");
2154MODULE_LICENSE("GPL v2"); 2253MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index fdb45674e2f6..33df9ec91795 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -20,12 +20,12 @@
20 20
21 21
22/* Write a CRT register value spread across multiple registers */ 22/* Write a CRT register value spread across multiple registers */
23void svga_wcrt_multi(const struct vga_regset *regset, u32 value) { 23void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
24 24{
25 u8 regval, bitval, bitnum; 25 u8 regval, bitval, bitnum;
26 26
27 while (regset->regnum != VGA_REGSET_END_VAL) { 27 while (regset->regnum != VGA_REGSET_END_VAL) {
28 regval = vga_rcrt(NULL, regset->regnum); 28 regval = vga_rcrt(regbase, regset->regnum);
29 bitnum = regset->lowbit; 29 bitnum = regset->lowbit;
30 while (bitnum <= regset->highbit) { 30 while (bitnum <= regset->highbit) {
31 bitval = 1 << bitnum; 31 bitval = 1 << bitnum;
@@ -34,18 +34,18 @@ void svga_wcrt_multi(const struct vga_regset *regset, u32 value) {
34 bitnum ++; 34 bitnum ++;
35 value = value >> 1; 35 value = value >> 1;
36 } 36 }
37 vga_wcrt(NULL, regset->regnum, regval); 37 vga_wcrt(regbase, regset->regnum, regval);
38 regset ++; 38 regset ++;
39 } 39 }
40} 40}
41 41
42/* Write a sequencer register value spread across multiple registers */ 42/* Write a sequencer register value spread across multiple registers */
43void svga_wseq_multi(const struct vga_regset *regset, u32 value) { 43void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
44 44{
45 u8 regval, bitval, bitnum; 45 u8 regval, bitval, bitnum;
46 46
47 while (regset->regnum != VGA_REGSET_END_VAL) { 47 while (regset->regnum != VGA_REGSET_END_VAL) {
48 regval = vga_rseq(NULL, regset->regnum); 48 regval = vga_rseq(regbase, regset->regnum);
49 bitnum = regset->lowbit; 49 bitnum = regset->lowbit;
50 while (bitnum <= regset->highbit) { 50 while (bitnum <= regset->highbit) {
51 bitval = 1 << bitnum; 51 bitval = 1 << bitnum;
@@ -54,7 +54,7 @@ void svga_wseq_multi(const struct vga_regset *regset, u32 value) {
54 bitnum ++; 54 bitnum ++;
55 value = value >> 1; 55 value = value >> 1;
56 } 56 }
57 vga_wseq(NULL, regset->regnum, regval); 57 vga_wseq(regbase, regset->regnum, regval);
58 regset ++; 58 regset ++;
59 } 59 }
60} 60}
@@ -75,95 +75,95 @@ static unsigned int svga_regset_size(const struct vga_regset *regset)
75 75
76 76
77/* Set graphics controller registers to sane values */ 77/* Set graphics controller registers to sane values */
78void svga_set_default_gfx_regs(void) 78void svga_set_default_gfx_regs(void __iomem *regbase)
79{ 79{
80 /* All standard GFX registers (GR00 - GR08) */ 80 /* All standard GFX registers (GR00 - GR08) */
81 vga_wgfx(NULL, VGA_GFX_SR_VALUE, 0x00); 81 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0x00);
82 vga_wgfx(NULL, VGA_GFX_SR_ENABLE, 0x00); 82 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0x00);
83 vga_wgfx(NULL, VGA_GFX_COMPARE_VALUE, 0x00); 83 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0x00);
84 vga_wgfx(NULL, VGA_GFX_DATA_ROTATE, 0x00); 84 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0x00);
85 vga_wgfx(NULL, VGA_GFX_PLANE_READ, 0x00); 85 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0x00);
86 vga_wgfx(NULL, VGA_GFX_MODE, 0x00); 86 vga_wgfx(regbase, VGA_GFX_MODE, 0x00);
87/* vga_wgfx(NULL, VGA_GFX_MODE, 0x20); */ 87/* vga_wgfx(regbase, VGA_GFX_MODE, 0x20); */
88/* vga_wgfx(NULL, VGA_GFX_MODE, 0x40); */ 88/* vga_wgfx(regbase, VGA_GFX_MODE, 0x40); */
89 vga_wgfx(NULL, VGA_GFX_MISC, 0x05); 89 vga_wgfx(regbase, VGA_GFX_MISC, 0x05);
90/* vga_wgfx(NULL, VGA_GFX_MISC, 0x01); */ 90/* vga_wgfx(regbase, VGA_GFX_MISC, 0x01); */
91 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x0F); 91 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x0F);
92 vga_wgfx(NULL, VGA_GFX_BIT_MASK, 0xFF); 92 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 0xFF);
93} 93}
94 94
95/* Set attribute controller registers to sane values */ 95/* Set attribute controller registers to sane values */
96void svga_set_default_atc_regs(void) 96void svga_set_default_atc_regs(void __iomem *regbase)
97{ 97{
98 u8 count; 98 u8 count;
99 99
100 vga_r(NULL, 0x3DA); 100 vga_r(regbase, 0x3DA);
101 vga_w(NULL, VGA_ATT_W, 0x00); 101 vga_w(regbase, VGA_ATT_W, 0x00);
102 102
103 /* All standard ATC registers (AR00 - AR14) */ 103 /* All standard ATC registers (AR00 - AR14) */
104 for (count = 0; count <= 0xF; count ++) 104 for (count = 0; count <= 0xF; count ++)
105 svga_wattr(count, count); 105 svga_wattr(regbase, count, count);
106 106
107 svga_wattr(VGA_ATC_MODE, 0x01); 107 svga_wattr(regbase, VGA_ATC_MODE, 0x01);
108/* svga_wattr(VGA_ATC_MODE, 0x41); */ 108/* svga_wattr(regbase, VGA_ATC_MODE, 0x41); */
109 svga_wattr(VGA_ATC_OVERSCAN, 0x00); 109 svga_wattr(regbase, VGA_ATC_OVERSCAN, 0x00);
110 svga_wattr(VGA_ATC_PLANE_ENABLE, 0x0F); 110 svga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 0x0F);
111 svga_wattr(VGA_ATC_PEL, 0x00); 111 svga_wattr(regbase, VGA_ATC_PEL, 0x00);
112 svga_wattr(VGA_ATC_COLOR_PAGE, 0x00); 112 svga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0x00);
113 113
114 vga_r(NULL, 0x3DA); 114 vga_r(regbase, 0x3DA);
115 vga_w(NULL, VGA_ATT_W, 0x20); 115 vga_w(regbase, VGA_ATT_W, 0x20);
116} 116}
117 117
118/* Set sequencer registers to sane values */ 118/* Set sequencer registers to sane values */
119void svga_set_default_seq_regs(void) 119void svga_set_default_seq_regs(void __iomem *regbase)
120{ 120{
121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */ 121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */
122 vga_wseq(NULL, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS); 122 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
123 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES); 123 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
124 vga_wseq(NULL, VGA_SEQ_CHARACTER_MAP, 0x00); 124 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
125/* vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */ 125/* vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
126 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE); 126 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
127} 127}
128 128
129/* Set CRTC registers to sane values */ 129/* Set CRTC registers to sane values */
130void svga_set_default_crt_regs(void) 130void svga_set_default_crt_regs(void __iomem *regbase)
131{ 131{
132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */ 132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */
133 svga_wcrt_mask(0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */ 133 svga_wcrt_mask(regbase, 0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
134 vga_wcrt(NULL, VGA_CRTC_PRESET_ROW, 0); 134 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
135 svga_wcrt_mask(VGA_CRTC_MAX_SCAN, 0, 0x1F); 135 svga_wcrt_mask(regbase, VGA_CRTC_MAX_SCAN, 0, 0x1F);
136 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0); 136 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
137 vga_wcrt(NULL, VGA_CRTC_MODE, 0xE3); 137 vga_wcrt(regbase, VGA_CRTC_MODE, 0xE3);
138} 138}
139 139
140void svga_set_textmode_vga_regs(void) 140void svga_set_textmode_vga_regs(void __iomem *regbase)
141{ 141{
142 /* svga_wseq_mask(0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */ 142 /* svga_wseq_mask(regbase, 0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
143 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM); 143 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
144 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, 0x03); 144 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x03);
145 145
146 vga_wcrt(NULL, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */ 146 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
147 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0x1f); 147 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0x1f);
148 svga_wcrt_mask(VGA_CRTC_MODE, 0x23, 0x7f); 148 svga_wcrt_mask(regbase, VGA_CRTC_MODE, 0x23, 0x7f);
149 149
150 vga_wcrt(NULL, VGA_CRTC_CURSOR_START, 0x0d); 150 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0x0d);
151 vga_wcrt(NULL, VGA_CRTC_CURSOR_END, 0x0e); 151 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 0x0e);
152 vga_wcrt(NULL, VGA_CRTC_CURSOR_HI, 0x00); 152 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0x00);
153 vga_wcrt(NULL, VGA_CRTC_CURSOR_LO, 0x00); 153 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0x00);
154 154
155 vga_wgfx(NULL, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */ 155 vga_wgfx(regbase, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
156 vga_wgfx(NULL, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */ 156 vga_wgfx(regbase, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
157 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x00); 157 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x00);
158 158
159 vga_r(NULL, 0x3DA); 159 vga_r(regbase, 0x3DA);
160 vga_w(NULL, VGA_ATT_W, 0x00); 160 vga_w(regbase, VGA_ATT_W, 0x00);
161 161
162 svga_wattr(0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */ 162 svga_wattr(regbase, 0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
163 svga_wattr(0x13, 0x08); /* Horizontal Pixel Panning Register */ 163 svga_wattr(regbase, 0x13, 0x08); /* Horizontal Pixel Panning Register */
164 164
165 vga_r(NULL, 0x3DA); 165 vga_r(regbase, 0x3DA);
166 vga_w(NULL, VGA_ATT_W, 0x20); 166 vga_w(regbase, VGA_ATT_W, 0x20);
167} 167}
168 168
169#if 0 169#if 0
@@ -299,7 +299,7 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
299} 299}
300 300
301/* Set cursor in text (tileblit) mode */ 301/* Set cursor in text (tileblit) mode */
302void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) 302void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor)
303{ 303{
304 u8 cs = 0x0d; 304 u8 cs = 0x0d;
305 u8 ce = 0x0e; 305 u8 ce = 0x0e;
@@ -310,7 +310,7 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
310 if (! cursor -> mode) 310 if (! cursor -> mode)
311 return; 311 return;
312 312
313 svga_wcrt_mask(0x0A, 0x20, 0x20); /* disable cursor */ 313 svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20); /* disable cursor */
314 314
315 if (cursor -> shape == FB_TILE_CURSOR_NONE) 315 if (cursor -> shape == FB_TILE_CURSOR_NONE)
316 return; 316 return;
@@ -334,11 +334,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
334 } 334 }
335 335
336 /* set cursor position */ 336 /* set cursor position */
337 vga_wcrt(NULL, 0x0E, pos >> 8); 337 vga_wcrt(regbase, 0x0E, pos >> 8);
338 vga_wcrt(NULL, 0x0F, pos & 0xFF); 338 vga_wcrt(regbase, 0x0F, pos & 0xFF);
339 339
340 vga_wcrt(NULL, 0x0B, ce); /* set cursor end */ 340 vga_wcrt(regbase, 0x0B, ce); /* set cursor end */
341 vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */ 341 vga_wcrt(regbase, 0x0A, cs); /* set cursor start and enable it */
342} 342}
343 343
344int svga_get_tilemax(struct fb_info *info) 344int svga_get_tilemax(struct fb_info *info)
@@ -507,8 +507,9 @@ int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screenin
507} 507}
508 508
509/* Set CRT timing registers */ 509/* Set CRT timing registers */
510void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, 510void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
511 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node) 511 struct fb_var_screeninfo *var,
512 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
512{ 513{
513 u8 regval; 514 u8 regval;
514 u32 value; 515 u32 value;
@@ -516,66 +517,66 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
516 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 517 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
517 value = (value * hmul) / hdiv; 518 value = (value * hmul) / hdiv;
518 pr_debug("fb%d: horizontal total : %d\n", node, value); 519 pr_debug("fb%d: horizontal total : %d\n", node, value);
519 svga_wcrt_multi(tm->h_total_regs, (value / 8) - 5); 520 svga_wcrt_multi(regbase, tm->h_total_regs, (value / 8) - 5);
520 521
521 value = var->xres; 522 value = var->xres;
522 value = (value * hmul) / hdiv; 523 value = (value * hmul) / hdiv;
523 pr_debug("fb%d: horizontal display : %d\n", node, value); 524 pr_debug("fb%d: horizontal display : %d\n", node, value);
524 svga_wcrt_multi(tm->h_display_regs, (value / 8) - 1); 525 svga_wcrt_multi(regbase, tm->h_display_regs, (value / 8) - 1);
525 526
526 value = var->xres; 527 value = var->xres;
527 value = (value * hmul) / hdiv; 528 value = (value * hmul) / hdiv;
528 pr_debug("fb%d: horizontal blank start: %d\n", node, value); 529 pr_debug("fb%d: horizontal blank start: %d\n", node, value);
529 svga_wcrt_multi(tm->h_blank_start_regs, (value / 8) - 1 + hborder); 530 svga_wcrt_multi(regbase, tm->h_blank_start_regs, (value / 8) - 1 + hborder);
530 531
531 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 532 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
532 value = (value * hmul) / hdiv; 533 value = (value * hmul) / hdiv;
533 pr_debug("fb%d: horizontal blank end : %d\n", node, value); 534 pr_debug("fb%d: horizontal blank end : %d\n", node, value);
534 svga_wcrt_multi(tm->h_blank_end_regs, (value / 8) - 1 - hborder); 535 svga_wcrt_multi(regbase, tm->h_blank_end_regs, (value / 8) - 1 - hborder);
535 536
536 value = var->xres + var->right_margin; 537 value = var->xres + var->right_margin;
537 value = (value * hmul) / hdiv; 538 value = (value * hmul) / hdiv;
538 pr_debug("fb%d: horizontal sync start : %d\n", node, value); 539 pr_debug("fb%d: horizontal sync start : %d\n", node, value);
539 svga_wcrt_multi(tm->h_sync_start_regs, (value / 8)); 540 svga_wcrt_multi(regbase, tm->h_sync_start_regs, (value / 8));
540 541
541 value = var->xres + var->right_margin + var->hsync_len; 542 value = var->xres + var->right_margin + var->hsync_len;
542 value = (value * hmul) / hdiv; 543 value = (value * hmul) / hdiv;
543 pr_debug("fb%d: horizontal sync end : %d\n", node, value); 544 pr_debug("fb%d: horizontal sync end : %d\n", node, value);
544 svga_wcrt_multi(tm->h_sync_end_regs, (value / 8)); 545 svga_wcrt_multi(regbase, tm->h_sync_end_regs, (value / 8));
545 546
546 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 547 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
547 value = (value * vmul) / vdiv; 548 value = (value * vmul) / vdiv;
548 pr_debug("fb%d: vertical total : %d\n", node, value); 549 pr_debug("fb%d: vertical total : %d\n", node, value);
549 svga_wcrt_multi(tm->v_total_regs, value - 2); 550 svga_wcrt_multi(regbase, tm->v_total_regs, value - 2);
550 551
551 value = var->yres; 552 value = var->yres;
552 value = (value * vmul) / vdiv; 553 value = (value * vmul) / vdiv;
553 pr_debug("fb%d: vertical display : %d\n", node, value); 554 pr_debug("fb%d: vertical display : %d\n", node, value);
554 svga_wcrt_multi(tm->v_display_regs, value - 1); 555 svga_wcrt_multi(regbase, tm->v_display_regs, value - 1);
555 556
556 value = var->yres; 557 value = var->yres;
557 value = (value * vmul) / vdiv; 558 value = (value * vmul) / vdiv;
558 pr_debug("fb%d: vertical blank start : %d\n", node, value); 559 pr_debug("fb%d: vertical blank start : %d\n", node, value);
559 svga_wcrt_multi(tm->v_blank_start_regs, value); 560 svga_wcrt_multi(regbase, tm->v_blank_start_regs, value);
560 561
561 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 562 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
562 value = (value * vmul) / vdiv; 563 value = (value * vmul) / vdiv;
563 pr_debug("fb%d: vertical blank end : %d\n", node, value); 564 pr_debug("fb%d: vertical blank end : %d\n", node, value);
564 svga_wcrt_multi(tm->v_blank_end_regs, value - 2); 565 svga_wcrt_multi(regbase, tm->v_blank_end_regs, value - 2);
565 566
566 value = var->yres + var->lower_margin; 567 value = var->yres + var->lower_margin;
567 value = (value * vmul) / vdiv; 568 value = (value * vmul) / vdiv;
568 pr_debug("fb%d: vertical sync start : %d\n", node, value); 569 pr_debug("fb%d: vertical sync start : %d\n", node, value);
569 svga_wcrt_multi(tm->v_sync_start_regs, value); 570 svga_wcrt_multi(regbase, tm->v_sync_start_regs, value);
570 571
571 value = var->yres + var->lower_margin + var->vsync_len; 572 value = var->yres + var->lower_margin + var->vsync_len;
572 value = (value * vmul) / vdiv; 573 value = (value * vmul) / vdiv;
573 pr_debug("fb%d: vertical sync end : %d\n", node, value); 574 pr_debug("fb%d: vertical sync end : %d\n", node, value);
574 svga_wcrt_multi(tm->v_sync_end_regs, value); 575 svga_wcrt_multi(regbase, tm->v_sync_end_regs, value);
575 576
576 /* Set horizontal and vertical sync pulse polarity in misc register */ 577 /* Set horizontal and vertical sync pulse polarity in misc register */
577 578
578 regval = vga_r(NULL, VGA_MIS_R); 579 regval = vga_r(regbase, VGA_MIS_R);
579 if (var->sync & FB_SYNC_HOR_HIGH_ACT) { 580 if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
580 pr_debug("fb%d: positive horizontal sync\n", node); 581 pr_debug("fb%d: positive horizontal sync\n", node);
581 regval = regval & ~0x80; 582 regval = regval & ~0x80;
@@ -590,7 +591,7 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
590 pr_debug("fb%d: negative vertical sync\n\n", node); 591 pr_debug("fb%d: negative vertical sync\n\n", node);
591 regval = regval | 0x40; 592 regval = regval | 0x40;
592 } 593 }
593 vga_w(NULL, VGA_MIS_W, regval); 594 vga_w(regbase, VGA_MIS_W, regval);
594} 595}
595 596
596 597
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 855b71993f61..07c66e946634 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -480,6 +480,7 @@ out_dealloc_cmap:
480 480
481out_unmap_regs: 481out_unmap_regs:
482 tcx_unmap_regs(op, info, par); 482 tcx_unmap_regs(op, info, par);
483 framebuffer_release(info);
483 484
484out_err: 485out_err:
485 return err; 486 return err;
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index dfef88c803d4..9710bf8caeae 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -250,8 +250,7 @@ static irqreturn_t tmiofb_irq(int irq, void *__info)
250 */ 250 */
251static int tmiofb_hw_stop(struct platform_device *dev) 251static int tmiofb_hw_stop(struct platform_device *dev)
252{ 252{
253 struct mfd_cell *cell = dev->dev.platform_data; 253 struct tmio_fb_data *data = mfd_get_data(dev);
254 struct tmio_fb_data *data = cell->driver_data;
255 struct fb_info *info = platform_get_drvdata(dev); 254 struct fb_info *info = platform_get_drvdata(dev);
256 struct tmiofb_par *par = info->par; 255 struct tmiofb_par *par = info->par;
257 256
@@ -268,7 +267,7 @@ static int tmiofb_hw_stop(struct platform_device *dev)
268 */ 267 */
269static int tmiofb_hw_init(struct platform_device *dev) 268static int tmiofb_hw_init(struct platform_device *dev)
270{ 269{
271 struct mfd_cell *cell = dev->dev.platform_data; 270 const struct mfd_cell *cell = mfd_get_cell(dev);
272 struct fb_info *info = platform_get_drvdata(dev); 271 struct fb_info *info = platform_get_drvdata(dev);
273 struct tmiofb_par *par = info->par; 272 struct tmiofb_par *par = info->par;
274 const struct resource *nlcr = &cell->resources[0]; 273 const struct resource *nlcr = &cell->resources[0];
@@ -312,8 +311,7 @@ static int tmiofb_hw_init(struct platform_device *dev)
312 */ 311 */
313static void tmiofb_hw_mode(struct platform_device *dev) 312static void tmiofb_hw_mode(struct platform_device *dev)
314{ 313{
315 struct mfd_cell *cell = dev->dev.platform_data; 314 struct tmio_fb_data *data = mfd_get_data(dev);
316 struct tmio_fb_data *data = cell->driver_data;
317 struct fb_info *info = platform_get_drvdata(dev); 315 struct fb_info *info = platform_get_drvdata(dev);
318 struct fb_videomode *mode = info->mode; 316 struct fb_videomode *mode = info->mode;
319 struct tmiofb_par *par = info->par; 317 struct tmiofb_par *par = info->par;
@@ -559,9 +557,8 @@ static int tmiofb_ioctl(struct fb_info *fbi,
559static struct fb_videomode * 557static struct fb_videomode *
560tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) 558tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
561{ 559{
562 struct mfd_cell *cell = 560 struct tmio_fb_data *data =
563 info->device->platform_data; 561 mfd_get_data(to_platform_device(info->device));
564 struct tmio_fb_data *data = cell->driver_data;
565 struct fb_videomode *best = NULL; 562 struct fb_videomode *best = NULL;
566 int i; 563 int i;
567 564
@@ -581,9 +578,8 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
581{ 578{
582 579
583 struct fb_videomode *mode; 580 struct fb_videomode *mode;
584 struct mfd_cell *cell = 581 struct tmio_fb_data *data =
585 info->device->platform_data; 582 mfd_get_data(to_platform_device(info->device));
586 struct tmio_fb_data *data = cell->driver_data;
587 583
588 mode = tmiofb_find_mode(info, var); 584 mode = tmiofb_find_mode(info, var);
589 if (!mode || var->bits_per_pixel > 16) 585 if (!mode || var->bits_per_pixel > 16)
@@ -683,8 +679,8 @@ static struct fb_ops tmiofb_ops = {
683 679
684static int __devinit tmiofb_probe(struct platform_device *dev) 680static int __devinit tmiofb_probe(struct platform_device *dev)
685{ 681{
686 struct mfd_cell *cell = dev->dev.platform_data; 682 const struct mfd_cell *cell = mfd_get_cell(dev);
687 struct tmio_fb_data *data = cell->driver_data; 683 struct tmio_fb_data *data = mfd_get_data(dev);
688 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); 684 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
689 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); 685 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
690 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); 686 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
@@ -811,7 +807,7 @@ err_ioremap_ccr:
811 807
812static int __devexit tmiofb_remove(struct platform_device *dev) 808static int __devexit tmiofb_remove(struct platform_device *dev)
813{ 809{
814 struct mfd_cell *cell = dev->dev.platform_data; 810 const struct mfd_cell *cell = mfd_get_cell(dev);
815 struct fb_info *info = platform_get_drvdata(dev); 811 struct fb_info *info = platform_get_drvdata(dev);
816 int irq = platform_get_irq(dev, 0); 812 int irq = platform_get_irq(dev, 0);
817 struct tmiofb_par *par; 813 struct tmiofb_par *par;
@@ -941,7 +937,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
941#ifdef CONFIG_FB_TMIO_ACCELL 937#ifdef CONFIG_FB_TMIO_ACCELL
942 struct tmiofb_par *par = info->par; 938 struct tmiofb_par *par = info->par;
943#endif 939#endif
944 struct mfd_cell *cell = dev->dev.platform_data; 940 const struct mfd_cell *cell = mfd_get_cell(dev);
945 int retval = 0; 941 int retval = 0;
946 942
947 console_lock(); 943 console_lock();
@@ -973,7 +969,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
973static int tmiofb_resume(struct platform_device *dev) 969static int tmiofb_resume(struct platform_device *dev)
974{ 970{
975 struct fb_info *info = platform_get_drvdata(dev); 971 struct fb_info *info = platform_get_drvdata(dev);
976 struct mfd_cell *cell = dev->dev.platform_data; 972 const struct mfd_cell *cell = mfd_get_cell(dev);
977 int retval = 0; 973 int retval = 0;
978 974
979 console_lock(); 975 console_lock();
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 5180a215d781..7f8472cc993b 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -1552,8 +1552,7 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1552 int rc; 1552 int rc;
1553 1553
1554 /* Find the largest power-of-two */ 1554 /* Find the largest power-of-two */
1555 while (temp_size & (temp_size - 1)) 1555 temp_size = roundup_pow_of_two(temp_size);
1556 temp_size &= (temp_size - 1);
1557 1556
1558 /* Try and find a power of two to add */ 1557 /* Try and find a power of two to add */
1559 do { 1558 do {
@@ -1566,6 +1565,28 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1566#endif /* CONFIG_MTRR */ 1565#endif /* CONFIG_MTRR */
1567} 1566}
1568 1567
1568static void __devinit uvesafb_ioremap(struct fb_info *info)
1569{
1570#ifdef CONFIG_X86
1571 switch (mtrr) {
1572 case 1: /* uncachable */
1573 info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
1574 break;
1575 case 2: /* write-back */
1576 info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
1577 break;
1578 case 3: /* write-combining */
1579 info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
1580 break;
1581 case 4: /* write-through */
1582 default:
1583 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1584 break;
1585 }
1586#else
1587 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1588#endif /* CONFIG_X86 */
1589}
1569 1590
1570static ssize_t uvesafb_show_vbe_ver(struct device *dev, 1591static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1571 struct device_attribute *attr, char *buf) 1592 struct device_attribute *attr, char *buf)
@@ -1736,15 +1757,22 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1736 1757
1737 uvesafb_init_info(info, mode); 1758 uvesafb_init_info(info, mode);
1738 1759
1760 if (!request_region(0x3c0, 32, "uvesafb")) {
1761 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1762 err = -EIO;
1763 goto out_mode;
1764 }
1765
1739 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len, 1766 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
1740 "uvesafb")) { 1767 "uvesafb")) {
1741 printk(KERN_ERR "uvesafb: cannot reserve video memory at " 1768 printk(KERN_ERR "uvesafb: cannot reserve video memory at "
1742 "0x%lx\n", info->fix.smem_start); 1769 "0x%lx\n", info->fix.smem_start);
1743 err = -EIO; 1770 err = -EIO;
1744 goto out_mode; 1771 goto out_reg;
1745 } 1772 }
1746 1773
1747 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 1774 uvesafb_init_mtrr(info);
1775 uvesafb_ioremap(info);
1748 1776
1749 if (!info->screen_base) { 1777 if (!info->screen_base) {
1750 printk(KERN_ERR 1778 printk(KERN_ERR
@@ -1755,20 +1783,13 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1755 goto out_mem; 1783 goto out_mem;
1756 } 1784 }
1757 1785
1758 if (!request_region(0x3c0, 32, "uvesafb")) {
1759 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1760 err = -EIO;
1761 goto out_unmap;
1762 }
1763
1764 uvesafb_init_mtrr(info);
1765 platform_set_drvdata(dev, info); 1786 platform_set_drvdata(dev, info);
1766 1787
1767 if (register_framebuffer(info) < 0) { 1788 if (register_framebuffer(info) < 0) {
1768 printk(KERN_ERR 1789 printk(KERN_ERR
1769 "uvesafb: failed to register framebuffer device\n"); 1790 "uvesafb: failed to register framebuffer device\n");
1770 err = -EINVAL; 1791 err = -EINVAL;
1771 goto out_reg; 1792 goto out_unmap;
1772 } 1793 }
1773 1794
1774 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, " 1795 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -1785,12 +1806,12 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1785 1806
1786 return 0; 1807 return 0;
1787 1808
1788out_reg:
1789 release_region(0x3c0, 32);
1790out_unmap: 1809out_unmap:
1791 iounmap(info->screen_base); 1810 iounmap(info->screen_base);
1792out_mem: 1811out_mem:
1793 release_mem_region(info->fix.smem_start, info->fix.smem_len); 1812 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1813out_reg:
1814 release_region(0x3c0, 32);
1794out_mode: 1815out_mode:
1795 if (!list_empty(&info->modelist)) 1816 if (!list_empty(&info->modelist))
1796 fb_destroy_modelist(&info->modelist); 1817 fb_destroy_modelist(&info->modelist);
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 931a567f9aff..970e43d13f52 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -891,8 +891,7 @@ static int vmlfb_set_par(struct fb_info *info)
891 int ret; 891 int ret;
892 892
893 mutex_lock(&vml_mutex); 893 mutex_lock(&vml_mutex);
894 list_del(&vinfo->head); 894 list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
895 list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
896 ret = vmlfb_set_par_locked(vinfo); 895 ret = vmlfb_set_par_locked(vinfo);
897 896
898 mutex_unlock(&vml_mutex); 897 mutex_unlock(&vml_mutex);
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 6a069d047914..a99bbe86db13 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -303,19 +303,6 @@ static int __init vesafb_probe(struct platform_device *dev)
303 info->apertures->ranges[0].base = screen_info.lfb_base; 303 info->apertures->ranges[0].base = screen_info.lfb_base;
304 info->apertures->ranges[0].size = size_total; 304 info->apertures->ranges[0].size = size_total;
305 305
306 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
307 if (!info->screen_base) {
308 printk(KERN_ERR
309 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
310 vesafb_fix.smem_len, vesafb_fix.smem_start);
311 err = -EIO;
312 goto err;
313 }
314
315 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
316 "using %dk, total %dk\n",
317 vesafb_fix.smem_start, info->screen_base,
318 size_remap/1024, size_total/1024);
319 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", 306 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
320 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); 307 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
321 308
@@ -438,8 +425,7 @@ static int __init vesafb_probe(struct platform_device *dev)
438 int rc; 425 int rc;
439 426
440 /* Find the largest power-of-two */ 427 /* Find the largest power-of-two */
441 while (temp_size & (temp_size - 1)) 428 temp_size = roundup_pow_of_two(temp_size);
442 temp_size &= (temp_size - 1);
443 429
444 /* Try and find a power of two to add */ 430 /* Try and find a power of two to add */
445 do { 431 do {
@@ -451,6 +437,34 @@ static int __init vesafb_probe(struct platform_device *dev)
451 } 437 }
452#endif 438#endif
453 439
440 switch (mtrr) {
441 case 1: /* uncachable */
442 info->screen_base = ioremap_nocache(vesafb_fix.smem_start, vesafb_fix.smem_len);
443 break;
444 case 2: /* write-back */
445 info->screen_base = ioremap_cache(vesafb_fix.smem_start, vesafb_fix.smem_len);
446 break;
447 case 3: /* write-combining */
448 info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
449 break;
450 case 4: /* write-through */
451 default:
452 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
453 break;
454 }
455 if (!info->screen_base) {
456 printk(KERN_ERR
457 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
458 vesafb_fix.smem_len, vesafb_fix.smem_start);
459 err = -EIO;
460 goto err;
461 }
462
463 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
464 "using %dk, total %dk\n",
465 vesafb_fix.smem_start, info->screen_base,
466 size_remap/1024, size_total/1024);
467
454 info->fbops = &vesafb_ops; 468 info->fbops = &vesafb_ops;
455 info->var = vesafb_defined; 469 info->var = vesafb_defined;
456 info->fix = vesafb_fix; 470 info->fix = vesafb_fix;
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index a2965ab92cfb..f9b3e3dc2421 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -121,13 +121,19 @@ MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, d
121 121
122/* ------------------------------------------------------------------------- */ 122/* ------------------------------------------------------------------------- */
123 123
124static void vt8623fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
125{
126 struct vt8623fb_info *par = info->par;
127
128 svga_tilecursor(par->state.vgabase, info, cursor);
129}
124 130
125static struct fb_tile_ops vt8623fb_tile_ops = { 131static struct fb_tile_ops vt8623fb_tile_ops = {
126 .fb_settile = svga_settile, 132 .fb_settile = svga_settile,
127 .fb_tilecopy = svga_tilecopy, 133 .fb_tilecopy = svga_tilecopy,
128 .fb_tilefill = svga_tilefill, 134 .fb_tilefill = svga_tilefill,
129 .fb_tileblit = svga_tileblit, 135 .fb_tileblit = svga_tileblit,
130 .fb_tilecursor = svga_tilecursor, 136 .fb_tilecursor = vt8623fb_tilecursor,
131 .fb_get_tilemax = svga_get_tilemax, 137 .fb_get_tilemax = svga_get_tilemax,
132}; 138};
133 139
@@ -253,6 +259,7 @@ static void vt8623fb_fillrect(struct fb_info *info, const struct fb_fillrect *re
253 259
254static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock) 260static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
255{ 261{
262 struct vt8623fb_info *par = info->par;
256 u16 m, n, r; 263 u16 m, n, r;
257 u8 regval; 264 u8 regval;
258 int rv; 265 int rv;
@@ -264,18 +271,18 @@ static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
264 } 271 }
265 272
266 /* Set VGA misc register */ 273 /* Set VGA misc register */
267 regval = vga_r(NULL, VGA_MIS_R); 274 regval = vga_r(par->state.vgabase, VGA_MIS_R);
268 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 275 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
269 276
270 /* Set clock registers */ 277 /* Set clock registers */
271 vga_wseq(NULL, 0x46, (n | (r << 6))); 278 vga_wseq(par->state.vgabase, 0x46, (n | (r << 6)));
272 vga_wseq(NULL, 0x47, m); 279 vga_wseq(par->state.vgabase, 0x47, m);
273 280
274 udelay(1000); 281 udelay(1000);
275 282
276 /* PLL reset */ 283 /* PLL reset */
277 svga_wseq_mask(0x40, 0x02, 0x02); 284 svga_wseq_mask(par->state.vgabase, 0x40, 0x02, 0x02);
278 svga_wseq_mask(0x40, 0x00, 0x02); 285 svga_wseq_mask(par->state.vgabase, 0x40, 0x00, 0x02);
279} 286}
280 287
281 288
@@ -285,7 +292,10 @@ static int vt8623fb_open(struct fb_info *info, int user)
285 292
286 mutex_lock(&(par->open_lock)); 293 mutex_lock(&(par->open_lock));
287 if (par->ref_count == 0) { 294 if (par->ref_count == 0) {
295 void __iomem *vgabase = par->state.vgabase;
296
288 memset(&(par->state), 0, sizeof(struct vgastate)); 297 memset(&(par->state), 0, sizeof(struct vgastate));
298 par->state.vgabase = vgabase;
289 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 299 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
290 par->state.num_crtc = 0xA2; 300 par->state.num_crtc = 0xA2;
291 par->state.num_seq = 0x50; 301 par->state.num_seq = 0x50;
@@ -373,6 +383,7 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
373static int vt8623fb_set_par(struct fb_info *info) 383static int vt8623fb_set_par(struct fb_info *info)
374{ 384{
375 u32 mode, offset_value, fetch_value, screen_size; 385 u32 mode, offset_value, fetch_value, screen_size;
386 struct vt8623fb_info *par = info->par;
376 u32 bpp = info->var.bits_per_pixel; 387 u32 bpp = info->var.bits_per_pixel;
377 388
378 if (bpp != 0) { 389 if (bpp != 0) {
@@ -414,82 +425,82 @@ static int vt8623fb_set_par(struct fb_info *info)
414 info->var.activate = FB_ACTIVATE_NOW; 425 info->var.activate = FB_ACTIVATE_NOW;
415 426
416 /* Unlock registers */ 427 /* Unlock registers */
417 svga_wseq_mask(0x10, 0x01, 0x01); 428 svga_wseq_mask(par->state.vgabase, 0x10, 0x01, 0x01);
418 svga_wcrt_mask(0x11, 0x00, 0x80); 429 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
419 svga_wcrt_mask(0x47, 0x00, 0x01); 430 svga_wcrt_mask(par->state.vgabase, 0x47, 0x00, 0x01);
420 431
421 /* Device, screen and sync off */ 432 /* Device, screen and sync off */
422 svga_wseq_mask(0x01, 0x20, 0x20); 433 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
423 svga_wcrt_mask(0x36, 0x30, 0x30); 434 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
424 svga_wcrt_mask(0x17, 0x00, 0x80); 435 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
425 436
426 /* Set default values */ 437 /* Set default values */
427 svga_set_default_gfx_regs(); 438 svga_set_default_gfx_regs(par->state.vgabase);
428 svga_set_default_atc_regs(); 439 svga_set_default_atc_regs(par->state.vgabase);
429 svga_set_default_seq_regs(); 440 svga_set_default_seq_regs(par->state.vgabase);
430 svga_set_default_crt_regs(); 441 svga_set_default_crt_regs(par->state.vgabase);
431 svga_wcrt_multi(vt8623_line_compare_regs, 0xFFFFFFFF); 442 svga_wcrt_multi(par->state.vgabase, vt8623_line_compare_regs, 0xFFFFFFFF);
432 svga_wcrt_multi(vt8623_start_address_regs, 0); 443 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, 0);
433 444
434 svga_wcrt_multi(vt8623_offset_regs, offset_value); 445 svga_wcrt_multi(par->state.vgabase, vt8623_offset_regs, offset_value);
435 svga_wseq_multi(vt8623_fetch_count_regs, fetch_value); 446 svga_wseq_multi(par->state.vgabase, vt8623_fetch_count_regs, fetch_value);
436 447
437 /* Clear H/V Skew */ 448 /* Clear H/V Skew */
438 svga_wcrt_mask(0x03, 0x00, 0x60); 449 svga_wcrt_mask(par->state.vgabase, 0x03, 0x00, 0x60);
439 svga_wcrt_mask(0x05, 0x00, 0x60); 450 svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60);
440 451
441 if (info->var.vmode & FB_VMODE_DOUBLE) 452 if (info->var.vmode & FB_VMODE_DOUBLE)
442 svga_wcrt_mask(0x09, 0x80, 0x80); 453 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
443 else 454 else
444 svga_wcrt_mask(0x09, 0x00, 0x80); 455 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
445 456
446 svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus 457 svga_wseq_mask(par->state.vgabase, 0x1E, 0xF0, 0xF0); // DI/DVP bus
447 svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus 458 svga_wseq_mask(par->state.vgabase, 0x2A, 0x0F, 0x0F); // DI/DVP bus
448 svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold 459 svga_wseq_mask(par->state.vgabase, 0x16, 0x08, 0xBF); // FIFO read threshold
449 vga_wseq(NULL, 0x17, 0x1F); // FIFO depth 460 vga_wseq(par->state.vgabase, 0x17, 0x1F); // FIFO depth
450 vga_wseq(NULL, 0x18, 0x4E); 461 vga_wseq(par->state.vgabase, 0x18, 0x4E);
451 svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ? 462 svga_wseq_mask(par->state.vgabase, 0x1A, 0x08, 0x08); // enable MMIO ?
452 463
453 vga_wcrt(NULL, 0x32, 0x00); 464 vga_wcrt(par->state.vgabase, 0x32, 0x00);
454 vga_wcrt(NULL, 0x34, 0x00); 465 vga_wcrt(par->state.vgabase, 0x34, 0x00);
455 vga_wcrt(NULL, 0x6A, 0x80); 466 vga_wcrt(par->state.vgabase, 0x6A, 0x80);
456 vga_wcrt(NULL, 0x6A, 0xC0); 467 vga_wcrt(par->state.vgabase, 0x6A, 0xC0);
457 468
458 vga_wgfx(NULL, 0x20, 0x00); 469 vga_wgfx(par->state.vgabase, 0x20, 0x00);
459 vga_wgfx(NULL, 0x21, 0x00); 470 vga_wgfx(par->state.vgabase, 0x21, 0x00);
460 vga_wgfx(NULL, 0x22, 0x00); 471 vga_wgfx(par->state.vgabase, 0x22, 0x00);
461 472
462 /* Set SR15 according to number of bits per pixel */ 473 /* Set SR15 according to number of bits per pixel */
463 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix)); 474 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix));
464 switch (mode) { 475 switch (mode) {
465 case 0: 476 case 0:
466 pr_debug("fb%d: text mode\n", info->node); 477 pr_debug("fb%d: text mode\n", info->node);
467 svga_set_textmode_vga_regs(); 478 svga_set_textmode_vga_regs(par->state.vgabase);
468 svga_wseq_mask(0x15, 0x00, 0xFE); 479 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
469 svga_wcrt_mask(0x11, 0x60, 0x70); 480 svga_wcrt_mask(par->state.vgabase, 0x11, 0x60, 0x70);
470 break; 481 break;
471 case 1: 482 case 1:
472 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 483 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
473 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 484 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
474 svga_wseq_mask(0x15, 0x20, 0xFE); 485 svga_wseq_mask(par->state.vgabase, 0x15, 0x20, 0xFE);
475 svga_wcrt_mask(0x11, 0x00, 0x70); 486 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
476 break; 487 break;
477 case 2: 488 case 2:
478 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 489 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
479 svga_wseq_mask(0x15, 0x00, 0xFE); 490 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
480 svga_wcrt_mask(0x11, 0x00, 0x70); 491 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
481 break; 492 break;
482 case 3: 493 case 3:
483 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 494 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
484 svga_wseq_mask(0x15, 0x22, 0xFE); 495 svga_wseq_mask(par->state.vgabase, 0x15, 0x22, 0xFE);
485 break; 496 break;
486 case 4: 497 case 4:
487 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 498 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
488 svga_wseq_mask(0x15, 0xB6, 0xFE); 499 svga_wseq_mask(par->state.vgabase, 0x15, 0xB6, 0xFE);
489 break; 500 break;
490 case 5: 501 case 5:
491 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 502 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
492 svga_wseq_mask(0x15, 0xAE, 0xFE); 503 svga_wseq_mask(par->state.vgabase, 0x15, 0xAE, 0xFE);
493 break; 504 break;
494 default: 505 default:
495 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n"); 506 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n");
@@ -497,16 +508,16 @@ static int vt8623fb_set_par(struct fb_info *info)
497 } 508 }
498 509
499 vt8623_set_pixclock(info, info->var.pixclock); 510 vt8623_set_pixclock(info, info->var.pixclock);
500 svga_set_timings(&vt8623_timing_regs, &(info->var), 1, 1, 511 svga_set_timings(par->state.vgabase, &vt8623_timing_regs, &(info->var), 1, 1,
501 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1, 512 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
502 1, info->node); 513 1, info->node);
503 514
504 memset_io(info->screen_base, 0x00, screen_size); 515 memset_io(info->screen_base, 0x00, screen_size);
505 516
506 /* Device and screen back on */ 517 /* Device and screen back on */
507 svga_wcrt_mask(0x17, 0x80, 0x80); 518 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
508 svga_wcrt_mask(0x36, 0x00, 0x30); 519 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
509 svga_wseq_mask(0x01, 0x00, 0x20); 520 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
510 521
511 return 0; 522 return 0;
512} 523}
@@ -569,31 +580,33 @@ static int vt8623fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
569 580
570static int vt8623fb_blank(int blank_mode, struct fb_info *info) 581static int vt8623fb_blank(int blank_mode, struct fb_info *info)
571{ 582{
583 struct vt8623fb_info *par = info->par;
584
572 switch (blank_mode) { 585 switch (blank_mode) {
573 case FB_BLANK_UNBLANK: 586 case FB_BLANK_UNBLANK:
574 pr_debug("fb%d: unblank\n", info->node); 587 pr_debug("fb%d: unblank\n", info->node);
575 svga_wcrt_mask(0x36, 0x00, 0x30); 588 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
576 svga_wseq_mask(0x01, 0x00, 0x20); 589 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
577 break; 590 break;
578 case FB_BLANK_NORMAL: 591 case FB_BLANK_NORMAL:
579 pr_debug("fb%d: blank\n", info->node); 592 pr_debug("fb%d: blank\n", info->node);
580 svga_wcrt_mask(0x36, 0x00, 0x30); 593 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
581 svga_wseq_mask(0x01, 0x20, 0x20); 594 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
582 break; 595 break;
583 case FB_BLANK_HSYNC_SUSPEND: 596 case FB_BLANK_HSYNC_SUSPEND:
584 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node); 597 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node);
585 svga_wcrt_mask(0x36, 0x10, 0x30); 598 svga_wcrt_mask(par->state.vgabase, 0x36, 0x10, 0x30);
586 svga_wseq_mask(0x01, 0x20, 0x20); 599 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
587 break; 600 break;
588 case FB_BLANK_VSYNC_SUSPEND: 601 case FB_BLANK_VSYNC_SUSPEND:
589 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node); 602 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node);
590 svga_wcrt_mask(0x36, 0x20, 0x30); 603 svga_wcrt_mask(par->state.vgabase, 0x36, 0x20, 0x30);
591 svga_wseq_mask(0x01, 0x20, 0x20); 604 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
592 break; 605 break;
593 case FB_BLANK_POWERDOWN: 606 case FB_BLANK_POWERDOWN:
594 pr_debug("fb%d: DPMS off (no sync)\n", info->node); 607 pr_debug("fb%d: DPMS off (no sync)\n", info->node);
595 svga_wcrt_mask(0x36, 0x30, 0x30); 608 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
596 svga_wseq_mask(0x01, 0x20, 0x20); 609 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
597 break; 610 break;
598 } 611 }
599 612
@@ -603,6 +616,7 @@ static int vt8623fb_blank(int blank_mode, struct fb_info *info)
603 616
604static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 617static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
605{ 618{
619 struct vt8623fb_info *par = info->par;
606 unsigned int offset; 620 unsigned int offset;
607 621
608 /* Calculate the offset */ 622 /* Calculate the offset */
@@ -616,7 +630,7 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
616 } 630 }
617 631
618 /* Set the offset */ 632 /* Set the offset */
619 svga_wcrt_multi(vt8623_start_address_regs, offset); 633 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, offset);
620 634
621 return 0; 635 return 0;
622} 636}
@@ -647,6 +661,8 @@ static struct fb_ops vt8623fb_ops = {
647 661
648static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 662static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
649{ 663{
664 struct pci_bus_region bus_reg;
665 struct resource vga_res;
650 struct fb_info *info; 666 struct fb_info *info;
651 struct vt8623fb_info *par; 667 struct vt8623fb_info *par;
652 unsigned int memsize1, memsize2; 668 unsigned int memsize1, memsize2;
@@ -705,9 +721,18 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
705 goto err_iomap_2; 721 goto err_iomap_2;
706 } 722 }
707 723
724 bus_reg.start = 0;
725 bus_reg.end = 64 * 1024;
726
727 vga_res.flags = IORESOURCE_IO;
728
729 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
730
731 par->state.vgabase = (void __iomem *) vga_res.start;
732
708 /* Find how many physical memory there is on card */ 733 /* Find how many physical memory there is on card */
709 memsize1 = (vga_rseq(NULL, 0x34) + 1) >> 1; 734 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;
710 memsize2 = vga_rseq(NULL, 0x39) << 2; 735 memsize2 = vga_rseq(par->state.vgabase, 0x39) << 2;
711 736
712 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2)) 737 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2))
713 info->screen_size = memsize1 << 20; 738 info->screen_size = memsize1 << 20;
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 6b85e7fefa43..95921b77cf86 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -90,7 +90,7 @@ struct ds1wm_data {
90 void __iomem *map; 90 void __iomem *map;
91 int bus_shift; /* # of shifts to calc register offsets */ 91 int bus_shift; /* # of shifts to calc register offsets */
92 struct platform_device *pdev; 92 struct platform_device *pdev;
93 struct mfd_cell *cell; 93 const struct mfd_cell *cell;
94 int irq; 94 int irq;
95 int active_high; 95 int active_high;
96 int slave_present; 96 int slave_present;
@@ -216,7 +216,7 @@ static int ds1wm_find_divisor(int gclk)
216static void ds1wm_up(struct ds1wm_data *ds1wm_data) 216static void ds1wm_up(struct ds1wm_data *ds1wm_data)
217{ 217{
218 int divisor; 218 int divisor;
219 struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data; 219 struct ds1wm_driver_data *plat = mfd_get_data(ds1wm_data->pdev);
220 220
221 if (ds1wm_data->cell->enable) 221 if (ds1wm_data->cell->enable)
222 ds1wm_data->cell->enable(ds1wm_data->pdev); 222 ds1wm_data->cell->enable(ds1wm_data->pdev);
@@ -330,16 +330,11 @@ static int ds1wm_probe(struct platform_device *pdev)
330 struct ds1wm_data *ds1wm_data; 330 struct ds1wm_data *ds1wm_data;
331 struct ds1wm_driver_data *plat; 331 struct ds1wm_driver_data *plat;
332 struct resource *res; 332 struct resource *res;
333 struct mfd_cell *cell;
334 int ret; 333 int ret;
335 334
336 if (!pdev) 335 if (!pdev)
337 return -ENODEV; 336 return -ENODEV;
338 337
339 cell = pdev->dev.platform_data;
340 if (!cell)
341 return -ENODEV;
342
343 ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL); 338 ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL);
344 if (!ds1wm_data) 339 if (!ds1wm_data)
345 return -ENOMEM; 340 return -ENOMEM;
@@ -356,13 +351,13 @@ static int ds1wm_probe(struct platform_device *pdev)
356 ret = -ENOMEM; 351 ret = -ENOMEM;
357 goto err0; 352 goto err0;
358 } 353 }
359 plat = cell->driver_data; 354 plat = mfd_get_data(pdev);
360 355
361 /* calculate bus shift from mem resource */ 356 /* calculate bus shift from mem resource */
362 ds1wm_data->bus_shift = resource_size(res) >> 3; 357 ds1wm_data->bus_shift = resource_size(res) >> 3;
363 358
364 ds1wm_data->pdev = pdev; 359 ds1wm_data->pdev = pdev;
365 ds1wm_data->cell = cell; 360 ds1wm_data->cell = mfd_get_cell(pdev);
366 361
367 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 362 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
368 if (!res) { 363 if (!res) {
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 3939e53f5f98..d8e725082fdc 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -37,6 +37,7 @@
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/mfd/rdc321x.h> 39#include <linux/mfd/rdc321x.h>
40#include <linux/mfd/core.h>
40 41
41#define RDC_WDT_MASK 0x80000000 /* Mask */ 42#define RDC_WDT_MASK 0x80000000 /* Mask */
42#define RDC_WDT_EN 0x00800000 /* Enable bit */ 43#define RDC_WDT_EN 0x00800000 /* Enable bit */
@@ -231,7 +232,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
231 struct resource *r; 232 struct resource *r;
232 struct rdc321x_wdt_pdata *pdata; 233 struct rdc321x_wdt_pdata *pdata;
233 234
234 pdata = platform_get_drvdata(pdev); 235 pdata = mfd_get_data(pdev);
235 if (!pdata) { 236 if (!pdata) {
236 dev_err(&pdev->dev, "no platform data supplied\n"); 237 dev_err(&pdev->dev, "no platform data supplied\n");
237 return -ENODEV; 238 return -ENODEV;
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 92444e94f842..d5250c5aae21 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -72,7 +72,6 @@ static sector_t _adfs_bmap(struct address_space *mapping, sector_t block)
72static const struct address_space_operations adfs_aops = { 72static const struct address_space_operations adfs_aops = {
73 .readpage = adfs_readpage, 73 .readpage = adfs_readpage,
74 .writepage = adfs_writepage, 74 .writepage = adfs_writepage,
75 .sync_page = block_sync_page,
76 .write_begin = adfs_write_begin, 75 .write_begin = adfs_write_begin,
77 .write_end = generic_write_end, 76 .write_end = generic_write_end,
78 .bmap = _adfs_bmap 77 .bmap = _adfs_bmap
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 0a90dcd46de2..acf321b70fcd 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -429,7 +429,6 @@ static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
429const struct address_space_operations affs_aops = { 429const struct address_space_operations affs_aops = {
430 .readpage = affs_readpage, 430 .readpage = affs_readpage,
431 .writepage = affs_writepage, 431 .writepage = affs_writepage,
432 .sync_page = block_sync_page,
433 .write_begin = affs_write_begin, 432 .write_begin = affs_write_begin,
434 .write_end = generic_write_end, 433 .write_end = generic_write_end,
435 .bmap = _affs_bmap 434 .bmap = _affs_bmap
@@ -786,7 +785,6 @@ out:
786const struct address_space_operations affs_aops_ofs = { 785const struct address_space_operations affs_aops_ofs = {
787 .readpage = affs_readpage_ofs, 786 .readpage = affs_readpage_ofs,
788 //.writepage = affs_writepage_ofs, 787 //.writepage = affs_writepage_ofs,
789 //.sync_page = affs_sync_page_ofs,
790 .write_begin = affs_write_begin_ofs, 788 .write_begin = affs_write_begin_ofs,
791 .write_end = affs_write_end_ofs 789 .write_end = affs_write_end_ofs
792}; 790};
diff --git a/fs/aio.c b/fs/aio.c
index ebb6a22e4e1b..e29ec485af25 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -34,8 +34,6 @@
34#include <linux/security.h> 34#include <linux/security.h>
35#include <linux/eventfd.h> 35#include <linux/eventfd.h>
36#include <linux/blkdev.h> 36#include <linux/blkdev.h>
37#include <linux/mempool.h>
38#include <linux/hash.h>
39#include <linux/compat.h> 37#include <linux/compat.h>
40 38
41#include <asm/kmap_types.h> 39#include <asm/kmap_types.h>
@@ -65,14 +63,6 @@ static DECLARE_WORK(fput_work, aio_fput_routine);
65static DEFINE_SPINLOCK(fput_lock); 63static DEFINE_SPINLOCK(fput_lock);
66static LIST_HEAD(fput_head); 64static LIST_HEAD(fput_head);
67 65
68#define AIO_BATCH_HASH_BITS 3 /* allocated on-stack, so don't go crazy */
69#define AIO_BATCH_HASH_SIZE (1 << AIO_BATCH_HASH_BITS)
70struct aio_batch_entry {
71 struct hlist_node list;
72 struct address_space *mapping;
73};
74mempool_t *abe_pool;
75
76static void aio_kick_handler(struct work_struct *); 66static void aio_kick_handler(struct work_struct *);
77static void aio_queue_work(struct kioctx *); 67static void aio_queue_work(struct kioctx *);
78 68
@@ -86,8 +76,7 @@ static int __init aio_setup(void)
86 kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); 76 kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
87 77
88 aio_wq = alloc_workqueue("aio", 0, 1); /* used to limit concurrency */ 78 aio_wq = alloc_workqueue("aio", 0, 1); /* used to limit concurrency */
89 abe_pool = mempool_create_kmalloc_pool(1, sizeof(struct aio_batch_entry)); 79 BUG_ON(!aio_wq);
90 BUG_ON(!aio_wq || !abe_pool);
91 80
92 pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page)); 81 pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page));
93 82
@@ -1525,57 +1514,8 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1525 return 0; 1514 return 0;
1526} 1515}
1527 1516
1528static void aio_batch_add(struct address_space *mapping,
1529 struct hlist_head *batch_hash)
1530{
1531 struct aio_batch_entry *abe;
1532 struct hlist_node *pos;
1533 unsigned bucket;
1534
1535 bucket = hash_ptr(mapping, AIO_BATCH_HASH_BITS);
1536 hlist_for_each_entry(abe, pos, &batch_hash[bucket], list) {
1537 if (abe->mapping == mapping)
1538 return;
1539 }
1540
1541 abe = mempool_alloc(abe_pool, GFP_KERNEL);
1542
1543 /*
1544 * we should be using igrab here, but
1545 * we don't want to hammer on the global
1546 * inode spinlock just to take an extra
1547 * reference on a file that we must already
1548 * have a reference to.
1549 *
1550 * When we're called, we always have a reference
1551 * on the file, so we must always have a reference
1552 * on the inode, so ihold() is safe here.
1553 */
1554 ihold(mapping->host);
1555 abe->mapping = mapping;
1556 hlist_add_head(&abe->list, &batch_hash[bucket]);
1557 return;
1558}
1559
1560static void aio_batch_free(struct hlist_head *batch_hash)
1561{
1562 struct aio_batch_entry *abe;
1563 struct hlist_node *pos, *n;
1564 int i;
1565
1566 for (i = 0; i < AIO_BATCH_HASH_SIZE; i++) {
1567 hlist_for_each_entry_safe(abe, pos, n, &batch_hash[i], list) {
1568 blk_run_address_space(abe->mapping);
1569 iput(abe->mapping->host);
1570 hlist_del(&abe->list);
1571 mempool_free(abe, abe_pool);
1572 }
1573 }
1574}
1575
1576static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, 1517static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1577 struct iocb *iocb, struct hlist_head *batch_hash, 1518 struct iocb *iocb, bool compat)
1578 bool compat)
1579{ 1519{
1580 struct kiocb *req; 1520 struct kiocb *req;
1581 struct file *file; 1521 struct file *file;
@@ -1666,11 +1606,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1666 ; 1606 ;
1667 } 1607 }
1668 spin_unlock_irq(&ctx->ctx_lock); 1608 spin_unlock_irq(&ctx->ctx_lock);
1669 if (req->ki_opcode == IOCB_CMD_PREAD ||
1670 req->ki_opcode == IOCB_CMD_PREADV ||
1671 req->ki_opcode == IOCB_CMD_PWRITE ||
1672 req->ki_opcode == IOCB_CMD_PWRITEV)
1673 aio_batch_add(file->f_mapping, batch_hash);
1674 1609
1675 aio_put_req(req); /* drop extra ref to req */ 1610 aio_put_req(req); /* drop extra ref to req */
1676 return 0; 1611 return 0;
@@ -1687,7 +1622,7 @@ long do_io_submit(aio_context_t ctx_id, long nr,
1687 struct kioctx *ctx; 1622 struct kioctx *ctx;
1688 long ret = 0; 1623 long ret = 0;
1689 int i; 1624 int i;
1690 struct hlist_head batch_hash[AIO_BATCH_HASH_SIZE] = { { 0, }, }; 1625 struct blk_plug plug;
1691 1626
1692 if (unlikely(nr < 0)) 1627 if (unlikely(nr < 0))
1693 return -EINVAL; 1628 return -EINVAL;
@@ -1704,6 +1639,8 @@ long do_io_submit(aio_context_t ctx_id, long nr,
1704 return -EINVAL; 1639 return -EINVAL;
1705 } 1640 }
1706 1641
1642 blk_start_plug(&plug);
1643
1707 /* 1644 /*
1708 * AKPM: should this return a partial result if some of the IOs were 1645 * AKPM: should this return a partial result if some of the IOs were
1709 * successfully submitted? 1646 * successfully submitted?
@@ -1722,11 +1659,11 @@ long do_io_submit(aio_context_t ctx_id, long nr,
1722 break; 1659 break;
1723 } 1660 }
1724 1661
1725 ret = io_submit_one(ctx, user_iocb, &tmp, batch_hash, compat); 1662 ret = io_submit_one(ctx, user_iocb, &tmp, compat);
1726 if (ret) 1663 if (ret)
1727 break; 1664 break;
1728 } 1665 }
1729 aio_batch_free(batch_hash); 1666 blk_finish_plug(&plug);
1730 1667
1731 put_ioctx(ctx); 1668 put_ioctx(ctx);
1732 return i ? i : ret; 1669 return i ? i : ret;
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index b1d0c794747b..06457ed8f3e7 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -75,7 +75,6 @@ static const struct inode_operations befs_dir_inode_operations = {
75 75
76static const struct address_space_operations befs_aops = { 76static const struct address_space_operations befs_aops = {
77 .readpage = befs_readpage, 77 .readpage = befs_readpage,
78 .sync_page = block_sync_page,
79 .bmap = befs_bmap, 78 .bmap = befs_bmap,
80}; 79};
81 80
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index eb67edd0f8ea..f20e8a71062f 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -186,7 +186,6 @@ static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
186const struct address_space_operations bfs_aops = { 186const struct address_space_operations bfs_aops = {
187 .readpage = bfs_readpage, 187 .readpage = bfs_readpage,
188 .writepage = bfs_writepage, 188 .writepage = bfs_writepage,
189 .sync_page = block_sync_page,
190 .write_begin = bfs_write_begin, 189 .write_begin = bfs_write_begin,
191 .write_end = generic_write_end, 190 .write_end = generic_write_end,
192 .bmap = bfs_bmap, 191 .bmap = bfs_bmap,
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index e49cce234c65..9c5e6b2cd11a 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -761,6 +761,9 @@ int bioset_integrity_create(struct bio_set *bs, int pool_size)
761{ 761{
762 unsigned int max_slab = vecs_to_idx(BIO_MAX_PAGES); 762 unsigned int max_slab = vecs_to_idx(BIO_MAX_PAGES);
763 763
764 if (bs->bio_integrity_pool)
765 return 0;
766
764 bs->bio_integrity_pool = 767 bs->bio_integrity_pool =
765 mempool_create_slab_pool(pool_size, bip_slab[max_slab].slab); 768 mempool_create_slab_pool(pool_size, bip_slab[max_slab].slab);
766 769
diff --git a/fs/bio.c b/fs/bio.c
index 4cf2a52fbc54..4d6d4b6c2bf1 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -43,7 +43,7 @@ static mempool_t *bio_split_pool __read_mostly;
43 * unsigned short 43 * unsigned short
44 */ 44 */
45#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) } 45#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
46struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { 46static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
47 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), 47 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
48}; 48};
49#undef BV 49#undef BV
@@ -1636,9 +1636,6 @@ struct bio_set *bioset_create(unsigned int pool_size, unsigned int front_pad)
1636 if (!bs->bio_pool) 1636 if (!bs->bio_pool)
1637 goto bad; 1637 goto bad;
1638 1638
1639 if (bioset_integrity_create(bs, pool_size))
1640 goto bad;
1641
1642 if (!biovec_create_pools(bs, pool_size)) 1639 if (!biovec_create_pools(bs, pool_size))
1643 return bs; 1640 return bs;
1644 1641
@@ -1656,12 +1653,10 @@ static void __init biovec_init_slabs(void)
1656 int size; 1653 int size;
1657 struct biovec_slab *bvs = bvec_slabs + i; 1654 struct biovec_slab *bvs = bvec_slabs + i;
1658 1655
1659#ifndef CONFIG_BLK_DEV_INTEGRITY
1660 if (bvs->nr_vecs <= BIO_INLINE_VECS) { 1656 if (bvs->nr_vecs <= BIO_INLINE_VECS) {
1661 bvs->slab = NULL; 1657 bvs->slab = NULL;
1662 continue; 1658 continue;
1663 } 1659 }
1664#endif
1665 1660
1666 size = bvs->nr_vecs * sizeof(struct bio_vec); 1661 size = bvs->nr_vecs * sizeof(struct bio_vec);
1667 bvs->slab = kmem_cache_create(bvs->name, size, 0, 1662 bvs->slab = kmem_cache_create(bvs->name, size, 0,
@@ -1684,6 +1679,9 @@ static int __init init_bio(void)
1684 if (!fs_bio_set) 1679 if (!fs_bio_set)
1685 panic("bio: can't allocate bios\n"); 1680 panic("bio: can't allocate bios\n");
1686 1681
1682 if (bioset_integrity_create(fs_bio_set, BIO_POOL_SIZE))
1683 panic("bio: can't create integrity pool\n");
1684
1687 bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES, 1685 bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES,
1688 sizeof(struct bio_pair)); 1686 sizeof(struct bio_pair));
1689 if (!bio_split_pool) 1687 if (!bio_split_pool)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 2bbc0e62102f..c1511c674f53 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1089,6 +1089,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1089 if (!disk) 1089 if (!disk)
1090 goto out; 1090 goto out;
1091 1091
1092 disk_block_events(disk);
1092 mutex_lock_nested(&bdev->bd_mutex, for_part); 1093 mutex_lock_nested(&bdev->bd_mutex, for_part);
1093 if (!bdev->bd_openers) { 1094 if (!bdev->bd_openers) {
1094 bdev->bd_disk = disk; 1095 bdev->bd_disk = disk;
@@ -1110,10 +1111,11 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1110 */ 1111 */
1111 disk_put_part(bdev->bd_part); 1112 disk_put_part(bdev->bd_part);
1112 bdev->bd_part = NULL; 1113 bdev->bd_part = NULL;
1113 module_put(disk->fops->owner);
1114 put_disk(disk);
1115 bdev->bd_disk = NULL; 1114 bdev->bd_disk = NULL;
1116 mutex_unlock(&bdev->bd_mutex); 1115 mutex_unlock(&bdev->bd_mutex);
1116 disk_unblock_events(disk);
1117 module_put(disk->fops->owner);
1118 put_disk(disk);
1117 goto restart; 1119 goto restart;
1118 } 1120 }
1119 if (ret) 1121 if (ret)
@@ -1150,9 +1152,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1150 bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); 1152 bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
1151 } 1153 }
1152 } else { 1154 } else {
1153 module_put(disk->fops->owner);
1154 put_disk(disk);
1155 disk = NULL;
1156 if (bdev->bd_contains == bdev) { 1155 if (bdev->bd_contains == bdev) {
1157 if (bdev->bd_disk->fops->open) { 1156 if (bdev->bd_disk->fops->open) {
1158 ret = bdev->bd_disk->fops->open(bdev, mode); 1157 ret = bdev->bd_disk->fops->open(bdev, mode);
@@ -1162,11 +1161,15 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1162 if (bdev->bd_invalidated) 1161 if (bdev->bd_invalidated)
1163 rescan_partitions(bdev->bd_disk, bdev); 1162 rescan_partitions(bdev->bd_disk, bdev);
1164 } 1163 }
1164 /* only one opener holds refs to the module and disk */
1165 module_put(disk->fops->owner);
1166 put_disk(disk);
1165 } 1167 }
1166 bdev->bd_openers++; 1168 bdev->bd_openers++;
1167 if (for_part) 1169 if (for_part)
1168 bdev->bd_part_count++; 1170 bdev->bd_part_count++;
1169 mutex_unlock(&bdev->bd_mutex); 1171 mutex_unlock(&bdev->bd_mutex);
1172 disk_unblock_events(disk);
1170 return 0; 1173 return 0;
1171 1174
1172 out_clear: 1175 out_clear:
@@ -1179,10 +1182,10 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1179 bdev->bd_contains = NULL; 1182 bdev->bd_contains = NULL;
1180 out_unlock_bdev: 1183 out_unlock_bdev:
1181 mutex_unlock(&bdev->bd_mutex); 1184 mutex_unlock(&bdev->bd_mutex);
1182 out: 1185 disk_unblock_events(disk);
1183 if (disk) 1186 module_put(disk->fops->owner);
1184 module_put(disk->fops->owner);
1185 put_disk(disk); 1187 put_disk(disk);
1188 out:
1186 bdput(bdev); 1189 bdput(bdev);
1187 1190
1188 return ret; 1191 return ret;
@@ -1448,14 +1451,13 @@ int blkdev_put(struct block_device *bdev, fmode_t mode)
1448 if (bdev_free) { 1451 if (bdev_free) {
1449 if (bdev->bd_write_holder) { 1452 if (bdev->bd_write_holder) {
1450 disk_unblock_events(bdev->bd_disk); 1453 disk_unblock_events(bdev->bd_disk);
1451 bdev->bd_write_holder = false;
1452 } else
1453 disk_check_events(bdev->bd_disk); 1454 disk_check_events(bdev->bd_disk);
1455 bdev->bd_write_holder = false;
1456 }
1454 } 1457 }
1455 1458
1456 mutex_unlock(&bdev->bd_mutex); 1459 mutex_unlock(&bdev->bd_mutex);
1457 } else 1460 }
1458 disk_check_events(bdev->bd_disk);
1459 1461
1460 return __blkdev_put(bdev, mode, 0); 1462 return __blkdev_put(bdev, mode, 0);
1461} 1463}
@@ -1529,7 +1531,6 @@ static int blkdev_releasepage(struct page *page, gfp_t wait)
1529static const struct address_space_operations def_blk_aops = { 1531static const struct address_space_operations def_blk_aops = {
1530 .readpage = blkdev_readpage, 1532 .readpage = blkdev_readpage,
1531 .writepage = blkdev_writepage, 1533 .writepage = blkdev_writepage,
1532 .sync_page = block_sync_page,
1533 .write_begin = blkdev_write_begin, 1534 .write_begin = blkdev_write_begin,
1534 .write_end = blkdev_write_end, 1535 .write_end = blkdev_write_end,
1535 .writepages = generic_writepages, 1536 .writepages = generic_writepages,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 100b07f021b4..830d261d0e6b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -847,7 +847,6 @@ static const struct address_space_operations btree_aops = {
847 .writepages = btree_writepages, 847 .writepages = btree_writepages,
848 .releasepage = btree_releasepage, 848 .releasepage = btree_releasepage,
849 .invalidatepage = btree_invalidatepage, 849 .invalidatepage = btree_invalidatepage,
850 .sync_page = block_sync_page,
851#ifdef CONFIG_MIGRATION 850#ifdef CONFIG_MIGRATION
852 .migratepage = btree_migratepage, 851 .migratepage = btree_migratepage,
853#endif 852#endif
@@ -1331,82 +1330,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
1331} 1330}
1332 1331
1333/* 1332/*
1334 * this unplugs every device on the box, and it is only used when page
1335 * is null
1336 */
1337static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
1338{
1339 struct btrfs_device *device;
1340 struct btrfs_fs_info *info;
1341
1342 info = (struct btrfs_fs_info *)bdi->unplug_io_data;
1343 list_for_each_entry(device, &info->fs_devices->devices, dev_list) {
1344 if (!device->bdev)
1345 continue;
1346
1347 bdi = blk_get_backing_dev_info(device->bdev);
1348 if (bdi->unplug_io_fn)
1349 bdi->unplug_io_fn(bdi, page);
1350 }
1351}
1352
1353static void btrfs_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
1354{
1355 struct inode *inode;
1356 struct extent_map_tree *em_tree;
1357 struct extent_map *em;
1358 struct address_space *mapping;
1359 u64 offset;
1360
1361 /* the generic O_DIRECT read code does this */
1362 if (1 || !page) {
1363 __unplug_io_fn(bdi, page);
1364 return;
1365 }
1366
1367 /*
1368 * page->mapping may change at any time. Get a consistent copy
1369 * and use that for everything below
1370 */
1371 smp_mb();
1372 mapping = page->mapping;
1373 if (!mapping)
1374 return;
1375
1376 inode = mapping->host;
1377
1378 /*
1379 * don't do the expensive searching for a small number of
1380 * devices
1381 */
1382 if (BTRFS_I(inode)->root->fs_info->fs_devices->open_devices <= 2) {
1383 __unplug_io_fn(bdi, page);
1384 return;
1385 }
1386
1387 offset = page_offset(page);
1388
1389 em_tree = &BTRFS_I(inode)->extent_tree;
1390 read_lock(&em_tree->lock);
1391 em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE);
1392 read_unlock(&em_tree->lock);
1393 if (!em) {
1394 __unplug_io_fn(bdi, page);
1395 return;
1396 }
1397
1398 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
1399 free_extent_map(em);
1400 __unplug_io_fn(bdi, page);
1401 return;
1402 }
1403 offset = offset - em->start;
1404 btrfs_unplug_page(&BTRFS_I(inode)->root->fs_info->mapping_tree,
1405 em->block_start + offset, page);
1406 free_extent_map(em);
1407}
1408
1409/*
1410 * If this fails, caller must call bdi_destroy() to get rid of the 1333 * If this fails, caller must call bdi_destroy() to get rid of the
1411 * bdi again. 1334 * bdi again.
1412 */ 1335 */
@@ -1420,8 +1343,6 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
1420 return err; 1343 return err;
1421 1344
1422 bdi->ra_pages = default_backing_dev_info.ra_pages; 1345 bdi->ra_pages = default_backing_dev_info.ra_pages;
1423 bdi->unplug_io_fn = btrfs_unplug_io_fn;
1424 bdi->unplug_io_data = info;
1425 bdi->congested_fn = btrfs_congested_fn; 1346 bdi->congested_fn = btrfs_congested_fn;
1426 bdi->congested_data = info; 1347 bdi->congested_data = info;
1427 return 0; 1348 return 0;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 714adc4ac4c2..b5b92824a271 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2188,7 +2188,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2188 unsigned long nr_written = 0; 2188 unsigned long nr_written = 0;
2189 2189
2190 if (wbc->sync_mode == WB_SYNC_ALL) 2190 if (wbc->sync_mode == WB_SYNC_ALL)
2191 write_flags = WRITE_SYNC_PLUG; 2191 write_flags = WRITE_SYNC;
2192 else 2192 else
2193 write_flags = WRITE; 2193 write_flags = WRITE;
2194 2194
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 512c3d1da083..119520bdb9a5 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7340,7 +7340,6 @@ static const struct address_space_operations btrfs_aops = {
7340 .writepage = btrfs_writepage, 7340 .writepage = btrfs_writepage,
7341 .writepages = btrfs_writepages, 7341 .writepages = btrfs_writepages,
7342 .readpages = btrfs_readpages, 7342 .readpages = btrfs_readpages,
7343 .sync_page = block_sync_page,
7344 .direct_IO = btrfs_direct_IO, 7343 .direct_IO = btrfs_direct_IO,
7345 .invalidatepage = btrfs_invalidatepage, 7344 .invalidatepage = btrfs_invalidatepage,
7346 .releasepage = btrfs_releasepage, 7345 .releasepage = btrfs_releasepage,
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index dd13eb81ee40..9d554e8e6583 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -162,7 +162,6 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
162 struct bio *cur; 162 struct bio *cur;
163 int again = 0; 163 int again = 0;
164 unsigned long num_run; 164 unsigned long num_run;
165 unsigned long num_sync_run;
166 unsigned long batch_run = 0; 165 unsigned long batch_run = 0;
167 unsigned long limit; 166 unsigned long limit;
168 unsigned long last_waited = 0; 167 unsigned long last_waited = 0;
@@ -173,11 +172,6 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
173 limit = btrfs_async_submit_limit(fs_info); 172 limit = btrfs_async_submit_limit(fs_info);
174 limit = limit * 2 / 3; 173 limit = limit * 2 / 3;
175 174
176 /* we want to make sure that every time we switch from the sync
177 * list to the normal list, we unplug
178 */
179 num_sync_run = 0;
180
181loop: 175loop:
182 spin_lock(&device->io_lock); 176 spin_lock(&device->io_lock);
183 177
@@ -223,15 +217,6 @@ loop_lock:
223 217
224 spin_unlock(&device->io_lock); 218 spin_unlock(&device->io_lock);
225 219
226 /*
227 * if we're doing the regular priority list, make sure we unplug
228 * for any high prio bios we've sent down
229 */
230 if (pending_bios == &device->pending_bios && num_sync_run > 0) {
231 num_sync_run = 0;
232 blk_run_backing_dev(bdi, NULL);
233 }
234
235 while (pending) { 220 while (pending) {
236 221
237 rmb(); 222 rmb();
@@ -259,19 +244,11 @@ loop_lock:
259 244
260 BUG_ON(atomic_read(&cur->bi_cnt) == 0); 245 BUG_ON(atomic_read(&cur->bi_cnt) == 0);
261 246
262 if (cur->bi_rw & REQ_SYNC)
263 num_sync_run++;
264
265 submit_bio(cur->bi_rw, cur); 247 submit_bio(cur->bi_rw, cur);
266 num_run++; 248 num_run++;
267 batch_run++; 249 batch_run++;
268 if (need_resched()) { 250 if (need_resched())
269 if (num_sync_run) {
270 blk_run_backing_dev(bdi, NULL);
271 num_sync_run = 0;
272 }
273 cond_resched(); 251 cond_resched();
274 }
275 252
276 /* 253 /*
277 * we made progress, there is more work to do and the bdi 254 * we made progress, there is more work to do and the bdi
@@ -304,13 +281,8 @@ loop_lock:
304 * against it before looping 281 * against it before looping
305 */ 282 */
306 last_waited = ioc->last_waited; 283 last_waited = ioc->last_waited;
307 if (need_resched()) { 284 if (need_resched())
308 if (num_sync_run) {
309 blk_run_backing_dev(bdi, NULL);
310 num_sync_run = 0;
311 }
312 cond_resched(); 285 cond_resched();
313 }
314 continue; 286 continue;
315 } 287 }
316 spin_lock(&device->io_lock); 288 spin_lock(&device->io_lock);
@@ -323,22 +295,6 @@ loop_lock:
323 } 295 }
324 } 296 }
325 297
326 if (num_sync_run) {
327 num_sync_run = 0;
328 blk_run_backing_dev(bdi, NULL);
329 }
330 /*
331 * IO has already been through a long path to get here. Checksumming,
332 * async helper threads, perhaps compression. We've done a pretty
333 * good job of collecting a batch of IO and should just unplug
334 * the device right away.
335 *
336 * This will help anyone who is waiting on the IO, they might have
337 * already unplugged, but managed to do so before the bio they
338 * cared about found its way down here.
339 */
340 blk_run_backing_dev(bdi, NULL);
341
342 cond_resched(); 298 cond_resched();
343 if (again) 299 if (again)
344 goto loop; 300 goto loop;
@@ -2955,7 +2911,7 @@ static int find_live_mirror(struct map_lookup *map, int first, int num,
2955static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 2911static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
2956 u64 logical, u64 *length, 2912 u64 logical, u64 *length,
2957 struct btrfs_multi_bio **multi_ret, 2913 struct btrfs_multi_bio **multi_ret,
2958 int mirror_num, struct page *unplug_page) 2914 int mirror_num)
2959{ 2915{
2960 struct extent_map *em; 2916 struct extent_map *em;
2961 struct map_lookup *map; 2917 struct map_lookup *map;
@@ -2987,11 +2943,6 @@ again:
2987 em = lookup_extent_mapping(em_tree, logical, *length); 2943 em = lookup_extent_mapping(em_tree, logical, *length);
2988 read_unlock(&em_tree->lock); 2944 read_unlock(&em_tree->lock);
2989 2945
2990 if (!em && unplug_page) {
2991 kfree(multi);
2992 return 0;
2993 }
2994
2995 if (!em) { 2946 if (!em) {
2996 printk(KERN_CRIT "unable to find logical %llu len %llu\n", 2947 printk(KERN_CRIT "unable to find logical %llu len %llu\n",
2997 (unsigned long long)logical, 2948 (unsigned long long)logical,
@@ -3047,13 +2998,13 @@ again:
3047 *length = em->len - offset; 2998 *length = em->len - offset;
3048 } 2999 }
3049 3000
3050 if (!multi_ret && !unplug_page) 3001 if (!multi_ret)
3051 goto out; 3002 goto out;
3052 3003
3053 num_stripes = 1; 3004 num_stripes = 1;
3054 stripe_index = 0; 3005 stripe_index = 0;
3055 if (map->type & BTRFS_BLOCK_GROUP_RAID1) { 3006 if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
3056 if (unplug_page || (rw & REQ_WRITE)) 3007 if (rw & REQ_WRITE)
3057 num_stripes = map->num_stripes; 3008 num_stripes = map->num_stripes;
3058 else if (mirror_num) 3009 else if (mirror_num)
3059 stripe_index = mirror_num - 1; 3010 stripe_index = mirror_num - 1;
@@ -3075,7 +3026,7 @@ again:
3075 stripe_index = do_div(stripe_nr, factor); 3026 stripe_index = do_div(stripe_nr, factor);
3076 stripe_index *= map->sub_stripes; 3027 stripe_index *= map->sub_stripes;
3077 3028
3078 if (unplug_page || (rw & REQ_WRITE)) 3029 if (rw & REQ_WRITE)
3079 num_stripes = map->sub_stripes; 3030 num_stripes = map->sub_stripes;
3080 else if (mirror_num) 3031 else if (mirror_num)
3081 stripe_index += mirror_num - 1; 3032 stripe_index += mirror_num - 1;
@@ -3095,22 +3046,10 @@ again:
3095 BUG_ON(stripe_index >= map->num_stripes); 3046 BUG_ON(stripe_index >= map->num_stripes);
3096 3047
3097 for (i = 0; i < num_stripes; i++) { 3048 for (i = 0; i < num_stripes; i++) {
3098 if (unplug_page) { 3049 multi->stripes[i].physical =
3099 struct btrfs_device *device; 3050 map->stripes[stripe_index].physical +
3100 struct backing_dev_info *bdi; 3051 stripe_offset + stripe_nr * map->stripe_len;
3101 3052 multi->stripes[i].dev = map->stripes[stripe_index].dev;
3102 device = map->stripes[stripe_index].dev;
3103 if (device->bdev) {
3104 bdi = blk_get_backing_dev_info(device->bdev);
3105 if (bdi->unplug_io_fn)
3106 bdi->unplug_io_fn(bdi, unplug_page);
3107 }
3108 } else {
3109 multi->stripes[i].physical =
3110 map->stripes[stripe_index].physical +
3111 stripe_offset + stripe_nr * map->stripe_len;
3112 multi->stripes[i].dev = map->stripes[stripe_index].dev;
3113 }
3114 stripe_index++; 3053 stripe_index++;
3115 } 3054 }
3116 if (multi_ret) { 3055 if (multi_ret) {
@@ -3128,7 +3067,7 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
3128 struct btrfs_multi_bio **multi_ret, int mirror_num) 3067 struct btrfs_multi_bio **multi_ret, int mirror_num)
3129{ 3068{
3130 return __btrfs_map_block(map_tree, rw, logical, length, multi_ret, 3069 return __btrfs_map_block(map_tree, rw, logical, length, multi_ret,
3131 mirror_num, NULL); 3070 mirror_num);
3132} 3071}
3133 3072
3134int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, 3073int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
@@ -3196,14 +3135,6 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
3196 return 0; 3135 return 0;
3197} 3136}
3198 3137
3199int btrfs_unplug_page(struct btrfs_mapping_tree *map_tree,
3200 u64 logical, struct page *page)
3201{
3202 u64 length = PAGE_CACHE_SIZE;
3203 return __btrfs_map_block(map_tree, READ, logical, &length,
3204 NULL, 0, page);
3205}
3206
3207static void end_bio_multi_stripe(struct bio *bio, int err) 3138static void end_bio_multi_stripe(struct bio *bio, int err)
3208{ 3139{
3209 struct btrfs_multi_bio *multi = bio->bi_private; 3140 struct btrfs_multi_bio *multi = bio->bi_private;
diff --git a/fs/buffer.c b/fs/buffer.c
index da666f3148f9..a08bb8e61c6f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -54,23 +54,15 @@ init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private)
54} 54}
55EXPORT_SYMBOL(init_buffer); 55EXPORT_SYMBOL(init_buffer);
56 56
57static int sync_buffer(void *word) 57static int sleep_on_buffer(void *word)
58{ 58{
59 struct block_device *bd;
60 struct buffer_head *bh
61 = container_of(word, struct buffer_head, b_state);
62
63 smp_mb();
64 bd = bh->b_bdev;
65 if (bd)
66 blk_run_address_space(bd->bd_inode->i_mapping);
67 io_schedule(); 59 io_schedule();
68 return 0; 60 return 0;
69} 61}
70 62
71void __lock_buffer(struct buffer_head *bh) 63void __lock_buffer(struct buffer_head *bh)
72{ 64{
73 wait_on_bit_lock(&bh->b_state, BH_Lock, sync_buffer, 65 wait_on_bit_lock(&bh->b_state, BH_Lock, sleep_on_buffer,
74 TASK_UNINTERRUPTIBLE); 66 TASK_UNINTERRUPTIBLE);
75} 67}
76EXPORT_SYMBOL(__lock_buffer); 68EXPORT_SYMBOL(__lock_buffer);
@@ -90,7 +82,7 @@ EXPORT_SYMBOL(unlock_buffer);
90 */ 82 */
91void __wait_on_buffer(struct buffer_head * bh) 83void __wait_on_buffer(struct buffer_head * bh)
92{ 84{
93 wait_on_bit(&bh->b_state, BH_Lock, sync_buffer, TASK_UNINTERRUPTIBLE); 85 wait_on_bit(&bh->b_state, BH_Lock, sleep_on_buffer, TASK_UNINTERRUPTIBLE);
94} 86}
95EXPORT_SYMBOL(__wait_on_buffer); 87EXPORT_SYMBOL(__wait_on_buffer);
96 88
@@ -749,10 +741,12 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
749{ 741{
750 struct buffer_head *bh; 742 struct buffer_head *bh;
751 struct list_head tmp; 743 struct list_head tmp;
752 struct address_space *mapping, *prev_mapping = NULL; 744 struct address_space *mapping;
753 int err = 0, err2; 745 int err = 0, err2;
746 struct blk_plug plug;
754 747
755 INIT_LIST_HEAD(&tmp); 748 INIT_LIST_HEAD(&tmp);
749 blk_start_plug(&plug);
756 750
757 spin_lock(lock); 751 spin_lock(lock);
758 while (!list_empty(list)) { 752 while (!list_empty(list)) {
@@ -775,7 +769,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
775 * still in flight on potentially older 769 * still in flight on potentially older
776 * contents. 770 * contents.
777 */ 771 */
778 write_dirty_buffer(bh, WRITE_SYNC_PLUG); 772 write_dirty_buffer(bh, WRITE_SYNC);
779 773
780 /* 774 /*
781 * Kick off IO for the previous mapping. Note 775 * Kick off IO for the previous mapping. Note
@@ -783,16 +777,16 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
783 * wait_on_buffer() will do that for us 777 * wait_on_buffer() will do that for us
784 * through sync_buffer(). 778 * through sync_buffer().
785 */ 779 */
786 if (prev_mapping && prev_mapping != mapping)
787 blk_run_address_space(prev_mapping);
788 prev_mapping = mapping;
789
790 brelse(bh); 780 brelse(bh);
791 spin_lock(lock); 781 spin_lock(lock);
792 } 782 }
793 } 783 }
794 } 784 }
795 785
786 spin_unlock(lock);
787 blk_finish_plug(&plug);
788 spin_lock(lock);
789
796 while (!list_empty(&tmp)) { 790 while (!list_empty(&tmp)) {
797 bh = BH_ENTRY(tmp.prev); 791 bh = BH_ENTRY(tmp.prev);
798 get_bh(bh); 792 get_bh(bh);
@@ -1614,14 +1608,8 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
1614 * prevents this contention from occurring. 1608 * prevents this contention from occurring.
1615 * 1609 *
1616 * If block_write_full_page() is called with wbc->sync_mode == 1610 * If block_write_full_page() is called with wbc->sync_mode ==
1617 * WB_SYNC_ALL, the writes are posted using WRITE_SYNC_PLUG; this 1611 * WB_SYNC_ALL, the writes are posted using WRITE_SYNC; this
1618 * causes the writes to be flagged as synchronous writes, but the 1612 * causes the writes to be flagged as synchronous writes.
1619 * block device queue will NOT be unplugged, since usually many pages
1620 * will be pushed to the out before the higher-level caller actually
1621 * waits for the writes to be completed. The various wait functions,
1622 * such as wait_on_writeback_range() will ultimately call sync_page()
1623 * which will ultimately call blk_run_backing_dev(), which will end up
1624 * unplugging the device queue.
1625 */ 1613 */
1626static int __block_write_full_page(struct inode *inode, struct page *page, 1614static int __block_write_full_page(struct inode *inode, struct page *page,
1627 get_block_t *get_block, struct writeback_control *wbc, 1615 get_block_t *get_block, struct writeback_control *wbc,
@@ -1634,7 +1622,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
1634 const unsigned blocksize = 1 << inode->i_blkbits; 1622 const unsigned blocksize = 1 << inode->i_blkbits;
1635 int nr_underway = 0; 1623 int nr_underway = 0;
1636 int write_op = (wbc->sync_mode == WB_SYNC_ALL ? 1624 int write_op = (wbc->sync_mode == WB_SYNC_ALL ?
1637 WRITE_SYNC_PLUG : WRITE); 1625 WRITE_SYNC : WRITE);
1638 1626
1639 BUG_ON(!PageLocked(page)); 1627 BUG_ON(!PageLocked(page));
1640 1628
@@ -3138,17 +3126,6 @@ out:
3138} 3126}
3139EXPORT_SYMBOL(try_to_free_buffers); 3127EXPORT_SYMBOL(try_to_free_buffers);
3140 3128
3141void block_sync_page(struct page *page)
3142{
3143 struct address_space *mapping;
3144
3145 smp_mb();
3146 mapping = page_mapping(page);
3147 if (mapping)
3148 blk_run_backing_dev(mapping->backing_dev_info, page);
3149}
3150EXPORT_SYMBOL(block_sync_page);
3151
3152/* 3129/*
3153 * There are no bdflush tunables left. But distributions are 3130 * There are no bdflush tunables left. But distributions are
3154 * still running obsolete flush daemons, so we terminate them here. 3131 * still running obsolete flush daemons, so we terminate them here.
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e964b1cd5dd0..c27d236738fc 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1569,34 +1569,6 @@ int cifs_fsync(struct file *file, int datasync)
1569 return rc; 1569 return rc;
1570} 1570}
1571 1571
1572/* static void cifs_sync_page(struct page *page)
1573{
1574 struct address_space *mapping;
1575 struct inode *inode;
1576 unsigned long index = page->index;
1577 unsigned int rpages = 0;
1578 int rc = 0;
1579
1580 cFYI(1, "sync page %p", page);
1581 mapping = page->mapping;
1582 if (!mapping)
1583 return 0;
1584 inode = mapping->host;
1585 if (!inode)
1586 return; */
1587
1588/* fill in rpages then
1589 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
1590
1591/* cFYI(1, "rpages is %d for sync page of Index %ld", rpages, index);
1592
1593#if 0
1594 if (rc < 0)
1595 return rc;
1596 return 0;
1597#endif
1598} */
1599
1600/* 1572/*
1601 * As file closes, flush all cached write data for this inode checking 1573 * As file closes, flush all cached write data for this inode checking
1602 * for write behind errors. 1574 * for write behind errors.
@@ -2510,7 +2482,6 @@ const struct address_space_operations cifs_addr_ops = {
2510 .set_page_dirty = __set_page_dirty_nobuffers, 2482 .set_page_dirty = __set_page_dirty_nobuffers,
2511 .releasepage = cifs_release_page, 2483 .releasepage = cifs_release_page,
2512 .invalidatepage = cifs_invalidate_page, 2484 .invalidatepage = cifs_invalidate_page,
2513 /* .sync_page = cifs_sync_page, */
2514 /* .direct_IO = */ 2485 /* .direct_IO = */
2515}; 2486};
2516 2487
@@ -2528,6 +2499,5 @@ const struct address_space_operations cifs_addr_ops_smallbuf = {
2528 .set_page_dirty = __set_page_dirty_nobuffers, 2499 .set_page_dirty = __set_page_dirty_nobuffers,
2529 .releasepage = cifs_release_page, 2500 .releasepage = cifs_release_page,
2530 .invalidatepage = cifs_invalidate_page, 2501 .invalidatepage = cifs_invalidate_page,
2531 /* .sync_page = cifs_sync_page, */
2532 /* .direct_IO = */ 2502 /* .direct_IO = */
2533}; 2503};
diff --git a/fs/direct-io.c b/fs/direct-io.c
index dcb5577cde1d..ac5f164170e3 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1110,11 +1110,8 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
1110 ((rw & READ) || (dio->result == dio->size))) 1110 ((rw & READ) || (dio->result == dio->size)))
1111 ret = -EIOCBQUEUED; 1111 ret = -EIOCBQUEUED;
1112 1112
1113 if (ret != -EIOCBQUEUED) { 1113 if (ret != -EIOCBQUEUED)
1114 /* All IO is now issued, send it on its way */
1115 blk_run_address_space(inode->i_mapping);
1116 dio_await_completion(dio); 1114 dio_await_completion(dio);
1117 }
1118 1115
1119 /* 1116 /*
1120 * Sync will always be dropping the final ref and completing the 1117 * Sync will always be dropping the final ref and completing the
@@ -1176,7 +1173,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1176 struct dio *dio; 1173 struct dio *dio;
1177 1174
1178 if (rw & WRITE) 1175 if (rw & WRITE)
1179 rw = WRITE_ODIRECT_PLUG; 1176 rw = WRITE_ODIRECT;
1180 1177
1181 if (bdev) 1178 if (bdev)
1182 bdev_blkbits = blksize_bits(bdev_logical_block_size(bdev)); 1179 bdev_blkbits = blksize_bits(bdev_logical_block_size(bdev));
diff --git a/fs/efs/inode.c b/fs/efs/inode.c
index a8e7797b9477..9c13412e6c99 100644
--- a/fs/efs/inode.c
+++ b/fs/efs/inode.c
@@ -23,7 +23,6 @@ static sector_t _efs_bmap(struct address_space *mapping, sector_t block)
23} 23}
24static const struct address_space_operations efs_aops = { 24static const struct address_space_operations efs_aops = {
25 .readpage = efs_readpage, 25 .readpage = efs_readpage,
26 .sync_page = block_sync_page,
27 .bmap = _efs_bmap 26 .bmap = _efs_bmap
28}; 27};
29 28
diff --git a/fs/exofs/common.h b/fs/exofs/common.h
index f0d520312d8b..5e74ad3d4009 100644
--- a/fs/exofs/common.h
+++ b/fs/exofs/common.h
@@ -53,10 +53,14 @@
53#define EXOFS_ROOT_ID 0x10002 /* object ID for root directory */ 53#define EXOFS_ROOT_ID 0x10002 /* object ID for root directory */
54 54
55/* exofs Application specific page/attribute */ 55/* exofs Application specific page/attribute */
56/* Inode attrs */
56# define EXOFS_APAGE_FS_DATA (OSD_APAGE_APP_DEFINED_FIRST + 3) 57# define EXOFS_APAGE_FS_DATA (OSD_APAGE_APP_DEFINED_FIRST + 3)
57# define EXOFS_ATTR_INODE_DATA 1 58# define EXOFS_ATTR_INODE_DATA 1
58# define EXOFS_ATTR_INODE_FILE_LAYOUT 2 59# define EXOFS_ATTR_INODE_FILE_LAYOUT 2
59# define EXOFS_ATTR_INODE_DIR_LAYOUT 3 60# define EXOFS_ATTR_INODE_DIR_LAYOUT 3
61/* Partition attrs */
62# define EXOFS_APAGE_SB_DATA (0xF0000000U + 3)
63# define EXOFS_ATTR_SB_STATS 1
60 64
61/* 65/*
62 * The maximum number of files we can have is limited by the size of the 66 * The maximum number of files we can have is limited by the size of the
@@ -86,8 +90,8 @@ enum {
86 */ 90 */
87enum {EXOFS_FSCB_VER = 1, EXOFS_DT_VER = 1}; 91enum {EXOFS_FSCB_VER = 1, EXOFS_DT_VER = 1};
88struct exofs_fscb { 92struct exofs_fscb {
89 __le64 s_nextid; /* Highest object ID used */ 93 __le64 s_nextid; /* Only used after mkfs */
90 __le64 s_numfiles; /* Number of files on fs */ 94 __le64 s_numfiles; /* Only used after mkfs */
91 __le32 s_version; /* == EXOFS_FSCB_VER */ 95 __le32 s_version; /* == EXOFS_FSCB_VER */
92 __le16 s_magic; /* Magic signature */ 96 __le16 s_magic; /* Magic signature */
93 __le16 s_newfs; /* Non-zero if this is a new fs */ 97 __le16 s_newfs; /* Non-zero if this is a new fs */
@@ -98,6 +102,16 @@ struct exofs_fscb {
98} __packed; 102} __packed;
99 103
100/* 104/*
105 * This struct is set on the FS partition's attributes.
106 * [EXOFS_APAGE_SB_DATA, EXOFS_ATTR_SB_STATS] and is written together
107 * with the create command, to atomically persist the sb writeable information.
108 */
109struct exofs_sb_stats {
110 __le64 s_nextid; /* Highest object ID used */
111 __le64 s_numfiles; /* Number of files on fs */
112} __packed;
113
114/*
101 * Describes the raid used in the FS. It is part of the device table. 115 * Describes the raid used in the FS. It is part of the device table.
102 * This here is taken from the pNFS-objects definition. In exofs we 116 * This here is taken from the pNFS-objects definition. In exofs we
103 * use one raid policy through-out the filesystem. (NOTE: the funny 117 * use one raid policy through-out the filesystem. (NOTE: the funny
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
index dcc941d82d67..d0941c6a1f72 100644
--- a/fs/exofs/dir.c
+++ b/fs/exofs/dir.c
@@ -124,7 +124,7 @@ out:
124 124
125Ebadsize: 125Ebadsize:
126 EXOFS_ERR("ERROR [exofs_check_page]: " 126 EXOFS_ERR("ERROR [exofs_check_page]: "
127 "size of directory #%lu is not a multiple of chunk size", 127 "size of directory(0x%lx) is not a multiple of chunk size\n",
128 dir->i_ino 128 dir->i_ino
129 ); 129 );
130 goto fail; 130 goto fail;
@@ -142,8 +142,8 @@ Espan:
142 goto bad_entry; 142 goto bad_entry;
143bad_entry: 143bad_entry:
144 EXOFS_ERR( 144 EXOFS_ERR(
145 "ERROR [exofs_check_page]: bad entry in directory #%lu: %s - " 145 "ERROR [exofs_check_page]: bad entry in directory(0x%lx): %s - "
146 "offset=%lu, inode=%llu, rec_len=%d, name_len=%d", 146 "offset=%lu, inode=0x%llu, rec_len=%d, name_len=%d\n",
147 dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs, 147 dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
148 _LLU(le64_to_cpu(p->inode_no)), 148 _LLU(le64_to_cpu(p->inode_no)),
149 rec_len, p->name_len); 149 rec_len, p->name_len);
@@ -151,8 +151,8 @@ bad_entry:
151Eend: 151Eend:
152 p = (struct exofs_dir_entry *)(kaddr + offs); 152 p = (struct exofs_dir_entry *)(kaddr + offs);
153 EXOFS_ERR("ERROR [exofs_check_page]: " 153 EXOFS_ERR("ERROR [exofs_check_page]: "
154 "entry in directory #%lu spans the page boundary" 154 "entry in directory(0x%lx) spans the page boundary"
155 "offset=%lu, inode=%llu", 155 "offset=%lu, inode=0x%llx\n",
156 dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs, 156 dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
157 _LLU(le64_to_cpu(p->inode_no))); 157 _LLU(le64_to_cpu(p->inode_no)));
158fail: 158fail:
@@ -261,9 +261,8 @@ exofs_readdir(struct file *filp, void *dirent, filldir_t filldir)
261 struct page *page = exofs_get_page(inode, n); 261 struct page *page = exofs_get_page(inode, n);
262 262
263 if (IS_ERR(page)) { 263 if (IS_ERR(page)) {
264 EXOFS_ERR("ERROR: " 264 EXOFS_ERR("ERROR: bad page in directory(0x%lx)\n",
265 "bad page in #%lu", 265 inode->i_ino);
266 inode->i_ino);
267 filp->f_pos += PAGE_CACHE_SIZE - offset; 266 filp->f_pos += PAGE_CACHE_SIZE - offset;
268 return PTR_ERR(page); 267 return PTR_ERR(page);
269 } 268 }
@@ -283,7 +282,8 @@ exofs_readdir(struct file *filp, void *dirent, filldir_t filldir)
283 for (; (char *)de <= limit; de = exofs_next_entry(de)) { 282 for (; (char *)de <= limit; de = exofs_next_entry(de)) {
284 if (de->rec_len == 0) { 283 if (de->rec_len == 0) {
285 EXOFS_ERR("ERROR: " 284 EXOFS_ERR("ERROR: "
286 "zero-length directory entry"); 285 "zero-length entry in directory(0x%lx)\n",
286 inode->i_ino);
287 exofs_put_page(page); 287 exofs_put_page(page);
288 return -EIO; 288 return -EIO;
289 } 289 }
@@ -342,9 +342,9 @@ struct exofs_dir_entry *exofs_find_entry(struct inode *dir,
342 kaddr += exofs_last_byte(dir, n) - reclen; 342 kaddr += exofs_last_byte(dir, n) - reclen;
343 while ((char *) de <= kaddr) { 343 while ((char *) de <= kaddr) {
344 if (de->rec_len == 0) { 344 if (de->rec_len == 0) {
345 EXOFS_ERR( 345 EXOFS_ERR("ERROR: zero-length entry in "
346 "ERROR: exofs_find_entry: " 346 "directory(0x%lx)\n",
347 "zero-length directory entry"); 347 dir->i_ino);
348 exofs_put_page(page); 348 exofs_put_page(page);
349 goto out; 349 goto out;
350 } 350 }
@@ -472,7 +472,8 @@ int exofs_add_link(struct dentry *dentry, struct inode *inode)
472 } 472 }
473 if (de->rec_len == 0) { 473 if (de->rec_len == 0) {
474 EXOFS_ERR("ERROR: exofs_add_link: " 474 EXOFS_ERR("ERROR: exofs_add_link: "
475 "zero-length directory entry"); 475 "zero-length entry in directory(0x%lx)\n",
476 inode->i_ino);
476 err = -EIO; 477 err = -EIO;
477 goto out_unlock; 478 goto out_unlock;
478 } 479 }
@@ -491,7 +492,8 @@ int exofs_add_link(struct dentry *dentry, struct inode *inode)
491 exofs_put_page(page); 492 exofs_put_page(page);
492 } 493 }
493 494
494 EXOFS_ERR("exofs_add_link: BAD dentry=%p or inode=%p", dentry, inode); 495 EXOFS_ERR("exofs_add_link: BAD dentry=%p or inode=0x%lx\n",
496 dentry, inode->i_ino);
495 return -EINVAL; 497 return -EINVAL;
496 498
497got_it: 499got_it:
@@ -542,7 +544,8 @@ int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page)
542 while (de < dir) { 544 while (de < dir) {
543 if (de->rec_len == 0) { 545 if (de->rec_len == 0) {
544 EXOFS_ERR("ERROR: exofs_delete_entry:" 546 EXOFS_ERR("ERROR: exofs_delete_entry:"
545 "zero-length directory entry"); 547 "zero-length entry in directory(0x%lx)\n",
548 inode->i_ino);
546 err = -EIO; 549 err = -EIO;
547 goto out; 550 goto out;
548 } 551 }
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 2dc925fa1010..c965806c2821 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -77,7 +77,7 @@ struct exofs_layout {
77 * our extension to the in-memory superblock 77 * our extension to the in-memory superblock
78 */ 78 */
79struct exofs_sb_info { 79struct exofs_sb_info {
80 struct exofs_fscb s_fscb; /* Written often, pre-allocate*/ 80 struct exofs_sb_stats s_ess; /* Written often, pre-allocate*/
81 int s_timeout; /* timeout for OSD operations */ 81 int s_timeout; /* timeout for OSD operations */
82 uint64_t s_nextid; /* highest object ID used */ 82 uint64_t s_nextid; /* highest object ID used */
83 uint32_t s_numfiles; /* number of files on fs */ 83 uint32_t s_numfiles; /* number of files on fs */
@@ -256,6 +256,8 @@ static inline int exofs_oi_read(struct exofs_i_info *oi,
256} 256}
257 257
258/* inode.c */ 258/* inode.c */
259unsigned exofs_max_io_pages(struct exofs_layout *layout,
260 unsigned expected_pages);
259int exofs_setattr(struct dentry *, struct iattr *); 261int exofs_setattr(struct dentry *, struct iattr *);
260int exofs_write_begin(struct file *file, struct address_space *mapping, 262int exofs_write_begin(struct file *file, struct address_space *mapping,
261 loff_t pos, unsigned len, unsigned flags, 263 loff_t pos, unsigned len, unsigned flags,
@@ -279,7 +281,7 @@ int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *,
279 struct inode *); 281 struct inode *);
280 282
281/* super.c */ 283/* super.c */
282int exofs_sync_fs(struct super_block *sb, int wait); 284int exofs_sbi_write_stats(struct exofs_sb_info *sbi);
283 285
284/********************* 286/*********************
285 * operation vectors * 287 * operation vectors *
diff --git a/fs/exofs/file.c b/fs/exofs/file.c
index b905c79b4f0a..45ca323d8363 100644
--- a/fs/exofs/file.c
+++ b/fs/exofs/file.c
@@ -45,22 +45,8 @@ static int exofs_release_file(struct inode *inode, struct file *filp)
45static int exofs_file_fsync(struct file *filp, int datasync) 45static int exofs_file_fsync(struct file *filp, int datasync)
46{ 46{
47 int ret; 47 int ret;
48 struct inode *inode = filp->f_mapping->host;
49 struct super_block *sb;
50
51 if (!(inode->i_state & I_DIRTY))
52 return 0;
53 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
54 return 0;
55
56 ret = sync_inode_metadata(inode, 1);
57
58 /* This is a good place to write the sb */
59 /* TODO: Sechedule an sb-sync on create */
60 sb = inode->i_sb;
61 if (sb->s_dirt)
62 exofs_sync_fs(sb, 1);
63 48
49 ret = sync_inode_metadata(filp->f_mapping->host, 1);
64 return ret; 50 return ret;
65} 51}
66 52
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index a7555238c41a..8472c098445d 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -43,6 +43,17 @@ enum { BIO_MAX_PAGES_KMALLOC =
43 PAGE_SIZE / sizeof(struct page *), 43 PAGE_SIZE / sizeof(struct page *),
44}; 44};
45 45
46unsigned exofs_max_io_pages(struct exofs_layout *layout,
47 unsigned expected_pages)
48{
49 unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC);
50
51 /* TODO: easily support bio chaining */
52 pages = min_t(unsigned, pages,
53 layout->group_width * BIO_MAX_PAGES_KMALLOC);
54 return pages;
55}
56
46struct page_collect { 57struct page_collect {
47 struct exofs_sb_info *sbi; 58 struct exofs_sb_info *sbi;
48 struct inode *inode; 59 struct inode *inode;
@@ -97,8 +108,7 @@ static void _pcol_reset(struct page_collect *pcol)
97 108
98static int pcol_try_alloc(struct page_collect *pcol) 109static int pcol_try_alloc(struct page_collect *pcol)
99{ 110{
100 unsigned pages = min_t(unsigned, pcol->expected_pages, 111 unsigned pages;
101 MAX_PAGES_KMALLOC);
102 112
103 if (!pcol->ios) { /* First time allocate io_state */ 113 if (!pcol->ios) { /* First time allocate io_state */
104 int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); 114 int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios);
@@ -108,8 +118,7 @@ static int pcol_try_alloc(struct page_collect *pcol)
108 } 118 }
109 119
110 /* TODO: easily support bio chaining */ 120 /* TODO: easily support bio chaining */
111 pages = min_t(unsigned, pages, 121 pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages);
112 pcol->sbi->layout.group_width * BIO_MAX_PAGES_KMALLOC);
113 122
114 for (; pages; pages >>= 1) { 123 for (; pages; pages >>= 1) {
115 pcol->pages = kmalloc(pages * sizeof(struct page *), 124 pcol->pages = kmalloc(pages * sizeof(struct page *),
@@ -350,8 +359,10 @@ static int readpage_strip(void *data, struct page *page)
350 359
351 if (!pcol->read_4_write) 360 if (!pcol->read_4_write)
352 unlock_page(page); 361 unlock_page(page);
353 EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," 362 EXOFS_DBGMSG("readpage_strip(0x%lx) empty page len=%zx "
354 " splitting\n", inode->i_ino, page->index); 363 "read_4_write=%d index=0x%lx end_index=0x%lx "
364 "splitting\n", inode->i_ino, len,
365 pcol->read_4_write, page->index, end_index);
355 366
356 return read_exec(pcol); 367 return read_exec(pcol);
357 } 368 }
@@ -722,11 +733,28 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
722 733
723 /* read modify write */ 734 /* read modify write */
724 if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) { 735 if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) {
736 loff_t i_size = i_size_read(mapping->host);
737 pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
738 size_t rlen;
739
740 if (page->index < end_index)
741 rlen = PAGE_CACHE_SIZE;
742 else if (page->index == end_index)
743 rlen = i_size & ~PAGE_CACHE_MASK;
744 else
745 rlen = 0;
746
747 if (!rlen) {
748 clear_highpage(page);
749 SetPageUptodate(page);
750 goto out;
751 }
752
725 ret = _readpage(page, true); 753 ret = _readpage(page, true);
726 if (ret) { 754 if (ret) {
727 /*SetPageError was done by _readpage. Is it ok?*/ 755 /*SetPageError was done by _readpage. Is it ok?*/
728 unlock_page(page); 756 unlock_page(page);
729 EXOFS_DBGMSG("__readpage_filler failed\n"); 757 EXOFS_DBGMSG("__readpage failed\n");
730 } 758 }
731 } 759 }
732out: 760out:
@@ -795,7 +823,6 @@ const struct address_space_operations exofs_aops = {
795 .direct_IO = NULL, /* TODO: Should be trivial to do */ 823 .direct_IO = NULL, /* TODO: Should be trivial to do */
796 824
797 /* With these NULL has special meaning or default is not exported */ 825 /* With these NULL has special meaning or default is not exported */
798 .sync_page = NULL,
799 .get_xip_mem = NULL, 826 .get_xip_mem = NULL,
800 .migratepage = NULL, 827 .migratepage = NULL,
801 .launder_page = NULL, 828 .launder_page = NULL,
@@ -1030,6 +1057,7 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino)
1030 memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); 1057 memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data));
1031 } 1058 }
1032 1059
1060 inode->i_mapping->backing_dev_info = sb->s_bdi;
1033 if (S_ISREG(inode->i_mode)) { 1061 if (S_ISREG(inode->i_mode)) {
1034 inode->i_op = &exofs_file_inode_operations; 1062 inode->i_op = &exofs_file_inode_operations;
1035 inode->i_fop = &exofs_file_operations; 1063 inode->i_fop = &exofs_file_operations;
@@ -1073,6 +1101,7 @@ int __exofs_wait_obj_created(struct exofs_i_info *oi)
1073 } 1101 }
1074 return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0; 1102 return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0;
1075} 1103}
1104
1076/* 1105/*
1077 * Callback function from exofs_new_inode(). The important thing is that we 1106 * Callback function from exofs_new_inode(). The important thing is that we
1078 * set the obj_created flag so that other methods know that the object exists on 1107 * set the obj_created flag so that other methods know that the object exists on
@@ -1130,7 +1159,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)
1130 1159
1131 sbi = sb->s_fs_info; 1160 sbi = sb->s_fs_info;
1132 1161
1133 sb->s_dirt = 1; 1162 inode->i_mapping->backing_dev_info = sb->s_bdi;
1134 inode_init_owner(inode, dir, mode); 1163 inode_init_owner(inode, dir, mode);
1135 inode->i_ino = sbi->s_nextid++; 1164 inode->i_ino = sbi->s_nextid++;
1136 inode->i_blkbits = EXOFS_BLKSHIFT; 1165 inode->i_blkbits = EXOFS_BLKSHIFT;
@@ -1141,6 +1170,8 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)
1141 spin_unlock(&sbi->s_next_gen_lock); 1170 spin_unlock(&sbi->s_next_gen_lock);
1142 insert_inode_hash(inode); 1171 insert_inode_hash(inode);
1143 1172
1173 exofs_sbi_write_stats(sbi); /* Make sure new sbi->s_nextid is on disk */
1174
1144 mark_inode_dirty(inode); 1175 mark_inode_dirty(inode);
1145 1176
1146 ret = exofs_get_io_state(&sbi->layout, &ios); 1177 ret = exofs_get_io_state(&sbi->layout, &ios);
@@ -1271,7 +1302,8 @@ out:
1271 1302
1272int exofs_write_inode(struct inode *inode, struct writeback_control *wbc) 1303int exofs_write_inode(struct inode *inode, struct writeback_control *wbc)
1273{ 1304{
1274 return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 1305 /* FIXME: fix fsync and use wbc->sync_mode == WB_SYNC_ALL */
1306 return exofs_update_inode(inode, 1);
1275} 1307}
1276 1308
1277/* 1309/*
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 8c6c4669b381..06065bd37fc3 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -48,6 +48,7 @@
48 * struct to hold what we get from mount options 48 * struct to hold what we get from mount options
49 */ 49 */
50struct exofs_mountopt { 50struct exofs_mountopt {
51 bool is_osdname;
51 const char *dev_name; 52 const char *dev_name;
52 uint64_t pid; 53 uint64_t pid;
53 int timeout; 54 int timeout;
@@ -56,7 +57,7 @@ struct exofs_mountopt {
56/* 57/*
57 * exofs-specific mount-time options. 58 * exofs-specific mount-time options.
58 */ 59 */
59enum { Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err }; 60enum { Opt_name, Opt_pid, Opt_to, Opt_err };
60 61
61/* 62/*
62 * Our mount-time options. These should ideally be 64-bit unsigned, but the 63 * Our mount-time options. These should ideally be 64-bit unsigned, but the
@@ -64,6 +65,7 @@ enum { Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err };
64 * sufficient for most applications now. 65 * sufficient for most applications now.
65 */ 66 */
66static match_table_t tokens = { 67static match_table_t tokens = {
68 {Opt_name, "osdname=%s"},
67 {Opt_pid, "pid=%u"}, 69 {Opt_pid, "pid=%u"},
68 {Opt_to, "to=%u"}, 70 {Opt_to, "to=%u"},
69 {Opt_err, NULL} 71 {Opt_err, NULL}
@@ -94,6 +96,14 @@ static int parse_options(char *options, struct exofs_mountopt *opts)
94 96
95 token = match_token(p, tokens, args); 97 token = match_token(p, tokens, args);
96 switch (token) { 98 switch (token) {
99 case Opt_name:
100 opts->dev_name = match_strdup(&args[0]);
101 if (unlikely(!opts->dev_name)) {
102 EXOFS_ERR("Error allocating dev_name");
103 return -ENOMEM;
104 }
105 opts->is_osdname = true;
106 break;
97 case Opt_pid: 107 case Opt_pid:
98 if (0 == match_strlcpy(str, &args[0], sizeof(str))) 108 if (0 == match_strlcpy(str, &args[0], sizeof(str)))
99 return -EINVAL; 109 return -EINVAL;
@@ -203,6 +213,101 @@ static void destroy_inodecache(void)
203static const struct super_operations exofs_sops; 213static const struct super_operations exofs_sops;
204static const struct export_operations exofs_export_ops; 214static const struct export_operations exofs_export_ops;
205 215
216static const struct osd_attr g_attr_sb_stats = ATTR_DEF(
217 EXOFS_APAGE_SB_DATA,
218 EXOFS_ATTR_SB_STATS,
219 sizeof(struct exofs_sb_stats));
220
221static int __sbi_read_stats(struct exofs_sb_info *sbi)
222{
223 struct osd_attr attrs[] = {
224 [0] = g_attr_sb_stats,
225 };
226 struct exofs_io_state *ios;
227 int ret;
228
229 ret = exofs_get_io_state(&sbi->layout, &ios);
230 if (unlikely(ret)) {
231 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
232 return ret;
233 }
234
235 ios->cred = sbi->s_cred;
236
237 ios->in_attr = attrs;
238 ios->in_attr_len = ARRAY_SIZE(attrs);
239
240 ret = exofs_sbi_read(ios);
241 if (unlikely(ret)) {
242 EXOFS_ERR("Error reading super_block stats => %d\n", ret);
243 goto out;
244 }
245
246 ret = extract_attr_from_ios(ios, &attrs[0]);
247 if (ret) {
248 EXOFS_ERR("%s: extract_attr of sb_stats failed\n", __func__);
249 goto out;
250 }
251 if (attrs[0].len) {
252 struct exofs_sb_stats *ess;
253
254 if (unlikely(attrs[0].len != sizeof(*ess))) {
255 EXOFS_ERR("%s: Wrong version of exofs_sb_stats "
256 "size(%d) != expected(%zd)\n",
257 __func__, attrs[0].len, sizeof(*ess));
258 goto out;
259 }
260
261 ess = attrs[0].val_ptr;
262 sbi->s_nextid = le64_to_cpu(ess->s_nextid);
263 sbi->s_numfiles = le32_to_cpu(ess->s_numfiles);
264 }
265
266out:
267 exofs_put_io_state(ios);
268 return ret;
269}
270
271static void stats_done(struct exofs_io_state *ios, void *p)
272{
273 exofs_put_io_state(ios);
274 /* Good thanks nothing to do anymore */
275}
276
277/* Asynchronously write the stats attribute */
278int exofs_sbi_write_stats(struct exofs_sb_info *sbi)
279{
280 struct osd_attr attrs[] = {
281 [0] = g_attr_sb_stats,
282 };
283 struct exofs_io_state *ios;
284 int ret;
285
286 ret = exofs_get_io_state(&sbi->layout, &ios);
287 if (unlikely(ret)) {
288 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
289 return ret;
290 }
291
292 sbi->s_ess.s_nextid = cpu_to_le64(sbi->s_nextid);
293 sbi->s_ess.s_numfiles = cpu_to_le64(sbi->s_numfiles);
294 attrs[0].val_ptr = &sbi->s_ess;
295
296 ios->cred = sbi->s_cred;
297 ios->done = stats_done;
298 ios->private = sbi;
299 ios->out_attr = attrs;
300 ios->out_attr_len = ARRAY_SIZE(attrs);
301
302 ret = exofs_sbi_write(ios);
303 if (unlikely(ret)) {
304 EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__);
305 exofs_put_io_state(ios);
306 }
307
308 return ret;
309}
310
206/* 311/*
207 * Write the superblock to the OSD 312 * Write the superblock to the OSD
208 */ 313 */
@@ -213,18 +318,25 @@ int exofs_sync_fs(struct super_block *sb, int wait)
213 struct exofs_io_state *ios; 318 struct exofs_io_state *ios;
214 int ret = -ENOMEM; 319 int ret = -ENOMEM;
215 320
216 lock_super(sb); 321 fscb = kmalloc(sizeof(*fscb), GFP_KERNEL);
322 if (unlikely(!fscb))
323 return -ENOMEM;
324
217 sbi = sb->s_fs_info; 325 sbi = sb->s_fs_info;
218 fscb = &sbi->s_fscb;
219 326
327 /* NOTE: We no longer dirty the super_block anywhere in exofs. The
328 * reason we write the fscb here on unmount is so we can stay backwards
329 * compatible with fscb->s_version == 1. (What we are not compatible
330 * with is if a new version FS crashed and then we try to mount an old
331 * version). Otherwise the exofs_fscb is read-only from mkfs time. All
332 * the writeable info is set in exofs_sbi_write_stats() above.
333 */
220 ret = exofs_get_io_state(&sbi->layout, &ios); 334 ret = exofs_get_io_state(&sbi->layout, &ios);
221 if (ret) 335 if (unlikely(ret))
222 goto out; 336 goto out;
223 337
224 /* Note: We only write the changing part of the fscb. .i.e upto the 338 lock_super(sb);
225 * the fscb->s_dev_table_oid member. There is no read-modify-write 339
226 * here.
227 */
228 ios->length = offsetof(struct exofs_fscb, s_dev_table_oid); 340 ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
229 memset(fscb, 0, ios->length); 341 memset(fscb, 0, ios->length);
230 fscb->s_nextid = cpu_to_le64(sbi->s_nextid); 342 fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
@@ -239,16 +351,17 @@ int exofs_sync_fs(struct super_block *sb, int wait)
239 ios->cred = sbi->s_cred; 351 ios->cred = sbi->s_cred;
240 352
241 ret = exofs_sbi_write(ios); 353 ret = exofs_sbi_write(ios);
242 if (unlikely(ret)) { 354 if (unlikely(ret))
243 EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__); 355 EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__);
244 goto out; 356 else
245 } 357 sb->s_dirt = 0;
246 sb->s_dirt = 0; 358
247 359
360 unlock_super(sb);
248out: 361out:
249 EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret); 362 EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
250 exofs_put_io_state(ios); 363 exofs_put_io_state(ios);
251 unlock_super(sb); 364 kfree(fscb);
252 return ret; 365 return ret;
253} 366}
254 367
@@ -292,13 +405,14 @@ static void exofs_put_super(struct super_block *sb)
292 int num_pend; 405 int num_pend;
293 struct exofs_sb_info *sbi = sb->s_fs_info; 406 struct exofs_sb_info *sbi = sb->s_fs_info;
294 407
295 if (sb->s_dirt)
296 exofs_write_super(sb);
297
298 /* make sure there are no pending commands */ 408 /* make sure there are no pending commands */
299 for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0; 409 for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
300 num_pend = atomic_read(&sbi->s_curr_pending)) { 410 num_pend = atomic_read(&sbi->s_curr_pending)) {
301 wait_queue_head_t wq; 411 wait_queue_head_t wq;
412
413 printk(KERN_NOTICE "%s: !!Pending operations in flight. "
414 "This is a BUG. please report to osd-dev@open-osd.org\n",
415 __func__);
302 init_waitqueue_head(&wq); 416 init_waitqueue_head(&wq);
303 wait_event_timeout(wq, 417 wait_event_timeout(wq,
304 (atomic_read(&sbi->s_curr_pending) == 0), 418 (atomic_read(&sbi->s_curr_pending) == 0),
@@ -390,6 +504,23 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
390 return 0; 504 return 0;
391} 505}
392 506
507static unsigned __ra_pages(struct exofs_layout *layout)
508{
509 const unsigned _MIN_RA = 32; /* min 128K read-ahead */
510 unsigned ra_pages = layout->group_width * layout->stripe_unit /
511 PAGE_SIZE;
512 unsigned max_io_pages = exofs_max_io_pages(layout, ~0);
513
514 ra_pages *= 2; /* two stripes */
515 if (ra_pages < _MIN_RA)
516 ra_pages = roundup(_MIN_RA, ra_pages / 2);
517
518 if (ra_pages > max_io_pages)
519 ra_pages = max_io_pages;
520
521 return ra_pages;
522}
523
393/* @odi is valid only as long as @fscb_dev is valid */ 524/* @odi is valid only as long as @fscb_dev is valid */
394static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev, 525static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev,
395 struct osd_dev_info *odi) 526 struct osd_dev_info *odi)
@@ -495,7 +626,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi,
495 } 626 }
496 627
497 od = osduld_info_lookup(&odi); 628 od = osduld_info_lookup(&odi);
498 if (unlikely(IS_ERR(od))) { 629 if (IS_ERR(od)) {
499 ret = PTR_ERR(od); 630 ret = PTR_ERR(od);
500 EXOFS_ERR("ERROR: device requested is not found " 631 EXOFS_ERR("ERROR: device requested is not found "
501 "osd_name-%s =>%d\n", odi.osdname, ret); 632 "osd_name-%s =>%d\n", odi.osdname, ret);
@@ -558,9 +689,17 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
558 goto free_bdi; 689 goto free_bdi;
559 690
560 /* use mount options to fill superblock */ 691 /* use mount options to fill superblock */
561 od = osduld_path_lookup(opts->dev_name); 692 if (opts->is_osdname) {
693 struct osd_dev_info odi = {.systemid_len = 0};
694
695 odi.osdname_len = strlen(opts->dev_name);
696 odi.osdname = (u8 *)opts->dev_name;
697 od = osduld_info_lookup(&odi);
698 } else {
699 od = osduld_path_lookup(opts->dev_name);
700 }
562 if (IS_ERR(od)) { 701 if (IS_ERR(od)) {
563 ret = PTR_ERR(od); 702 ret = -EINVAL;
564 goto free_sbi; 703 goto free_sbi;
565 } 704 }
566 705
@@ -594,6 +733,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
594 goto free_sbi; 733 goto free_sbi;
595 734
596 sb->s_magic = le16_to_cpu(fscb.s_magic); 735 sb->s_magic = le16_to_cpu(fscb.s_magic);
736 /* NOTE: we read below to be backward compatible with old versions */
597 sbi->s_nextid = le64_to_cpu(fscb.s_nextid); 737 sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
598 sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles); 738 sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles);
599 739
@@ -604,7 +744,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
604 ret = -EINVAL; 744 ret = -EINVAL;
605 goto free_sbi; 745 goto free_sbi;
606 } 746 }
607 if (le32_to_cpu(fscb.s_version) != EXOFS_FSCB_VER) { 747 if (le32_to_cpu(fscb.s_version) > EXOFS_FSCB_VER) {
608 EXOFS_ERR("ERROR: Bad FSCB version expected-%d got-%d\n", 748 EXOFS_ERR("ERROR: Bad FSCB version expected-%d got-%d\n",
609 EXOFS_FSCB_VER, le32_to_cpu(fscb.s_version)); 749 EXOFS_FSCB_VER, le32_to_cpu(fscb.s_version));
610 ret = -EINVAL; 750 ret = -EINVAL;
@@ -622,7 +762,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
622 goto free_sbi; 762 goto free_sbi;
623 } 763 }
624 764
765 __sbi_read_stats(sbi);
766
625 /* set up operation vectors */ 767 /* set up operation vectors */
768 sbi->bdi.ra_pages = __ra_pages(&sbi->layout);
626 sb->s_bdi = &sbi->bdi; 769 sb->s_bdi = &sbi->bdi;
627 sb->s_fs_info = sbi; 770 sb->s_fs_info = sbi;
628 sb->s_op = &exofs_sops; 771 sb->s_op = &exofs_sops;
@@ -652,6 +795,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
652 795
653 _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0], 796 _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0],
654 sbi->layout.s_pid); 797 sbi->layout.s_pid);
798 if (opts->is_osdname)
799 kfree(opts->dev_name);
655 return 0; 800 return 0;
656 801
657free_sbi: 802free_sbi:
@@ -660,6 +805,8 @@ free_bdi:
660 EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", 805 EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
661 opts->dev_name, sbi->layout.s_pid, ret); 806 opts->dev_name, sbi->layout.s_pid, ret);
662 exofs_free_sbi(sbi); 807 exofs_free_sbi(sbi);
808 if (opts->is_osdname)
809 kfree(opts->dev_name);
663 return ret; 810 return ret;
664} 811}
665 812
@@ -677,7 +824,8 @@ static struct dentry *exofs_mount(struct file_system_type *type,
677 if (ret) 824 if (ret)
678 return ERR_PTR(ret); 825 return ERR_PTR(ret);
679 826
680 opts.dev_name = dev_name; 827 if (!opts.dev_name)
828 opts.dev_name = dev_name;
681 return mount_nodev(type, flags, &opts, exofs_fill_super); 829 return mount_nodev(type, flags, &opts, exofs_fill_super);
682} 830}
683 831
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 40ad210a5049..c47f706878b5 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -860,7 +860,6 @@ const struct address_space_operations ext2_aops = {
860 .readpage = ext2_readpage, 860 .readpage = ext2_readpage,
861 .readpages = ext2_readpages, 861 .readpages = ext2_readpages,
862 .writepage = ext2_writepage, 862 .writepage = ext2_writepage,
863 .sync_page = block_sync_page,
864 .write_begin = ext2_write_begin, 863 .write_begin = ext2_write_begin,
865 .write_end = ext2_write_end, 864 .write_end = ext2_write_end,
866 .bmap = ext2_bmap, 865 .bmap = ext2_bmap,
@@ -880,7 +879,6 @@ const struct address_space_operations ext2_nobh_aops = {
880 .readpage = ext2_readpage, 879 .readpage = ext2_readpage,
881 .readpages = ext2_readpages, 880 .readpages = ext2_readpages,
882 .writepage = ext2_nobh_writepage, 881 .writepage = ext2_nobh_writepage,
883 .sync_page = block_sync_page,
884 .write_begin = ext2_nobh_write_begin, 882 .write_begin = ext2_nobh_write_begin,
885 .write_end = nobh_write_end, 883 .write_end = nobh_write_end,
886 .bmap = ext2_bmap, 884 .bmap = ext2_bmap,
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index ae94f6d949f5..fe2541d250e4 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1894,7 +1894,6 @@ static const struct address_space_operations ext3_ordered_aops = {
1894 .readpage = ext3_readpage, 1894 .readpage = ext3_readpage,
1895 .readpages = ext3_readpages, 1895 .readpages = ext3_readpages,
1896 .writepage = ext3_ordered_writepage, 1896 .writepage = ext3_ordered_writepage,
1897 .sync_page = block_sync_page,
1898 .write_begin = ext3_write_begin, 1897 .write_begin = ext3_write_begin,
1899 .write_end = ext3_ordered_write_end, 1898 .write_end = ext3_ordered_write_end,
1900 .bmap = ext3_bmap, 1899 .bmap = ext3_bmap,
@@ -1910,7 +1909,6 @@ static const struct address_space_operations ext3_writeback_aops = {
1910 .readpage = ext3_readpage, 1909 .readpage = ext3_readpage,
1911 .readpages = ext3_readpages, 1910 .readpages = ext3_readpages,
1912 .writepage = ext3_writeback_writepage, 1911 .writepage = ext3_writeback_writepage,
1913 .sync_page = block_sync_page,
1914 .write_begin = ext3_write_begin, 1912 .write_begin = ext3_write_begin,
1915 .write_end = ext3_writeback_write_end, 1913 .write_end = ext3_writeback_write_end,
1916 .bmap = ext3_bmap, 1914 .bmap = ext3_bmap,
@@ -1926,7 +1924,6 @@ static const struct address_space_operations ext3_journalled_aops = {
1926 .readpage = ext3_readpage, 1924 .readpage = ext3_readpage,
1927 .readpages = ext3_readpages, 1925 .readpages = ext3_readpages,
1928 .writepage = ext3_journalled_writepage, 1926 .writepage = ext3_journalled_writepage,
1929 .sync_page = block_sync_page,
1930 .write_begin = ext3_write_begin, 1927 .write_begin = ext3_write_begin,
1931 .write_end = ext3_journalled_write_end, 1928 .write_end = ext3_journalled_write_end,
1932 .set_page_dirty = ext3_journalled_set_page_dirty, 1929 .set_page_dirty = ext3_journalled_set_page_dirty,
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 9f7f9e49914f..9297ad46c465 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3903,7 +3903,6 @@ static const struct address_space_operations ext4_ordered_aops = {
3903 .readpage = ext4_readpage, 3903 .readpage = ext4_readpage,
3904 .readpages = ext4_readpages, 3904 .readpages = ext4_readpages,
3905 .writepage = ext4_writepage, 3905 .writepage = ext4_writepage,
3906 .sync_page = block_sync_page,
3907 .write_begin = ext4_write_begin, 3906 .write_begin = ext4_write_begin,
3908 .write_end = ext4_ordered_write_end, 3907 .write_end = ext4_ordered_write_end,
3909 .bmap = ext4_bmap, 3908 .bmap = ext4_bmap,
@@ -3919,7 +3918,6 @@ static const struct address_space_operations ext4_writeback_aops = {
3919 .readpage = ext4_readpage, 3918 .readpage = ext4_readpage,
3920 .readpages = ext4_readpages, 3919 .readpages = ext4_readpages,
3921 .writepage = ext4_writepage, 3920 .writepage = ext4_writepage,
3922 .sync_page = block_sync_page,
3923 .write_begin = ext4_write_begin, 3921 .write_begin = ext4_write_begin,
3924 .write_end = ext4_writeback_write_end, 3922 .write_end = ext4_writeback_write_end,
3925 .bmap = ext4_bmap, 3923 .bmap = ext4_bmap,
@@ -3935,7 +3933,6 @@ static const struct address_space_operations ext4_journalled_aops = {
3935 .readpage = ext4_readpage, 3933 .readpage = ext4_readpage,
3936 .readpages = ext4_readpages, 3934 .readpages = ext4_readpages,
3937 .writepage = ext4_writepage, 3935 .writepage = ext4_writepage,
3938 .sync_page = block_sync_page,
3939 .write_begin = ext4_write_begin, 3936 .write_begin = ext4_write_begin,
3940 .write_end = ext4_journalled_write_end, 3937 .write_end = ext4_journalled_write_end,
3941 .set_page_dirty = ext4_journalled_set_page_dirty, 3938 .set_page_dirty = ext4_journalled_set_page_dirty,
@@ -3951,7 +3948,6 @@ static const struct address_space_operations ext4_da_aops = {
3951 .readpages = ext4_readpages, 3948 .readpages = ext4_readpages,
3952 .writepage = ext4_writepage, 3949 .writepage = ext4_writepage,
3953 .writepages = ext4_da_writepages, 3950 .writepages = ext4_da_writepages,
3954 .sync_page = block_sync_page,
3955 .write_begin = ext4_da_write_begin, 3951 .write_begin = ext4_da_write_begin,
3956 .write_end = ext4_da_write_end, 3952 .write_end = ext4_da_write_end,
3957 .bmap = ext4_bmap, 3953 .bmap = ext4_bmap,
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 955cc309142f..e2cd90e4bb7c 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -310,8 +310,7 @@ static int io_submit_init(struct ext4_io_submit *io,
310 io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh); 310 io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh);
311 311
312 io->io_bio = bio; 312 io->io_bio = bio;
313 io->io_op = (wbc->sync_mode == WB_SYNC_ALL ? 313 io->io_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
314 WRITE_SYNC_PLUG : WRITE);
315 io->io_next_block = bh->b_blocknr; 314 io->io_next_block = bh->b_blocknr;
316 return 0; 315 return 0;
317} 316}
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 0e277ec4b612..8d68690bdcf1 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -236,7 +236,6 @@ static const struct address_space_operations fat_aops = {
236 .readpages = fat_readpages, 236 .readpages = fat_readpages,
237 .writepage = fat_writepage, 237 .writepage = fat_writepage,
238 .writepages = fat_writepages, 238 .writepages = fat_writepages,
239 .sync_page = block_sync_page,
240 .write_begin = fat_write_begin, 239 .write_begin = fat_write_begin,
241 .write_end = fat_write_end, 240 .write_end = fat_write_end,
242 .direct_IO = fat_direct_IO, 241 .direct_IO = fat_direct_IO,
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
index 1429f3ae1e86..5d318c44f855 100644
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -44,7 +44,6 @@ static sector_t vxfs_bmap(struct address_space *, sector_t);
44const struct address_space_operations vxfs_aops = { 44const struct address_space_operations vxfs_aops = {
45 .readpage = vxfs_readpage, 45 .readpage = vxfs_readpage,
46 .bmap = vxfs_bmap, 46 .bmap = vxfs_bmap,
47 .sync_page = block_sync_page,
48}; 47};
49 48
50inline void 49inline void
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 051b1a084528..cc6ec4b2f0ff 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -870,7 +870,6 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
870 870
871 fc->bdi.name = "fuse"; 871 fc->bdi.name = "fuse";
872 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 872 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
873 fc->bdi.unplug_io_fn = default_unplug_io_fn;
874 /* fuse does it's own writeback accounting */ 873 /* fuse does it's own writeback accounting */
875 fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; 874 fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB;
876 875
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index aad77e4f61b5..c71995b111bf 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -1117,7 +1117,6 @@ static const struct address_space_operations gfs2_writeback_aops = {
1117 .writepages = gfs2_writeback_writepages, 1117 .writepages = gfs2_writeback_writepages,
1118 .readpage = gfs2_readpage, 1118 .readpage = gfs2_readpage,
1119 .readpages = gfs2_readpages, 1119 .readpages = gfs2_readpages,
1120 .sync_page = block_sync_page,
1121 .write_begin = gfs2_write_begin, 1120 .write_begin = gfs2_write_begin,
1122 .write_end = gfs2_write_end, 1121 .write_end = gfs2_write_end,
1123 .bmap = gfs2_bmap, 1122 .bmap = gfs2_bmap,
@@ -1133,7 +1132,6 @@ static const struct address_space_operations gfs2_ordered_aops = {
1133 .writepage = gfs2_ordered_writepage, 1132 .writepage = gfs2_ordered_writepage,
1134 .readpage = gfs2_readpage, 1133 .readpage = gfs2_readpage,
1135 .readpages = gfs2_readpages, 1134 .readpages = gfs2_readpages,
1136 .sync_page = block_sync_page,
1137 .write_begin = gfs2_write_begin, 1135 .write_begin = gfs2_write_begin,
1138 .write_end = gfs2_write_end, 1136 .write_end = gfs2_write_end,
1139 .set_page_dirty = gfs2_set_page_dirty, 1137 .set_page_dirty = gfs2_set_page_dirty,
@@ -1151,7 +1149,6 @@ static const struct address_space_operations gfs2_jdata_aops = {
1151 .writepages = gfs2_jdata_writepages, 1149 .writepages = gfs2_jdata_writepages,
1152 .readpage = gfs2_readpage, 1150 .readpage = gfs2_readpage,
1153 .readpages = gfs2_readpages, 1151 .readpages = gfs2_readpages,
1154 .sync_page = block_sync_page,
1155 .write_begin = gfs2_write_begin, 1152 .write_begin = gfs2_write_begin,
1156 .write_end = gfs2_write_end, 1153 .write_end = gfs2_write_end,
1157 .set_page_dirty = gfs2_set_page_dirty, 1154 .set_page_dirty = gfs2_set_page_dirty,
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index e7ed31f858dd..5b102c1887fd 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -121,7 +121,7 @@ __acquires(&sdp->sd_ail_lock)
121 lock_buffer(bh); 121 lock_buffer(bh);
122 if (test_clear_buffer_dirty(bh)) { 122 if (test_clear_buffer_dirty(bh)) {
123 bh->b_end_io = end_buffer_write_sync; 123 bh->b_end_io = end_buffer_write_sync;
124 submit_bh(WRITE_SYNC_PLUG, bh); 124 submit_bh(WRITE_SYNC, bh);
125 } else { 125 } else {
126 unlock_buffer(bh); 126 unlock_buffer(bh);
127 brelse(bh); 127 brelse(bh);
@@ -647,7 +647,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp)
647 lock_buffer(bh); 647 lock_buffer(bh);
648 if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) { 648 if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) {
649 bh->b_end_io = end_buffer_write_sync; 649 bh->b_end_io = end_buffer_write_sync;
650 submit_bh(WRITE_SYNC_PLUG, bh); 650 submit_bh(WRITE_SYNC, bh);
651 } else { 651 } else {
652 unlock_buffer(bh); 652 unlock_buffer(bh);
653 brelse(bh); 653 brelse(bh);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index e919abf25ecd..51d27f00ebb4 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -204,7 +204,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
204 } 204 }
205 205
206 gfs2_log_unlock(sdp); 206 gfs2_log_unlock(sdp);
207 submit_bh(WRITE_SYNC_PLUG, bh); 207 submit_bh(WRITE_SYNC, bh);
208 gfs2_log_lock(sdp); 208 gfs2_log_lock(sdp);
209 209
210 n = 0; 210 n = 0;
@@ -214,7 +214,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
214 gfs2_log_unlock(sdp); 214 gfs2_log_unlock(sdp);
215 lock_buffer(bd2->bd_bh); 215 lock_buffer(bd2->bd_bh);
216 bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); 216 bh = gfs2_log_fake_buf(sdp, bd2->bd_bh);
217 submit_bh(WRITE_SYNC_PLUG, bh); 217 submit_bh(WRITE_SYNC, bh);
218 gfs2_log_lock(sdp); 218 gfs2_log_lock(sdp);
219 if (++n >= num) 219 if (++n >= num)
220 break; 220 break;
@@ -356,7 +356,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
356 sdp->sd_log_num_revoke--; 356 sdp->sd_log_num_revoke--;
357 357
358 if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { 358 if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) {
359 submit_bh(WRITE_SYNC_PLUG, bh); 359 submit_bh(WRITE_SYNC, bh);
360 360
361 bh = gfs2_log_get_buf(sdp); 361 bh = gfs2_log_get_buf(sdp);
362 mh = (struct gfs2_meta_header *)bh->b_data; 362 mh = (struct gfs2_meta_header *)bh->b_data;
@@ -373,7 +373,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
373 } 373 }
374 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 374 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
375 375
376 submit_bh(WRITE_SYNC_PLUG, bh); 376 submit_bh(WRITE_SYNC, bh);
377} 377}
378 378
379static void revoke_lo_before_scan(struct gfs2_jdesc *jd, 379static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
@@ -575,7 +575,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
575 ptr = bh_log_ptr(bh); 575 ptr = bh_log_ptr(bh);
576 576
577 get_bh(bh); 577 get_bh(bh);
578 submit_bh(WRITE_SYNC_PLUG, bh); 578 submit_bh(WRITE_SYNC, bh);
579 gfs2_log_lock(sdp); 579 gfs2_log_lock(sdp);
580 while(!list_empty(list)) { 580 while(!list_empty(list)) {
581 bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list); 581 bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list);
@@ -601,7 +601,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
601 } else { 601 } else {
602 bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh); 602 bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh);
603 } 603 }
604 submit_bh(WRITE_SYNC_PLUG, bh1); 604 submit_bh(WRITE_SYNC, bh1);
605 gfs2_log_lock(sdp); 605 gfs2_log_lock(sdp);
606 ptr += 2; 606 ptr += 2;
607 } 607 }
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 01d97f486553..675349b5a133 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -37,7 +37,7 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb
37 struct buffer_head *bh, *head; 37 struct buffer_head *bh, *head;
38 int nr_underway = 0; 38 int nr_underway = 0;
39 int write_op = REQ_META | 39 int write_op = REQ_META |
40 (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC_PLUG : WRITE); 40 (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
41 41
42 BUG_ON(!PageLocked(page)); 42 BUG_ON(!PageLocked(page));
43 BUG_ON(!page_has_buffers(page)); 43 BUG_ON(!page_has_buffers(page));
@@ -94,7 +94,6 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb
94const struct address_space_operations gfs2_meta_aops = { 94const struct address_space_operations gfs2_meta_aops = {
95 .writepage = gfs2_aspace_writepage, 95 .writepage = gfs2_aspace_writepage,
96 .releasepage = gfs2_releasepage, 96 .releasepage = gfs2_releasepage,
97 .sync_page = block_sync_page,
98}; 97};
99 98
100/** 99/**
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index dffb4e996643..fff16c968e67 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -150,7 +150,6 @@ static int hfs_writepages(struct address_space *mapping,
150const struct address_space_operations hfs_btree_aops = { 150const struct address_space_operations hfs_btree_aops = {
151 .readpage = hfs_readpage, 151 .readpage = hfs_readpage,
152 .writepage = hfs_writepage, 152 .writepage = hfs_writepage,
153 .sync_page = block_sync_page,
154 .write_begin = hfs_write_begin, 153 .write_begin = hfs_write_begin,
155 .write_end = generic_write_end, 154 .write_end = generic_write_end,
156 .bmap = hfs_bmap, 155 .bmap = hfs_bmap,
@@ -160,7 +159,6 @@ const struct address_space_operations hfs_btree_aops = {
160const struct address_space_operations hfs_aops = { 159const struct address_space_operations hfs_aops = {
161 .readpage = hfs_readpage, 160 .readpage = hfs_readpage,
162 .writepage = hfs_writepage, 161 .writepage = hfs_writepage,
163 .sync_page = block_sync_page,
164 .write_begin = hfs_write_begin, 162 .write_begin = hfs_write_begin,
165 .write_end = generic_write_end, 163 .write_end = generic_write_end,
166 .bmap = hfs_bmap, 164 .bmap = hfs_bmap,
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index a8df651747f0..b248a6cfcad9 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -146,7 +146,6 @@ static int hfsplus_writepages(struct address_space *mapping,
146const struct address_space_operations hfsplus_btree_aops = { 146const struct address_space_operations hfsplus_btree_aops = {
147 .readpage = hfsplus_readpage, 147 .readpage = hfsplus_readpage,
148 .writepage = hfsplus_writepage, 148 .writepage = hfsplus_writepage,
149 .sync_page = block_sync_page,
150 .write_begin = hfsplus_write_begin, 149 .write_begin = hfsplus_write_begin,
151 .write_end = generic_write_end, 150 .write_end = generic_write_end,
152 .bmap = hfsplus_bmap, 151 .bmap = hfsplus_bmap,
@@ -156,7 +155,6 @@ const struct address_space_operations hfsplus_btree_aops = {
156const struct address_space_operations hfsplus_aops = { 155const struct address_space_operations hfsplus_aops = {
157 .readpage = hfsplus_readpage, 156 .readpage = hfsplus_readpage,
158 .writepage = hfsplus_writepage, 157 .writepage = hfsplus_writepage,
159 .sync_page = block_sync_page,
160 .write_begin = hfsplus_write_begin, 158 .write_begin = hfsplus_write_begin,
161 .write_end = generic_write_end, 159 .write_end = generic_write_end,
162 .bmap = hfsplus_bmap, 160 .bmap = hfsplus_bmap,
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index 2dbae20450f8..9b9eb6933e43 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -119,7 +119,6 @@ static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
119const struct address_space_operations hpfs_aops = { 119const struct address_space_operations hpfs_aops = {
120 .readpage = hpfs_readpage, 120 .readpage = hpfs_readpage,
121 .writepage = hpfs_writepage, 121 .writepage = hpfs_writepage,
122 .sync_page = block_sync_page,
123 .write_begin = hpfs_write_begin, 122 .write_begin = hpfs_write_begin,
124 .write_end = generic_write_end, 123 .write_end = generic_write_end,
125 .bmap = _hpfs_bmap 124 .bmap = _hpfs_bmap
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index a0f3833c0dbf..3db5ba4568fc 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -1158,7 +1158,6 @@ static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
1158 1158
1159static const struct address_space_operations isofs_aops = { 1159static const struct address_space_operations isofs_aops = {
1160 .readpage = isofs_readpage, 1160 .readpage = isofs_readpage,
1161 .sync_page = block_sync_page,
1162 .bmap = _isofs_bmap 1161 .bmap = _isofs_bmap
1163}; 1162};
1164 1163
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 34a4861c14b8..da871ee084d3 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -20,6 +20,7 @@
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/pagemap.h> 21#include <linux/pagemap.h>
22#include <linux/bio.h> 22#include <linux/bio.h>
23#include <linux/blkdev.h>
23 24
24/* 25/*
25 * Default IO end handler for temporary BJ_IO buffer_heads. 26 * Default IO end handler for temporary BJ_IO buffer_heads.
@@ -294,7 +295,7 @@ void journal_commit_transaction(journal_t *journal)
294 int first_tag = 0; 295 int first_tag = 0;
295 int tag_flag; 296 int tag_flag;
296 int i; 297 int i;
297 int write_op = WRITE_SYNC; 298 struct blk_plug plug;
298 299
299 /* 300 /*
300 * First job: lock down the current transaction and wait for 301 * First job: lock down the current transaction and wait for
@@ -327,13 +328,6 @@ void journal_commit_transaction(journal_t *journal)
327 spin_lock(&journal->j_state_lock); 328 spin_lock(&journal->j_state_lock);
328 commit_transaction->t_state = T_LOCKED; 329 commit_transaction->t_state = T_LOCKED;
329 330
330 /*
331 * Use plugged writes here, since we want to submit several before
332 * we unplug the device. We don't do explicit unplugging in here,
333 * instead we rely on sync_buffer() doing the unplug for us.
334 */
335 if (commit_transaction->t_synchronous_commit)
336 write_op = WRITE_SYNC_PLUG;
337 spin_lock(&commit_transaction->t_handle_lock); 331 spin_lock(&commit_transaction->t_handle_lock);
338 while (commit_transaction->t_updates) { 332 while (commit_transaction->t_updates) {
339 DEFINE_WAIT(wait); 333 DEFINE_WAIT(wait);
@@ -418,8 +412,10 @@ void journal_commit_transaction(journal_t *journal)
418 * Now start flushing things to disk, in the order they appear 412 * Now start flushing things to disk, in the order they appear
419 * on the transaction lists. Data blocks go first. 413 * on the transaction lists. Data blocks go first.
420 */ 414 */
415 blk_start_plug(&plug);
421 err = journal_submit_data_buffers(journal, commit_transaction, 416 err = journal_submit_data_buffers(journal, commit_transaction,
422 write_op); 417 WRITE_SYNC);
418 blk_finish_plug(&plug);
423 419
424 /* 420 /*
425 * Wait for all previously submitted IO to complete. 421 * Wait for all previously submitted IO to complete.
@@ -480,7 +476,9 @@ void journal_commit_transaction(journal_t *journal)
480 err = 0; 476 err = 0;
481 } 477 }
482 478
483 journal_write_revoke_records(journal, commit_transaction, write_op); 479 blk_start_plug(&plug);
480
481 journal_write_revoke_records(journal, commit_transaction, WRITE_SYNC);
484 482
485 /* 483 /*
486 * If we found any dirty or locked buffers, then we should have 484 * If we found any dirty or locked buffers, then we should have
@@ -650,7 +648,7 @@ start_journal_io:
650 clear_buffer_dirty(bh); 648 clear_buffer_dirty(bh);
651 set_buffer_uptodate(bh); 649 set_buffer_uptodate(bh);
652 bh->b_end_io = journal_end_buffer_io_sync; 650 bh->b_end_io = journal_end_buffer_io_sync;
653 submit_bh(write_op, bh); 651 submit_bh(WRITE_SYNC, bh);
654 } 652 }
655 cond_resched(); 653 cond_resched();
656 654
@@ -661,6 +659,8 @@ start_journal_io:
661 } 659 }
662 } 660 }
663 661
662 blk_finish_plug(&plug);
663
664 /* Lo and behold: we have just managed to send a transaction to 664 /* Lo and behold: we have just managed to send a transaction to
665 the log. Before we can commit it, wait for the IO so far to 665 the log. Before we can commit it, wait for the IO so far to
666 complete. Control buffers being written are on the 666 complete. Control buffers being written are on the
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index f3ad1598b201..fa36d7662b21 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -137,9 +137,9 @@ static int journal_submit_commit_record(journal_t *journal,
137 if (journal->j_flags & JBD2_BARRIER && 137 if (journal->j_flags & JBD2_BARRIER &&
138 !JBD2_HAS_INCOMPAT_FEATURE(journal, 138 !JBD2_HAS_INCOMPAT_FEATURE(journal,
139 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) 139 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT))
140 ret = submit_bh(WRITE_SYNC_PLUG | WRITE_FLUSH_FUA, bh); 140 ret = submit_bh(WRITE_SYNC | WRITE_FLUSH_FUA, bh);
141 else 141 else
142 ret = submit_bh(WRITE_SYNC_PLUG, bh); 142 ret = submit_bh(WRITE_SYNC, bh);
143 143
144 *cbh = bh; 144 *cbh = bh;
145 return ret; 145 return ret;
@@ -329,7 +329,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
329 int tag_bytes = journal_tag_bytes(journal); 329 int tag_bytes = journal_tag_bytes(journal);
330 struct buffer_head *cbh = NULL; /* For transactional checksums */ 330 struct buffer_head *cbh = NULL; /* For transactional checksums */
331 __u32 crc32_sum = ~0; 331 __u32 crc32_sum = ~0;
332 int write_op = WRITE_SYNC; 332 struct blk_plug plug;
333 333
334 /* 334 /*
335 * First job: lock down the current transaction and wait for 335 * First job: lock down the current transaction and wait for
@@ -363,13 +363,6 @@ void jbd2_journal_commit_transaction(journal_t *journal)
363 write_lock(&journal->j_state_lock); 363 write_lock(&journal->j_state_lock);
364 commit_transaction->t_state = T_LOCKED; 364 commit_transaction->t_state = T_LOCKED;
365 365
366 /*
367 * Use plugged writes here, since we want to submit several before
368 * we unplug the device. We don't do explicit unplugging in here,
369 * instead we rely on sync_buffer() doing the unplug for us.
370 */
371 if (commit_transaction->t_synchronous_commit)
372 write_op = WRITE_SYNC_PLUG;
373 trace_jbd2_commit_locking(journal, commit_transaction); 366 trace_jbd2_commit_locking(journal, commit_transaction);
374 stats.run.rs_wait = commit_transaction->t_max_wait; 367 stats.run.rs_wait = commit_transaction->t_max_wait;
375 stats.run.rs_locked = jiffies; 368 stats.run.rs_locked = jiffies;
@@ -469,8 +462,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
469 if (err) 462 if (err)
470 jbd2_journal_abort(journal, err); 463 jbd2_journal_abort(journal, err);
471 464
465 blk_start_plug(&plug);
472 jbd2_journal_write_revoke_records(journal, commit_transaction, 466 jbd2_journal_write_revoke_records(journal, commit_transaction,
473 write_op); 467 WRITE_SYNC);
468 blk_finish_plug(&plug);
474 469
475 jbd_debug(3, "JBD: commit phase 2\n"); 470 jbd_debug(3, "JBD: commit phase 2\n");
476 471
@@ -497,6 +492,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
497 err = 0; 492 err = 0;
498 descriptor = NULL; 493 descriptor = NULL;
499 bufs = 0; 494 bufs = 0;
495 blk_start_plug(&plug);
500 while (commit_transaction->t_buffers) { 496 while (commit_transaction->t_buffers) {
501 497
502 /* Find the next buffer to be journaled... */ 498 /* Find the next buffer to be journaled... */
@@ -658,7 +654,7 @@ start_journal_io:
658 clear_buffer_dirty(bh); 654 clear_buffer_dirty(bh);
659 set_buffer_uptodate(bh); 655 set_buffer_uptodate(bh);
660 bh->b_end_io = journal_end_buffer_io_sync; 656 bh->b_end_io = journal_end_buffer_io_sync;
661 submit_bh(write_op, bh); 657 submit_bh(WRITE_SYNC, bh);
662 } 658 }
663 cond_resched(); 659 cond_resched();
664 stats.run.rs_blocks_logged += bufs; 660 stats.run.rs_blocks_logged += bufs;
@@ -699,6 +695,8 @@ start_journal_io:
699 __jbd2_journal_abort_hard(journal); 695 __jbd2_journal_abort_hard(journal);
700 } 696 }
701 697
698 blk_finish_plug(&plug);
699
702 /* Lo and behold: we have just managed to send a transaction to 700 /* Lo and behold: we have just managed to send a transaction to
703 the log. Before we can commit it, wait for the IO so far to 701 the log. Before we can commit it, wait for the IO so far to
704 complete. Control buffers being written are on the 702 complete. Control buffers being written are on the
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 9978803ceedc..eddbb373209e 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -352,7 +352,6 @@ const struct address_space_operations jfs_aops = {
352 .readpages = jfs_readpages, 352 .readpages = jfs_readpages,
353 .writepage = jfs_writepage, 353 .writepage = jfs_writepage,
354 .writepages = jfs_writepages, 354 .writepages = jfs_writepages,
355 .sync_page = block_sync_page,
356 .write_begin = jfs_write_begin, 355 .write_begin = jfs_write_begin,
357 .write_end = nobh_write_end, 356 .write_end = nobh_write_end,
358 .bmap = jfs_bmap, 357 .bmap = jfs_bmap,
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 48b44bd8267b..6740d34cd82b 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -583,7 +583,6 @@ static void metapage_invalidatepage(struct page *page, unsigned long offset)
583const struct address_space_operations jfs_metapage_aops = { 583const struct address_space_operations jfs_metapage_aops = {
584 .readpage = metapage_readpage, 584 .readpage = metapage_readpage,
585 .writepage = metapage_writepage, 585 .writepage = metapage_writepage,
586 .sync_page = block_sync_page,
587 .releasepage = metapage_releasepage, 586 .releasepage = metapage_releasepage,
588 .invalidatepage = metapage_invalidatepage, 587 .invalidatepage = metapage_invalidatepage,
589 .set_page_dirty = __set_page_dirty_nobuffers, 588 .set_page_dirty = __set_page_dirty_nobuffers,
diff --git a/fs/locks.c b/fs/locks.c
index 822c3d1843af..0a4f50dfadfb 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -414,17 +414,7 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
414 fl->fl_ops = NULL; 414 fl->fl_ops = NULL;
415 fl->fl_lmops = NULL; 415 fl->fl_lmops = NULL;
416 416
417 switch (l->l_type) { 417 return assign_type(fl, l->l_type);
418 case F_RDLCK:
419 case F_WRLCK:
420 case F_UNLCK:
421 fl->fl_type = l->l_type;
422 break;
423 default:
424 return -EINVAL;
425 }
426
427 return (0);
428} 418}
429#endif 419#endif
430 420
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c
index 723bc5bca09a..1adc8d455f0e 100644
--- a/fs/logfs/dev_bdev.c
+++ b/fs/logfs/dev_bdev.c
@@ -39,7 +39,6 @@ static int sync_request(struct page *page, struct block_device *bdev, int rw)
39 bio.bi_end_io = request_complete; 39 bio.bi_end_io = request_complete;
40 40
41 submit_bio(rw, &bio); 41 submit_bio(rw, &bio);
42 generic_unplug_device(bdev_get_queue(bdev));
43 wait_for_completion(&complete); 42 wait_for_completion(&complete);
44 return test_bit(BIO_UPTODATE, &bio.bi_flags) ? 0 : -EIO; 43 return test_bit(BIO_UPTODATE, &bio.bi_flags) ? 0 : -EIO;
45} 44}
@@ -168,7 +167,6 @@ static void bdev_writeseg(struct super_block *sb, u64 ofs, size_t len)
168 } 167 }
169 len = PAGE_ALIGN(len); 168 len = PAGE_ALIGN(len);
170 __bdev_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT); 169 __bdev_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT);
171 generic_unplug_device(bdev_get_queue(logfs_super(sb)->s_bdev));
172} 170}
173 171
174 172
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index ae0b83f476a6..adcdc0a4e182 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -399,7 +399,6 @@ static sector_t minix_bmap(struct address_space *mapping, sector_t block)
399static const struct address_space_operations minix_aops = { 399static const struct address_space_operations minix_aops = {
400 .readpage = minix_readpage, 400 .readpage = minix_readpage,
401 .writepage = minix_writepage, 401 .writepage = minix_writepage,
402 .sync_page = block_sync_page,
403 .write_begin = minix_write_begin, 402 .write_begin = minix_write_begin,
404 .write_end = generic_write_end, 403 .write_end = generic_write_end,
405 .bmap = minix_bmap 404 .bmap = minix_bmap
diff --git a/fs/mpage.c b/fs/mpage.c
index d78455a81ec9..0afc809e46e0 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -364,6 +364,9 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
364 sector_t last_block_in_bio = 0; 364 sector_t last_block_in_bio = 0;
365 struct buffer_head map_bh; 365 struct buffer_head map_bh;
366 unsigned long first_logical_block = 0; 366 unsigned long first_logical_block = 0;
367 struct blk_plug plug;
368
369 blk_start_plug(&plug);
367 370
368 map_bh.b_state = 0; 371 map_bh.b_state = 0;
369 map_bh.b_size = 0; 372 map_bh.b_size = 0;
@@ -385,6 +388,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
385 BUG_ON(!list_empty(pages)); 388 BUG_ON(!list_empty(pages));
386 if (bio) 389 if (bio)
387 mpage_bio_submit(READ, bio); 390 mpage_bio_submit(READ, bio);
391 blk_finish_plug(&plug);
388 return 0; 392 return 0;
389} 393}
390EXPORT_SYMBOL(mpage_readpages); 394EXPORT_SYMBOL(mpage_readpages);
@@ -666,8 +670,11 @@ int
666mpage_writepages(struct address_space *mapping, 670mpage_writepages(struct address_space *mapping,
667 struct writeback_control *wbc, get_block_t get_block) 671 struct writeback_control *wbc, get_block_t get_block)
668{ 672{
673 struct blk_plug plug;
669 int ret; 674 int ret;
670 675
676 blk_start_plug(&plug);
677
671 if (!get_block) 678 if (!get_block)
672 ret = generic_writepages(mapping, wbc); 679 ret = generic_writepages(mapping, wbc);
673 else { 680 else {
@@ -682,6 +689,7 @@ mpage_writepages(struct address_space *mapping,
682 if (mpd.bio) 689 if (mpd.bio)
683 mpage_bio_submit(WRITE, mpd.bio); 690 mpage_bio_submit(WRITE, mpd.bio);
684 } 691 }
692 blk_finish_plug(&plug);
685 return ret; 693 return ret;
686} 694}
687EXPORT_SYMBOL(mpage_writepages); 695EXPORT_SYMBOL(mpage_writepages);
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 8b31e5f8795d..ad000aeb21a2 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -299,7 +299,6 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
299 299
300#define EXPORT_HASHBITS 8 300#define EXPORT_HASHBITS 8
301#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) 301#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
302#define EXPORT_HASHMASK (EXPORT_HASHMAX -1)
303 302
304static struct cache_head *export_table[EXPORT_HASHMAX]; 303static struct cache_head *export_table[EXPORT_HASHMAX];
305 304
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 6d2c397d458b..55780a22fdbd 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -63,7 +63,6 @@ struct ent {
63 63
64#define ENT_HASHBITS 8 64#define ENT_HASHBITS 8
65#define ENT_HASHMAX (1 << ENT_HASHBITS) 65#define ENT_HASHMAX (1 << ENT_HASHBITS)
66#define ENT_HASHMASK (ENT_HASHMAX - 1)
67 66
68static void 67static void
69ent_init(struct cache_head *cnew, struct cache_head *citm) 68ent_init(struct cache_head *cnew, struct cache_head *citm)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index db52546143d1..5fcb1396a7e3 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -984,8 +984,8 @@ typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
984 void *); 984 void *);
985enum nfsd4_op_flags { 985enum nfsd4_op_flags {
986 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 986 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
987 ALLOWED_ON_ABSENT_FS = 2 << 0, /* ops processed on absent fs */ 987 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */
988 ALLOWED_AS_FIRST_OP = 3 << 0, /* ops reqired first in compound */ 988 ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */
989}; 989};
990 990
991struct nfsd4_operation { 991struct nfsd4_operation {
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 7b566ec14e18..fbde6f79922e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -148,7 +148,7 @@ static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
148/* hash table for nfs4_file */ 148/* hash table for nfs4_file */
149#define FILE_HASH_BITS 8 149#define FILE_HASH_BITS 8
150#define FILE_HASH_SIZE (1 << FILE_HASH_BITS) 150#define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
151#define FILE_HASH_MASK (FILE_HASH_SIZE - 1) 151
152/* hash table for (open)nfs4_stateid */ 152/* hash table for (open)nfs4_stateid */
153#define STATEID_HASH_BITS 10 153#define STATEID_HASH_BITS 10
154#define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS) 154#define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS)
@@ -316,64 +316,6 @@ static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
316static struct list_head client_lru; 316static struct list_head client_lru;
317static struct list_head close_lru; 317static struct list_head close_lru;
318 318
319static void unhash_generic_stateid(struct nfs4_stateid *stp)
320{
321 list_del(&stp->st_hash);
322 list_del(&stp->st_perfile);
323 list_del(&stp->st_perstateowner);
324}
325
326static void free_generic_stateid(struct nfs4_stateid *stp)
327{
328 put_nfs4_file(stp->st_file);
329 kmem_cache_free(stateid_slab, stp);
330}
331
332static void release_lock_stateid(struct nfs4_stateid *stp)
333{
334 struct file *file;
335
336 unhash_generic_stateid(stp);
337 file = find_any_file(stp->st_file);
338 if (file)
339 locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
340 free_generic_stateid(stp);
341}
342
343static void unhash_lockowner(struct nfs4_stateowner *sop)
344{
345 struct nfs4_stateid *stp;
346
347 list_del(&sop->so_idhash);
348 list_del(&sop->so_strhash);
349 list_del(&sop->so_perstateid);
350 while (!list_empty(&sop->so_stateids)) {
351 stp = list_first_entry(&sop->so_stateids,
352 struct nfs4_stateid, st_perstateowner);
353 release_lock_stateid(stp);
354 }
355}
356
357static void release_lockowner(struct nfs4_stateowner *sop)
358{
359 unhash_lockowner(sop);
360 nfs4_put_stateowner(sop);
361}
362
363static void
364release_stateid_lockowners(struct nfs4_stateid *open_stp)
365{
366 struct nfs4_stateowner *lock_sop;
367
368 while (!list_empty(&open_stp->st_lockowners)) {
369 lock_sop = list_entry(open_stp->st_lockowners.next,
370 struct nfs4_stateowner, so_perstateid);
371 /* list_del(&open_stp->st_lockowners); */
372 BUG_ON(lock_sop->so_is_open_owner);
373 release_lockowner(lock_sop);
374 }
375}
376
377/* 319/*
378 * We store the NONE, READ, WRITE, and BOTH bits separately in the 320 * We store the NONE, READ, WRITE, and BOTH bits separately in the
379 * st_{access,deny}_bmap field of the stateid, in order to track not 321 * st_{access,deny}_bmap field of the stateid, in order to track not
@@ -446,13 +388,71 @@ static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp)
446 return nfs4_access_to_omode(access); 388 return nfs4_access_to_omode(access);
447} 389}
448 390
449static void release_open_stateid(struct nfs4_stateid *stp) 391static void unhash_generic_stateid(struct nfs4_stateid *stp)
392{
393 list_del(&stp->st_hash);
394 list_del(&stp->st_perfile);
395 list_del(&stp->st_perstateowner);
396}
397
398static void free_generic_stateid(struct nfs4_stateid *stp)
450{ 399{
451 int oflag = nfs4_access_bmap_to_omode(stp); 400 int oflag = nfs4_access_bmap_to_omode(stp);
452 401
402 nfs4_file_put_access(stp->st_file, oflag);
403 put_nfs4_file(stp->st_file);
404 kmem_cache_free(stateid_slab, stp);
405}
406
407static void release_lock_stateid(struct nfs4_stateid *stp)
408{
409 struct file *file;
410
411 unhash_generic_stateid(stp);
412 file = find_any_file(stp->st_file);
413 if (file)
414 locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
415 free_generic_stateid(stp);
416}
417
418static void unhash_lockowner(struct nfs4_stateowner *sop)
419{
420 struct nfs4_stateid *stp;
421
422 list_del(&sop->so_idhash);
423 list_del(&sop->so_strhash);
424 list_del(&sop->so_perstateid);
425 while (!list_empty(&sop->so_stateids)) {
426 stp = list_first_entry(&sop->so_stateids,
427 struct nfs4_stateid, st_perstateowner);
428 release_lock_stateid(stp);
429 }
430}
431
432static void release_lockowner(struct nfs4_stateowner *sop)
433{
434 unhash_lockowner(sop);
435 nfs4_put_stateowner(sop);
436}
437
438static void
439release_stateid_lockowners(struct nfs4_stateid *open_stp)
440{
441 struct nfs4_stateowner *lock_sop;
442
443 while (!list_empty(&open_stp->st_lockowners)) {
444 lock_sop = list_entry(open_stp->st_lockowners.next,
445 struct nfs4_stateowner, so_perstateid);
446 /* list_del(&open_stp->st_lockowners); */
447 BUG_ON(lock_sop->so_is_open_owner);
448 release_lockowner(lock_sop);
449 }
450}
451
452static void release_open_stateid(struct nfs4_stateid *stp)
453{
453 unhash_generic_stateid(stp); 454 unhash_generic_stateid(stp);
454 release_stateid_lockowners(stp); 455 release_stateid_lockowners(stp);
455 nfs4_file_put_access(stp->st_file, oflag);
456 free_generic_stateid(stp); 456 free_generic_stateid(stp);
457} 457}
458 458
@@ -608,7 +608,8 @@ static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4
608 u32 maxrpc = nfsd_serv->sv_max_mesg; 608 u32 maxrpc = nfsd_serv->sv_max_mesg;
609 609
610 new->maxreqs = numslots; 610 new->maxreqs = numslots;
611 new->maxresp_cached = slotsize + NFSD_MIN_HDR_SEQ_SZ; 611 new->maxresp_cached = min_t(u32, req->maxresp_cached,
612 slotsize + NFSD_MIN_HDR_SEQ_SZ);
612 new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc); 613 new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc);
613 new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc); 614 new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc);
614 new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND); 615 new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND);
@@ -3735,6 +3736,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
3735 stp->st_stateid.si_stateownerid = sop->so_id; 3736 stp->st_stateid.si_stateownerid = sop->so_id;
3736 stp->st_stateid.si_fileid = fp->fi_id; 3737 stp->st_stateid.si_fileid = fp->fi_id;
3737 stp->st_stateid.si_generation = 0; 3738 stp->st_stateid.si_generation = 0;
3739 stp->st_access_bmap = 0;
3738 stp->st_deny_bmap = open_stp->st_deny_bmap; 3740 stp->st_deny_bmap = open_stp->st_deny_bmap;
3739 stp->st_openstp = open_stp; 3741 stp->st_openstp = open_stp;
3740 3742
@@ -3749,6 +3751,17 @@ check_lock_length(u64 offset, u64 length)
3749 LOFF_OVERFLOW(offset, length))); 3751 LOFF_OVERFLOW(offset, length)));
3750} 3752}
3751 3753
3754static void get_lock_access(struct nfs4_stateid *lock_stp, u32 access)
3755{
3756 struct nfs4_file *fp = lock_stp->st_file;
3757 int oflag = nfs4_access_to_omode(access);
3758
3759 if (test_bit(access, &lock_stp->st_access_bmap))
3760 return;
3761 nfs4_file_get_access(fp, oflag);
3762 __set_bit(access, &lock_stp->st_access_bmap);
3763}
3764
3752/* 3765/*
3753 * LOCK operation 3766 * LOCK operation
3754 */ 3767 */
@@ -3765,7 +3778,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3765 struct file_lock conflock; 3778 struct file_lock conflock;
3766 __be32 status = 0; 3779 __be32 status = 0;
3767 unsigned int strhashval; 3780 unsigned int strhashval;
3768 unsigned int cmd;
3769 int err; 3781 int err;
3770 3782
3771 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", 3783 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
@@ -3847,22 +3859,18 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3847 switch (lock->lk_type) { 3859 switch (lock->lk_type) {
3848 case NFS4_READ_LT: 3860 case NFS4_READ_LT:
3849 case NFS4_READW_LT: 3861 case NFS4_READW_LT:
3850 if (find_readable_file(lock_stp->st_file)) { 3862 filp = find_readable_file(lock_stp->st_file);
3851 nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ); 3863 if (filp)
3852 filp = find_readable_file(lock_stp->st_file); 3864 get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
3853 }
3854 file_lock.fl_type = F_RDLCK; 3865 file_lock.fl_type = F_RDLCK;
3855 cmd = F_SETLK; 3866 break;
3856 break;
3857 case NFS4_WRITE_LT: 3867 case NFS4_WRITE_LT:
3858 case NFS4_WRITEW_LT: 3868 case NFS4_WRITEW_LT:
3859 if (find_writeable_file(lock_stp->st_file)) { 3869 filp = find_writeable_file(lock_stp->st_file);
3860 nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE); 3870 if (filp)
3861 filp = find_writeable_file(lock_stp->st_file); 3871 get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
3862 }
3863 file_lock.fl_type = F_WRLCK; 3872 file_lock.fl_type = F_WRLCK;
3864 cmd = F_SETLK; 3873 break;
3865 break;
3866 default: 3874 default:
3867 status = nfserr_inval; 3875 status = nfserr_inval;
3868 goto out; 3876 goto out;
@@ -3886,7 +3894,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3886 * Note: locks.c uses the BKL to protect the inode's lock list. 3894 * Note: locks.c uses the BKL to protect the inode's lock list.
3887 */ 3895 */
3888 3896
3889 err = vfs_lock_file(filp, cmd, &file_lock, &conflock); 3897 err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock);
3890 switch (-err) { 3898 switch (-err) {
3891 case 0: /* success! */ 3899 case 0: /* success! */
3892 update_stateid(&lock_stp->st_stateid); 3900 update_stateid(&lock_stp->st_stateid);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 615f0a9f0600..c6766af00d98 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1142,7 +1142,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1142 1142
1143 u32 dummy; 1143 u32 dummy;
1144 char *machine_name; 1144 char *machine_name;
1145 int i, j; 1145 int i;
1146 int nr_secflavs; 1146 int nr_secflavs;
1147 1147
1148 READ_BUF(16); 1148 READ_BUF(16);
@@ -1215,8 +1215,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1215 READ_BUF(4); 1215 READ_BUF(4);
1216 READ32(dummy); 1216 READ32(dummy);
1217 READ_BUF(dummy * 4); 1217 READ_BUF(dummy * 4);
1218 for (j = 0; j < dummy; ++j)
1219 READ32(dummy);
1220 break; 1218 break;
1221 case RPC_AUTH_GSS: 1219 case RPC_AUTH_GSS:
1222 dprintk("RPC_AUTH_GSS callback secflavor " 1220 dprintk("RPC_AUTH_GSS callback secflavor "
@@ -1232,7 +1230,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1232 READ_BUF(4); 1230 READ_BUF(4);
1233 READ32(dummy); 1231 READ32(dummy);
1234 READ_BUF(dummy); 1232 READ_BUF(dummy);
1235 p += XDR_QUADLEN(dummy);
1236 break; 1233 break;
1237 default: 1234 default:
1238 dprintk("Illegal callback secflavor\n"); 1235 dprintk("Illegal callback secflavor\n");
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 33b3e2b06779..1f5eae40f34e 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -12,13 +12,14 @@
12#include <linux/nfsd/syscall.h> 12#include <linux/nfsd/syscall.h>
13#include <linux/lockd/lockd.h> 13#include <linux/lockd/lockd.h>
14#include <linux/sunrpc/clnt.h> 14#include <linux/sunrpc/clnt.h>
15#include <linux/sunrpc/gss_api.h>
15 16
16#include "idmap.h" 17#include "idmap.h"
17#include "nfsd.h" 18#include "nfsd.h"
18#include "cache.h" 19#include "cache.h"
19 20
20/* 21/*
21 * We have a single directory with 9 nodes in it. 22 * We have a single directory with several nodes in it.
22 */ 23 */
23enum { 24enum {
24 NFSD_Root = 1, 25 NFSD_Root = 1,
@@ -42,6 +43,7 @@ enum {
42 NFSD_Versions, 43 NFSD_Versions,
43 NFSD_Ports, 44 NFSD_Ports,
44 NFSD_MaxBlkSize, 45 NFSD_MaxBlkSize,
46 NFSD_SupportedEnctypes,
45 /* 47 /*
46 * The below MUST come last. Otherwise we leave a hole in nfsd_files[] 48 * The below MUST come last. Otherwise we leave a hole in nfsd_files[]
47 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops 49 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -187,6 +189,34 @@ static struct file_operations export_features_operations = {
187 .release = single_release, 189 .release = single_release,
188}; 190};
189 191
192#ifdef CONFIG_SUNRPC_GSS
193static int supported_enctypes_show(struct seq_file *m, void *v)
194{
195 struct gss_api_mech *k5mech;
196
197 k5mech = gss_mech_get_by_name("krb5");
198 if (k5mech == NULL)
199 goto out;
200 if (k5mech->gm_upcall_enctypes != NULL)
201 seq_printf(m, k5mech->gm_upcall_enctypes);
202 gss_mech_put(k5mech);
203out:
204 return 0;
205}
206
207static int supported_enctypes_open(struct inode *inode, struct file *file)
208{
209 return single_open(file, supported_enctypes_show, NULL);
210}
211
212static struct file_operations supported_enctypes_ops = {
213 .open = supported_enctypes_open,
214 .read = seq_read,
215 .llseek = seq_lseek,
216 .release = single_release,
217};
218#endif /* CONFIG_SUNRPC_GSS */
219
190extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); 220extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
191extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); 221extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
192 222
@@ -1397,6 +1427,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1397 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, 1427 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
1398 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, 1428 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
1399 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, 1429 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
1430#ifdef CONFIG_SUNRPC_GSS
1431 [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
1432#endif /* CONFIG_SUNRPC_GSS */
1400#ifdef CONFIG_NFSD_V4 1433#ifdef CONFIG_NFSD_V4
1401 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, 1434 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
1402 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, 1435 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 2d31224b07bf..6bd2f3c21f2b 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -367,16 +367,12 @@ struct nfs4_file {
367 struct list_head fi_delegations; 367 struct list_head fi_delegations;
368 /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ 368 /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
369 struct file * fi_fds[3]; 369 struct file * fi_fds[3];
370 /* One each for O_RDONLY, O_WRONLY: */
371 atomic_t fi_access[2];
372 /* 370 /*
373 * Each open stateid contributes 1 to either fi_readers or 371 * Each open or lock stateid contributes 1 to either
374 * fi_writers, or both, depending on the open mode. A 372 * fi_access[O_RDONLY], fi_access[O_WRONLY], or both, depending
375 * delegation also takes an fi_readers reference. Lock 373 * on open or lock mode:
376 * stateid's take none.
377 */ 374 */
378 atomic_t fi_readers; 375 atomic_t fi_access[2];
379 atomic_t fi_writers;
380 struct file *fi_deleg_file; 376 struct file *fi_deleg_file;
381 struct file_lock *fi_lease; 377 struct file_lock *fi_lease;
382 atomic_t fi_delegees; 378 atomic_t fi_delegees;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index ff93025ae2f7..2e1cebde90df 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1749,8 +1749,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1749 if (host_err) 1749 if (host_err)
1750 goto out_drop_write; 1750 goto out_drop_write;
1751 } 1751 }
1752 if (host_err)
1753 goto out_drop_write;
1754 host_err = vfs_rename(fdir, odentry, tdir, ndentry); 1752 host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1755 if (!host_err) { 1753 if (!host_err) {
1756 host_err = commit_metadata(tfhp); 1754 host_err = commit_metadata(tfhp);
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 85f7baa15f5d..609cd223eea8 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -34,15 +34,10 @@
34#include "page.h" 34#include "page.h"
35#include "btnode.h" 35#include "btnode.h"
36 36
37
38static const struct address_space_operations def_btnode_aops = {
39 .sync_page = block_sync_page,
40};
41
42void nilfs_btnode_cache_init(struct address_space *btnc, 37void nilfs_btnode_cache_init(struct address_space *btnc,
43 struct backing_dev_info *bdi) 38 struct backing_dev_info *bdi)
44{ 39{
45 nilfs_mapping_init(btnc, bdi, &def_btnode_aops); 40 nilfs_mapping_init(btnc, bdi);
46} 41}
47 42
48void nilfs_btnode_cache_clear(struct address_space *btnc) 43void nilfs_btnode_cache_clear(struct address_space *btnc)
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index caf9a6a3fb54..1c2a3e23f8b2 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -49,7 +49,6 @@
49#include "ifile.h" 49#include "ifile.h"
50 50
51static const struct address_space_operations def_gcinode_aops = { 51static const struct address_space_operations def_gcinode_aops = {
52 .sync_page = block_sync_page,
53}; 52};
54 53
55/* 54/*
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index d5625be236a8..c0aa27490c02 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -280,7 +280,6 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
280const struct address_space_operations nilfs_aops = { 280const struct address_space_operations nilfs_aops = {
281 .writepage = nilfs_writepage, 281 .writepage = nilfs_writepage,
282 .readpage = nilfs_readpage, 282 .readpage = nilfs_readpage,
283 .sync_page = block_sync_page,
284 .writepages = nilfs_writepages, 283 .writepages = nilfs_writepages,
285 .set_page_dirty = nilfs_set_page_dirty, 284 .set_page_dirty = nilfs_set_page_dirty,
286 .readpages = nilfs_readpages, 285 .readpages = nilfs_readpages,
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index a0babd2bff6a..a649b05f7069 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -399,7 +399,6 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
399 399
400static const struct address_space_operations def_mdt_aops = { 400static const struct address_space_operations def_mdt_aops = {
401 .writepage = nilfs_mdt_write_page, 401 .writepage = nilfs_mdt_write_page,
402 .sync_page = block_sync_page,
403}; 402};
404 403
405static const struct inode_operations def_mdt_iops; 404static const struct inode_operations def_mdt_iops;
@@ -438,10 +437,6 @@ void nilfs_mdt_set_entry_size(struct inode *inode, unsigned entry_size,
438 mi->mi_first_entry_offset = DIV_ROUND_UP(header_size, entry_size); 437 mi->mi_first_entry_offset = DIV_ROUND_UP(header_size, entry_size);
439} 438}
440 439
441static const struct address_space_operations shadow_map_aops = {
442 .sync_page = block_sync_page,
443};
444
445/** 440/**
446 * nilfs_mdt_setup_shadow_map - setup shadow map and bind it to metadata file 441 * nilfs_mdt_setup_shadow_map - setup shadow map and bind it to metadata file
447 * @inode: inode of the metadata file 442 * @inode: inode of the metadata file
@@ -455,9 +450,9 @@ int nilfs_mdt_setup_shadow_map(struct inode *inode,
455 450
456 INIT_LIST_HEAD(&shadow->frozen_buffers); 451 INIT_LIST_HEAD(&shadow->frozen_buffers);
457 address_space_init_once(&shadow->frozen_data); 452 address_space_init_once(&shadow->frozen_data);
458 nilfs_mapping_init(&shadow->frozen_data, bdi, &shadow_map_aops); 453 nilfs_mapping_init(&shadow->frozen_data, bdi);
459 address_space_init_once(&shadow->frozen_btnodes); 454 address_space_init_once(&shadow->frozen_btnodes);
460 nilfs_mapping_init(&shadow->frozen_btnodes, bdi, &shadow_map_aops); 455 nilfs_mapping_init(&shadow->frozen_btnodes, bdi);
461 mi->mi_shadow = shadow; 456 mi->mi_shadow = shadow;
462 return 0; 457 return 0;
463} 458}
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index a585b35fd6bc..4d2a1ee0eb47 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -493,15 +493,14 @@ unsigned nilfs_page_count_clean_buffers(struct page *page,
493} 493}
494 494
495void nilfs_mapping_init(struct address_space *mapping, 495void nilfs_mapping_init(struct address_space *mapping,
496 struct backing_dev_info *bdi, 496 struct backing_dev_info *bdi)
497 const struct address_space_operations *aops)
498{ 497{
499 mapping->host = NULL; 498 mapping->host = NULL;
500 mapping->flags = 0; 499 mapping->flags = 0;
501 mapping_set_gfp_mask(mapping, GFP_NOFS); 500 mapping_set_gfp_mask(mapping, GFP_NOFS);
502 mapping->assoc_mapping = NULL; 501 mapping->assoc_mapping = NULL;
503 mapping->backing_dev_info = bdi; 502 mapping->backing_dev_info = bdi;
504 mapping->a_ops = aops; 503 mapping->a_ops = NULL;
505} 504}
506 505
507/* 506/*
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index 2a00953ebd5f..f06b79ad7493 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -62,8 +62,7 @@ int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
62void nilfs_copy_back_pages(struct address_space *, struct address_space *); 62void nilfs_copy_back_pages(struct address_space *, struct address_space *);
63void nilfs_clear_dirty_pages(struct address_space *); 63void nilfs_clear_dirty_pages(struct address_space *);
64void nilfs_mapping_init(struct address_space *mapping, 64void nilfs_mapping_init(struct address_space *mapping,
65 struct backing_dev_info *bdi, 65 struct backing_dev_info *bdi);
66 const struct address_space_operations *aops);
67unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); 66unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned);
68unsigned long nilfs_find_uncommitted_extent(struct inode *inode, 67unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
69 sector_t start_blk, 68 sector_t start_blk,
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 0f83e93935b2..2853ff20f85a 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -509,7 +509,7 @@ static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
509 * Last BIO is always sent through the following 509 * Last BIO is always sent through the following
510 * submission. 510 * submission.
511 */ 511 */
512 rw |= REQ_SYNC | REQ_UNPLUG; 512 rw |= REQ_SYNC;
513 res = nilfs_segbuf_submit_bio(segbuf, &wi, rw); 513 res = nilfs_segbuf_submit_bio(segbuf, &wi, rw);
514 } 514 }
515 515
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index c3c2c7ac9020..0b1e885b8cf8 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1543,8 +1543,6 @@ err_out:
1543 */ 1543 */
1544const struct address_space_operations ntfs_aops = { 1544const struct address_space_operations ntfs_aops = {
1545 .readpage = ntfs_readpage, /* Fill page with data. */ 1545 .readpage = ntfs_readpage, /* Fill page with data. */
1546 .sync_page = block_sync_page, /* Currently, just unplugs the
1547 disk request queue. */
1548#ifdef NTFS_RW 1546#ifdef NTFS_RW
1549 .writepage = ntfs_writepage, /* Write dirty page to disk. */ 1547 .writepage = ntfs_writepage, /* Write dirty page to disk. */
1550#endif /* NTFS_RW */ 1548#endif /* NTFS_RW */
@@ -1560,8 +1558,6 @@ const struct address_space_operations ntfs_aops = {
1560 */ 1558 */
1561const struct address_space_operations ntfs_mst_aops = { 1559const struct address_space_operations ntfs_mst_aops = {
1562 .readpage = ntfs_readpage, /* Fill page with data. */ 1560 .readpage = ntfs_readpage, /* Fill page with data. */
1563 .sync_page = block_sync_page, /* Currently, just unplugs the
1564 disk request queue. */
1565#ifdef NTFS_RW 1561#ifdef NTFS_RW
1566 .writepage = ntfs_writepage, /* Write dirty page to disk. */ 1562 .writepage = ntfs_writepage, /* Write dirty page to disk. */
1567 .set_page_dirty = __set_page_dirty_nobuffers, /* Set the page dirty 1563 .set_page_dirty = __set_page_dirty_nobuffers, /* Set the page dirty
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 6551c7cbad92..ef9ed854255c 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -698,8 +698,7 @@ lock_retry_remap:
698 "uptodate! Unplugging the disk queue " 698 "uptodate! Unplugging the disk queue "
699 "and rescheduling."); 699 "and rescheduling.");
700 get_bh(tbh); 700 get_bh(tbh);
701 blk_run_address_space(mapping); 701 io_schedule();
702 schedule();
703 put_bh(tbh); 702 put_bh(tbh);
704 if (unlikely(!buffer_uptodate(tbh))) 703 if (unlikely(!buffer_uptodate(tbh)))
705 goto read_err; 704 goto read_err;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 1fbb0e20131b..daea0359e974 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -2043,7 +2043,6 @@ const struct address_space_operations ocfs2_aops = {
2043 .write_begin = ocfs2_write_begin, 2043 .write_begin = ocfs2_write_begin,
2044 .write_end = ocfs2_write_end, 2044 .write_end = ocfs2_write_end,
2045 .bmap = ocfs2_bmap, 2045 .bmap = ocfs2_bmap,
2046 .sync_page = block_sync_page,
2047 .direct_IO = ocfs2_direct_IO, 2046 .direct_IO = ocfs2_direct_IO,
2048 .invalidatepage = ocfs2_invalidatepage, 2047 .invalidatepage = ocfs2_invalidatepage,
2049 .releasepage = ocfs2_releasepage, 2048 .releasepage = ocfs2_releasepage,
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index b108e863d8f6..1adab287bd24 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -367,11 +367,7 @@ static inline void o2hb_bio_wait_dec(struct o2hb_bio_wait_ctxt *wc,
367static void o2hb_wait_on_io(struct o2hb_region *reg, 367static void o2hb_wait_on_io(struct o2hb_region *reg,
368 struct o2hb_bio_wait_ctxt *wc) 368 struct o2hb_bio_wait_ctxt *wc)
369{ 369{
370 struct address_space *mapping = reg->hr_bdev->bd_inode->i_mapping;
371
372 blk_run_address_space(mapping);
373 o2hb_bio_wait_dec(wc, 1); 370 o2hb_bio_wait_dec(wc, 1);
374
375 wait_for_completion(&wc->wc_io_complete); 371 wait_for_completion(&wc->wc_io_complete);
376} 372}
377 373
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 8a6d34fa668a..d738a7e493dd 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -372,7 +372,6 @@ const struct address_space_operations omfs_aops = {
372 .readpages = omfs_readpages, 372 .readpages = omfs_readpages,
373 .writepage = omfs_writepage, 373 .writepage = omfs_writepage,
374 .writepages = omfs_writepages, 374 .writepages = omfs_writepages,
375 .sync_page = block_sync_page,
376 .write_begin = omfs_write_begin, 375 .write_begin = omfs_write_begin,
377 .write_end = generic_write_end, 376 .write_end = generic_write_end,
378 .bmap = omfs_bmap, 377 .bmap = omfs_bmap,
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 9c21119512b9..ac546975031f 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -290,7 +290,8 @@ ssize_t part_inflight_show(struct device *dev,
290{ 290{
291 struct hd_struct *p = dev_to_part(dev); 291 struct hd_struct *p = dev_to_part(dev);
292 292
293 return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]); 293 return sprintf(buf, "%8u %8u\n", atomic_read(&p->in_flight[0]),
294 atomic_read(&p->in_flight[1]));
294} 295}
295 296
296#ifdef CONFIG_FAIL_MAKE_REQUEST 297#ifdef CONFIG_FAIL_MAKE_REQUEST
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index ce9ad84d5dd9..f835a25625ff 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -48,6 +48,10 @@ void pstore_set_kmsg_bytes(int bytes)
48/* Tag each group of saved records with a sequence number */ 48/* Tag each group of saved records with a sequence number */
49static int oopscount; 49static int oopscount;
50 50
51static char *reason_str[] = {
52 "Oops", "Panic", "Kexec", "Restart", "Halt", "Poweroff", "Emergency"
53};
54
51/* 55/*
52 * callback from kmsg_dump. (s2,l2) has the most recently 56 * callback from kmsg_dump. (s2,l2) has the most recently
53 * written bytes, older bytes are in (s1,l1). Save as much 57 * written bytes, older bytes are in (s1,l1). Save as much
@@ -61,15 +65,20 @@ static void pstore_dump(struct kmsg_dumper *dumper,
61 unsigned long s1_start, s2_start; 65 unsigned long s1_start, s2_start;
62 unsigned long l1_cpy, l2_cpy; 66 unsigned long l1_cpy, l2_cpy;
63 unsigned long size, total = 0; 67 unsigned long size, total = 0;
64 char *dst; 68 char *dst, *why;
65 u64 id; 69 u64 id;
66 int hsize, part = 1; 70 int hsize, part = 1;
67 71
72 if (reason < ARRAY_SIZE(reason_str))
73 why = reason_str[reason];
74 else
75 why = "Unknown";
76
68 mutex_lock(&psinfo->buf_mutex); 77 mutex_lock(&psinfo->buf_mutex);
69 oopscount++; 78 oopscount++;
70 while (total < kmsg_bytes) { 79 while (total < kmsg_bytes) {
71 dst = psinfo->buf; 80 dst = psinfo->buf;
72 hsize = sprintf(dst, "Oops#%d Part%d\n", oopscount, part++); 81 hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part++);
73 size = psinfo->bufsize - hsize; 82 size = psinfo->bufsize - hsize;
74 dst += hsize; 83 dst += hsize;
75 84
@@ -86,7 +95,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
86 memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); 95 memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy);
87 96
88 id = psinfo->write(PSTORE_TYPE_DMESG, hsize + l1_cpy + l2_cpy); 97 id = psinfo->write(PSTORE_TYPE_DMESG, hsize + l1_cpy + l2_cpy);
89 if (pstore_is_mounted()) 98 if (reason == KMSG_DUMP_OOPS && pstore_is_mounted())
90 pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id, 99 pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id,
91 psinfo->buf, hsize + l1_cpy + l2_cpy, 100 psinfo->buf, hsize + l1_cpy + l2_cpy,
92 CURRENT_TIME, psinfo->erase); 101 CURRENT_TIME, psinfo->erase);
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index e63b4171d583..2b0646613f5a 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -335,7 +335,6 @@ static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
335static const struct address_space_operations qnx4_aops = { 335static const struct address_space_operations qnx4_aops = {
336 .readpage = qnx4_readpage, 336 .readpage = qnx4_readpage,
337 .writepage = qnx4_writepage, 337 .writepage = qnx4_writepage,
338 .sync_page = block_sync_page,
339 .write_begin = qnx4_write_begin, 338 .write_begin = qnx4_write_begin,
340 .write_end = generic_write_end, 339 .write_end = generic_write_end,
341 .bmap = qnx4_bmap 340 .bmap = qnx4_bmap
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 1bba24bad820..4fd5bb33dbb5 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3217,7 +3217,6 @@ const struct address_space_operations reiserfs_address_space_operations = {
3217 .readpages = reiserfs_readpages, 3217 .readpages = reiserfs_readpages,
3218 .releasepage = reiserfs_releasepage, 3218 .releasepage = reiserfs_releasepage,
3219 .invalidatepage = reiserfs_invalidatepage, 3219 .invalidatepage = reiserfs_invalidatepage,
3220 .sync_page = block_sync_page,
3221 .write_begin = reiserfs_write_begin, 3220 .write_begin = reiserfs_write_begin,
3222 .write_end = reiserfs_write_end, 3221 .write_end = reiserfs_write_end,
3223 .bmap = reiserfs_aop_bmap, 3222 .bmap = reiserfs_aop_bmap,
diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
index aa68a8a31518..efc309fa3035 100644
--- a/fs/squashfs/Kconfig
+++ b/fs/squashfs/Kconfig
@@ -5,12 +5,12 @@ config SQUASHFS
5 help 5 help
6 Saying Y here includes support for SquashFS 4.0 (a Compressed 6 Saying Y here includes support for SquashFS 4.0 (a Compressed
7 Read-Only File System). Squashfs is a highly compressed read-only 7 Read-Only File System). Squashfs is a highly compressed read-only
8 filesystem for Linux. It uses zlib/lzo compression to compress both 8 filesystem for Linux. It uses zlib, lzo or xz compression to
9 files, inodes and directories. Inodes in the system are very small 9 compress both files, inodes and directories. Inodes in the system
10 and all blocks are packed to minimise data overhead. Block sizes 10 are very small and all blocks are packed to minimise data overhead.
11 greater than 4K are supported up to a maximum of 1 Mbytes (default 11 Block sizes greater than 4K are supported up to a maximum of 1 Mbytes
12 block size 128K). SquashFS 4.0 supports 64 bit filesystems and files 12 (default block size 128K). SquashFS 4.0 supports 64 bit filesystems
13 (larger than 4GB), full uid/gid information, hard links and 13 and files (larger than 4GB), full uid/gid information, hard links and
14 timestamps. 14 timestamps.
15 15
16 Squashfs is intended for general read-only filesystem use, for 16 Squashfs is intended for general read-only filesystem use, for
diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c
index a5940e54c4dd..e921bd213738 100644
--- a/fs/squashfs/decompressor.c
+++ b/fs/squashfs/decompressor.c
@@ -23,6 +23,7 @@
23 23
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/slab.h>
26#include <linux/buffer_head.h> 27#include <linux/buffer_head.h>
27 28
28#include "squashfs_fs.h" 29#include "squashfs_fs.h"
@@ -74,3 +75,36 @@ const struct squashfs_decompressor *squashfs_lookup_decompressor(int id)
74 75
75 return decompressor[i]; 76 return decompressor[i];
76} 77}
78
79
80void *squashfs_decompressor_init(struct super_block *sb, unsigned short flags)
81{
82 struct squashfs_sb_info *msblk = sb->s_fs_info;
83 void *strm, *buffer = NULL;
84 int length = 0;
85
86 /*
87 * Read decompressor specific options from file system if present
88 */
89 if (SQUASHFS_COMP_OPTS(flags)) {
90 buffer = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
91 if (buffer == NULL)
92 return ERR_PTR(-ENOMEM);
93
94 length = squashfs_read_data(sb, &buffer,
95 sizeof(struct squashfs_super_block), 0, NULL,
96 PAGE_CACHE_SIZE, 1);
97
98 if (length < 0) {
99 strm = ERR_PTR(length);
100 goto finished;
101 }
102 }
103
104 strm = msblk->decompressor->init(msblk, buffer, length);
105
106finished:
107 kfree(buffer);
108
109 return strm;
110}
diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h
index 3b305a70f7aa..099745ad5691 100644
--- a/fs/squashfs/decompressor.h
+++ b/fs/squashfs/decompressor.h
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26struct squashfs_decompressor { 26struct squashfs_decompressor {
27 void *(*init)(struct squashfs_sb_info *); 27 void *(*init)(struct squashfs_sb_info *, void *, int);
28 void (*free)(void *); 28 void (*free)(void *);
29 int (*decompress)(struct squashfs_sb_info *, void **, 29 int (*decompress)(struct squashfs_sb_info *, void **,
30 struct buffer_head **, int, int, int, int, int); 30 struct buffer_head **, int, int, int, int, int);
@@ -33,11 +33,6 @@ struct squashfs_decompressor {
33 int supported; 33 int supported;
34}; 34};
35 35
36static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk)
37{
38 return msblk->decompressor->init(msblk);
39}
40
41static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk, 36static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk,
42 void *s) 37 void *s)
43{ 38{
diff --git a/fs/squashfs/dir.c b/fs/squashfs/dir.c
index 0dc340aa2be9..3f79cd1d0c19 100644
--- a/fs/squashfs/dir.c
+++ b/fs/squashfs/dir.c
@@ -172,6 +172,11 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
172 length += sizeof(dirh); 172 length += sizeof(dirh);
173 173
174 dir_count = le32_to_cpu(dirh.count) + 1; 174 dir_count = le32_to_cpu(dirh.count) + 1;
175
176 /* dir_count should never be larger than 256 */
177 if (dir_count > 256)
178 goto failed_read;
179
175 while (dir_count--) { 180 while (dir_count--) {
176 /* 181 /*
177 * Read directory entry. 182 * Read directory entry.
@@ -183,6 +188,10 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
183 188
184 size = le16_to_cpu(dire->size) + 1; 189 size = le16_to_cpu(dire->size) + 1;
185 190
191 /* size should never be larger than SQUASHFS_NAME_LEN */
192 if (size > SQUASHFS_NAME_LEN)
193 goto failed_read;
194
186 err = squashfs_read_metadata(inode->i_sb, dire->name, 195 err = squashfs_read_metadata(inode->i_sb, dire->name,
187 &block, &offset, size); 196 &block, &offset, size);
188 if (err < 0) 197 if (err < 0)
diff --git a/fs/squashfs/lzo_wrapper.c b/fs/squashfs/lzo_wrapper.c
index 7da759e34c52..00f4dfc5f088 100644
--- a/fs/squashfs/lzo_wrapper.c
+++ b/fs/squashfs/lzo_wrapper.c
@@ -37,7 +37,7 @@ struct squashfs_lzo {
37 void *output; 37 void *output;
38}; 38};
39 39
40static void *lzo_init(struct squashfs_sb_info *msblk) 40static void *lzo_init(struct squashfs_sb_info *msblk, void *buff, int len)
41{ 41{
42 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); 42 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
43 43
@@ -58,7 +58,7 @@ failed2:
58failed: 58failed:
59 ERROR("Failed to allocate lzo workspace\n"); 59 ERROR("Failed to allocate lzo workspace\n");
60 kfree(stream); 60 kfree(stream);
61 return NULL; 61 return ERR_PTR(-ENOMEM);
62} 62}
63 63
64 64
diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c
index 7a9464d08cf6..5d922a6701ab 100644
--- a/fs/squashfs/namei.c
+++ b/fs/squashfs/namei.c
@@ -176,6 +176,11 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry,
176 length += sizeof(dirh); 176 length += sizeof(dirh);
177 177
178 dir_count = le32_to_cpu(dirh.count) + 1; 178 dir_count = le32_to_cpu(dirh.count) + 1;
179
180 /* dir_count should never be larger than 256 */
181 if (dir_count > 256)
182 goto data_error;
183
179 while (dir_count--) { 184 while (dir_count--) {
180 /* 185 /*
181 * Read directory entry. 186 * Read directory entry.
@@ -187,6 +192,10 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry,
187 192
188 size = le16_to_cpu(dire->size) + 1; 193 size = le16_to_cpu(dire->size) + 1;
189 194
195 /* size should never be larger than SQUASHFS_NAME_LEN */
196 if (size > SQUASHFS_NAME_LEN)
197 goto data_error;
198
190 err = squashfs_read_metadata(dir->i_sb, dire->name, 199 err = squashfs_read_metadata(dir->i_sb, dire->name,
191 &block, &offset, size); 200 &block, &offset, size);
192 if (err < 0) 201 if (err < 0)
@@ -228,6 +237,9 @@ exit_lookup:
228 d_add(dentry, inode); 237 d_add(dentry, inode);
229 return ERR_PTR(0); 238 return ERR_PTR(0);
230 239
240data_error:
241 err = -EIO;
242
231read_failure: 243read_failure:
232 ERROR("Unable to read directory block [%llx:%x]\n", 244 ERROR("Unable to read directory block [%llx:%x]\n",
233 squashfs_i(dir)->start + msblk->directory_table, 245 squashfs_i(dir)->start + msblk->directory_table,
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
index ba729d808876..1f2e608b8785 100644
--- a/fs/squashfs/squashfs.h
+++ b/fs/squashfs/squashfs.h
@@ -48,6 +48,7 @@ extern int squashfs_read_table(struct super_block *, void *, u64, int);
48 48
49/* decompressor.c */ 49/* decompressor.c */
50extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); 50extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
51extern void *squashfs_decompressor_init(struct super_block *, unsigned short);
51 52
52/* export.c */ 53/* export.c */
53extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, 54extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64,
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index 39533feffd6d..4582c568ef4d 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -57,6 +57,7 @@
57#define SQUASHFS_ALWAYS_FRAG 5 57#define SQUASHFS_ALWAYS_FRAG 5
58#define SQUASHFS_DUPLICATE 6 58#define SQUASHFS_DUPLICATE 6
59#define SQUASHFS_EXPORT 7 59#define SQUASHFS_EXPORT 7
60#define SQUASHFS_COMP_OPT 10
60 61
61#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) 62#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
62 63
@@ -81,6 +82,9 @@
81#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ 82#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
82 SQUASHFS_EXPORT) 83 SQUASHFS_EXPORT)
83 84
85#define SQUASHFS_COMP_OPTS(flags) SQUASHFS_BIT(flags, \
86 SQUASHFS_COMP_OPT)
87
84/* Max number of types and file types */ 88/* Max number of types and file types */
85#define SQUASHFS_DIR_TYPE 1 89#define SQUASHFS_DIR_TYPE 1
86#define SQUASHFS_REG_TYPE 2 90#define SQUASHFS_REG_TYPE 2
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 20700b9f2b4c..5c8184c061a4 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -199,10 +199,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
199 199
200 err = -ENOMEM; 200 err = -ENOMEM;
201 201
202 msblk->stream = squashfs_decompressor_init(msblk);
203 if (msblk->stream == NULL)
204 goto failed_mount;
205
206 msblk->block_cache = squashfs_cache_init("metadata", 202 msblk->block_cache = squashfs_cache_init("metadata",
207 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); 203 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
208 if (msblk->block_cache == NULL) 204 if (msblk->block_cache == NULL)
@@ -215,6 +211,13 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
215 goto failed_mount; 211 goto failed_mount;
216 } 212 }
217 213
214 msblk->stream = squashfs_decompressor_init(sb, flags);
215 if (IS_ERR(msblk->stream)) {
216 err = PTR_ERR(msblk->stream);
217 msblk->stream = NULL;
218 goto failed_mount;
219 }
220
218 /* Allocate and read id index table */ 221 /* Allocate and read id index table */
219 msblk->id_table = squashfs_read_id_index_table(sb, 222 msblk->id_table = squashfs_read_id_index_table(sb,
220 le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids)); 223 le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids));
@@ -370,8 +373,8 @@ static void squashfs_put_super(struct super_block *sb)
370} 373}
371 374
372 375
373static struct dentry *squashfs_mount(struct file_system_type *fs_type, int flags, 376static struct dentry *squashfs_mount(struct file_system_type *fs_type,
374 const char *dev_name, void *data) 377 int flags, const char *dev_name, void *data)
375{ 378{
376 return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super); 379 return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super);
377} 380}
diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c
index c4eb40018256..aa47a286d1f8 100644
--- a/fs/squashfs/xz_wrapper.c
+++ b/fs/squashfs/xz_wrapper.c
@@ -26,10 +26,10 @@
26#include <linux/buffer_head.h> 26#include <linux/buffer_head.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/xz.h> 28#include <linux/xz.h>
29#include <linux/bitops.h>
29 30
30#include "squashfs_fs.h" 31#include "squashfs_fs.h"
31#include "squashfs_fs_sb.h" 32#include "squashfs_fs_sb.h"
32#include "squashfs_fs_i.h"
33#include "squashfs.h" 33#include "squashfs.h"
34#include "decompressor.h" 34#include "decompressor.h"
35 35
@@ -38,24 +38,57 @@ struct squashfs_xz {
38 struct xz_buf buf; 38 struct xz_buf buf;
39}; 39};
40 40
41static void *squashfs_xz_init(struct squashfs_sb_info *msblk) 41struct comp_opts {
42 __le32 dictionary_size;
43 __le32 flags;
44};
45
46static void *squashfs_xz_init(struct squashfs_sb_info *msblk, void *buff,
47 int len)
42{ 48{
43 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); 49 struct comp_opts *comp_opts = buff;
50 struct squashfs_xz *stream;
51 int dict_size = msblk->block_size;
52 int err, n;
53
54 if (comp_opts) {
55 /* check compressor options are the expected length */
56 if (len < sizeof(*comp_opts)) {
57 err = -EIO;
58 goto failed;
59 }
44 60
45 struct squashfs_xz *stream = kmalloc(sizeof(*stream), GFP_KERNEL); 61 dict_size = le32_to_cpu(comp_opts->dictionary_size);
46 if (stream == NULL) 62
63 /* the dictionary size should be 2^n or 2^n+2^(n+1) */
64 n = ffs(dict_size) - 1;
65 if (dict_size != (1 << n) && dict_size != (1 << n) +
66 (1 << (n + 1))) {
67 err = -EIO;
68 goto failed;
69 }
70 }
71
72 dict_size = max_t(int, dict_size, SQUASHFS_METADATA_SIZE);
73
74 stream = kmalloc(sizeof(*stream), GFP_KERNEL);
75 if (stream == NULL) {
76 err = -ENOMEM;
47 goto failed; 77 goto failed;
78 }
48 79
49 stream->state = xz_dec_init(XZ_PREALLOC, block_size); 80 stream->state = xz_dec_init(XZ_PREALLOC, dict_size);
50 if (stream->state == NULL) 81 if (stream->state == NULL) {
82 kfree(stream);
83 err = -ENOMEM;
51 goto failed; 84 goto failed;
85 }
52 86
53 return stream; 87 return stream;
54 88
55failed: 89failed:
56 ERROR("Failed to allocate xz workspace\n"); 90 ERROR("Failed to initialise xz decompressor\n");
57 kfree(stream); 91 return ERR_PTR(err);
58 return NULL;
59} 92}
60 93
61 94
diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c
index 4661ae2b1cec..517688b32ffa 100644
--- a/fs/squashfs/zlib_wrapper.c
+++ b/fs/squashfs/zlib_wrapper.c
@@ -26,19 +26,19 @@
26#include <linux/buffer_head.h> 26#include <linux/buffer_head.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/zlib.h> 28#include <linux/zlib.h>
29#include <linux/vmalloc.h>
29 30
30#include "squashfs_fs.h" 31#include "squashfs_fs.h"
31#include "squashfs_fs_sb.h" 32#include "squashfs_fs_sb.h"
32#include "squashfs.h" 33#include "squashfs.h"
33#include "decompressor.h" 34#include "decompressor.h"
34 35
35static void *zlib_init(struct squashfs_sb_info *dummy) 36static void *zlib_init(struct squashfs_sb_info *dummy, void *buff, int len)
36{ 37{
37 z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); 38 z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
38 if (stream == NULL) 39 if (stream == NULL)
39 goto failed; 40 goto failed;
40 stream->workspace = kmalloc(zlib_inflate_workspacesize(), 41 stream->workspace = vmalloc(zlib_inflate_workspacesize());
41 GFP_KERNEL);
42 if (stream->workspace == NULL) 42 if (stream->workspace == NULL)
43 goto failed; 43 goto failed;
44 44
@@ -47,7 +47,7 @@ static void *zlib_init(struct squashfs_sb_info *dummy)
47failed: 47failed:
48 ERROR("Failed to allocate zlib workspace\n"); 48 ERROR("Failed to allocate zlib workspace\n");
49 kfree(stream); 49 kfree(stream);
50 return NULL; 50 return ERR_PTR(-ENOMEM);
51} 51}
52 52
53 53
@@ -56,7 +56,7 @@ static void zlib_free(void *strm)
56 z_stream *stream = strm; 56 z_stream *stream = strm;
57 57
58 if (stream) 58 if (stream)
59 kfree(stream->workspace); 59 vfree(stream->workspace);
60 kfree(stream); 60 kfree(stream);
61} 61}
62 62
diff --git a/fs/super.c b/fs/super.c
index e84864908264..8a06881b1920 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -71,6 +71,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
71#else 71#else
72 INIT_LIST_HEAD(&s->s_files); 72 INIT_LIST_HEAD(&s->s_files);
73#endif 73#endif
74 s->s_bdi = &default_backing_dev_info;
74 INIT_LIST_HEAD(&s->s_instances); 75 INIT_LIST_HEAD(&s->s_instances);
75 INIT_HLIST_BL_HEAD(&s->s_anon); 76 INIT_HLIST_BL_HEAD(&s->s_anon);
76 INIT_LIST_HEAD(&s->s_inodes); 77 INIT_LIST_HEAD(&s->s_inodes);
@@ -936,6 +937,7 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
936 sb = root->d_sb; 937 sb = root->d_sb;
937 BUG_ON(!sb); 938 BUG_ON(!sb);
938 WARN_ON(!sb->s_bdi); 939 WARN_ON(!sb->s_bdi);
940 WARN_ON(sb->s_bdi == &default_backing_dev_info);
939 sb->s_flags |= MS_BORN; 941 sb->s_flags |= MS_BORN;
940 942
941 error = security_sb_kern_mount(sb, flags, secdata); 943 error = security_sb_kern_mount(sb, flags, secdata);
diff --git a/fs/sync.c b/fs/sync.c
index 92ca208777d5..c38ec163da6c 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -34,7 +34,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
34 * This should be safe, as we require bdi backing to actually 34 * This should be safe, as we require bdi backing to actually
35 * write out data in the first place 35 * write out data in the first place
36 */ 36 */
37 if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info) 37 if (sb->s_bdi == &noop_backing_dev_info)
38 return 0; 38 return 0;
39 39
40 if (sb->s_qcop && sb->s_qcop->quota_sync) 40 if (sb->s_qcop && sb->s_qcop->quota_sync)
@@ -80,7 +80,7 @@ EXPORT_SYMBOL_GPL(sync_filesystem);
80 80
81static void sync_one_sb(struct super_block *sb, void *arg) 81static void sync_one_sb(struct super_block *sb, void *arg)
82{ 82{
83 if (!(sb->s_flags & MS_RDONLY) && sb->s_bdi) 83 if (!(sb->s_flags & MS_RDONLY))
84 __sync_filesystem(sb, *(int *)arg); 84 __sync_filesystem(sb, *(int *)arg);
85} 85}
86/* 86/*
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index 9ca66276315e..fa8d43c92bb8 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -488,7 +488,6 @@ static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
488const struct address_space_operations sysv_aops = { 488const struct address_space_operations sysv_aops = {
489 .readpage = sysv_readpage, 489 .readpage = sysv_readpage,
490 .writepage = sysv_writepage, 490 .writepage = sysv_writepage,
491 .sync_page = block_sync_page,
492 .write_begin = sysv_write_begin, 491 .write_begin = sysv_write_begin,
493 .write_end = generic_write_end, 492 .write_end = generic_write_end,
494 .bmap = sysv_bmap 493 .bmap = sysv_bmap
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 1d1859dc3de5..d7440904be17 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -58,12 +58,3 @@ config UBIFS_FS_DEBUG
58 down UBIFS. You can then further enable / disable individual debugging 58 down UBIFS. You can then further enable / disable individual debugging
59 features using UBIFS module parameters and the corresponding sysfs 59 features using UBIFS module parameters and the corresponding sysfs
60 interfaces. 60 interfaces.
61
62config UBIFS_FS_DEBUG_CHKS
63 bool "Enable extra checks"
64 depends on UBIFS_FS_DEBUG
65 help
66 If extra checks are enabled UBIFS will check the consistency of its
67 internal data structures during operation. However, UBIFS performance
68 is dramatically slower when this option is selected especially if the
69 file system is large.
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 01c2b028e525..f25a7339f800 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -818,7 +818,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
818 printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", 818 printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
819 current->pid, lnum); 819 current->pid, lnum);
820 820
821 buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 821 buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
822 if (!buf) { 822 if (!buf) {
823 ubifs_err("cannot allocate memory for dumping LEB %d", lnum); 823 ubifs_err("cannot allocate memory for dumping LEB %d", lnum);
824 return; 824 return;
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index d77db7e36484..28be1e6a65e8 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -448,10 +448,12 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
448 if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) { 448 if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) {
449 /* 449 /*
450 * We change whole page so no need to load it. But we 450 * We change whole page so no need to load it. But we
451 * have to set the @PG_checked flag to make the further 451 * do not know whether this page exists on the media or
452 * code know that the page is new. This might be not 452 * not, so we assume the latter because it requires
453 * true, but it is better to budget more than to read 453 * larger budget. The assumption is that it is better
454 * the page from the media. 454 * to budget a bit more than to read the page from the
455 * media. Thus, we are setting the @PG_checked flag
456 * here.
455 */ 457 */
456 SetPageChecked(page); 458 SetPageChecked(page);
457 skipped_read = 1; 459 skipped_read = 1;
@@ -559,6 +561,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
559 dbg_gen("copied %d instead of %d, read page and repeat", 561 dbg_gen("copied %d instead of %d, read page and repeat",
560 copied, len); 562 copied, len);
561 cancel_budget(c, page, ui, appending); 563 cancel_budget(c, page, ui, appending);
564 ClearPageChecked(page);
562 565
563 /* 566 /*
564 * Return 0 to force VFS to repeat the whole operation, or the 567 * Return 0 to force VFS to repeat the whole operation, or the
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index c7b25e2f7764..0ee0847f2421 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -1094,7 +1094,7 @@ static int scan_check_cb(struct ubifs_info *c,
1094 } 1094 }
1095 } 1095 }
1096 1096
1097 buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 1097 buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
1098 if (!buf) { 1098 if (!buf) {
1099 ubifs_err("cannot allocate memory to scan LEB %d", lnum); 1099 ubifs_err("cannot allocate memory to scan LEB %d", lnum);
1100 goto out; 1100 goto out;
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 0a3c2c3f5c4a..0c9c69bd983a 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -1633,7 +1633,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
1633 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) 1633 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
1634 return 0; 1634 return 0;
1635 1635
1636 buf = p = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 1636 buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
1637 if (!buf) { 1637 if (!buf) {
1638 ubifs_err("cannot allocate memory for ltab checking"); 1638 ubifs_err("cannot allocate memory for ltab checking");
1639 return 0; 1639 return 0;
@@ -1885,7 +1885,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
1885 1885
1886 printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", 1886 printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
1887 current->pid, lnum); 1887 current->pid, lnum);
1888 buf = p = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 1888 buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
1889 if (!buf) { 1889 if (!buf) {
1890 ubifs_err("cannot allocate memory to dump LPT"); 1890 ubifs_err("cannot allocate memory to dump LPT");
1891 return; 1891 return;
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index 2cdbd31641d7..09df318e368f 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -898,7 +898,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci)
898 if (c->no_orphs) 898 if (c->no_orphs)
899 return 0; 899 return 0;
900 900
901 buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); 901 buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
902 if (!buf) { 902 if (!buf) {
903 ubifs_err("cannot allocate memory to check orphans"); 903 ubifs_err("cannot allocate memory to check orphans");
904 return 0; 904 return 0;
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index e5dc1e120e8d..6ddd9973e681 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2011,7 +2011,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
2011 */ 2011 */
2012 c->bdi.name = "ubifs", 2012 c->bdi.name = "ubifs",
2013 c->bdi.capabilities = BDI_CAP_MAP_COPY; 2013 c->bdi.capabilities = BDI_CAP_MAP_COPY;
2014 c->bdi.unplug_io_fn = default_unplug_io_fn;
2015 err = bdi_init(&c->bdi); 2014 err = bdi_init(&c->bdi);
2016 if (err) 2015 if (err)
2017 goto out_close; 2016 goto out_close;
diff --git a/fs/udf/file.c b/fs/udf/file.c
index f391a2adc699..2a346bb1d9f5 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -98,7 +98,6 @@ static int udf_adinicb_write_end(struct file *file,
98const struct address_space_operations udf_adinicb_aops = { 98const struct address_space_operations udf_adinicb_aops = {
99 .readpage = udf_adinicb_readpage, 99 .readpage = udf_adinicb_readpage,
100 .writepage = udf_adinicb_writepage, 100 .writepage = udf_adinicb_writepage,
101 .sync_page = block_sync_page,
102 .write_begin = simple_write_begin, 101 .write_begin = simple_write_begin,
103 .write_end = udf_adinicb_write_end, 102 .write_end = udf_adinicb_write_end,
104}; 103};
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index ccc814321414..1d1358ed80c1 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -140,7 +140,6 @@ static sector_t udf_bmap(struct address_space *mapping, sector_t block)
140const struct address_space_operations udf_aops = { 140const struct address_space_operations udf_aops = {
141 .readpage = udf_readpage, 141 .readpage = udf_readpage,
142 .writepage = udf_writepage, 142 .writepage = udf_writepage,
143 .sync_page = block_sync_page,
144 .write_begin = udf_write_begin, 143 .write_begin = udf_write_begin,
145 .write_end = generic_write_end, 144 .write_end = generic_write_end,
146 .bmap = udf_bmap, 145 .bmap = udf_bmap,
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 03c255f12df5..27a4babe7df0 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -552,7 +552,6 @@ static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
552const struct address_space_operations ufs_aops = { 552const struct address_space_operations ufs_aops = {
553 .readpage = ufs_readpage, 553 .readpage = ufs_readpage,
554 .writepage = ufs_writepage, 554 .writepage = ufs_writepage,
555 .sync_page = block_sync_page,
556 .write_begin = ufs_write_begin, 555 .write_begin = ufs_write_begin,
557 .write_end = generic_write_end, 556 .write_end = generic_write_end,
558 .bmap = ufs_bmap 557 .bmap = ufs_bmap
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index e56a4f567212..11014302c9ca 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -479,7 +479,7 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size)
479 break; 479 break;
480 if (IS_SYNC(inode) && (inode->i_state & I_DIRTY)) 480 if (IS_SYNC(inode) && (inode->i_state & I_DIRTY))
481 ufs_sync_inode (inode); 481 ufs_sync_inode (inode);
482 blk_run_address_space(inode->i_mapping); 482 blk_flush_plug(current);
483 yield(); 483 yield();
484 } 484 }
485 485
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 8c5c87277456..52dbd14260ba 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -413,8 +413,7 @@ xfs_submit_ioend_bio(
413 if (xfs_ioend_new_eof(ioend)) 413 if (xfs_ioend_new_eof(ioend))
414 xfs_mark_inode_dirty(XFS_I(ioend->io_inode)); 414 xfs_mark_inode_dirty(XFS_I(ioend->io_inode));
415 415
416 submit_bio(wbc->sync_mode == WB_SYNC_ALL ? 416 submit_bio(wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE, bio);
417 WRITE_SYNC_PLUG : WRITE, bio);
418} 417}
419 418
420STATIC struct bio * 419STATIC struct bio *
@@ -1495,7 +1494,6 @@ const struct address_space_operations xfs_address_space_operations = {
1495 .readpages = xfs_vm_readpages, 1494 .readpages = xfs_vm_readpages,
1496 .writepage = xfs_vm_writepage, 1495 .writepage = xfs_vm_writepage,
1497 .writepages = xfs_vm_writepages, 1496 .writepages = xfs_vm_writepages,
1498 .sync_page = block_sync_page,
1499 .releasepage = xfs_vm_releasepage, 1497 .releasepage = xfs_vm_releasepage,
1500 .invalidatepage = xfs_vm_invalidatepage, 1498 .invalidatepage = xfs_vm_invalidatepage,
1501 .write_begin = xfs_vm_write_begin, 1499 .write_begin = xfs_vm_write_begin,
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 5cb230f2cb4f..c05324d3282c 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -990,7 +990,7 @@ xfs_buf_lock(
990 if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE)) 990 if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE))
991 xfs_log_force(bp->b_target->bt_mount, 0); 991 xfs_log_force(bp->b_target->bt_mount, 0);
992 if (atomic_read(&bp->b_io_remaining)) 992 if (atomic_read(&bp->b_io_remaining))
993 blk_run_address_space(bp->b_target->bt_mapping); 993 blk_flush_plug(current);
994 down(&bp->b_sema); 994 down(&bp->b_sema);
995 XB_SET_OWNER(bp); 995 XB_SET_OWNER(bp);
996 996
@@ -1034,9 +1034,7 @@ xfs_buf_wait_unpin(
1034 set_current_state(TASK_UNINTERRUPTIBLE); 1034 set_current_state(TASK_UNINTERRUPTIBLE);
1035 if (atomic_read(&bp->b_pin_count) == 0) 1035 if (atomic_read(&bp->b_pin_count) == 0)
1036 break; 1036 break;
1037 if (atomic_read(&bp->b_io_remaining)) 1037 io_schedule();
1038 blk_run_address_space(bp->b_target->bt_mapping);
1039 schedule();
1040 } 1038 }
1041 remove_wait_queue(&bp->b_waiters, &wait); 1039 remove_wait_queue(&bp->b_waiters, &wait);
1042 set_current_state(TASK_RUNNING); 1040 set_current_state(TASK_RUNNING);
@@ -1442,7 +1440,7 @@ xfs_buf_iowait(
1442 trace_xfs_buf_iowait(bp, _RET_IP_); 1440 trace_xfs_buf_iowait(bp, _RET_IP_);
1443 1441
1444 if (atomic_read(&bp->b_io_remaining)) 1442 if (atomic_read(&bp->b_io_remaining))
1445 blk_run_address_space(bp->b_target->bt_mapping); 1443 blk_flush_plug(current);
1446 wait_for_completion(&bp->b_iowait); 1444 wait_for_completion(&bp->b_iowait);
1447 1445
1448 trace_xfs_buf_iowait_done(bp, _RET_IP_); 1446 trace_xfs_buf_iowait_done(bp, _RET_IP_);
@@ -1666,7 +1664,6 @@ xfs_mapping_buftarg(
1666 struct inode *inode; 1664 struct inode *inode;
1667 struct address_space *mapping; 1665 struct address_space *mapping;
1668 static const struct address_space_operations mapping_aops = { 1666 static const struct address_space_operations mapping_aops = {
1669 .sync_page = block_sync_page,
1670 .migratepage = fail_migrate_page, 1667 .migratepage = fail_migrate_page,
1671 }; 1668 };
1672 1669
@@ -1947,7 +1944,7 @@ xfsbufd(
1947 count++; 1944 count++;
1948 } 1945 }
1949 if (count) 1946 if (count)
1950 blk_run_address_space(target->bt_mapping); 1947 blk_flush_plug(current);
1951 1948
1952 } while (!kthread_should_stop()); 1949 } while (!kthread_should_stop());
1953 1950
@@ -1995,7 +1992,7 @@ xfs_flush_buftarg(
1995 1992
1996 if (wait) { 1993 if (wait) {
1997 /* Expedite and wait for IO to complete. */ 1994 /* Expedite and wait for IO to complete. */
1998 blk_run_address_space(target->bt_mapping); 1995 blk_flush_plug(current);
1999 while (!list_empty(&wait_list)) { 1996 while (!list_empty(&wait_list)) {
2000 bp = list_first_entry(&wait_list, struct xfs_buf, b_list); 1997 bp = list_first_entry(&wait_list, struct xfs_buf, b_list);
2001 1998
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h
index ef1cef77d32b..d7bd661bfae7 100644
--- a/include/acpi/acoutput.h
+++ b/include/acpi/acoutput.h
@@ -183,13 +183,19 @@
183 183
184#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES) 184#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES)
185/* 185/*
186 * Module name is included in both debug and non-debug versions primarily for 186 * The module name is used primarily for error and debug messages.
187 * error messages. The __FILE__ macro is not very useful for this, because it 187 * The __FILE__ macro is not very useful for this, because it
188 * often includes the entire pathname to the module 188 * usually includes the entire pathname to the module making the
189 * debug output difficult to read.
189 */ 190 */
190#define ACPI_MODULE_NAME(name) static const char ACPI_UNUSED_VAR _acpi_module_name[] = name; 191#define ACPI_MODULE_NAME(name) static const char ACPI_UNUSED_VAR _acpi_module_name[] = name;
191#else 192#else
193/*
194 * For the no-debug and no-error-msg cases, we must at least define
195 * a null module name.
196 */
192#define ACPI_MODULE_NAME(name) 197#define ACPI_MODULE_NAME(name)
198#define _acpi_module_name ""
193#endif 199#endif
194 200
195/* 201/*
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index ff103ba96b78..3a10ef5914eb 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -250,7 +250,6 @@ struct acpi_device_wakeup {
250 struct acpi_handle_list resources; 250 struct acpi_handle_list resources;
251 struct acpi_device_wakeup_flags flags; 251 struct acpi_device_wakeup_flags flags;
252 int prepare_count; 252 int prepare_count;
253 int run_wake_count;
254}; 253};
255 254
256/* Device */ 255/* Device */
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index e46ec95a8ada..f6ad63d25b73 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,7 +47,7 @@
47 47
48/* Current ACPICA subsystem version in YYYYMMDD format */ 48/* Current ACPICA subsystem version in YYYYMMDD format */
49 49
50#define ACPI_CA_VERSION 0x20110112 50#define ACPI_CA_VERSION 0x20110316
51 51
52#include "actypes.h" 52#include "actypes.h"
53#include "actbl.h" 53#include "actbl.h"
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index 7e42bfee0e29..d41c94885211 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -343,4 +343,20 @@ struct acpi_table_desc {
343#include <acpi/actbl1.h> 343#include <acpi/actbl1.h>
344#include <acpi/actbl2.h> 344#include <acpi/actbl2.h>
345 345
346/*
347 * Sizes of the various flavors of FADT. We need to look closely
348 * at the FADT length because the version number essentially tells
349 * us nothing because of many BIOS bugs where the version does not
350 * match the expected length. In other words, the length of the
351 * FADT is the bottom line as to what the version really is.
352 *
353 * For reference, the values below are as follows:
354 * FADT V1 size: 0x74
355 * FADT V2 size: 0x84
356 * FADT V3+ size: 0xF4
357 */
358#define ACPI_FADT_V1_SIZE (u32) (ACPI_FADT_OFFSET (flags) + 4)
359#define ACPI_FADT_V2_SIZE (u32) (ACPI_FADT_OFFSET (reserved4[0]) + 3)
360#define ACPI_FADT_V3_SIZE (u32) (sizeof (struct acpi_table_fadt))
361
346#endif /* __ACTBL_H__ */ 362#endif /* __ACTBL_H__ */
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index 0fc15dfb2e22..58bdd0545c5a 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Name: actbl2.h - ACPI Specification Revision 2.0 Tables 3 * Name: actbl2.h - ACPI Table Definitions (tables not in ACPI spec)
4 * 4 *
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
@@ -716,6 +716,68 @@ struct acpi_table_mchi {
716 716
717/******************************************************************************* 717/*******************************************************************************
718 * 718 *
719 * SLIC - Software Licensing Description Table
720 * Version 1
721 *
722 * Conforms to "OEM Activation 2.0 for Windows Vista Operating Systems",
723 * Copyright 2006
724 *
725 ******************************************************************************/
726
727/* Basic SLIC table is only the common ACPI header */
728
729struct acpi_table_slic {
730 struct acpi_table_header header; /* Common ACPI table header */
731};
732
733/* Common SLIC subtable header */
734
735struct acpi_slic_header {
736 u32 type;
737 u32 length;
738};
739
740/* Values for Type field above */
741
742enum acpi_slic_type {
743 ACPI_SLIC_TYPE_PUBLIC_KEY = 0,
744 ACPI_SLIC_TYPE_WINDOWS_MARKER = 1,
745 ACPI_SLIC_TYPE_RESERVED = 2 /* 2 and greater are reserved */
746};
747
748/*
749 * SLIC Sub-tables, correspond to Type in struct acpi_slic_header
750 */
751
752/* 0: Public Key Structure */
753
754struct acpi_slic_key {
755 struct acpi_slic_header header;
756 u8 key_type;
757 u8 version;
758 u16 reserved;
759 u32 algorithm;
760 char magic[4];
761 u32 bit_length;
762 u32 exponent;
763 u8 modulus[128];
764};
765
766/* 1: Windows Marker Structure */
767
768struct acpi_slic_marker {
769 struct acpi_slic_header header;
770 u32 version;
771 char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
772 char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
773 char windows_flag[8];
774 u32 slic_version;
775 u8 reserved[16];
776 u8 signature[128];
777};
778
779/*******************************************************************************
780 *
719 * SPCR - Serial Port Console Redirection table 781 * SPCR - Serial Port Console Redirection table
720 * Version 1 782 * Version 1
721 * 783 *
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index c4dbb132d902..e67b523a50e1 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -30,10 +30,11 @@ int apei_hest_parse(apei_hest_func_t func, void *data);
30 30
31int erst_write(const struct cper_record_header *record); 31int erst_write(const struct cper_record_header *record);
32ssize_t erst_get_record_count(void); 32ssize_t erst_get_record_count(void);
33int erst_get_next_record_id(u64 *record_id); 33int erst_get_record_id_begin(int *pos);
34int erst_get_record_id_next(int *pos, u64 *record_id);
35void erst_get_record_id_end(void);
34ssize_t erst_read(u64 record_id, struct cper_record_header *record, 36ssize_t erst_read(u64 record_id, struct cper_record_header *record,
35 size_t buflen); 37 size_t buflen);
36ssize_t erst_read_next(struct cper_record_header *record, size_t buflen);
37int erst_clear(u64 record_id); 38int erst_clear(u64 record_id);
38 39
39#endif 40#endif
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 9ac431396176..4be33b4ca2f8 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -463,12 +463,15 @@ struct drm_irq_busid {
463enum drm_vblank_seq_type { 463enum drm_vblank_seq_type {
464 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ 464 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
465 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ 465 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
466 /* bits 1-6 are reserved for high crtcs */
467 _DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e,
466 _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ 468 _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */
467 _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ 469 _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
468 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ 470 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
469 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ 471 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
470 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */ 472 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */
471}; 473};
474#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1
472 475
473#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) 476#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
474#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ 477#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \
@@ -753,6 +756,7 @@ struct drm_event_vblank {
753}; 756};
754 757
755#define DRM_CAP_DUMB_BUFFER 0x1 758#define DRM_CAP_DUMB_BUFFER 0x1
759#define DRM_CAP_VBLANK_HIGH_CRTC 0x2
756 760
757/* typedef area */ 761/* typedef area */
758#ifndef __KERNEL__ 762#ifndef __KERNEL__
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index b0ada6f37dd6..75cf611641e6 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -233,6 +233,7 @@ header-y += magic.h
233header-y += major.h 233header-y += major.h
234header-y += map_to_7segment.h 234header-y += map_to_7segment.h
235header-y += matroxfb.h 235header-y += matroxfb.h
236header-y += media.h
236header-y += mempolicy.h 237header-y += mempolicy.h
237header-y += meye.h 238header-y += meye.h
238header-y += mii.h 239header-y += mii.h
@@ -276,6 +277,7 @@ header-y += nfsacl.h
276header-y += nl80211.h 277header-y += nl80211.h
277header-y += nubus.h 278header-y += nubus.h
278header-y += nvram.h 279header-y += nvram.h
280header-y += omap3isp.h
279header-y += omapfb.h 281header-y += omapfb.h
280header-y += oom.h 282header-y += oom.h
281header-y += param.h 283header-y += param.h
@@ -370,6 +372,8 @@ header-y += unistd.h
370header-y += usbdevice_fs.h 372header-y += usbdevice_fs.h
371header-y += utime.h 373header-y += utime.h
372header-y += utsname.h 374header-y += utsname.h
375header-y += v4l2-mediabus.h
376header-y += v4l2-subdev.h
373header-y += veth.h 377header-y += veth.h
374header-y += vhost.h 378header-y += vhost.h
375header-y += videodev2.h 379header-y += videodev2.h
diff --git a/include/linux/acpi_io.h b/include/linux/acpi_io.h
index 7180013a4a3a..4afd7102459d 100644
--- a/include/linux/acpi_io.h
+++ b/include/linux/acpi_io.h
@@ -10,7 +10,6 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
10 return ioremap_cache(phys, size); 10 return ioremap_cache(phys, size);
11} 11}
12 12
13int acpi_os_map_generic_address(struct acpi_generic_address *addr); 13void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
14void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
15 14
16#endif 15#endif
diff --git a/include/linux/aer.h b/include/linux/aer.h
index f7df1eefc107..8414de22a779 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -7,6 +7,28 @@
7#ifndef _AER_H_ 7#ifndef _AER_H_
8#define _AER_H_ 8#define _AER_H_
9 9
10struct aer_header_log_regs {
11 unsigned int dw0;
12 unsigned int dw1;
13 unsigned int dw2;
14 unsigned int dw3;
15};
16
17struct aer_capability_regs {
18 u32 header;
19 u32 uncor_status;
20 u32 uncor_mask;
21 u32 uncor_severity;
22 u32 cor_status;
23 u32 cor_mask;
24 u32 cap_control;
25 struct aer_header_log_regs header_log;
26 u32 root_command;
27 u32 root_status;
28 u16 cor_err_source;
29 u16 uncor_err_source;
30};
31
10#if defined(CONFIG_PCIEAER) 32#if defined(CONFIG_PCIEAER)
11/* pci-e port driver needs this function to enable aer */ 33/* pci-e port driver needs this function to enable aer */
12extern int pci_enable_pcie_error_reporting(struct pci_dev *dev); 34extern int pci_enable_pcie_error_reporting(struct pci_dev *dev);
@@ -27,5 +49,7 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
27} 49}
28#endif 50#endif
29 51
52extern void cper_print_aer(const char *prefix, int cper_severity,
53 struct aer_capability_regs *aer);
30#endif //_AER_H_ 54#endif //_AER_H_
31 55
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 4ce34fa937d4..96f4094b706d 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -66,8 +66,6 @@ struct backing_dev_info {
66 unsigned int capabilities; /* Device capabilities */ 66 unsigned int capabilities; /* Device capabilities */
67 congested_fn *congested_fn; /* Function pointer if device is md/dm */ 67 congested_fn *congested_fn; /* Function pointer if device is md/dm */
68 void *congested_data; /* Pointer to aux data for congested func */ 68 void *congested_data; /* Pointer to aux data for congested func */
69 void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
70 void *unplug_io_data;
71 69
72 char *name; 70 char *name;
73 71
@@ -251,7 +249,6 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
251 249
252extern struct backing_dev_info default_backing_dev_info; 250extern struct backing_dev_info default_backing_dev_info;
253extern struct backing_dev_info noop_backing_dev_info; 251extern struct backing_dev_info noop_backing_dev_info;
254void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
255 252
256int writeback_in_progress(struct backing_dev_info *bdi); 253int writeback_in_progress(struct backing_dev_info *bdi);
257 254
@@ -336,17 +333,4 @@ static inline int bdi_sched_wait(void *word)
336 return 0; 333 return 0;
337} 334}
338 335
339static inline void blk_run_backing_dev(struct backing_dev_info *bdi,
340 struct page *page)
341{
342 if (bdi && bdi->unplug_io_fn)
343 bdi->unplug_io_fn(bdi, page);
344}
345
346static inline void blk_run_address_space(struct address_space *mapping)
347{
348 if (mapping)
349 blk_run_backing_dev(mapping->backing_dev_info, NULL);
350}
351
352#endif /* _LINUX_BACKING_DEV_H */ 336#endif /* _LINUX_BACKING_DEV_H */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 35dcdb3589bc..ce33e6868a2f 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -304,7 +304,6 @@ struct biovec_slab {
304}; 304};
305 305
306extern struct bio_set *fs_bio_set; 306extern struct bio_set *fs_bio_set;
307extern struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly;
308 307
309/* 308/*
310 * a small number of entries is fine, not going to be performance critical. 309 * a small number of entries is fine, not going to be performance critical.
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 46ad5197537a..be50d9e70a7d 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -128,7 +128,6 @@ enum rq_flag_bits {
128 __REQ_NOIDLE, /* don't anticipate more IO after this one */ 128 __REQ_NOIDLE, /* don't anticipate more IO after this one */
129 129
130 /* bio only flags */ 130 /* bio only flags */
131 __REQ_UNPLUG, /* unplug the immediately after submission */
132 __REQ_RAHEAD, /* read ahead, can fail anytime */ 131 __REQ_RAHEAD, /* read ahead, can fail anytime */
133 __REQ_THROTTLED, /* This bio has already been subjected to 132 __REQ_THROTTLED, /* This bio has already been subjected to
134 * throttling rules. Don't do it again. */ 133 * throttling rules. Don't do it again. */
@@ -148,9 +147,11 @@ enum rq_flag_bits {
148 __REQ_ALLOCED, /* request came from our alloc pool */ 147 __REQ_ALLOCED, /* request came from our alloc pool */
149 __REQ_COPY_USER, /* contains copies of user pages */ 148 __REQ_COPY_USER, /* contains copies of user pages */
150 __REQ_FLUSH, /* request for cache flush */ 149 __REQ_FLUSH, /* request for cache flush */
150 __REQ_FLUSH_SEQ, /* request for flush sequence */
151 __REQ_IO_STAT, /* account I/O stat */ 151 __REQ_IO_STAT, /* account I/O stat */
152 __REQ_MIXED_MERGE, /* merge of different types, fail separately */ 152 __REQ_MIXED_MERGE, /* merge of different types, fail separately */
153 __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */ 153 __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */
154 __REQ_ON_PLUG, /* on plug list */
154 __REQ_NR_BITS, /* stops here */ 155 __REQ_NR_BITS, /* stops here */
155}; 156};
156 157
@@ -170,7 +171,6 @@ enum rq_flag_bits {
170 REQ_NOIDLE | REQ_FLUSH | REQ_FUA) 171 REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
171#define REQ_CLONE_MASK REQ_COMMON_MASK 172#define REQ_CLONE_MASK REQ_COMMON_MASK
172 173
173#define REQ_UNPLUG (1 << __REQ_UNPLUG)
174#define REQ_RAHEAD (1 << __REQ_RAHEAD) 174#define REQ_RAHEAD (1 << __REQ_RAHEAD)
175#define REQ_THROTTLED (1 << __REQ_THROTTLED) 175#define REQ_THROTTLED (1 << __REQ_THROTTLED)
176 176
@@ -188,8 +188,10 @@ enum rq_flag_bits {
188#define REQ_ALLOCED (1 << __REQ_ALLOCED) 188#define REQ_ALLOCED (1 << __REQ_ALLOCED)
189#define REQ_COPY_USER (1 << __REQ_COPY_USER) 189#define REQ_COPY_USER (1 << __REQ_COPY_USER)
190#define REQ_FLUSH (1 << __REQ_FLUSH) 190#define REQ_FLUSH (1 << __REQ_FLUSH)
191#define REQ_FLUSH_SEQ (1 << __REQ_FLUSH_SEQ)
191#define REQ_IO_STAT (1 << __REQ_IO_STAT) 192#define REQ_IO_STAT (1 << __REQ_IO_STAT)
192#define REQ_MIXED_MERGE (1 << __REQ_MIXED_MERGE) 193#define REQ_MIXED_MERGE (1 << __REQ_MIXED_MERGE)
193#define REQ_SECURE (1 << __REQ_SECURE) 194#define REQ_SECURE (1 << __REQ_SECURE)
195#define REQ_ON_PLUG (1 << __REQ_ON_PLUG)
194 196
195#endif /* __LINUX_BLK_TYPES_H */ 197#endif /* __LINUX_BLK_TYPES_H */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d5063e1b5555..16a902f099ac 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -108,11 +108,17 @@ struct request {
108 108
109 /* 109 /*
110 * Three pointers are available for the IO schedulers, if they need 110 * Three pointers are available for the IO schedulers, if they need
111 * more they have to dynamically allocate it. 111 * more they have to dynamically allocate it. Flush requests are
112 * never put on the IO scheduler. So let the flush fields share
113 * space with the three elevator_private pointers.
112 */ 114 */
113 void *elevator_private; 115 union {
114 void *elevator_private2; 116 void *elevator_private[3];
115 void *elevator_private3; 117 struct {
118 unsigned int seq;
119 struct list_head list;
120 } flush;
121 };
116 122
117 struct gendisk *rq_disk; 123 struct gendisk *rq_disk;
118 struct hd_struct *part; 124 struct hd_struct *part;
@@ -190,7 +196,6 @@ typedef void (request_fn_proc) (struct request_queue *q);
190typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); 196typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
191typedef int (prep_rq_fn) (struct request_queue *, struct request *); 197typedef int (prep_rq_fn) (struct request_queue *, struct request *);
192typedef void (unprep_rq_fn) (struct request_queue *, struct request *); 198typedef void (unprep_rq_fn) (struct request_queue *, struct request *);
193typedef void (unplug_fn) (struct request_queue *);
194 199
195struct bio_vec; 200struct bio_vec;
196struct bvec_merge_data { 201struct bvec_merge_data {
@@ -273,7 +278,6 @@ struct request_queue
273 make_request_fn *make_request_fn; 278 make_request_fn *make_request_fn;
274 prep_rq_fn *prep_rq_fn; 279 prep_rq_fn *prep_rq_fn;
275 unprep_rq_fn *unprep_rq_fn; 280 unprep_rq_fn *unprep_rq_fn;
276 unplug_fn *unplug_fn;
277 merge_bvec_fn *merge_bvec_fn; 281 merge_bvec_fn *merge_bvec_fn;
278 softirq_done_fn *softirq_done_fn; 282 softirq_done_fn *softirq_done_fn;
279 rq_timed_out_fn *rq_timed_out_fn; 283 rq_timed_out_fn *rq_timed_out_fn;
@@ -287,12 +291,9 @@ struct request_queue
287 struct request *boundary_rq; 291 struct request *boundary_rq;
288 292
289 /* 293 /*
290 * Auto-unplugging state 294 * Delayed queue handling
291 */ 295 */
292 struct timer_list unplug_timer; 296 struct delayed_work delay_work;
293 int unplug_thresh; /* After this many requests */
294 unsigned long unplug_delay; /* After this many jiffies */
295 struct work_struct unplug_work;
296 297
297 struct backing_dev_info backing_dev_info; 298 struct backing_dev_info backing_dev_info;
298 299
@@ -363,11 +364,12 @@ struct request_queue
363 * for flush operations 364 * for flush operations
364 */ 365 */
365 unsigned int flush_flags; 366 unsigned int flush_flags;
366 unsigned int flush_seq; 367 unsigned int flush_pending_idx:1;
367 int flush_err; 368 unsigned int flush_running_idx:1;
369 unsigned long flush_pending_since;
370 struct list_head flush_queue[2];
371 struct list_head flush_data_in_flight;
368 struct request flush_rq; 372 struct request flush_rq;
369 struct request *orig_flush_rq;
370 struct list_head pending_flushes;
371 373
372 struct mutex sysfs_lock; 374 struct mutex sysfs_lock;
373 375
@@ -387,14 +389,13 @@ struct request_queue
387#define QUEUE_FLAG_ASYNCFULL 4 /* write queue has been filled */ 389#define QUEUE_FLAG_ASYNCFULL 4 /* write queue has been filled */
388#define QUEUE_FLAG_DEAD 5 /* queue being torn down */ 390#define QUEUE_FLAG_DEAD 5 /* queue being torn down */
389#define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */ 391#define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */
390#define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */ 392#define QUEUE_FLAG_ELVSWITCH 7 /* don't use elevator, just do FIFO */
391#define QUEUE_FLAG_ELVSWITCH 8 /* don't use elevator, just do FIFO */ 393#define QUEUE_FLAG_BIDI 8 /* queue supports bidi requests */
392#define QUEUE_FLAG_BIDI 9 /* queue supports bidi requests */ 394#define QUEUE_FLAG_NOMERGES 9 /* disable merge attempts */
393#define QUEUE_FLAG_NOMERGES 10 /* disable merge attempts */ 395#define QUEUE_FLAG_SAME_COMP 10 /* force complete on same CPU */
394#define QUEUE_FLAG_SAME_COMP 11 /* force complete on same CPU */ 396#define QUEUE_FLAG_FAIL_IO 11 /* fake timeout */
395#define QUEUE_FLAG_FAIL_IO 12 /* fake timeout */ 397#define QUEUE_FLAG_STACKABLE 12 /* supports request stacking */
396#define QUEUE_FLAG_STACKABLE 13 /* supports request stacking */ 398#define QUEUE_FLAG_NONROT 13 /* non-rotational device (SSD) */
397#define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */
398#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ 399#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */
399#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ 400#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */
400#define QUEUE_FLAG_DISCARD 16 /* supports DISCARD */ 401#define QUEUE_FLAG_DISCARD 16 /* supports DISCARD */
@@ -472,7 +473,6 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
472 __clear_bit(flag, &q->queue_flags); 473 __clear_bit(flag, &q->queue_flags);
473} 474}
474 475
475#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
476#define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) 476#define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
477#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) 477#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
478#define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) 478#define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
@@ -667,9 +667,7 @@ extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
667extern void blk_rq_unprep_clone(struct request *rq); 667extern void blk_rq_unprep_clone(struct request *rq);
668extern int blk_insert_cloned_request(struct request_queue *q, 668extern int blk_insert_cloned_request(struct request_queue *q,
669 struct request *rq); 669 struct request *rq);
670extern void blk_plug_device(struct request_queue *); 670extern void blk_delay_queue(struct request_queue *, unsigned long);
671extern void blk_plug_device_unlocked(struct request_queue *);
672extern int blk_remove_plug(struct request_queue *);
673extern void blk_recount_segments(struct request_queue *, struct bio *); 671extern void blk_recount_segments(struct request_queue *, struct bio *);
674extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, 672extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
675 unsigned int, void __user *); 673 unsigned int, void __user *);
@@ -713,7 +711,6 @@ extern int blk_execute_rq(struct request_queue *, struct gendisk *,
713 struct request *, int); 711 struct request *, int);
714extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, 712extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,
715 struct request *, int, rq_end_io_fn *); 713 struct request *, int, rq_end_io_fn *);
716extern void blk_unplug(struct request_queue *q);
717 714
718static inline struct request_queue *bdev_get_queue(struct block_device *bdev) 715static inline struct request_queue *bdev_get_queue(struct block_device *bdev)
719{ 716{
@@ -850,7 +847,6 @@ extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bd
850 847
851extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); 848extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
852extern void blk_dump_rq_flags(struct request *, char *); 849extern void blk_dump_rq_flags(struct request *, char *);
853extern void generic_unplug_device(struct request_queue *);
854extern long nr_blockdev_pages(void); 850extern long nr_blockdev_pages(void);
855 851
856int blk_get_queue(struct request_queue *); 852int blk_get_queue(struct request_queue *);
@@ -858,6 +854,31 @@ struct request_queue *blk_alloc_queue(gfp_t);
858struct request_queue *blk_alloc_queue_node(gfp_t, int); 854struct request_queue *blk_alloc_queue_node(gfp_t, int);
859extern void blk_put_queue(struct request_queue *); 855extern void blk_put_queue(struct request_queue *);
860 856
857struct blk_plug {
858 unsigned long magic;
859 struct list_head list;
860 unsigned int should_sort;
861};
862
863extern void blk_start_plug(struct blk_plug *);
864extern void blk_finish_plug(struct blk_plug *);
865extern void __blk_flush_plug(struct task_struct *, struct blk_plug *);
866
867static inline void blk_flush_plug(struct task_struct *tsk)
868{
869 struct blk_plug *plug = tsk->plug;
870
871 if (unlikely(plug))
872 __blk_flush_plug(tsk, plug);
873}
874
875static inline bool blk_needs_flush_plug(struct task_struct *tsk)
876{
877 struct blk_plug *plug = tsk->plug;
878
879 return plug && !list_empty(&plug->list);
880}
881
861/* 882/*
862 * tag stuff 883 * tag stuff
863 */ 884 */
@@ -1135,7 +1156,6 @@ static inline uint64_t rq_io_start_time_ns(struct request *req)
1135extern int blk_throtl_init(struct request_queue *q); 1156extern int blk_throtl_init(struct request_queue *q);
1136extern void blk_throtl_exit(struct request_queue *q); 1157extern void blk_throtl_exit(struct request_queue *q);
1137extern int blk_throtl_bio(struct request_queue *q, struct bio **bio); 1158extern int blk_throtl_bio(struct request_queue *q, struct bio **bio);
1138extern void throtl_shutdown_timer_wq(struct request_queue *q);
1139#else /* CONFIG_BLK_DEV_THROTTLING */ 1159#else /* CONFIG_BLK_DEV_THROTTLING */
1140static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio) 1160static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio)
1141{ 1161{
@@ -1144,7 +1164,6 @@ static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio)
1144 1164
1145static inline int blk_throtl_init(struct request_queue *q) { return 0; } 1165static inline int blk_throtl_init(struct request_queue *q) { return 0; }
1146static inline int blk_throtl_exit(struct request_queue *q) { return 0; } 1166static inline int blk_throtl_exit(struct request_queue *q) { return 0; }
1147static inline void throtl_shutdown_timer_wq(struct request_queue *q) {}
1148#endif /* CONFIG_BLK_DEV_THROTTLING */ 1167#endif /* CONFIG_BLK_DEV_THROTTLING */
1149 1168
1150#define MODULE_ALIAS_BLOCKDEV(major,minor) \ 1169#define MODULE_ALIAS_BLOCKDEV(major,minor) \
@@ -1278,6 +1297,26 @@ static inline long nr_blockdev_pages(void)
1278 return 0; 1297 return 0;
1279} 1298}
1280 1299
1300struct blk_plug {
1301};
1302
1303static inline void blk_start_plug(struct blk_plug *plug)
1304{
1305}
1306
1307static inline void blk_finish_plug(struct blk_plug *plug)
1308{
1309}
1310
1311static inline void blk_flush_plug(struct task_struct *task)
1312{
1313}
1314
1315static inline bool blk_needs_flush_plug(struct task_struct *tsk)
1316{
1317 return false;
1318}
1319
1281#endif /* CONFIG_BLOCK */ 1320#endif /* CONFIG_BLOCK */
1282 1321
1283#endif 1322#endif
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 68d1fe7b877c..f5df23561b96 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -219,7 +219,6 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size);
219int block_commit_write(struct page *page, unsigned from, unsigned to); 219int block_commit_write(struct page *page, unsigned from, unsigned to);
220int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, 220int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
221 get_block_t get_block); 221 get_block_t get_block);
222void block_sync_page(struct page *);
223sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); 222sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
224int block_truncate_page(struct address_space *, loff_t, get_block_t *); 223int block_truncate_page(struct address_space *, loff_t, get_block_t *);
225int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned, 224int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned,
diff --git a/include/linux/cper.h b/include/linux/cper.h
index 3104aaff5dd0..372a25839fd1 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -388,5 +388,7 @@ struct cper_sec_pcie {
388#pragma pack() 388#pragma pack()
389 389
390u64 cper_next_record_id(void); 390u64 cper_next_record_id(void);
391void cper_print_bits(const char *prefix, unsigned int bits,
392 const char *strs[], unsigned int strs_size);
391 393
392#endif 394#endif
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 272496d1fae4..e2768834f397 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -286,11 +286,6 @@ void dm_table_add_target_callbacks(struct dm_table *t, struct dm_target_callback
286int dm_table_complete(struct dm_table *t); 286int dm_table_complete(struct dm_table *t);
287 287
288/* 288/*
289 * Unplug all devices in a table.
290 */
291void dm_table_unplug_all(struct dm_table *t);
292
293/*
294 * Table reference counting. 289 * Table reference counting.
295 */ 290 */
296struct dm_table *dm_get_live_table(struct mapped_device *md); 291struct dm_table *dm_get_live_table(struct mapped_device *md);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 4d857973d2c9..d93efcc44570 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -20,7 +20,6 @@ typedef void (elevator_bio_merged_fn) (struct request_queue *,
20typedef int (elevator_dispatch_fn) (struct request_queue *, int); 20typedef int (elevator_dispatch_fn) (struct request_queue *, int);
21 21
22typedef void (elevator_add_req_fn) (struct request_queue *, struct request *); 22typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
23typedef int (elevator_queue_empty_fn) (struct request_queue *);
24typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *); 23typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *);
25typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *); 24typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
26typedef int (elevator_may_queue_fn) (struct request_queue *, int); 25typedef int (elevator_may_queue_fn) (struct request_queue *, int);
@@ -46,7 +45,6 @@ struct elevator_ops
46 elevator_activate_req_fn *elevator_activate_req_fn; 45 elevator_activate_req_fn *elevator_activate_req_fn;
47 elevator_deactivate_req_fn *elevator_deactivate_req_fn; 46 elevator_deactivate_req_fn *elevator_deactivate_req_fn;
48 47
49 elevator_queue_empty_fn *elevator_queue_empty_fn;
50 elevator_completed_req_fn *elevator_completed_req_fn; 48 elevator_completed_req_fn *elevator_completed_req_fn;
51 49
52 elevator_request_list_fn *elevator_former_req_fn; 50 elevator_request_list_fn *elevator_former_req_fn;
@@ -101,17 +99,17 @@ struct elevator_queue
101 */ 99 */
102extern void elv_dispatch_sort(struct request_queue *, struct request *); 100extern void elv_dispatch_sort(struct request_queue *, struct request *);
103extern void elv_dispatch_add_tail(struct request_queue *, struct request *); 101extern void elv_dispatch_add_tail(struct request_queue *, struct request *);
104extern void elv_add_request(struct request_queue *, struct request *, int, int); 102extern void elv_add_request(struct request_queue *, struct request *, int);
105extern void __elv_add_request(struct request_queue *, struct request *, int, int); 103extern void __elv_add_request(struct request_queue *, struct request *, int);
106extern void elv_insert(struct request_queue *, struct request *, int); 104extern void elv_insert(struct request_queue *, struct request *, int);
107extern int elv_merge(struct request_queue *, struct request **, struct bio *); 105extern int elv_merge(struct request_queue *, struct request **, struct bio *);
106extern int elv_try_merge(struct request *, struct bio *);
108extern void elv_merge_requests(struct request_queue *, struct request *, 107extern void elv_merge_requests(struct request_queue *, struct request *,
109 struct request *); 108 struct request *);
110extern void elv_merged_request(struct request_queue *, struct request *, int); 109extern void elv_merged_request(struct request_queue *, struct request *, int);
111extern void elv_bio_merged(struct request_queue *q, struct request *, 110extern void elv_bio_merged(struct request_queue *q, struct request *,
112 struct bio *); 111 struct bio *);
113extern void elv_requeue_request(struct request_queue *, struct request *); 112extern void elv_requeue_request(struct request_queue *, struct request *);
114extern int elv_queue_empty(struct request_queue *);
115extern struct request *elv_former_request(struct request_queue *, struct request *); 113extern struct request *elv_former_request(struct request_queue *, struct request *);
116extern struct request *elv_latter_request(struct request_queue *, struct request *); 114extern struct request *elv_latter_request(struct request_queue *, struct request *);
117extern int elv_register_queue(struct request_queue *q); 115extern int elv_register_queue(struct request_queue *q);
@@ -167,6 +165,8 @@ extern struct request *elv_rb_find(struct rb_root *, sector_t);
167#define ELEVATOR_INSERT_BACK 2 165#define ELEVATOR_INSERT_BACK 2
168#define ELEVATOR_INSERT_SORT 3 166#define ELEVATOR_INSERT_SORT 3
169#define ELEVATOR_INSERT_REQUEUE 4 167#define ELEVATOR_INSERT_REQUEUE 4
168#define ELEVATOR_INSERT_FLUSH 5
169#define ELEVATOR_INSERT_SORT_MERGE 6
170 170
171/* 171/*
172 * return values from elevator_may_queue_fn 172 * return values from elevator_may_queue_fn
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ed6fdcc1484c..b677bd77f2d6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -138,16 +138,10 @@ struct inodes_stat_t {
138 * block layer could (in theory) choose to ignore this 138 * block layer could (in theory) choose to ignore this
139 * request if it runs into resource problems. 139 * request if it runs into resource problems.
140 * WRITE A normal async write. Device will be plugged. 140 * WRITE A normal async write. Device will be plugged.
141 * WRITE_SYNC_PLUG Synchronous write. Identical to WRITE, but passes down 141 * WRITE_SYNC Synchronous write. Identical to WRITE, but passes down
142 * the hint that someone will be waiting on this IO 142 * the hint that someone will be waiting on this IO
143 * shortly. The device must still be unplugged explicitly, 143 * shortly. The write equivalent of READ_SYNC.
144 * WRITE_SYNC_PLUG does not do this as we could be 144 * WRITE_ODIRECT Special case write for O_DIRECT only.
145 * submitting more writes before we actually wait on any
146 * of them.
147 * WRITE_SYNC Like WRITE_SYNC_PLUG, but also unplugs the device
148 * immediately after submission. The write equivalent
149 * of READ_SYNC.
150 * WRITE_ODIRECT_PLUG Special case write for O_DIRECT only.
151 * WRITE_FLUSH Like WRITE_SYNC but with preceding cache flush. 145 * WRITE_FLUSH Like WRITE_SYNC but with preceding cache flush.
152 * WRITE_FUA Like WRITE_SYNC but data is guaranteed to be on 146 * WRITE_FUA Like WRITE_SYNC but data is guaranteed to be on
153 * non-volatile media on completion. 147 * non-volatile media on completion.
@@ -163,18 +157,14 @@ struct inodes_stat_t {
163#define WRITE RW_MASK 157#define WRITE RW_MASK
164#define READA RWA_MASK 158#define READA RWA_MASK
165 159
166#define READ_SYNC (READ | REQ_SYNC | REQ_UNPLUG) 160#define READ_SYNC (READ | REQ_SYNC)
167#define READ_META (READ | REQ_META) 161#define READ_META (READ | REQ_META)
168#define WRITE_SYNC_PLUG (WRITE | REQ_SYNC | REQ_NOIDLE) 162#define WRITE_SYNC (WRITE | REQ_SYNC | REQ_NOIDLE)
169#define WRITE_SYNC (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG) 163#define WRITE_ODIRECT (WRITE | REQ_SYNC)
170#define WRITE_ODIRECT_PLUG (WRITE | REQ_SYNC)
171#define WRITE_META (WRITE | REQ_META) 164#define WRITE_META (WRITE | REQ_META)
172#define WRITE_FLUSH (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \ 165#define WRITE_FLUSH (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH)
173 REQ_FLUSH) 166#define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FUA)
174#define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \ 167#define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
175 REQ_FUA)
176#define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \
177 REQ_FLUSH | REQ_FUA)
178 168
179#define SEL_IN 1 169#define SEL_IN 1
180#define SEL_OUT 2 170#define SEL_OUT 2
@@ -586,7 +576,6 @@ typedef int (*read_actor_t)(read_descriptor_t *, struct page *,
586struct address_space_operations { 576struct address_space_operations {
587 int (*writepage)(struct page *page, struct writeback_control *wbc); 577 int (*writepage)(struct page *page, struct writeback_control *wbc);
588 int (*readpage)(struct file *, struct page *); 578 int (*readpage)(struct file *, struct page *);
589 void (*sync_page)(struct page *);
590 579
591 /* Write back some dirty pages from this mapping. */ 580 /* Write back some dirty pages from this mapping. */
592 int (*writepages)(struct address_space *, struct writeback_control *); 581 int (*writepages)(struct address_space *, struct writeback_control *);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index c0d5f6945c1e..d764a426e9fd 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -109,7 +109,7 @@ struct hd_struct {
109 int make_it_fail; 109 int make_it_fail;
110#endif 110#endif
111 unsigned long stamp; 111 unsigned long stamp;
112 int in_flight[2]; 112 atomic_t in_flight[2];
113#ifdef CONFIG_SMP 113#ifdef CONFIG_SMP
114 struct disk_stats __percpu *dkstats; 114 struct disk_stats __percpu *dkstats;
115#else 115#else
@@ -370,21 +370,21 @@ static inline void free_part_stats(struct hd_struct *part)
370 370
371static inline void part_inc_in_flight(struct hd_struct *part, int rw) 371static inline void part_inc_in_flight(struct hd_struct *part, int rw)
372{ 372{
373 part->in_flight[rw]++; 373 atomic_inc(&part->in_flight[rw]);
374 if (part->partno) 374 if (part->partno)
375 part_to_disk(part)->part0.in_flight[rw]++; 375 atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
376} 376}
377 377
378static inline void part_dec_in_flight(struct hd_struct *part, int rw) 378static inline void part_dec_in_flight(struct hd_struct *part, int rw)
379{ 379{
380 part->in_flight[rw]--; 380 atomic_dec(&part->in_flight[rw]);
381 if (part->partno) 381 if (part->partno)
382 part_to_disk(part)->part0.in_flight[rw]--; 382 atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
383} 383}
384 384
385static inline int part_in_flight(struct hd_struct *part) 385static inline int part_in_flight(struct hd_struct *part)
386{ 386{
387 return part->in_flight[0] + part->in_flight[1]; 387 return atomic_read(&part->in_flight[0]) + atomic_read(&part->in_flight[1]);
388} 388}
389 389
390static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk) 390static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 58afd9d2c438..0c0d1ae79981 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -698,6 +698,7 @@ struct twl4030_platform_data {
698 struct regulator_init_data *vana; 698 struct regulator_init_data *vana;
699 struct regulator_init_data *vcxio; 699 struct regulator_init_data *vcxio;
700 struct regulator_init_data *vusb; 700 struct regulator_init_data *vusb;
701 struct regulator_init_data *clk32kg;
701}; 702};
702 703
703/*----------------------------------------------------------------------*/ 704/*----------------------------------------------------------------------*/
@@ -777,5 +778,6 @@ static inline int twl4030charger_usb_en(int enable) { return 0; }
777 778
778/* INTERNAL LDOs */ 779/* INTERNAL LDOs */
779#define TWL6030_REG_VRTC 47 780#define TWL6030_REG_VRTC 47
781#define TWL6030_REG_CLK32KG 48
780 782
781#endif /* End of __TWL4030_H */ 783#endif /* End of __TWL4030_H */
diff --git a/include/linux/i2c/twl4030-madc.h b/include/linux/i2c/twl4030-madc.h
new file mode 100644
index 000000000000..6427d298fbfc
--- /dev/null
+++ b/include/linux/i2c/twl4030-madc.h
@@ -0,0 +1,141 @@
1/*
2 * twl4030_madc.h - Header for TWL4030 MADC
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 * J Keerthy <j-keerthy@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef _TWL4030_MADC_H
24#define _TWL4030_MADC_H
25
26struct twl4030_madc_conversion_method {
27 u8 sel;
28 u8 avg;
29 u8 rbase;
30 u8 ctrl;
31};
32
33#define TWL4030_MADC_MAX_CHANNELS 16
34
35
36/*
37 * twl4030_madc_request- madc request packet for channel conversion
38 * @channels: 16 bit bitmap for individual channels
39 * @do_avgP: sample the input channel for 4 consecutive cycles
40 * @method: RT, SW1, SW2
41 * @type: Polling or interrupt based method
42 */
43
44struct twl4030_madc_request {
45 unsigned long channels;
46 u16 do_avg;
47 u16 method;
48 u16 type;
49 bool active;
50 bool result_pending;
51 int rbuf[TWL4030_MADC_MAX_CHANNELS];
52 void (*func_cb)(int len, int channels, int *buf);
53};
54
55enum conversion_methods {
56 TWL4030_MADC_RT,
57 TWL4030_MADC_SW1,
58 TWL4030_MADC_SW2,
59 TWL4030_MADC_NUM_METHODS
60};
61
62enum sample_type {
63 TWL4030_MADC_WAIT,
64 TWL4030_MADC_IRQ_ONESHOT,
65 TWL4030_MADC_IRQ_REARM
66};
67
68#define TWL4030_MADC_CTRL1 0x00
69#define TWL4030_MADC_CTRL2 0x01
70
71#define TWL4030_MADC_RTSELECT_LSB 0x02
72#define TWL4030_MADC_SW1SELECT_LSB 0x06
73#define TWL4030_MADC_SW2SELECT_LSB 0x0A
74
75#define TWL4030_MADC_RTAVERAGE_LSB 0x04
76#define TWL4030_MADC_SW1AVERAGE_LSB 0x08
77#define TWL4030_MADC_SW2AVERAGE_LSB 0x0C
78
79#define TWL4030_MADC_CTRL_SW1 0x12
80#define TWL4030_MADC_CTRL_SW2 0x13
81
82#define TWL4030_MADC_RTCH0_LSB 0x17
83#define TWL4030_MADC_GPCH0_LSB 0x37
84
85#define TWL4030_MADC_MADCON (1 << 0) /* MADC power on */
86#define TWL4030_MADC_BUSY (1 << 0) /* MADC busy */
87/* MADC conversion completion */
88#define TWL4030_MADC_EOC_SW (1 << 1)
89/* MADC SWx start conversion */
90#define TWL4030_MADC_SW_START (1 << 5)
91#define TWL4030_MADC_ADCIN0 (1 << 0)
92#define TWL4030_MADC_ADCIN1 (1 << 1)
93#define TWL4030_MADC_ADCIN2 (1 << 2)
94#define TWL4030_MADC_ADCIN3 (1 << 3)
95#define TWL4030_MADC_ADCIN4 (1 << 4)
96#define TWL4030_MADC_ADCIN5 (1 << 5)
97#define TWL4030_MADC_ADCIN6 (1 << 6)
98#define TWL4030_MADC_ADCIN7 (1 << 7)
99#define TWL4030_MADC_ADCIN8 (1 << 8)
100#define TWL4030_MADC_ADCIN9 (1 << 9)
101#define TWL4030_MADC_ADCIN10 (1 << 10)
102#define TWL4030_MADC_ADCIN11 (1 << 11)
103#define TWL4030_MADC_ADCIN12 (1 << 12)
104#define TWL4030_MADC_ADCIN13 (1 << 13)
105#define TWL4030_MADC_ADCIN14 (1 << 14)
106#define TWL4030_MADC_ADCIN15 (1 << 15)
107
108/* Fixed channels */
109#define TWL4030_MADC_BTEMP TWL4030_MADC_ADCIN1
110#define TWL4030_MADC_VBUS TWL4030_MADC_ADCIN8
111#define TWL4030_MADC_VBKB TWL4030_MADC_ADCIN9
112#define TWL4030_MADC_ICHG TWL4030_MADC_ADCIN10
113#define TWL4030_MADC_VCHG TWL4030_MADC_ADCIN11
114#define TWL4030_MADC_VBAT TWL4030_MADC_ADCIN12
115
116/* Step size and prescaler ratio */
117#define TEMP_STEP_SIZE 147
118#define TEMP_PSR_R 100
119#define CURR_STEP_SIZE 147
120#define CURR_PSR_R1 44
121#define CURR_PSR_R2 88
122
123#define TWL4030_BCI_BCICTL1 0x23
124#define TWL4030_BCI_CGAIN 0x020
125#define TWL4030_BCI_MESBAT (1 << 1)
126#define TWL4030_BCI_TYPEN (1 << 4)
127#define TWL4030_BCI_ITHEN (1 << 3)
128
129#define REG_BCICTL2 0x024
130#define TWL4030_BCI_ITHSENS 0x007
131
132struct twl4030_madc_user_parms {
133 int channel;
134 int average;
135 int status;
136 u16 result;
137};
138
139int twl4030_madc_conversion(struct twl4030_madc_request *conv);
140int twl4030_get_madc_conversion(int channel_no);
141#endif
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index 092e4250a458..10ca03d0a250 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -297,6 +297,7 @@ extern int
297kgdb_handle_exception(int ex_vector, int signo, int err_code, 297kgdb_handle_exception(int ex_vector, int signo, int err_code,
298 struct pt_regs *regs); 298 struct pt_regs *regs);
299extern int kgdb_nmicallback(int cpu, void *regs); 299extern int kgdb_nmicallback(int cpu, void *regs);
300extern void gdbstub_exit(int status);
300 301
301extern int kgdb_single_step; 302extern int kgdb_single_step;
302extern atomic_t kgdb_active; 303extern atomic_t kgdb_active;
diff --git a/include/linux/media.h b/include/linux/media.h
new file mode 100644
index 000000000000..0ef883327de2
--- /dev/null
+++ b/include/linux/media.h
@@ -0,0 +1,132 @@
1/*
2 * Multimedia device API
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __LINUX_MEDIA_H
24#define __LINUX_MEDIA_H
25
26#include <linux/ioctl.h>
27#include <linux/types.h>
28#include <linux/version.h>
29
30#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0)
31
32struct media_device_info {
33 char driver[16];
34 char model[32];
35 char serial[40];
36 char bus_info[32];
37 __u32 media_version;
38 __u32 hw_revision;
39 __u32 driver_version;
40 __u32 reserved[31];
41};
42
43#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
44
45#define MEDIA_ENT_TYPE_SHIFT 16
46#define MEDIA_ENT_TYPE_MASK 0x00ff0000
47#define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff
48
49#define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT)
50#define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1)
51#define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2)
52#define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3)
53#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4)
54
55#define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT)
56#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1)
57#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2)
58#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3)
59
60#define MEDIA_ENT_FL_DEFAULT (1 << 0)
61
62struct media_entity_desc {
63 __u32 id;
64 char name[32];
65 __u32 type;
66 __u32 revision;
67 __u32 flags;
68 __u32 group_id;
69 __u16 pads;
70 __u16 links;
71
72 __u32 reserved[4];
73
74 union {
75 /* Node specifications */
76 struct {
77 __u32 major;
78 __u32 minor;
79 } v4l;
80 struct {
81 __u32 major;
82 __u32 minor;
83 } fb;
84 struct {
85 __u32 card;
86 __u32 device;
87 __u32 subdevice;
88 } alsa;
89 int dvb;
90
91 /* Sub-device specifications */
92 /* Nothing needed yet */
93 __u8 raw[184];
94 };
95};
96
97#define MEDIA_PAD_FL_SINK (1 << 0)
98#define MEDIA_PAD_FL_SOURCE (1 << 1)
99
100struct media_pad_desc {
101 __u32 entity; /* entity ID */
102 __u16 index; /* pad index */
103 __u32 flags; /* pad flags */
104 __u32 reserved[2];
105};
106
107#define MEDIA_LNK_FL_ENABLED (1 << 0)
108#define MEDIA_LNK_FL_IMMUTABLE (1 << 1)
109#define MEDIA_LNK_FL_DYNAMIC (1 << 2)
110
111struct media_link_desc {
112 struct media_pad_desc source;
113 struct media_pad_desc sink;
114 __u32 flags;
115 __u32 reserved[2];
116};
117
118struct media_links_enum {
119 __u32 entity;
120 /* Should have enough room for pads elements */
121 struct media_pad_desc __user *pads;
122 /* Should have enough room for links elements */
123 struct media_link_desc __user *links;
124 __u32 reserved[4];
125};
126
127#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info)
128#define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc)
129#define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum)
130#define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc)
131
132#endif /* __LINUX_MEDIA_H */
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 4db1fbd8969e..8fba7972ff5f 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -131,9 +131,11 @@ enum {
131 PM8607_ID_LDO8, 131 PM8607_ID_LDO8,
132 PM8607_ID_LDO9, 132 PM8607_ID_LDO9,
133 PM8607_ID_LDO10, 133 PM8607_ID_LDO10,
134 PM8607_ID_LDO11,
134 PM8607_ID_LDO12, 135 PM8607_ID_LDO12,
135 PM8607_ID_LDO13, 136 PM8607_ID_LDO13,
136 PM8607_ID_LDO14, 137 PM8607_ID_LDO14,
138 PM8607_ID_LDO15,
137 139
138 PM8607_ID_RG_MAX, 140 PM8607_ID_RG_MAX,
139}; 141};
@@ -310,8 +312,6 @@ struct pm860x_chip {
310 312
311}; 313};
312 314
313#define PM8607_MAX_REGULATOR PM8607_ID_RG_MAX /* 3 Bucks, 13 LDOs */
314
315enum { 315enum {
316 GI2C_PORT = 0, 316 GI2C_PORT = 0,
317 PI2C_PORT, 317 PI2C_PORT,
@@ -351,23 +351,31 @@ struct pm860x_platform_data {
351 struct pm860x_led_pdata *led; 351 struct pm860x_led_pdata *led;
352 struct pm860x_touch_pdata *touch; 352 struct pm860x_touch_pdata *touch;
353 struct pm860x_power_pdata *power; 353 struct pm860x_power_pdata *power;
354 struct regulator_init_data *regulator;
354 355
355 unsigned short companion_addr; /* I2C address of companion chip */ 356 unsigned short companion_addr; /* I2C address of companion chip */
356 int i2c_port; /* Controlled by GI2C or PI2C */ 357 int i2c_port; /* Controlled by GI2C or PI2C */
357 int irq_mode; /* Clear interrupt by read/write(0/1) */ 358 int irq_mode; /* Clear interrupt by read/write(0/1) */
358 int irq_base; /* IRQ base number of 88pm860x */ 359 int irq_base; /* IRQ base number of 88pm860x */
359 struct regulator_init_data *regulator[PM8607_MAX_REGULATOR]; 360 int num_leds;
361 int num_backlights;
362 int num_regulators;
360}; 363};
361 364
362extern char pm860x_backlight_name[][MFD_NAME_SIZE];
363extern char pm860x_led_name[][MFD_NAME_SIZE];
364
365extern int pm860x_reg_read(struct i2c_client *, int); 365extern int pm860x_reg_read(struct i2c_client *, int);
366extern int pm860x_reg_write(struct i2c_client *, int, unsigned char); 366extern int pm860x_reg_write(struct i2c_client *, int, unsigned char);
367extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *); 367extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *);
368extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *); 368extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *);
369extern int pm860x_set_bits(struct i2c_client *, int, unsigned char, 369extern int pm860x_set_bits(struct i2c_client *, int, unsigned char,
370 unsigned char); 370 unsigned char);
371extern int pm860x_page_reg_read(struct i2c_client *, int);
372extern int pm860x_page_reg_write(struct i2c_client *, int, unsigned char);
373extern int pm860x_page_bulk_read(struct i2c_client *, int, int,
374 unsigned char *);
375extern int pm860x_page_bulk_write(struct i2c_client *, int, int,
376 unsigned char *);
377extern int pm860x_page_set_bits(struct i2c_client *, int, unsigned char,
378 unsigned char);
371 379
372extern int pm860x_device_init(struct pm860x_chip *chip, 380extern int pm860x_device_init(struct pm860x_chip *chip,
373 struct pm860x_platform_data *pdata) __devinit ; 381 struct pm860x_platform_data *pdata) __devinit ;
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h
index 37f56b7c4c15..56f8dea72152 100644
--- a/include/linux/mfd/ab8500.h
+++ b/include/linux/mfd/ab8500.h
@@ -111,8 +111,8 @@
111 * @dev: parent device 111 * @dev: parent device
112 * @lock: read/write operations lock 112 * @lock: read/write operations lock
113 * @irq_lock: genirq bus lock 113 * @irq_lock: genirq bus lock
114 * @revision: chip revision
115 * @irq: irq line 114 * @irq: irq line
115 * @chip_id: chip revision id
116 * @write: register write 116 * @write: register write
117 * @read: register read 117 * @read: register read
118 * @rx_buf: rx buf for SPI 118 * @rx_buf: rx buf for SPI
@@ -124,7 +124,7 @@ struct ab8500 {
124 struct device *dev; 124 struct device *dev;
125 struct mutex lock; 125 struct mutex lock;
126 struct mutex irq_lock; 126 struct mutex irq_lock;
127 int revision; 127
128 int irq_base; 128 int irq_base;
129 int irq; 129 int irq;
130 u8 chip_id; 130 u8 chip_id;
diff --git a/include/linux/mfd/ab8500/gpadc.h b/include/linux/mfd/ab8500/gpadc.h
new file mode 100644
index 000000000000..46b954011f16
--- /dev/null
+++ b/include/linux/mfd/ab8500/gpadc.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2010 ST-Ericsson SA
3 * Licensed under GPLv2.
4 *
5 * Author: Arun R Murthy <arun.murthy@stericsson.com>
6 * Author: Daniel Willerud <daniel.willerud@stericsson.com>
7 */
8
9#ifndef _AB8500_GPADC_H
10#define _AB8500_GPADC_H
11
12/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2) */
13#define BAT_CTRL 0x01
14#define BTEMP_BALL 0x02
15#define MAIN_CHARGER_V 0x03
16#define ACC_DETECT1 0x04
17#define ACC_DETECT2 0x05
18#define ADC_AUX1 0x06
19#define ADC_AUX2 0x07
20#define MAIN_BAT_V 0x08
21#define VBUS_V 0x09
22#define MAIN_CHARGER_C 0x0A
23#define USB_CHARGER_C 0x0B
24#define BK_BAT_V 0x0C
25#define DIE_TEMP 0x0D
26
27struct ab8500_gpadc;
28
29struct ab8500_gpadc *ab8500_gpadc_get(char *name);
30int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input);
31
32#endif /* _AB8500_GPADC_H */
diff --git a/include/linux/mfd/ab8500/sysctrl.h b/include/linux/mfd/ab8500/sysctrl.h
new file mode 100644
index 000000000000..10da0291f8f8
--- /dev/null
+++ b/include/linux/mfd/ab8500/sysctrl.h
@@ -0,0 +1,254 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2010
3 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST Ericsson.
4 * License terms: GNU General Public License (GPL) version 2
5 */
6#ifndef __AB8500_SYSCTRL_H
7#define __AB8500_SYSCTRL_H
8
9#include <linux/bitops.h>
10
11#ifdef CONFIG_AB8500_CORE
12
13int ab8500_sysctrl_read(u16 reg, u8 *value);
14int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value);
15
16#else
17
18static inline int ab8500_sysctrl_read(u16 reg, u8 *value)
19{
20 return 0;
21}
22
23static inline int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
24{
25 return 0;
26}
27
28#endif /* CONFIG_AB8500_CORE */
29
30static inline int ab8500_sysctrl_set(u16 reg, u8 bits)
31{
32 return ab8500_sysctrl_write(reg, bits, bits);
33}
34
35static inline int ab8500_sysctrl_clear(u16 reg, u8 bits)
36{
37 return ab8500_sysctrl_write(reg, bits, 0);
38}
39
40/* Registers */
41#define AB8500_TURNONSTATUS 0x100
42#define AB8500_RESETSTATUS 0x101
43#define AB8500_PONKEY1PRESSSTATUS 0x102
44#define AB8500_SYSCLKREQSTATUS 0x142
45#define AB8500_STW4500CTRL1 0x180
46#define AB8500_STW4500CTRL2 0x181
47#define AB8500_STW4500CTRL3 0x200
48#define AB8500_MAINWDOGCTRL 0x201
49#define AB8500_MAINWDOGTIMER 0x202
50#define AB8500_LOWBAT 0x203
51#define AB8500_BATTOK 0x204
52#define AB8500_SYSCLKTIMER 0x205
53#define AB8500_SMPSCLKCTRL 0x206
54#define AB8500_SMPSCLKSEL1 0x207
55#define AB8500_SMPSCLKSEL2 0x208
56#define AB8500_SMPSCLKSEL3 0x209
57#define AB8500_SYSULPCLKCONF 0x20A
58#define AB8500_SYSULPCLKCTRL1 0x20B
59#define AB8500_SYSCLKCTRL 0x20C
60#define AB8500_SYSCLKREQ1VALID 0x20D
61#define AB8500_SYSTEMCTRLSUP 0x20F
62#define AB8500_SYSCLKREQ1RFCLKBUF 0x210
63#define AB8500_SYSCLKREQ2RFCLKBUF 0x211
64#define AB8500_SYSCLKREQ3RFCLKBUF 0x212
65#define AB8500_SYSCLKREQ4RFCLKBUF 0x213
66#define AB8500_SYSCLKREQ5RFCLKBUF 0x214
67#define AB8500_SYSCLKREQ6RFCLKBUF 0x215
68#define AB8500_SYSCLKREQ7RFCLKBUF 0x216
69#define AB8500_SYSCLKREQ8RFCLKBUF 0x217
70#define AB8500_DITHERCLKCTRL 0x220
71#define AB8500_SWATCTRL 0x230
72#define AB8500_HIQCLKCTRL 0x232
73#define AB8500_VSIMSYSCLKCTRL 0x233
74
75/* Bits */
76#define AB8500_TURNONSTATUS_PORNVBAT BIT(0)
77#define AB8500_TURNONSTATUS_PONKEY1DBF BIT(1)
78#define AB8500_TURNONSTATUS_PONKEY2DBF BIT(2)
79#define AB8500_TURNONSTATUS_RTCALARM BIT(3)
80#define AB8500_TURNONSTATUS_MAINCHDET BIT(4)
81#define AB8500_TURNONSTATUS_VBUSDET BIT(5)
82#define AB8500_TURNONSTATUS_USBIDDETECT BIT(6)
83
84#define AB8500_RESETSTATUS_RESETN4500NSTATUS BIT(0)
85#define AB8500_RESETSTATUS_SWRESETN4500NSTATUS BIT(2)
86
87#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_MASK 0x7F
88#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_SHIFT 0
89
90#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ1STATUS BIT(0)
91#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ2STATUS BIT(1)
92#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ3STATUS BIT(2)
93#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ4STATUS BIT(3)
94#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ5STATUS BIT(4)
95#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ6STATUS BIT(5)
96#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ7STATUS BIT(6)
97#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ8STATUS BIT(7)
98
99#define AB8500_STW4500CTRL1_SWOFF BIT(0)
100#define AB8500_STW4500CTRL1_SWRESET4500N BIT(1)
101#define AB8500_STW4500CTRL1_THDB8500SWOFF BIT(2)
102
103#define AB8500_STW4500CTRL2_RESETNVAUX1VALID BIT(0)
104#define AB8500_STW4500CTRL2_RESETNVAUX2VALID BIT(1)
105#define AB8500_STW4500CTRL2_RESETNVAUX3VALID BIT(2)
106#define AB8500_STW4500CTRL2_RESETNVMODVALID BIT(3)
107#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY1VALID BIT(4)
108#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY2VALID BIT(5)
109#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY3VALID BIT(6)
110#define AB8500_STW4500CTRL2_RESETNVSMPS1VALID BIT(7)
111
112#define AB8500_STW4500CTRL3_CLK32KOUT2DIS BIT(0)
113#define AB8500_STW4500CTRL3_RESETAUDN BIT(1)
114#define AB8500_STW4500CTRL3_RESETDENCN BIT(2)
115#define AB8500_STW4500CTRL3_THSDENA BIT(3)
116
117#define AB8500_MAINWDOGCTRL_MAINWDOGENA BIT(0)
118#define AB8500_MAINWDOGCTRL_MAINWDOGKICK BIT(1)
119#define AB8500_MAINWDOGCTRL_WDEXPTURNONVALID BIT(4)
120
121#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_MASK 0x7F
122#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_SHIFT 0
123
124#define AB8500_LOWBAT_LOWBATENA BIT(0)
125#define AB8500_LOWBAT_LOWBAT_MASK 0x7E
126#define AB8500_LOWBAT_LOWBAT_SHIFT 1
127
128#define AB8500_BATTOK_BATTOKSEL0THF_MASK 0x0F
129#define AB8500_BATTOK_BATTOKSEL0THF_SHIFT 0
130#define AB8500_BATTOK_BATTOKSEL1THF_MASK 0xF0
131#define AB8500_BATTOK_BATTOKSEL1THF_SHIFT 4
132
133#define AB8500_SYSCLKTIMER_SYSCLKTIMER_MASK 0x0F
134#define AB8500_SYSCLKTIMER_SYSCLKTIMER_SHIFT 0
135#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_MASK 0xF0
136#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_SHIFT 4
137
138#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_MASK 0x03
139#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_SHIFT 0
140#define AB8500_SMPSCLKCTRL_3M2CLKINTENA BIT(2)
141
142#define AB8500_SMPSCLKSEL1_VARMCLKSEL_MASK 0x07
143#define AB8500_SMPSCLKSEL1_VARMCLKSEL_SHIFT 0
144#define AB8500_SMPSCLKSEL1_VAPECLKSEL_MASK 0x38
145#define AB8500_SMPSCLKSEL1_VAPECLKSEL_SHIFT 3
146
147#define AB8500_SMPSCLKSEL2_VMODCLKSEL_MASK 0x07
148#define AB8500_SMPSCLKSEL2_VMODCLKSEL_SHIFT 0
149#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_MASK 0x38
150#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_SHIFT 3
151
152#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_MASK 0x07
153#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_SHIFT 0
154#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_MASK 0x38
155#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_SHIFT 3
156
157#define AB8500_SYSULPCLKCONF_ULPCLKCONF_MASK 0x03
158#define AB8500_SYSULPCLKCONF_ULPCLKCONF_SHIFT 0
159#define AB8500_SYSULPCLKCONF_CLK27MHZSTRE BIT(2)
160#define AB8500_SYSULPCLKCONF_TVOUTCLKDELN BIT(3)
161#define AB8500_SYSULPCLKCONF_TVOUTCLKINV BIT(4)
162#define AB8500_SYSULPCLKCONF_ULPCLKSTRE BIT(5)
163#define AB8500_SYSULPCLKCONF_CLK27MHZBUFENA BIT(6)
164#define AB8500_SYSULPCLKCONF_CLK27MHZPDENA BIT(7)
165
166#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK 0x03
167#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT 0
168#define AB8500_SYSULPCLKCTRL1_ULPCLKREQ BIT(2)
169#define AB8500_SYSULPCLKCTRL1_4500SYSCLKREQ BIT(3)
170#define AB8500_SYSULPCLKCTRL1_AUDIOCLKENA BIT(4)
171#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ BIT(5)
172#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ BIT(6)
173#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ BIT(7)
174
175#define AB8500_SYSCLKCTRL_TVOUTPLLENA BIT(0)
176#define AB8500_SYSCLKCTRL_TVOUTCLKENA BIT(1)
177#define AB8500_SYSCLKCTRL_USBCLKENA BIT(2)
178
179#define AB8500_SYSCLKREQ1VALID_SYSCLKREQ1VALID BIT(0)
180#define AB8500_SYSCLKREQ1VALID_ULPCLKREQ1VALID BIT(1)
181#define AB8500_SYSCLKREQ1VALID_USBSYSCLKREQ1VALID BIT(2)
182
183#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_MASK 0x03
184#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_SHIFT 0
185#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_MASK 0x0C
186#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_SHIFT 2
187#define AB8500_SYSTEMCTRLSUP_INTDB8500NOD BIT(4)
188
189#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF2 BIT(2)
190#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF3 BIT(3)
191#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF4 BIT(4)
192
193#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF2 BIT(2)
194#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF3 BIT(3)
195#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF4 BIT(4)
196
197#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF2 BIT(2)
198#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF3 BIT(3)
199#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF4 BIT(4)
200
201#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF2 BIT(2)
202#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF3 BIT(3)
203#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF4 BIT(4)
204
205#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF2 BIT(2)
206#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF3 BIT(3)
207#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF4 BIT(4)
208
209#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF2 BIT(2)
210#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF3 BIT(3)
211#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF4 BIT(4)
212
213#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF2 BIT(2)
214#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF3 BIT(3)
215#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF4 BIT(4)
216
217#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF2 BIT(2)
218#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF3 BIT(3)
219#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF4 BIT(4)
220
221#define AB8500_DITHERCLKCTRL_VARMDITHERENA BIT(0)
222#define AB8500_DITHERCLKCTRL_VSMPS3DITHERENA BIT(1)
223#define AB8500_DITHERCLKCTRL_VSMPS1DITHERENA BIT(2)
224#define AB8500_DITHERCLKCTRL_VSMPS2DITHERENA BIT(3)
225#define AB8500_DITHERCLKCTRL_VMODDITHERENA BIT(4)
226#define AB8500_DITHERCLKCTRL_VAPEDITHERENA BIT(5)
227#define AB8500_DITHERCLKCTRL_DITHERDEL_MASK 0xC0
228#define AB8500_DITHERCLKCTRL_DITHERDEL_SHIFT 6
229
230#define AB8500_SWATCTRL_UPDATERF BIT(0)
231#define AB8500_SWATCTRL_SWATENABLE BIT(1)
232#define AB8500_SWATCTRL_RFOFFTIMER_MASK 0x1C
233#define AB8500_SWATCTRL_RFOFFTIMER_SHIFT 2
234#define AB8500_SWATCTRL_SWATBIT5 BIT(6)
235
236#define AB8500_HIQCLKCTRL_SYSCLKREQ1HIQENAVALID BIT(0)
237#define AB8500_HIQCLKCTRL_SYSCLKREQ2HIQENAVALID BIT(1)
238#define AB8500_HIQCLKCTRL_SYSCLKREQ3HIQENAVALID BIT(2)
239#define AB8500_HIQCLKCTRL_SYSCLKREQ4HIQENAVALID BIT(3)
240#define AB8500_HIQCLKCTRL_SYSCLKREQ5HIQENAVALID BIT(4)
241#define AB8500_HIQCLKCTRL_SYSCLKREQ6HIQENAVALID BIT(5)
242#define AB8500_HIQCLKCTRL_SYSCLKREQ7HIQENAVALID BIT(6)
243#define AB8500_HIQCLKCTRL_SYSCLKREQ8HIQENAVALID BIT(7)
244
245#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ1VALID BIT(0)
246#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ2VALID BIT(1)
247#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ3VALID BIT(2)
248#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ4VALID BIT(3)
249#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ5VALID BIT(4)
250#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ6VALID BIT(5)
251#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ7VALID BIT(6)
252#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ8VALID BIT(7)
253
254#endif /* __AB8500_SYSCTRL_H */
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 67bd6f7ecf32..7d9b6ae1c203 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -186,7 +186,6 @@ struct abx500_init_settings {
186struct ab3550_platform_data { 186struct ab3550_platform_data {
187 struct {unsigned int base; unsigned int count; } irq; 187 struct {unsigned int base; unsigned int count; } irq;
188 void *dev_data[AB3550_NUM_DEVICES]; 188 void *dev_data[AB3550_NUM_DEVICES];
189 size_t dev_data_sz[AB3550_NUM_DEVICES];
190 struct abx500_init_settings *init_settings; 189 struct abx500_init_settings *init_settings;
191 unsigned int init_settings_sz; 190 unsigned int init_settings_sz;
192}; 191};
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index 835996e167e1..1408bf8eed5f 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -25,22 +25,20 @@ struct mfd_cell {
25 const char *name; 25 const char *name;
26 int id; 26 int id;
27 27
28 /* refcounting for multiple drivers to use a single cell */
29 atomic_t *usage_count;
28 int (*enable)(struct platform_device *dev); 30 int (*enable)(struct platform_device *dev);
29 int (*disable)(struct platform_device *dev); 31 int (*disable)(struct platform_device *dev);
32
30 int (*suspend)(struct platform_device *dev); 33 int (*suspend)(struct platform_device *dev);
31 int (*resume)(struct platform_device *dev); 34 int (*resume)(struct platform_device *dev);
32 35
33 /* driver-specific data for MFD-aware "cell" drivers */ 36 /* mfd_data can be used to pass data to client drivers */
34 void *driver_data; 37 void *mfd_data;
35
36 /* platform_data can be used to either pass data to "generic"
37 driver or as a hook to mfd_cell for the "cell" drivers */
38 void *platform_data;
39 size_t data_size;
40 38
41 /* 39 /*
42 * This resources can be specified relatively to the parent device. 40 * These resources can be specified relative to the parent device.
43 * For accessing device you should use resources from device 41 * For accessing hardware you should use resources from the platform dev
44 */ 42 */
45 int num_resources; 43 int num_resources;
46 const struct resource *resources; 44 const struct resource *resources;
@@ -55,11 +53,47 @@ struct mfd_cell {
55 bool pm_runtime_no_callbacks; 53 bool pm_runtime_no_callbacks;
56}; 54};
57 55
56/*
57 * Convenience functions for clients using shared cells. Refcounting
58 * happens automatically, with the cell's enable/disable callbacks
59 * being called only when a device is first being enabled or no other
60 * clients are making use of it.
61 */
62extern int mfd_cell_enable(struct platform_device *pdev);
63extern int mfd_cell_disable(struct platform_device *pdev);
64
65/*
66 * Given a platform device that's been created by mfd_add_devices(), fetch
67 * the mfd_cell that created it.
68 */
69static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
70{
71 return pdev->dev.platform_data;
72}
73
74/*
75 * Given a platform device that's been created by mfd_add_devices(), fetch
76 * the .mfd_data entry from the mfd_cell that created it.
77 */
78static inline void *mfd_get_data(struct platform_device *pdev)
79{
80 return mfd_get_cell(pdev)->mfd_data;
81}
82
58extern int mfd_add_devices(struct device *parent, int id, 83extern int mfd_add_devices(struct device *parent, int id,
59 const struct mfd_cell *cells, int n_devs, 84 struct mfd_cell *cells, int n_devs,
60 struct resource *mem_base, 85 struct resource *mem_base,
61 int irq_base); 86 int irq_base);
62 87
63extern void mfd_remove_devices(struct device *parent); 88extern void mfd_remove_devices(struct device *parent);
64 89
90/*
91 * For MFD drivers with clients sharing access to resources, these create
92 * multiple platform devices per cell. Contention handling must still be
93 * handled via drivers (ie, with enable/disable hooks).
94 */
95extern int mfd_shared_platform_driver_register(struct platform_driver *drv,
96 const char *cellname);
97extern void mfd_shared_platform_driver_unregister(struct platform_driver *drv);
98
65#endif 99#endif
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
new file mode 100644
index 000000000000..93a9477e075f
--- /dev/null
+++ b/include/linux/mfd/max8997-private.h
@@ -0,0 +1,347 @@
1/*
2 * max8997.h - Voltage regulator driver for the Maxim 8997
3 *
4 * Copyright (C) 2010 Samsung Electrnoics
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __LINUX_MFD_MAX8997_PRIV_H
23#define __LINUX_MFD_MAX8997_PRIV_H
24
25#include <linux/i2c.h>
26
27enum max8997_pmic_reg {
28 MAX8997_REG_PMIC_ID0 = 0x00,
29 MAX8997_REG_PMIC_ID1 = 0x01,
30 MAX8997_REG_INTSRC = 0x02,
31 MAX8997_REG_INT1 = 0x03,
32 MAX8997_REG_INT2 = 0x04,
33 MAX8997_REG_INT3 = 0x05,
34 MAX8997_REG_INT4 = 0x06,
35
36 MAX8997_REG_INT1MSK = 0x08,
37 MAX8997_REG_INT2MSK = 0x09,
38 MAX8997_REG_INT3MSK = 0x0a,
39 MAX8997_REG_INT4MSK = 0x0b,
40
41 MAX8997_REG_STATUS1 = 0x0d,
42 MAX8997_REG_STATUS2 = 0x0e,
43 MAX8997_REG_STATUS3 = 0x0f,
44 MAX8997_REG_STATUS4 = 0x10,
45
46 MAX8997_REG_MAINCON1 = 0x13,
47 MAX8997_REG_MAINCON2 = 0x14,
48 MAX8997_REG_BUCKRAMP = 0x15,
49
50 MAX8997_REG_BUCK1CTRL = 0x18,
51 MAX8997_REG_BUCK1DVS1 = 0x19,
52 MAX8997_REG_BUCK1DVS2 = 0x1a,
53 MAX8997_REG_BUCK1DVS3 = 0x1b,
54 MAX8997_REG_BUCK1DVS4 = 0x1c,
55 MAX8997_REG_BUCK1DVS5 = 0x1d,
56 MAX8997_REG_BUCK1DVS6 = 0x1e,
57 MAX8997_REG_BUCK1DVS7 = 0x1f,
58 MAX8997_REG_BUCK1DVS8 = 0x20,
59 MAX8997_REG_BUCK2CTRL = 0x21,
60 MAX8997_REG_BUCK2DVS1 = 0x22,
61 MAX8997_REG_BUCK2DVS2 = 0x23,
62 MAX8997_REG_BUCK2DVS3 = 0x24,
63 MAX8997_REG_BUCK2DVS4 = 0x25,
64 MAX8997_REG_BUCK2DVS5 = 0x26,
65 MAX8997_REG_BUCK2DVS6 = 0x27,
66 MAX8997_REG_BUCK2DVS7 = 0x28,
67 MAX8997_REG_BUCK2DVS8 = 0x29,
68 MAX8997_REG_BUCK3CTRL = 0x2a,
69 MAX8997_REG_BUCK3DVS = 0x2b,
70 MAX8997_REG_BUCK4CTRL = 0x2c,
71 MAX8997_REG_BUCK4DVS = 0x2d,
72 MAX8997_REG_BUCK5CTRL = 0x2e,
73 MAX8997_REG_BUCK5DVS1 = 0x2f,
74 MAX8997_REG_BUCK5DVS2 = 0x30,
75 MAX8997_REG_BUCK5DVS3 = 0x31,
76 MAX8997_REG_BUCK5DVS4 = 0x32,
77 MAX8997_REG_BUCK5DVS5 = 0x33,
78 MAX8997_REG_BUCK5DVS6 = 0x34,
79 MAX8997_REG_BUCK5DVS7 = 0x35,
80 MAX8997_REG_BUCK5DVS8 = 0x36,
81 MAX8997_REG_BUCK6CTRL = 0x37,
82 MAX8997_REG_BUCK6BPSKIPCTRL = 0x38,
83 MAX8997_REG_BUCK7CTRL = 0x39,
84 MAX8997_REG_BUCK7DVS = 0x3a,
85 MAX8997_REG_LDO1CTRL = 0x3b,
86 MAX8997_REG_LDO2CTRL = 0x3c,
87 MAX8997_REG_LDO3CTRL = 0x3d,
88 MAX8997_REG_LDO4CTRL = 0x3e,
89 MAX8997_REG_LDO5CTRL = 0x3f,
90 MAX8997_REG_LDO6CTRL = 0x40,
91 MAX8997_REG_LDO7CTRL = 0x41,
92 MAX8997_REG_LDO8CTRL = 0x42,
93 MAX8997_REG_LDO9CTRL = 0x43,
94 MAX8997_REG_LDO10CTRL = 0x44,
95 MAX8997_REG_LDO11CTRL = 0x45,
96 MAX8997_REG_LDO12CTRL = 0x46,
97 MAX8997_REG_LDO13CTRL = 0x47,
98 MAX8997_REG_LDO14CTRL = 0x48,
99 MAX8997_REG_LDO15CTRL = 0x49,
100 MAX8997_REG_LDO16CTRL = 0x4a,
101 MAX8997_REG_LDO17CTRL = 0x4b,
102 MAX8997_REG_LDO18CTRL = 0x4c,
103 MAX8997_REG_LDO21CTRL = 0x4d,
104
105 MAX8997_REG_MBCCTRL1 = 0x50,
106 MAX8997_REG_MBCCTRL2 = 0x51,
107 MAX8997_REG_MBCCTRL3 = 0x52,
108 MAX8997_REG_MBCCTRL4 = 0x53,
109 MAX8997_REG_MBCCTRL5 = 0x54,
110 MAX8997_REG_MBCCTRL6 = 0x55,
111 MAX8997_REG_OTPCGHCVS = 0x56,
112
113 MAX8997_REG_SAFEOUTCTRL = 0x5a,
114
115 MAX8997_REG_LBCNFG1 = 0x5e,
116 MAX8997_REG_LBCNFG2 = 0x5f,
117 MAX8997_REG_BBCCTRL = 0x60,
118
119 MAX8997_REG_FLASH1_CUR = 0x63, /* 0x63 ~ 0x6e for FLASH */
120 MAX8997_REG_FLASH2_CUR = 0x64,
121 MAX8997_REG_MOVIE_CUR = 0x65,
122 MAX8997_REG_GSMB_CUR = 0x66,
123 MAX8997_REG_BOOST_CNTL = 0x67,
124 MAX8997_REG_LEN_CNTL = 0x68,
125 MAX8997_REG_FLASH_CNTL = 0x69,
126 MAX8997_REG_WDT_CNTL = 0x6a,
127 MAX8997_REG_MAXFLASH1 = 0x6b,
128 MAX8997_REG_MAXFLASH2 = 0x6c,
129 MAX8997_REG_FLASHSTATUS = 0x6d,
130 MAX8997_REG_FLASHSTATUSMASK = 0x6e,
131
132 MAX8997_REG_GPIOCNTL1 = 0x70,
133 MAX8997_REG_GPIOCNTL2 = 0x71,
134 MAX8997_REG_GPIOCNTL3 = 0x72,
135 MAX8997_REG_GPIOCNTL4 = 0x73,
136 MAX8997_REG_GPIOCNTL5 = 0x74,
137 MAX8997_REG_GPIOCNTL6 = 0x75,
138 MAX8997_REG_GPIOCNTL7 = 0x76,
139 MAX8997_REG_GPIOCNTL8 = 0x77,
140 MAX8997_REG_GPIOCNTL9 = 0x78,
141 MAX8997_REG_GPIOCNTL10 = 0x79,
142 MAX8997_REG_GPIOCNTL11 = 0x7a,
143 MAX8997_REG_GPIOCNTL12 = 0x7b,
144
145 MAX8997_REG_LDO1CONFIG = 0x80,
146 MAX8997_REG_LDO2CONFIG = 0x81,
147 MAX8997_REG_LDO3CONFIG = 0x82,
148 MAX8997_REG_LDO4CONFIG = 0x83,
149 MAX8997_REG_LDO5CONFIG = 0x84,
150 MAX8997_REG_LDO6CONFIG = 0x85,
151 MAX8997_REG_LDO7CONFIG = 0x86,
152 MAX8997_REG_LDO8CONFIG = 0x87,
153 MAX8997_REG_LDO9CONFIG = 0x88,
154 MAX8997_REG_LDO10CONFIG = 0x89,
155 MAX8997_REG_LDO11CONFIG = 0x8a,
156 MAX8997_REG_LDO12CONFIG = 0x8b,
157 MAX8997_REG_LDO13CONFIG = 0x8c,
158 MAX8997_REG_LDO14CONFIG = 0x8d,
159 MAX8997_REG_LDO15CONFIG = 0x8e,
160 MAX8997_REG_LDO16CONFIG = 0x8f,
161 MAX8997_REG_LDO17CONFIG = 0x90,
162 MAX8997_REG_LDO18CONFIG = 0x91,
163 MAX8997_REG_LDO21CONFIG = 0x92,
164
165 MAX8997_REG_DVSOKTIMER1 = 0x97,
166 MAX8997_REG_DVSOKTIMER2 = 0x98,
167 MAX8997_REG_DVSOKTIMER4 = 0x99,
168 MAX8997_REG_DVSOKTIMER5 = 0x9a,
169
170 MAX8997_REG_PMIC_END = 0x9b,
171};
172
173enum max8997_muic_reg {
174 MAX8997_MUIC_REG_ID = 0x0,
175 MAX8997_MUIC_REG_INT1 = 0x1,
176 MAX8997_MUIC_REG_INT2 = 0x2,
177 MAX8997_MUIC_REG_INT3 = 0x3,
178 MAX8997_MUIC_REG_STATUS1 = 0x4,
179 MAX8997_MUIC_REG_STATUS2 = 0x5,
180 MAX8997_MUIC_REG_STATUS3 = 0x6,
181 MAX8997_MUIC_REG_INTMASK1 = 0x7,
182 MAX8997_MUIC_REG_INTMASK2 = 0x8,
183 MAX8997_MUIC_REG_INTMASK3 = 0x9,
184 MAX8997_MUIC_REG_CDETCTRL = 0xa,
185
186 MAX8997_MUIC_REG_CONTROL1 = 0xc,
187 MAX8997_MUIC_REG_CONTROL2 = 0xd,
188 MAX8997_MUIC_REG_CONTROL3 = 0xe,
189
190 MAX8997_MUIC_REG_END = 0xf,
191};
192
193enum max8997_haptic_reg {
194 MAX8997_HAPTIC_REG_GENERAL = 0x00,
195 MAX8997_HAPTIC_REG_CONF1 = 0x01,
196 MAX8997_HAPTIC_REG_CONF2 = 0x02,
197 MAX8997_HAPTIC_REG_DRVCONF = 0x03,
198 MAX8997_HAPTIC_REG_CYCLECONF1 = 0x04,
199 MAX8997_HAPTIC_REG_CYCLECONF2 = 0x05,
200 MAX8997_HAPTIC_REG_SIGCONF1 = 0x06,
201 MAX8997_HAPTIC_REG_SIGCONF2 = 0x07,
202 MAX8997_HAPTIC_REG_SIGCONF3 = 0x08,
203 MAX8997_HAPTIC_REG_SIGCONF4 = 0x09,
204 MAX8997_HAPTIC_REG_SIGDC1 = 0x0a,
205 MAX8997_HAPTIC_REG_SIGDC2 = 0x0b,
206 MAX8997_HAPTIC_REG_SIGPWMDC1 = 0x0c,
207 MAX8997_HAPTIC_REG_SIGPWMDC2 = 0x0d,
208 MAX8997_HAPTIC_REG_SIGPWMDC3 = 0x0e,
209 MAX8997_HAPTIC_REG_SIGPWMDC4 = 0x0f,
210 MAX8997_HAPTIC_REG_MTR_REV = 0x10,
211
212 MAX8997_HAPTIC_REG_END = 0x11,
213};
214
215/* slave addr = 0x0c: using "2nd part" of rev4 datasheet */
216enum max8997_rtc_reg {
217 MAX8997_RTC_CTRLMASK = 0x02,
218 MAX8997_RTC_CTRL = 0x03,
219 MAX8997_RTC_UPDATE1 = 0x04,
220 MAX8997_RTC_UPDATE2 = 0x05,
221 MAX8997_RTC_WTSR_SMPL = 0x06,
222
223 MAX8997_RTC_SEC = 0x10,
224 MAX8997_RTC_MIN = 0x11,
225 MAX8997_RTC_HOUR = 0x12,
226 MAX8997_RTC_DAY_OF_WEEK = 0x13,
227 MAX8997_RTC_MONTH = 0x14,
228 MAX8997_RTC_YEAR = 0x15,
229 MAX8997_RTC_DAY_OF_MONTH = 0x16,
230 MAX8997_RTC_ALARM1_SEC = 0x17,
231 MAX8997_RTC_ALARM1_MIN = 0x18,
232 MAX8997_RTC_ALARM1_HOUR = 0x19,
233 MAX8997_RTC_ALARM1_DAY_OF_WEEK = 0x1a,
234 MAX8997_RTC_ALARM1_MONTH = 0x1b,
235 MAX8997_RTC_ALARM1_YEAR = 0x1c,
236 MAX8997_RTC_ALARM1_DAY_OF_MONTH = 0x1d,
237 MAX8997_RTC_ALARM2_SEC = 0x1e,
238 MAX8997_RTC_ALARM2_MIN = 0x1f,
239 MAX8997_RTC_ALARM2_HOUR = 0x20,
240 MAX8997_RTC_ALARM2_DAY_OF_WEEK = 0x21,
241 MAX8997_RTC_ALARM2_MONTH = 0x22,
242 MAX8997_RTC_ALARM2_YEAR = 0x23,
243 MAX8997_RTC_ALARM2_DAY_OF_MONTH = 0x24,
244};
245
246enum max8997_irq_source {
247 PMIC_INT1 = 0,
248 PMIC_INT2,
249 PMIC_INT3,
250 PMIC_INT4,
251
252 FUEL_GAUGE, /* Ignored (MAX17042 driver handles) */
253
254 MUIC_INT1,
255 MUIC_INT2,
256 MUIC_INT3,
257
258 GPIO_LOW, /* Not implemented */
259 GPIO_HI, /* Not implemented */
260
261 FLASH_STATUS, /* Not implemented */
262
263 MAX8997_IRQ_GROUP_NR,
264};
265
266enum max8997_irq {
267 MAX8997_PMICIRQ_PWRONR,
268 MAX8997_PMICIRQ_PWRONF,
269 MAX8997_PMICIRQ_PWRON1SEC,
270 MAX8997_PMICIRQ_JIGONR,
271 MAX8997_PMICIRQ_JIGONF,
272 MAX8997_PMICIRQ_LOWBAT2,
273 MAX8997_PMICIRQ_LOWBAT1,
274
275 MAX8997_PMICIRQ_JIGR,
276 MAX8997_PMICIRQ_JIGF,
277 MAX8997_PMICIRQ_MR,
278 MAX8997_PMICIRQ_DVS1OK,
279 MAX8997_PMICIRQ_DVS2OK,
280 MAX8997_PMICIRQ_DVS3OK,
281 MAX8997_PMICIRQ_DVS4OK,
282
283 MAX8997_PMICIRQ_CHGINS,
284 MAX8997_PMICIRQ_CHGRM,
285 MAX8997_PMICIRQ_DCINOVP,
286 MAX8997_PMICIRQ_TOPOFFR,
287 MAX8997_PMICIRQ_CHGRSTF,
288 MAX8997_PMICIRQ_MBCHGTMEXPD,
289
290 MAX8997_PMICIRQ_RTC60S,
291 MAX8997_PMICIRQ_RTCA1,
292 MAX8997_PMICIRQ_RTCA2,
293 MAX8997_PMICIRQ_SMPL_INT,
294 MAX8997_PMICIRQ_RTC1S,
295 MAX8997_PMICIRQ_WTSR,
296
297 MAX8997_MUICIRQ_ADCError,
298 MAX8997_MUICIRQ_ADCLow,
299 MAX8997_MUICIRQ_ADC,
300
301 MAX8997_MUICIRQ_VBVolt,
302 MAX8997_MUICIRQ_DBChg,
303 MAX8997_MUICIRQ_DCDTmr,
304 MAX8997_MUICIRQ_ChgDetRun,
305 MAX8997_MUICIRQ_ChgTyp,
306
307 MAX8997_MUICIRQ_OVP,
308
309 MAX8997_IRQ_NR,
310};
311
312#define MAX8997_REG_BUCK1DVS(x) (MAX8997_REG_BUCK1DVS1 + (x) - 1)
313#define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1)
314#define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1)
315
316struct max8997_dev {
317 struct device *dev;
318 struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
319 struct i2c_client *rtc; /* slave addr 0x0c */
320 struct i2c_client *haptic; /* slave addr 0x90 */
321 struct i2c_client *muic; /* slave addr 0x4a */
322 struct mutex iolock;
323
324 int type;
325 struct platform_device *battery; /* battery control (not fuel gauge) */
326
327 bool wakeup;
328
329 /* For hibernation */
330 u8 reg_dump[MAX8997_REG_PMIC_END + MAX8997_MUIC_REG_END +
331 MAX8997_HAPTIC_REG_END];
332};
333
334enum max8997_types {
335 TYPE_MAX8997,
336 TYPE_MAX8966,
337};
338
339extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest);
340extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count,
341 u8 *buf);
342extern int max8997_write_reg(struct i2c_client *i2c, u8 reg, u8 value);
343extern int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count,
344 u8 *buf);
345extern int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask);
346
347#endif /* __LINUX_MFD_MAX8997_PRIV_H */
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
new file mode 100644
index 000000000000..cb671b3451bf
--- /dev/null
+++ b/include/linux/mfd/max8997.h
@@ -0,0 +1,114 @@
1/*
2 * max8997.h - Driver for the Maxim 8997/8966
3 *
4 * Copyright (C) 2009-2010 Samsung Electrnoics
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This driver is based on max8998.h
22 *
23 * MAX8997 has PMIC, MUIC, HAPTIC, RTC, FLASH, and Fuel Gauge devices.
24 * Except Fuel Gauge, every device shares the same I2C bus and included in
25 * this mfd driver. Although the fuel gauge is included in the chip, it is
26 * excluded from the driver because a) it has a different I2C bus from
27 * others and b) it can be enabled simply by using MAX17042 driver.
28 */
29
30#ifndef __LINUX_MFD_MAX8998_H
31#define __LINUX_MFD_MAX8998_H
32
33#include <linux/regulator/consumer.h>
34
35/* MAX8997/8966 regulator IDs */
36enum max8998_regulators {
37 MAX8997_LDO1 = 0,
38 MAX8997_LDO2,
39 MAX8997_LDO3,
40 MAX8997_LDO4,
41 MAX8997_LDO5,
42 MAX8997_LDO6,
43 MAX8997_LDO7,
44 MAX8997_LDO8,
45 MAX8997_LDO9,
46 MAX8997_LDO10,
47 MAX8997_LDO11,
48 MAX8997_LDO12,
49 MAX8997_LDO13,
50 MAX8997_LDO14,
51 MAX8997_LDO15,
52 MAX8997_LDO16,
53 MAX8997_LDO17,
54 MAX8997_LDO18,
55 MAX8997_LDO21,
56 MAX8997_BUCK1,
57 MAX8997_BUCK2,
58 MAX8997_BUCK3,
59 MAX8997_BUCK4,
60 MAX8997_BUCK5,
61 MAX8997_BUCK6,
62 MAX8997_BUCK7,
63 MAX8997_EN32KHZ_AP,
64 MAX8997_EN32KHZ_CP,
65 MAX8997_ENVICHG,
66 MAX8997_ESAFEOUT1,
67 MAX8997_ESAFEOUT2,
68 MAX8997_CHARGER_CV, /* control MBCCV of MBCCTRL3 */
69 MAX8997_CHARGER, /* charger current, MBCCTRL4 */
70 MAX8997_CHARGER_TOPOFF, /* MBCCTRL5 */
71
72 MAX8997_REG_MAX,
73};
74
75struct max8997_regulator_data {
76 int id;
77 struct regulator_init_data *initdata;
78};
79
80struct max8997_platform_data {
81 bool wakeup;
82 /* IRQ: Not implemented */
83 /* ---- PMIC ---- */
84 struct max8997_regulator_data *regulators;
85 int num_regulators;
86
87 /*
88 * SET1~3 DVS GPIOs control Buck1, 2, and 5 simultaneously. Therefore,
89 * With buckx_gpiodvs enabled, the buckx cannot be controlled
90 * independently. To control buckx (of 1, 2, and 5) independently,
91 * disable buckx_gpiodvs and control with BUCKxDVS1 register.
92 *
93 * When buckx_gpiodvs and bucky_gpiodvs are both enabled, set_voltage
94 * on buckx will change the voltage of bucky at the same time.
95 *
96 */
97 bool ignore_gpiodvs_side_effect;
98 int buck125_gpios[3]; /* GPIO of [0]SET1, [1]SET2, [2]SET3 */
99 int buck125_default_idx; /* Default value of SET1, 2, 3 */
100 unsigned int buck1_voltage[8]; /* buckx_voltage in uV */
101 bool buck1_gpiodvs;
102 unsigned int buck2_voltage[8];
103 bool buck2_gpiodvs;
104 unsigned int buck5_voltage[8];
105 bool buck5_gpiodvs;
106
107 /* MUIC: Not implemented */
108 /* HAPTIC: Not implemented */
109 /* RTC: Not implemented */
110 /* Flash: Not implemented */
111 /* Charger control: Not implemented */
112};
113
114#endif /* __LINUX_MFD_MAX8998_H */
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index a1d391b40e68..c064beaaccb7 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -146,8 +146,7 @@ struct mc13xxx_platform_data {
146#define MC13XXX_USE_LED (1 << 5) 146#define MC13XXX_USE_LED (1 << 5)
147 unsigned int flags; 147 unsigned int flags;
148 148
149 int num_regulators; 149 struct mc13xxx_regulator_platform_data regulators;
150 struct mc13xxx_regulator_init_data *regulators;
151 struct mc13xxx_leds_platform_data *leds; 150 struct mc13xxx_leds_platform_data *leds;
152}; 151};
153 152
diff --git a/include/linux/mfd/tps6105x.h b/include/linux/mfd/tps6105x.h
new file mode 100644
index 000000000000..386743dd931c
--- /dev/null
+++ b/include/linux/mfd/tps6105x.h
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2011 ST-Ericsson SA
3 * Written on behalf of Linaro for ST-Ericsson
4 *
5 * Author: Linus Walleij <linus.walleij@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9#ifndef MFD_TPS6105X_H
10#define MFD_TPS6105X_H
11
12#include <linux/i2c.h>
13#include <linux/regulator/machine.h>
14
15/*
16 * Register definitions to all subdrivers
17 */
18#define TPS6105X_REG_0 0x00
19#define TPS6105X_REG0_MODE_SHIFT 6
20#define TPS6105X_REG0_MODE_MASK (0x03<<6)
21/* These defines for both reg0 and reg1 */
22#define TPS6105X_REG0_MODE_SHUTDOWN 0x00
23#define TPS6105X_REG0_MODE_TORCH 0x01
24#define TPS6105X_REG0_MODE_TORCH_FLASH 0x02
25#define TPS6105X_REG0_MODE_VOLTAGE 0x03
26#define TPS6105X_REG0_VOLTAGE_SHIFT 4
27#define TPS6105X_REG0_VOLTAGE_MASK (3<<4)
28#define TPS6105X_REG0_VOLTAGE_450 0
29#define TPS6105X_REG0_VOLTAGE_500 1
30#define TPS6105X_REG0_VOLTAGE_525 2
31#define TPS6105X_REG0_VOLTAGE_500_2 3
32#define TPS6105X_REG0_DIMMING_SHIFT 3
33#define TPS6105X_REG0_TORCHC_SHIFT 0
34#define TPS6105X_REG0_TORCHC_MASK (7<<0)
35#define TPS6105X_REG0_TORCHC_0 0x00
36#define TPS6105X_REG0_TORCHC_50 0x01
37#define TPS6105X_REG0_TORCHC_75 0x02
38#define TPS6105X_REG0_TORCHC_100 0x03
39#define TPS6105X_REG0_TORCHC_150 0x04
40#define TPS6105X_REG0_TORCHC_200 0x05
41#define TPS6105X_REG0_TORCHC_250_400 0x06
42#define TPS6105X_REG0_TORCHC_250_500 0x07
43#define TPS6105X_REG_1 0x01
44#define TPS6105X_REG1_MODE_SHIFT 6
45#define TPS6105X_REG1_MODE_MASK (0x03<<6)
46#define TPS6105X_REG1_MODE_SHUTDOWN 0x00
47#define TPS6105X_REG1_MODE_TORCH 0x01
48#define TPS6105X_REG1_MODE_TORCH_FLASH 0x02
49#define TPS6105X_REG1_MODE_VOLTAGE 0x03
50#define TPS6105X_REG_2 0x02
51#define TPS6105X_REG_3 0x03
52
53/**
54 * enum tps6105x_mode - desired mode for the TPS6105x
55 * @TPS6105X_MODE_SHUTDOWN: this instance is inactive, not used for anything
56 * @TPS61905X_MODE_TORCH: this instance is used as a LED, usually a while
57 * LED, for example as backlight or flashlight. If this is set, the
58 * TPS6105X will register to the LED framework
59 * @TPS6105X_MODE_TORCH_FLASH: this instance is used as a flashgun, usually
60 * in a camera
61 * @TPS6105X_MODE_VOLTAGE: this instance is used as a voltage regulator and
62 * will register to the regulator framework
63 */
64enum tps6105x_mode {
65 TPS6105X_MODE_SHUTDOWN,
66 TPS6105X_MODE_TORCH,
67 TPS6105X_MODE_TORCH_FLASH,
68 TPS6105X_MODE_VOLTAGE,
69};
70
71/**
72 * struct tps6105x_platform_data - TPS61905x platform data
73 * @mode: what mode this instance shall be operated in,
74 * this is not selectable at runtime
75 * @regulator_data: initialization data for the voltage
76 * regulator if used as a voltage source
77 */
78struct tps6105x_platform_data {
79 enum tps6105x_mode mode;
80 struct regulator_init_data *regulator_data;
81};
82
83/**
84 * struct tps6105x - state holder for the TPS6105x drivers
85 * @mutex: mutex to serialize I2C accesses
86 * @i2c_client: corresponding I2C client
87 * @regulator: regulator device if used in voltage mode
88 */
89struct tps6105x {
90 struct tps6105x_platform_data *pdata;
91 struct mutex lock;
92 struct i2c_client *client;
93 struct regulator_dev *regulator;
94};
95
96extern int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value);
97extern int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf);
98extern int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg,
99 u8 bitmask, u8 bitvalues);
100
101#endif
diff --git a/include/linux/mfd/wl1273-core.h b/include/linux/mfd/wl1273-core.h
index 9787293eae5f..db2f3f454a1b 100644
--- a/include/linux/mfd/wl1273-core.h
+++ b/include/linux/mfd/wl1273-core.h
@@ -280,7 +280,9 @@ struct wl1273_core {
280 280
281 struct i2c_client *client; 281 struct i2c_client *client;
282 282
283 int (*read)(struct wl1273_core *core, u8, u16 *);
283 int (*write)(struct wl1273_core *core, u8, u16); 284 int (*write)(struct wl1273_core *core, u8, u16);
285 int (*write_data)(struct wl1273_core *core, u8 *, u16);
284 int (*set_audio)(struct wl1273_core *core, unsigned int); 286 int (*set_audio)(struct wl1273_core *core, unsigned int);
285 int (*set_volume)(struct wl1273_core *core, unsigned int); 287 int (*set_volume)(struct wl1273_core *core, unsigned int);
286}; 288};
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index 173086d42af4..afe4db49402d 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -104,11 +104,17 @@ struct wm831x_watchdog_pdata {
104#define WM831X_MAX_ISINK 2 104#define WM831X_MAX_ISINK 2
105 105
106struct wm831x_pdata { 106struct wm831x_pdata {
107 /** Used to distinguish multiple WM831x chips */
108 int wm831x_num;
109
107 /** Called before subdevices are set up */ 110 /** Called before subdevices are set up */
108 int (*pre_init)(struct wm831x *wm831x); 111 int (*pre_init)(struct wm831x *wm831x);
109 /** Called after subdevices are set up */ 112 /** Called after subdevices are set up */
110 int (*post_init)(struct wm831x *wm831x); 113 int (*post_init)(struct wm831x *wm831x);
111 114
115 /** Put the /IRQ line into CMOS mode */
116 bool irq_cmos;
117
112 int irq_base; 118 int irq_base;
113 int gpio_base; 119 int gpio_base;
114 struct wm831x_backlight_pdata *backlight; 120 struct wm831x_backlight_pdata *backlight;
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index ef4f0b6083a3..f0b69cdae41c 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -59,7 +59,7 @@ struct wm8994 {
59 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, 59 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
60 int bytes, void *dest); 60 int bytes, void *dest);
61 int (*write_dev)(struct wm8994 *wm8994, unsigned short reg, 61 int (*write_dev)(struct wm8994 *wm8994, unsigned short reg,
62 int bytes, void *src); 62 int bytes, const void *src);
63 63
64 void *control_data; 64 void *control_data;
65 65
@@ -88,6 +88,8 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
88 unsigned short mask, unsigned short val); 88 unsigned short mask, unsigned short val);
89int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 89int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
90 int count, u16 *buf); 90 int count, u16 *buf);
91int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
92 int count, const u16 *buf);
91 93
92 94
93/* Helper to save on boilerplate */ 95/* Helper to save on boilerplate */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index f9535b2c9558..7606d7db96c9 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -861,7 +861,7 @@ extern void pagefault_out_of_memory(void);
861#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) 861#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
862 862
863/* 863/*
864 * Flags passed to __show_mem() and __show_free_areas() to suppress output in 864 * Flags passed to show_mem() and __show_free_areas() to suppress output in
865 * various contexts. 865 * various contexts.
866 */ 866 */
867#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ 867#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */
@@ -1360,8 +1360,7 @@ extern void setup_per_zone_wmarks(void);
1360extern void calculate_zone_inactive_ratio(struct zone *zone); 1360extern void calculate_zone_inactive_ratio(struct zone *zone);
1361extern void mem_init(void); 1361extern void mem_init(void);
1362extern void __init mmap_init(void); 1362extern void __init mmap_init(void);
1363extern void show_mem(void); 1363extern void show_mem(unsigned int flags);
1364extern void __show_mem(unsigned int flags);
1365extern void si_meminfo(struct sysinfo * val); 1364extern void si_meminfo(struct sysinfo * val);
1366extern void si_meminfo_node(struct sysinfo *val, int nid); 1365extern void si_meminfo_node(struct sysinfo *val, int nid);
1367extern int after_bootmem; 1366extern int after_bootmem;
diff --git a/include/linux/mmc/boot.h b/include/linux/mmc/boot.h
new file mode 100644
index 000000000000..39d787c229cb
--- /dev/null
+++ b/include/linux/mmc/boot.h
@@ -0,0 +1,7 @@
1#ifndef MMC_BOOT_H
2#define MMC_BOOT_H
3
4enum { MMC_PROGRESS_ENTER, MMC_PROGRESS_INIT,
5 MMC_PROGRESS_LOAD, MMC_PROGRESS_DONE };
6
7#endif
diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
index 38d393092812..9eb9b4b96f55 100644
--- a/include/linux/mmc/sh_mmcif.h
+++ b/include/linux/mmc/sh_mmcif.h
@@ -104,9 +104,6 @@ static inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val)
104 104
105#define SH_MMCIF_BBS 512 /* boot block size */ 105#define SH_MMCIF_BBS 512 /* boot block size */
106 106
107enum { MMCIF_PROGRESS_ENTER, MMCIF_PROGRESS_INIT,
108 MMCIF_PROGRESS_LOAD, MMCIF_PROGRESS_DONE };
109
110static inline void sh_mmcif_boot_cmd_send(void __iomem *base, 107static inline void sh_mmcif_boot_cmd_send(void __iomem *base,
111 unsigned long cmd, unsigned long arg) 108 unsigned long cmd, unsigned long arg)
112{ 109{
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 17c7e21c0bd7..fb51ae38cea7 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -52,9 +52,6 @@ extern struct platform_device *of_platform_device_create(struct device_node *np,
52 const char *bus_id, 52 const char *bus_id,
53 struct device *parent); 53 struct device *parent);
54 54
55/* pseudo "matches" value to not do deep probe */
56#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
57
58extern int of_platform_bus_probe(struct device_node *root, 55extern int of_platform_bus_probe(struct device_node *root,
59 const struct of_device_id *matches, 56 const struct of_device_id *matches,
60 struct device *parent); 57 struct device *parent);
diff --git a/include/linux/omap3isp.h b/include/linux/omap3isp.h
new file mode 100644
index 000000000000..150822b4dbff
--- /dev/null
+++ b/include/linux/omap3isp.h
@@ -0,0 +1,646 @@
1/*
2 * omap3isp.h
3 *
4 * TI OMAP3 ISP - User-space API
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_USER_H
28#define OMAP3_ISP_USER_H
29
30#include <linux/types.h>
31
32/*
33 * Private IOCTLs
34 *
35 * VIDIOC_OMAP3ISP_CCDC_CFG: Set CCDC configuration
36 * VIDIOC_OMAP3ISP_PRV_CFG: Set preview engine configuration
37 * VIDIOC_OMAP3ISP_AEWB_CFG: Set AEWB module configuration
38 * VIDIOC_OMAP3ISP_HIST_CFG: Set histogram module configuration
39 * VIDIOC_OMAP3ISP_AF_CFG: Set auto-focus module configuration
40 * VIDIOC_OMAP3ISP_STAT_REQ: Read statistics (AEWB/AF/histogram) data
41 * VIDIOC_OMAP3ISP_STAT_EN: Enable/disable a statistics module
42 */
43
44#define VIDIOC_OMAP3ISP_CCDC_CFG \
45 _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct omap3isp_ccdc_update_config)
46#define VIDIOC_OMAP3ISP_PRV_CFG \
47 _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct omap3isp_prev_update_config)
48#define VIDIOC_OMAP3ISP_AEWB_CFG \
49 _IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct omap3isp_h3a_aewb_config)
50#define VIDIOC_OMAP3ISP_HIST_CFG \
51 _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct omap3isp_hist_config)
52#define VIDIOC_OMAP3ISP_AF_CFG \
53 _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct omap3isp_h3a_af_config)
54#define VIDIOC_OMAP3ISP_STAT_REQ \
55 _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct omap3isp_stat_data)
56#define VIDIOC_OMAP3ISP_STAT_EN \
57 _IOWR('V', BASE_VIDIOC_PRIVATE + 7, unsigned long)
58
59/*
60 * Events
61 *
62 * V4L2_EVENT_OMAP3ISP_AEWB: AEWB statistics data ready
63 * V4L2_EVENT_OMAP3ISP_AF: AF statistics data ready
64 * V4L2_EVENT_OMAP3ISP_HIST: Histogram statistics data ready
65 * V4L2_EVENT_OMAP3ISP_HS_VS: Horizontal/vertical synchronization detected
66 */
67
68#define V4L2_EVENT_OMAP3ISP_CLASS (V4L2_EVENT_PRIVATE_START | 0x100)
69#define V4L2_EVENT_OMAP3ISP_AEWB (V4L2_EVENT_OMAP3ISP_CLASS | 0x1)
70#define V4L2_EVENT_OMAP3ISP_AF (V4L2_EVENT_OMAP3ISP_CLASS | 0x2)
71#define V4L2_EVENT_OMAP3ISP_HIST (V4L2_EVENT_OMAP3ISP_CLASS | 0x3)
72#define V4L2_EVENT_OMAP3ISP_HS_VS (V4L2_EVENT_OMAP3ISP_CLASS | 0x4)
73
74struct omap3isp_stat_event_status {
75 __u32 frame_number;
76 __u16 config_counter;
77 __u8 buf_err;
78};
79
80/* AE/AWB related structures and flags*/
81
82/* H3A Range Constants */
83#define OMAP3ISP_AEWB_MAX_SATURATION_LIM 1023
84#define OMAP3ISP_AEWB_MIN_WIN_H 2
85#define OMAP3ISP_AEWB_MAX_WIN_H 256
86#define OMAP3ISP_AEWB_MIN_WIN_W 6
87#define OMAP3ISP_AEWB_MAX_WIN_W 256
88#define OMAP3ISP_AEWB_MIN_WINVC 1
89#define OMAP3ISP_AEWB_MIN_WINHC 1
90#define OMAP3ISP_AEWB_MAX_WINVC 128
91#define OMAP3ISP_AEWB_MAX_WINHC 36
92#define OMAP3ISP_AEWB_MAX_WINSTART 4095
93#define OMAP3ISP_AEWB_MIN_SUB_INC 2
94#define OMAP3ISP_AEWB_MAX_SUB_INC 32
95#define OMAP3ISP_AEWB_MAX_BUF_SIZE 83600
96
97#define OMAP3ISP_AF_IIRSH_MIN 0
98#define OMAP3ISP_AF_IIRSH_MAX 4095
99#define OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN 1
100#define OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MAX 36
101#define OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN 1
102#define OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MAX 128
103#define OMAP3ISP_AF_PAXEL_INCREMENT_MIN 2
104#define OMAP3ISP_AF_PAXEL_INCREMENT_MAX 32
105#define OMAP3ISP_AF_PAXEL_HEIGHT_MIN 2
106#define OMAP3ISP_AF_PAXEL_HEIGHT_MAX 256
107#define OMAP3ISP_AF_PAXEL_WIDTH_MIN 16
108#define OMAP3ISP_AF_PAXEL_WIDTH_MAX 256
109#define OMAP3ISP_AF_PAXEL_HZSTART_MIN 1
110#define OMAP3ISP_AF_PAXEL_HZSTART_MAX 4095
111#define OMAP3ISP_AF_PAXEL_VTSTART_MIN 0
112#define OMAP3ISP_AF_PAXEL_VTSTART_MAX 4095
113#define OMAP3ISP_AF_THRESHOLD_MAX 255
114#define OMAP3ISP_AF_COEF_MAX 4095
115#define OMAP3ISP_AF_PAXEL_SIZE 48
116#define OMAP3ISP_AF_MAX_BUF_SIZE 221184
117
118/**
119 * struct omap3isp_h3a_aewb_config - AE AWB configuration reset values
120 * saturation_limit: Saturation limit.
121 * @win_height: Window Height. Range 2 - 256, even values only.
122 * @win_width: Window Width. Range 6 - 256, even values only.
123 * @ver_win_count: Vertical Window Count. Range 1 - 128.
124 * @hor_win_count: Horizontal Window Count. Range 1 - 36.
125 * @ver_win_start: Vertical Window Start. Range 0 - 4095.
126 * @hor_win_start: Horizontal Window Start. Range 0 - 4095.
127 * @blk_ver_win_start: Black Vertical Windows Start. Range 0 - 4095.
128 * @blk_win_height: Black Window Height. Range 2 - 256, even values only.
129 * @subsample_ver_inc: Subsample Vertical points increment Range 2 - 32, even
130 * values only.
131 * @subsample_hor_inc: Subsample Horizontal points increment Range 2 - 32, even
132 * values only.
133 * @alaw_enable: AEW ALAW EN flag.
134 */
135struct omap3isp_h3a_aewb_config {
136 /*
137 * Common fields.
138 * They should be the first ones and must be in the same order as in
139 * ispstat_generic_config struct.
140 */
141 __u32 buf_size;
142 __u16 config_counter;
143
144 /* Private fields */
145 __u16 saturation_limit;
146 __u16 win_height;
147 __u16 win_width;
148 __u16 ver_win_count;
149 __u16 hor_win_count;
150 __u16 ver_win_start;
151 __u16 hor_win_start;
152 __u16 blk_ver_win_start;
153 __u16 blk_win_height;
154 __u16 subsample_ver_inc;
155 __u16 subsample_hor_inc;
156 __u8 alaw_enable;
157};
158
159/**
160 * struct omap3isp_stat_data - Statistic data sent to or received from user
161 * @ts: Timestamp of returned framestats.
162 * @buf: Pointer to pass to user.
163 * @frame_number: Frame number of requested stats.
164 * @cur_frame: Current frame number being processed.
165 * @config_counter: Number of the configuration associated with the data.
166 */
167struct omap3isp_stat_data {
168 struct timeval ts;
169 void __user *buf;
170 __u32 buf_size;
171 __u16 frame_number;
172 __u16 cur_frame;
173 __u16 config_counter;
174};
175
176
177/* Histogram related structs */
178
179/* Flags for number of bins */
180#define OMAP3ISP_HIST_BINS_32 0
181#define OMAP3ISP_HIST_BINS_64 1
182#define OMAP3ISP_HIST_BINS_128 2
183#define OMAP3ISP_HIST_BINS_256 3
184
185/* Number of bins * 4 colors * 4-bytes word */
186#define OMAP3ISP_HIST_MEM_SIZE_BINS(n) ((1 << ((n)+5))*4*4)
187
188#define OMAP3ISP_HIST_MEM_SIZE 1024
189#define OMAP3ISP_HIST_MIN_REGIONS 1
190#define OMAP3ISP_HIST_MAX_REGIONS 4
191#define OMAP3ISP_HIST_MAX_WB_GAIN 255
192#define OMAP3ISP_HIST_MIN_WB_GAIN 0
193#define OMAP3ISP_HIST_MAX_BIT_WIDTH 14
194#define OMAP3ISP_HIST_MIN_BIT_WIDTH 8
195#define OMAP3ISP_HIST_MAX_WG 4
196#define OMAP3ISP_HIST_MAX_BUF_SIZE 4096
197
198/* Source */
199#define OMAP3ISP_HIST_SOURCE_CCDC 0
200#define OMAP3ISP_HIST_SOURCE_MEM 1
201
202/* CFA pattern */
203#define OMAP3ISP_HIST_CFA_BAYER 0
204#define OMAP3ISP_HIST_CFA_FOVEONX3 1
205
206struct omap3isp_hist_region {
207 __u16 h_start;
208 __u16 h_end;
209 __u16 v_start;
210 __u16 v_end;
211};
212
213struct omap3isp_hist_config {
214 /*
215 * Common fields.
216 * They should be the first ones and must be in the same order as in
217 * ispstat_generic_config struct.
218 */
219 __u32 buf_size;
220 __u16 config_counter;
221
222 __u8 num_acc_frames; /* Num of image frames to be processed and
223 accumulated for each histogram frame */
224 __u16 hist_bins; /* number of bins: 32, 64, 128, or 256 */
225 __u8 cfa; /* BAYER or FOVEON X3 */
226 __u8 wg[OMAP3ISP_HIST_MAX_WG]; /* White Balance Gain */
227 __u8 num_regions; /* number of regions to be configured */
228 struct omap3isp_hist_region region[OMAP3ISP_HIST_MAX_REGIONS];
229};
230
231/* Auto Focus related structs */
232
233#define OMAP3ISP_AF_NUM_COEF 11
234
235enum omap3isp_h3a_af_fvmode {
236 OMAP3ISP_AF_MODE_SUMMED = 0,
237 OMAP3ISP_AF_MODE_PEAK = 1
238};
239
240/* Red, Green, and blue pixel location in the AF windows */
241enum omap3isp_h3a_af_rgbpos {
242 OMAP3ISP_AF_GR_GB_BAYER = 0, /* GR and GB as Bayer pattern */
243 OMAP3ISP_AF_RG_GB_BAYER = 1, /* RG and GB as Bayer pattern */
244 OMAP3ISP_AF_GR_BG_BAYER = 2, /* GR and BG as Bayer pattern */
245 OMAP3ISP_AF_RG_BG_BAYER = 3, /* RG and BG as Bayer pattern */
246 OMAP3ISP_AF_GG_RB_CUSTOM = 4, /* GG and RB as custom pattern */
247 OMAP3ISP_AF_RB_GG_CUSTOM = 5 /* RB and GG as custom pattern */
248};
249
250/* Contains the information regarding the Horizontal Median Filter */
251struct omap3isp_h3a_af_hmf {
252 __u8 enable; /* Status of Horizontal Median Filter */
253 __u8 threshold; /* Threshhold Value for Horizontal Median Filter */
254};
255
256/* Contains the information regarding the IIR Filters */
257struct omap3isp_h3a_af_iir {
258 __u16 h_start; /* IIR horizontal start */
259 __u16 coeff_set0[OMAP3ISP_AF_NUM_COEF]; /* Filter coefficient, set 0 */
260 __u16 coeff_set1[OMAP3ISP_AF_NUM_COEF]; /* Filter coefficient, set 1 */
261};
262
263/* Contains the information regarding the Paxels Structure in AF Engine */
264struct omap3isp_h3a_af_paxel {
265 __u16 h_start; /* Horizontal Start Position */
266 __u16 v_start; /* Vertical Start Position */
267 __u8 width; /* Width of the Paxel */
268 __u8 height; /* Height of the Paxel */
269 __u8 h_cnt; /* Horizontal Count */
270 __u8 v_cnt; /* vertical Count */
271 __u8 line_inc; /* Line Increment */
272};
273
274/* Contains the parameters required for hardware set up of AF Engine */
275struct omap3isp_h3a_af_config {
276 /*
277 * Common fields.
278 * They should be the first ones and must be in the same order as in
279 * ispstat_generic_config struct.
280 */
281 __u32 buf_size;
282 __u16 config_counter;
283
284 struct omap3isp_h3a_af_hmf hmf; /* HMF configurations */
285 struct omap3isp_h3a_af_iir iir; /* IIR filter configurations */
286 struct omap3isp_h3a_af_paxel paxel; /* Paxel parameters */
287 enum omap3isp_h3a_af_rgbpos rgb_pos; /* RGB Positions */
288 enum omap3isp_h3a_af_fvmode fvmode; /* Accumulator mode */
289 __u8 alaw_enable; /* AF ALAW status */
290};
291
292/* ISP CCDC structs */
293
294/* Abstraction layer CCDC configurations */
295#define OMAP3ISP_CCDC_ALAW (1 << 0)
296#define OMAP3ISP_CCDC_LPF (1 << 1)
297#define OMAP3ISP_CCDC_BLCLAMP (1 << 2)
298#define OMAP3ISP_CCDC_BCOMP (1 << 3)
299#define OMAP3ISP_CCDC_FPC (1 << 4)
300#define OMAP3ISP_CCDC_CULL (1 << 5)
301#define OMAP3ISP_CCDC_CONFIG_LSC (1 << 7)
302#define OMAP3ISP_CCDC_TBL_LSC (1 << 8)
303
304#define OMAP3ISP_RGB_MAX 3
305
306/* Enumeration constants for Alaw input width */
307enum omap3isp_alaw_ipwidth {
308 OMAP3ISP_ALAW_BIT12_3 = 0x3,
309 OMAP3ISP_ALAW_BIT11_2 = 0x4,
310 OMAP3ISP_ALAW_BIT10_1 = 0x5,
311 OMAP3ISP_ALAW_BIT9_0 = 0x6
312};
313
314/**
315 * struct omap3isp_ccdc_lsc_config - LSC configuration
316 * @offset: Table Offset of the gain table.
317 * @gain_mode_n: Vertical dimension of a paxel in LSC configuration.
318 * @gain_mode_m: Horizontal dimension of a paxel in LSC configuration.
319 * @gain_format: Gain table format.
320 * @fmtsph: Start pixel horizontal from start of the HS sync pulse.
321 * @fmtlnh: Number of pixels in horizontal direction to use for the data
322 * reformatter.
323 * @fmtslv: Start line from start of VS sync pulse for the data reformatter.
324 * @fmtlnv: Number of lines in vertical direction for the data reformatter.
325 * @initial_x: X position, in pixels, of the first active pixel in reference
326 * to the first active paxel. Must be an even number.
327 * @initial_y: Y position, in pixels, of the first active pixel in reference
328 * to the first active paxel. Must be an even number.
329 * @size: Size of LSC gain table. Filled when loaded from userspace.
330 */
331struct omap3isp_ccdc_lsc_config {
332 __u16 offset;
333 __u8 gain_mode_n;
334 __u8 gain_mode_m;
335 __u8 gain_format;
336 __u16 fmtsph;
337 __u16 fmtlnh;
338 __u16 fmtslv;
339 __u16 fmtlnv;
340 __u8 initial_x;
341 __u8 initial_y;
342 __u32 size;
343};
344
345/**
346 * struct omap3isp_ccdc_bclamp - Optical & Digital black clamp subtract
347 * @obgain: Optical black average gain.
348 * @obstpixel: Start Pixel w.r.t. HS pulse in Optical black sample.
349 * @oblines: Optical Black Sample lines.
350 * @oblen: Optical Black Sample Length.
351 * @dcsubval: Digital Black Clamp subtract value.
352 */
353struct omap3isp_ccdc_bclamp {
354 __u8 obgain;
355 __u8 obstpixel;
356 __u8 oblines;
357 __u8 oblen;
358 __u16 dcsubval;
359};
360
361/**
362 * struct omap3isp_ccdc_fpc - Faulty Pixels Correction
363 * @fpnum: Number of faulty pixels to be corrected in the frame.
364 * @fpcaddr: Memory address of the FPC Table
365 */
366struct omap3isp_ccdc_fpc {
367 __u16 fpnum;
368 __u32 fpcaddr;
369};
370
371/**
372 * struct omap3isp_ccdc_blcomp - Black Level Compensation parameters
373 * @b_mg: B/Mg pixels. 2's complement. -128 to +127.
374 * @gb_g: Gb/G pixels. 2's complement. -128 to +127.
375 * @gr_cy: Gr/Cy pixels. 2's complement. -128 to +127.
376 * @r_ye: R/Ye pixels. 2's complement. -128 to +127.
377 */
378struct omap3isp_ccdc_blcomp {
379 __u8 b_mg;
380 __u8 gb_g;
381 __u8 gr_cy;
382 __u8 r_ye;
383};
384
385/**
386 * omap3isp_ccdc_culling - Culling parameters
387 * @v_pattern: Vertical culling pattern.
388 * @h_odd: Horizontal Culling pattern for odd lines.
389 * @h_even: Horizontal Culling pattern for even lines.
390 */
391struct omap3isp_ccdc_culling {
392 __u8 v_pattern;
393 __u16 h_odd;
394 __u16 h_even;
395};
396
397/**
398 * omap3isp_ccdc_update_config - CCDC configuration
399 * @update: Specifies which CCDC registers should be updated.
400 * @flag: Specifies which CCDC functions should be enabled.
401 * @alawip: Enable/Disable A-Law compression.
402 * @bclamp: Black clamp control register.
403 * @blcomp: Black level compensation value for RGrGbB Pixels. 2's complement.
404 * @fpc: Number of faulty pixels corrected in the frame, address of FPC table.
405 * @cull: Cull control register.
406 * @lsc: Pointer to LSC gain table.
407 */
408struct omap3isp_ccdc_update_config {
409 __u16 update;
410 __u16 flag;
411 enum omap3isp_alaw_ipwidth alawip;
412 struct omap3isp_ccdc_bclamp __user *bclamp;
413 struct omap3isp_ccdc_blcomp __user *blcomp;
414 struct omap3isp_ccdc_fpc __user *fpc;
415 struct omap3isp_ccdc_lsc_config __user *lsc_cfg;
416 struct omap3isp_ccdc_culling __user *cull;
417 __u8 __user *lsc;
418};
419
420/* Preview configurations */
421#define OMAP3ISP_PREV_LUMAENH (1 << 0)
422#define OMAP3ISP_PREV_INVALAW (1 << 1)
423#define OMAP3ISP_PREV_HRZ_MED (1 << 2)
424#define OMAP3ISP_PREV_CFA (1 << 3)
425#define OMAP3ISP_PREV_CHROMA_SUPP (1 << 4)
426#define OMAP3ISP_PREV_WB (1 << 5)
427#define OMAP3ISP_PREV_BLKADJ (1 << 6)
428#define OMAP3ISP_PREV_RGB2RGB (1 << 7)
429#define OMAP3ISP_PREV_COLOR_CONV (1 << 8)
430#define OMAP3ISP_PREV_YC_LIMIT (1 << 9)
431#define OMAP3ISP_PREV_DEFECT_COR (1 << 10)
432#define OMAP3ISP_PREV_GAMMABYPASS (1 << 11)
433#define OMAP3ISP_PREV_DRK_FRM_CAPTURE (1 << 12)
434#define OMAP3ISP_PREV_DRK_FRM_SUBTRACT (1 << 13)
435#define OMAP3ISP_PREV_LENS_SHADING (1 << 14)
436#define OMAP3ISP_PREV_NF (1 << 15)
437#define OMAP3ISP_PREV_GAMMA (1 << 16)
438
439#define OMAP3ISP_PREV_NF_TBL_SIZE 64
440#define OMAP3ISP_PREV_CFA_TBL_SIZE 576
441#define OMAP3ISP_PREV_GAMMA_TBL_SIZE 1024
442#define OMAP3ISP_PREV_YENH_TBL_SIZE 128
443
444#define OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS 4
445
446/**
447 * struct omap3isp_prev_hmed - Horizontal Median Filter
448 * @odddist: Distance between consecutive pixels of same color in the odd line.
449 * @evendist: Distance between consecutive pixels of same color in the even
450 * line.
451 * @thres: Horizontal median filter threshold.
452 */
453struct omap3isp_prev_hmed {
454 __u8 odddist;
455 __u8 evendist;
456 __u8 thres;
457};
458
459/*
460 * Enumeration for CFA Formats supported by preview
461 */
462enum omap3isp_cfa_fmt {
463 OMAP3ISP_CFAFMT_BAYER,
464 OMAP3ISP_CFAFMT_SONYVGA,
465 OMAP3ISP_CFAFMT_RGBFOVEON,
466 OMAP3ISP_CFAFMT_DNSPL,
467 OMAP3ISP_CFAFMT_HONEYCOMB,
468 OMAP3ISP_CFAFMT_RRGGBBFOVEON
469};
470
471/**
472 * struct omap3isp_prev_cfa - CFA Interpolation
473 * @format: CFA Format Enum value supported by preview.
474 * @gradthrs_vert: CFA Gradient Threshold - Vertical.
475 * @gradthrs_horz: CFA Gradient Threshold - Horizontal.
476 * @table: Pointer to the CFA table.
477 */
478struct omap3isp_prev_cfa {
479 enum omap3isp_cfa_fmt format;
480 __u8 gradthrs_vert;
481 __u8 gradthrs_horz;
482 __u32 table[OMAP3ISP_PREV_CFA_TBL_SIZE];
483};
484
485/**
486 * struct omap3isp_prev_csup - Chrominance Suppression
487 * @gain: Gain.
488 * @thres: Threshold.
489 * @hypf_en: Flag to enable/disable the High Pass Filter.
490 */
491struct omap3isp_prev_csup {
492 __u8 gain;
493 __u8 thres;
494 __u8 hypf_en;
495};
496
497/**
498 * struct omap3isp_prev_wbal - White Balance
499 * @dgain: Digital gain (U10Q8).
500 * @coef3: White balance gain - COEF 3 (U8Q5).
501 * @coef2: White balance gain - COEF 2 (U8Q5).
502 * @coef1: White balance gain - COEF 1 (U8Q5).
503 * @coef0: White balance gain - COEF 0 (U8Q5).
504 */
505struct omap3isp_prev_wbal {
506 __u16 dgain;
507 __u8 coef3;
508 __u8 coef2;
509 __u8 coef1;
510 __u8 coef0;
511};
512
513/**
514 * struct omap3isp_prev_blkadj - Black Level Adjustment
515 * @red: Black level offset adjustment for Red in 2's complement format
516 * @green: Black level offset adjustment for Green in 2's complement format
517 * @blue: Black level offset adjustment for Blue in 2's complement format
518 */
519struct omap3isp_prev_blkadj {
520 /*Black level offset adjustment for Red in 2's complement format */
521 __u8 red;
522 /*Black level offset adjustment for Green in 2's complement format */
523 __u8 green;
524 /* Black level offset adjustment for Blue in 2's complement format */
525 __u8 blue;
526};
527
528/**
529 * struct omap3isp_prev_rgbtorgb - RGB to RGB Blending
530 * @matrix: Blending values(S12Q8 format)
531 * [RR] [GR] [BR]
532 * [RG] [GG] [BG]
533 * [RB] [GB] [BB]
534 * @offset: Blending offset value for R,G,B in 2's complement integer format.
535 */
536struct omap3isp_prev_rgbtorgb {
537 __u16 matrix[OMAP3ISP_RGB_MAX][OMAP3ISP_RGB_MAX];
538 __u16 offset[OMAP3ISP_RGB_MAX];
539};
540
541/**
542 * struct omap3isp_prev_csc - Color Space Conversion from RGB-YCbYCr
543 * @matrix: Color space conversion coefficients(S10Q8)
544 * [CSCRY] [CSCGY] [CSCBY]
545 * [CSCRCB] [CSCGCB] [CSCBCB]
546 * [CSCRCR] [CSCGCR] [CSCBCR]
547 * @offset: CSC offset values for Y offset, CB offset and CR offset respectively
548 */
549struct omap3isp_prev_csc {
550 __u16 matrix[OMAP3ISP_RGB_MAX][OMAP3ISP_RGB_MAX];
551 __s16 offset[OMAP3ISP_RGB_MAX];
552};
553
554/**
555 * struct omap3isp_prev_yclimit - Y, C Value Limit
556 * @minC: Minimum C value
557 * @maxC: Maximum C value
558 * @minY: Minimum Y value
559 * @maxY: Maximum Y value
560 */
561struct omap3isp_prev_yclimit {
562 __u8 minC;
563 __u8 maxC;
564 __u8 minY;
565 __u8 maxY;
566};
567
568/**
569 * struct omap3isp_prev_dcor - Defect correction
570 * @couplet_mode_en: Flag to enable or disable the couplet dc Correction in NF
571 * @detect_correct: Thresholds for correction bit 0:10 detect 16:25 correct
572 */
573struct omap3isp_prev_dcor {
574 __u8 couplet_mode_en;
575 __u32 detect_correct[OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS];
576};
577
578/**
579 * struct omap3isp_prev_nf - Noise Filter
580 * @spread: Spread value to be used in Noise Filter
581 * @table: Pointer to the Noise Filter table
582 */
583struct omap3isp_prev_nf {
584 __u8 spread;
585 __u32 table[OMAP3ISP_PREV_NF_TBL_SIZE];
586};
587
588/**
589 * struct omap3isp_prev_gtables - Gamma correction tables
590 * @red: Array for red gamma table.
591 * @green: Array for green gamma table.
592 * @blue: Array for blue gamma table.
593 */
594struct omap3isp_prev_gtables {
595 __u32 red[OMAP3ISP_PREV_GAMMA_TBL_SIZE];
596 __u32 green[OMAP3ISP_PREV_GAMMA_TBL_SIZE];
597 __u32 blue[OMAP3ISP_PREV_GAMMA_TBL_SIZE];
598};
599
600/**
601 * struct omap3isp_prev_luma - Luma enhancement
602 * @table: Array for luma enhancement table.
603 */
604struct omap3isp_prev_luma {
605 __u32 table[OMAP3ISP_PREV_YENH_TBL_SIZE];
606};
607
608/**
609 * struct omap3isp_prev_update_config - Preview engine configuration (user)
610 * @update: Specifies which ISP Preview registers should be updated.
611 * @flag: Specifies which ISP Preview functions should be enabled.
612 * @shading_shift: 3bit value of shift used in shading compensation.
613 * @luma: Pointer to luma enhancement structure.
614 * @hmed: Pointer to structure containing the odd and even distance.
615 * between the pixels in the image along with the filter threshold.
616 * @cfa: Pointer to structure containing the CFA interpolation table, CFA.
617 * format in the image, vertical and horizontal gradient threshold.
618 * @csup: Pointer to Structure for Chrominance Suppression coefficients.
619 * @wbal: Pointer to structure for White Balance.
620 * @blkadj: Pointer to structure for Black Adjustment.
621 * @rgb2rgb: Pointer to structure for RGB to RGB Blending.
622 * @csc: Pointer to structure for Color Space Conversion from RGB-YCbYCr.
623 * @yclimit: Pointer to structure for Y, C Value Limit.
624 * @dcor: Pointer to structure for defect correction.
625 * @nf: Pointer to structure for Noise Filter
626 * @gamma: Pointer to gamma structure.
627 */
628struct omap3isp_prev_update_config {
629 __u32 update;
630 __u32 flag;
631 __u32 shading_shift;
632 struct omap3isp_prev_luma __user *luma;
633 struct omap3isp_prev_hmed __user *hmed;
634 struct omap3isp_prev_cfa __user *cfa;
635 struct omap3isp_prev_csup __user *csup;
636 struct omap3isp_prev_wbal __user *wbal;
637 struct omap3isp_prev_blkadj __user *blkadj;
638 struct omap3isp_prev_rgbtorgb __user *rgb2rgb;
639 struct omap3isp_prev_csc __user *csc;
640 struct omap3isp_prev_yclimit __user *yclimit;
641 struct omap3isp_prev_dcor __user *dcor;
642 struct omap3isp_prev_nf __user *nf;
643 struct omap3isp_prev_gtables __user *gamma;
644};
645
646#endif /* OMAP3_ISP_USER_H */
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 29ebba54c238..c11950652646 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -298,7 +298,6 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
298 298
299extern void __lock_page(struct page *page); 299extern void __lock_page(struct page *page);
300extern int __lock_page_killable(struct page *page); 300extern int __lock_page_killable(struct page *page);
301extern void __lock_page_nosync(struct page *page);
302extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm, 301extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
303 unsigned int flags); 302 unsigned int flags);
304extern void unlock_page(struct page *page); 303extern void unlock_page(struct page *page);
@@ -342,17 +341,6 @@ static inline int lock_page_killable(struct page *page)
342} 341}
343 342
344/* 343/*
345 * lock_page_nosync should only be used if we can't pin the page's inode.
346 * Doesn't play quite so well with block device plugging.
347 */
348static inline void lock_page_nosync(struct page *page)
349{
350 might_sleep();
351 if (!trylock_page(page))
352 __lock_page_nosync(page);
353}
354
355/*
356 * lock_page_or_retry - Lock the page, unless this would block and the 344 * lock_page_or_retry - Lock the page, unless this would block and the
357 * caller indicated that it can handle a retry. 345 * caller indicated that it can handle a retry.
358 */ 346 */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index bda221dfaf0a..11fd38151cc9 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2737,6 +2737,7 @@
2737#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 2737#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
2738#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 2738#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119
2739#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a 2739#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a
2740#define PCI_DEVICE_ID_INTEL_ITC_LPC 0x8186
2740#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 2741#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
2741#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 2742#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
2742#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca 2743#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 98fc7ed4b191..b8369d522bf8 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -99,6 +99,7 @@ struct robust_list_head;
99struct bio_list; 99struct bio_list;
100struct fs_struct; 100struct fs_struct;
101struct perf_event_context; 101struct perf_event_context;
102struct blk_plug;
102 103
103/* 104/*
104 * List of flags we want to share for kernel threads, 105 * List of flags we want to share for kernel threads,
@@ -1428,6 +1429,11 @@ struct task_struct {
1428/* stacked block device info */ 1429/* stacked block device info */
1429 struct bio_list *bio_list; 1430 struct bio_list *bio_list;
1430 1431
1432#ifdef CONFIG_BLOCK
1433/* stack plugging */
1434 struct blk_plug *plug;
1435#endif
1436
1431/* VM state */ 1437/* VM state */
1432 struct reclaim_state *reclaim_state; 1438 struct reclaim_state *reclaim_state;
1433 1439
diff --git a/include/linux/sm501.h b/include/linux/sm501.h
index 214f93209b8c..02fde50a79a5 100644
--- a/include/linux/sm501.h
+++ b/include/linux/sm501.h
@@ -172,3 +172,11 @@ struct sm501_platdata {
172 struct sm501_platdata_gpio_i2c *gpio_i2c; 172 struct sm501_platdata_gpio_i2c *gpio_i2c;
173 unsigned int gpio_i2c_nr; 173 unsigned int gpio_i2c_nr;
174}; 174};
175
176#if defined(CONFIG_PPC32)
177#define smc501_readl(addr) ioread32be((addr))
178#define smc501_writel(val, addr) iowrite32be((val), (addr))
179#else
180#define smc501_readl(addr) readl(addr)
181#define smc501_writel(val, addr) writel(val, addr)
182#endif
diff --git a/include/linux/svga.h b/include/linux/svga.h
index c59a51a2b0e7..bfa68e837d6a 100644
--- a/include/linux/svga.h
+++ b/include/linux/svga.h
@@ -67,25 +67,25 @@ struct svga_pll {
67 67
68/* Write a value to the attribute register */ 68/* Write a value to the attribute register */
69 69
70static inline void svga_wattr(u8 index, u8 data) 70static inline void svga_wattr(void __iomem *regbase, u8 index, u8 data)
71{ 71{
72 inb(0x3DA); 72 vga_r(regbase, VGA_IS1_RC);
73 outb(index, 0x3C0); 73 vga_w(regbase, VGA_ATT_IW, index);
74 outb(data, 0x3C0); 74 vga_w(regbase, VGA_ATT_W, data);
75} 75}
76 76
77/* Write a value to a sequence register with a mask */ 77/* Write a value to a sequence register with a mask */
78 78
79static inline void svga_wseq_mask(u8 index, u8 data, u8 mask) 79static inline void svga_wseq_mask(void __iomem *regbase, u8 index, u8 data, u8 mask)
80{ 80{
81 vga_wseq(NULL, index, (data & mask) | (vga_rseq(NULL, index) & ~mask)); 81 vga_wseq(regbase, index, (data & mask) | (vga_rseq(regbase, index) & ~mask));
82} 82}
83 83
84/* Write a value to a CRT register with a mask */ 84/* Write a value to a CRT register with a mask */
85 85
86static inline void svga_wcrt_mask(u8 index, u8 data, u8 mask) 86static inline void svga_wcrt_mask(void __iomem *regbase, u8 index, u8 data, u8 mask)
87{ 87{
88 vga_wcrt(NULL, index, (data & mask) | (vga_rcrt(NULL, index) & ~mask)); 88 vga_wcrt(regbase, index, (data & mask) | (vga_rcrt(regbase, index) & ~mask));
89} 89}
90 90
91static inline int svga_primary_device(struct pci_dev *dev) 91static inline int svga_primary_device(struct pci_dev *dev)
@@ -96,27 +96,27 @@ static inline int svga_primary_device(struct pci_dev *dev)
96} 96}
97 97
98 98
99void svga_wcrt_multi(const struct vga_regset *regset, u32 value); 99void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value);
100void svga_wseq_multi(const struct vga_regset *regset, u32 value); 100void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value);
101 101
102void svga_set_default_gfx_regs(void); 102void svga_set_default_gfx_regs(void __iomem *regbase);
103void svga_set_default_atc_regs(void); 103void svga_set_default_atc_regs(void __iomem *regbase);
104void svga_set_default_seq_regs(void); 104void svga_set_default_seq_regs(void __iomem *regbase);
105void svga_set_default_crt_regs(void); 105void svga_set_default_crt_regs(void __iomem *regbase);
106void svga_set_textmode_vga_regs(void); 106void svga_set_textmode_vga_regs(void __iomem *regbase);
107 107
108void svga_settile(struct fb_info *info, struct fb_tilemap *map); 108void svga_settile(struct fb_info *info, struct fb_tilemap *map);
109void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area); 109void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area);
110void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect); 110void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect);
111void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit); 111void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit);
112void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor); 112void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor);
113int svga_get_tilemax(struct fb_info *info); 113int svga_get_tilemax(struct fb_info *info);
114void svga_get_caps(struct fb_info *info, struct fb_blit_caps *caps, 114void svga_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
115 struct fb_var_screeninfo *var); 115 struct fb_var_screeninfo *var);
116 116
117int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node); 117int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node);
118int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node); 118int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node);
119void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node); 119void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node);
120 120
121int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix); 121int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix);
122 122
diff --git a/include/linux/swap.h b/include/linux/swap.h
index ed6ebe690f4a..a5c6da5d8df8 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -309,8 +309,6 @@ extern void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
309 struct page **pagep, swp_entry_t *ent); 309 struct page **pagep, swp_entry_t *ent);
310#endif 310#endif
311 311
312extern void swap_unplug_io_fn(struct backing_dev_info *, struct page *);
313
314#ifdef CONFIG_SWAP 312#ifdef CONFIG_SWAP
315/* linux/mm/page_io.c */ 313/* linux/mm/page_io.c */
316extern int swap_readpage(struct page *); 314extern int swap_readpage(struct page *);
diff --git a/include/linux/v4l2-mediabus.h b/include/linux/v4l2-mediabus.h
new file mode 100644
index 000000000000..7054a7a8065e
--- /dev/null
+++ b/include/linux/v4l2-mediabus.h
@@ -0,0 +1,108 @@
1/*
2 * Media Bus API header
3 *
4 * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_V4L2_MEDIABUS_H
12#define __LINUX_V4L2_MEDIABUS_H
13
14#include <linux/types.h>
15#include <linux/videodev2.h>
16
17/*
18 * These pixel codes uniquely identify data formats on the media bus. Mostly
19 * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is
20 * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the
21 * data format is fixed. Additionally, "2X8" means that one pixel is transferred
22 * in two 8-bit samples, "BE" or "LE" specify in which order those samples are
23 * transferred over the bus: "LE" means that the least significant bits are
24 * transferred first, "BE" means that the most significant bits are transferred
25 * first, and "PADHI" and "PADLO" define which bits - low or high, in the
26 * incomplete high byte, are filled with padding bits.
27 *
28 * The pixel codes are grouped by type, bus_width, bits per component, samples
29 * per pixel and order of subsamples. Numerical values are sorted using generic
30 * numerical sort order (8 thus comes before 10).
31 *
32 * As their value can't change when a new pixel code is inserted in the
33 * enumeration, the pixel codes are explicitly given a numerical value. The next
34 * free values for each category are listed below, update them when inserting
35 * new pixel codes.
36 */
37enum v4l2_mbus_pixelcode {
38 V4L2_MBUS_FMT_FIXED = 0x0001,
39
40 /* RGB - next is 0x1009 */
41 V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001,
42 V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002,
43 V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003,
44 V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE = 0x1004,
45 V4L2_MBUS_FMT_BGR565_2X8_BE = 0x1005,
46 V4L2_MBUS_FMT_BGR565_2X8_LE = 0x1006,
47 V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007,
48 V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008,
49
50 /* YUV (including grey) - next is 0x2013 */
51 V4L2_MBUS_FMT_Y8_1X8 = 0x2001,
52 V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002,
53 V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003,
54 V4L2_MBUS_FMT_YUYV8_1_5X8 = 0x2004,
55 V4L2_MBUS_FMT_YVYU8_1_5X8 = 0x2005,
56 V4L2_MBUS_FMT_UYVY8_2X8 = 0x2006,
57 V4L2_MBUS_FMT_VYUY8_2X8 = 0x2007,
58 V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008,
59 V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009,
60 V4L2_MBUS_FMT_Y10_1X10 = 0x200a,
61 V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b,
62 V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c,
63 V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f,
64 V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010,
65 V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011,
66 V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012,
67 V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d,
68 V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e,
69
70 /* Bayer - next is 0x3013 */
71 V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001,
72 V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002,
73 V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b,
74 V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c,
75 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009,
76 V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8 = 0x300d,
77 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE = 0x3003,
78 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE = 0x3004,
79 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE = 0x3005,
80 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE = 0x3006,
81 V4L2_MBUS_FMT_SBGGR10_1X10 = 0x3007,
82 V4L2_MBUS_FMT_SGBRG10_1X10 = 0x300e,
83 V4L2_MBUS_FMT_SGRBG10_1X10 = 0x300a,
84 V4L2_MBUS_FMT_SRGGB10_1X10 = 0x300f,
85 V4L2_MBUS_FMT_SBGGR12_1X12 = 0x3008,
86 V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010,
87 V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011,
88 V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012,
89};
90
91/**
92 * struct v4l2_mbus_framefmt - frame format on the media bus
93 * @width: frame width
94 * @height: frame height
95 * @code: data format code (from enum v4l2_mbus_pixelcode)
96 * @field: used interlacing type (from enum v4l2_field)
97 * @colorspace: colorspace of the data (from enum v4l2_colorspace)
98 */
99struct v4l2_mbus_framefmt {
100 __u32 width;
101 __u32 height;
102 __u32 code;
103 __u32 field;
104 __u32 colorspace;
105 __u32 reserved[7];
106};
107
108#endif
diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
new file mode 100644
index 000000000000..ed29cbbebfef
--- /dev/null
+++ b/include/linux/v4l2-subdev.h
@@ -0,0 +1,141 @@
1/*
2 * V4L2 subdev userspace API
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __LINUX_V4L2_SUBDEV_H
24#define __LINUX_V4L2_SUBDEV_H
25
26#include <linux/ioctl.h>
27#include <linux/types.h>
28#include <linux/v4l2-mediabus.h>
29
30/**
31 * enum v4l2_subdev_format_whence - Media bus format type
32 * @V4L2_SUBDEV_FORMAT_TRY: try format, for negotiation only
33 * @V4L2_SUBDEV_FORMAT_ACTIVE: active format, applied to the device
34 */
35enum v4l2_subdev_format_whence {
36 V4L2_SUBDEV_FORMAT_TRY = 0,
37 V4L2_SUBDEV_FORMAT_ACTIVE = 1,
38};
39
40/**
41 * struct v4l2_subdev_format - Pad-level media bus format
42 * @which: format type (from enum v4l2_subdev_format_whence)
43 * @pad: pad number, as reported by the media API
44 * @format: media bus format (format code and frame size)
45 */
46struct v4l2_subdev_format {
47 __u32 which;
48 __u32 pad;
49 struct v4l2_mbus_framefmt format;
50 __u32 reserved[8];
51};
52
53/**
54 * struct v4l2_subdev_crop - Pad-level crop settings
55 * @which: format type (from enum v4l2_subdev_format_whence)
56 * @pad: pad number, as reported by the media API
57 * @rect: pad crop rectangle boundaries
58 */
59struct v4l2_subdev_crop {
60 __u32 which;
61 __u32 pad;
62 struct v4l2_rect rect;
63 __u32 reserved[8];
64};
65
66/**
67 * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration
68 * @pad: pad number, as reported by the media API
69 * @index: format index during enumeration
70 * @code: format code (from enum v4l2_mbus_pixelcode)
71 */
72struct v4l2_subdev_mbus_code_enum {
73 __u32 pad;
74 __u32 index;
75 __u32 code;
76 __u32 reserved[9];
77};
78
79/**
80 * struct v4l2_subdev_frame_size_enum - Media bus format enumeration
81 * @pad: pad number, as reported by the media API
82 * @index: format index during enumeration
83 * @code: format code (from enum v4l2_mbus_pixelcode)
84 */
85struct v4l2_subdev_frame_size_enum {
86 __u32 index;
87 __u32 pad;
88 __u32 code;
89 __u32 min_width;
90 __u32 max_width;
91 __u32 min_height;
92 __u32 max_height;
93 __u32 reserved[9];
94};
95
96/**
97 * struct v4l2_subdev_frame_interval - Pad-level frame rate
98 * @pad: pad number, as reported by the media API
99 * @interval: frame interval in seconds
100 */
101struct v4l2_subdev_frame_interval {
102 __u32 pad;
103 struct v4l2_fract interval;
104 __u32 reserved[9];
105};
106
107/**
108 * struct v4l2_subdev_frame_interval_enum - Frame interval enumeration
109 * @pad: pad number, as reported by the media API
110 * @index: frame interval index during enumeration
111 * @code: format code (from enum v4l2_mbus_pixelcode)
112 * @width: frame width in pixels
113 * @height: frame height in pixels
114 * @interval: frame interval in seconds
115 */
116struct v4l2_subdev_frame_interval_enum {
117 __u32 index;
118 __u32 pad;
119 __u32 code;
120 __u32 width;
121 __u32 height;
122 struct v4l2_fract interval;
123 __u32 reserved[9];
124};
125
126#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
127#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
128#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
129 _IOWR('V', 21, struct v4l2_subdev_frame_interval)
130#define VIDIOC_SUBDEV_S_FRAME_INTERVAL \
131 _IOWR('V', 22, struct v4l2_subdev_frame_interval)
132#define VIDIOC_SUBDEV_ENUM_MBUS_CODE \
133 _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum)
134#define VIDIOC_SUBDEV_ENUM_FRAME_SIZE \
135 _IOWR('V', 74, struct v4l2_subdev_frame_size_enum)
136#define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \
137 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
138#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop)
139#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop)
140
141#endif
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 5f6f47044abf..aa6c393b7ae9 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -70,6 +70,7 @@
70 * Moved from videodev.h 70 * Moved from videodev.h
71 */ 71 */
72#define VIDEO_MAX_FRAME 32 72#define VIDEO_MAX_FRAME 32
73#define VIDEO_MAX_PLANES 8
73 74
74#ifndef __KERNEL__ 75#ifndef __KERNEL__
75 76
@@ -157,9 +158,23 @@ enum v4l2_buf_type {
157 /* Experimental */ 158 /* Experimental */
158 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, 159 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
159#endif 160#endif
161 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
162 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
160 V4L2_BUF_TYPE_PRIVATE = 0x80, 163 V4L2_BUF_TYPE_PRIVATE = 0x80,
161}; 164};
162 165
166#define V4L2_TYPE_IS_MULTIPLANAR(type) \
167 ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \
168 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
169
170#define V4L2_TYPE_IS_OUTPUT(type) \
171 ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \
172 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \
173 || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \
174 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \
175 || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \
176 || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
177
163enum v4l2_tuner_type { 178enum v4l2_tuner_type {
164 V4L2_TUNER_RADIO = 1, 179 V4L2_TUNER_RADIO = 1,
165 V4L2_TUNER_ANALOG_TV = 2, 180 V4L2_TUNER_ANALOG_TV = 2,
@@ -245,6 +260,11 @@ struct v4l2_capability {
245#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ 260#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
246#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ 261#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
247 262
263/* Is a video capture device that supports multiplanar formats */
264#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
265/* Is a video output device that supports multiplanar formats */
266#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
267
248#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ 268#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
249#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ 269#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
250#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ 270#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
@@ -319,6 +339,13 @@ struct v4l2_pix_format {
319#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ 339#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
320#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ 340#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
321 341
342/* two non contiguous planes - one Y, one Cr + Cb interleaved */
343#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
344#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
345
346/* three non contiguous planes - Y, Cb, Cr */
347#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */
348
322/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ 349/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
323#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ 350#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
324#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ 351#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
@@ -328,6 +355,10 @@ struct v4l2_pix_format {
328#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ 355#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */
329#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ 356#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */
330#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ 357#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */
358#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */
359#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */
360#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */
361#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */
331 /* 10bit raw bayer DPCM compressed to 8 bits */ 362 /* 10bit raw bayer DPCM compressed to 8 bits */
332#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') 363#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
333 /* 364 /*
@@ -365,6 +396,7 @@ struct v4l2_pix_format {
365#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ 396#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
366#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ 397#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */
367#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ 398#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */
399#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */
368 400
369/* 401/*
370 * F O R M A T E N U M E R A T I O N 402 * F O R M A T E N U M E R A T I O N
@@ -517,6 +549,62 @@ struct v4l2_requestbuffers {
517 __u32 reserved[2]; 549 __u32 reserved[2];
518}; 550};
519 551
552/**
553 * struct v4l2_plane - plane info for multi-planar buffers
554 * @bytesused: number of bytes occupied by data in the plane (payload)
555 * @length: size of this plane (NOT the payload) in bytes
556 * @mem_offset: when memory in the associated struct v4l2_buffer is
557 * V4L2_MEMORY_MMAP, equals the offset from the start of
558 * the device memory for this plane (or is a "cookie" that
559 * should be passed to mmap() called on the video node)
560 * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
561 * pointing to this plane
562 * @data_offset: offset in the plane to the start of data; usually 0,
563 * unless there is a header in front of the data
564 *
565 * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer
566 * with two planes can have one plane for Y, and another for interleaved CbCr
567 * components. Each plane can reside in a separate memory buffer, or even in
568 * a completely separate memory node (e.g. in embedded devices).
569 */
570struct v4l2_plane {
571 __u32 bytesused;
572 __u32 length;
573 union {
574 __u32 mem_offset;
575 unsigned long userptr;
576 } m;
577 __u32 data_offset;
578 __u32 reserved[11];
579};
580
581/**
582 * struct v4l2_buffer - video buffer info
583 * @index: id number of the buffer
584 * @type: buffer type (type == *_MPLANE for multiplanar buffers)
585 * @bytesused: number of bytes occupied by data in the buffer (payload);
586 * unused (set to 0) for multiplanar buffers
587 * @flags: buffer informational flags
588 * @field: field order of the image in the buffer
589 * @timestamp: frame timestamp
590 * @timecode: frame timecode
591 * @sequence: sequence count of this frame
592 * @memory: the method, in which the actual video data is passed
593 * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
594 * offset from the start of the device memory for this plane,
595 * (or a "cookie" that should be passed to mmap() as offset)
596 * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
597 * a userspace pointer pointing to this buffer
598 * @planes: for multiplanar buffers; userspace pointer to the array of plane
599 * info structs for this buffer
600 * @length: size in bytes of the buffer (NOT its payload) for single-plane
601 * buffers (when type != *_MPLANE); number of elements in the
602 * planes array for multi-plane buffers
603 * @input: input number from which the video data has has been captured
604 *
605 * Contains data exchanged by application and driver using one of the Streaming
606 * I/O methods.
607 */
520struct v4l2_buffer { 608struct v4l2_buffer {
521 __u32 index; 609 __u32 index;
522 enum v4l2_buf_type type; 610 enum v4l2_buf_type type;
@@ -532,6 +620,7 @@ struct v4l2_buffer {
532 union { 620 union {
533 __u32 offset; 621 __u32 offset;
534 unsigned long userptr; 622 unsigned long userptr;
623 struct v4l2_plane *planes;
535 } m; 624 } m;
536 __u32 length; 625 __u32 length;
537 __u32 input; 626 __u32 input;
@@ -1622,12 +1711,56 @@ struct v4l2_mpeg_vbi_fmt_ivtv {
1622 * A G G R E G A T E S T R U C T U R E S 1711 * A G G R E G A T E S T R U C T U R E S
1623 */ 1712 */
1624 1713
1625/* Stream data format 1714/**
1715 * struct v4l2_plane_pix_format - additional, per-plane format definition
1716 * @sizeimage: maximum size in bytes required for data, for which
1717 * this plane will be used
1718 * @bytesperline: distance in bytes between the leftmost pixels in two
1719 * adjacent lines
1720 */
1721struct v4l2_plane_pix_format {
1722 __u32 sizeimage;
1723 __u16 bytesperline;
1724 __u16 reserved[7];
1725} __attribute__ ((packed));
1726
1727/**
1728 * struct v4l2_pix_format_mplane - multiplanar format definition
1729 * @width: image width in pixels
1730 * @height: image height in pixels
1731 * @pixelformat: little endian four character code (fourcc)
1732 * @field: field order (for interlaced video)
1733 * @colorspace: supplemental to pixelformat
1734 * @plane_fmt: per-plane information
1735 * @num_planes: number of planes for this format
1736 */
1737struct v4l2_pix_format_mplane {
1738 __u32 width;
1739 __u32 height;
1740 __u32 pixelformat;
1741 enum v4l2_field field;
1742 enum v4l2_colorspace colorspace;
1743
1744 struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES];
1745 __u8 num_planes;
1746 __u8 reserved[11];
1747} __attribute__ ((packed));
1748
1749/**
1750 * struct v4l2_format - stream data format
1751 * @type: type of the data stream
1752 * @pix: definition of an image format
1753 * @pix_mp: definition of a multiplanar image format
1754 * @win: definition of an overlaid image
1755 * @vbi: raw VBI capture or output parameters
1756 * @sliced: sliced VBI capture or output parameters
1757 * @raw_data: placeholder for future extensions and custom formats
1626 */ 1758 */
1627struct v4l2_format { 1759struct v4l2_format {
1628 enum v4l2_buf_type type; 1760 enum v4l2_buf_type type;
1629 union { 1761 union {
1630 struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ 1762 struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
1763 struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
1631 struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ 1764 struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
1632 struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ 1765 struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
1633 struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ 1766 struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
@@ -1635,7 +1768,6 @@ struct v4l2_format {
1635 } fmt; 1768 } fmt;
1636}; 1769};
1637 1770
1638
1639/* Stream type-dependent parameters 1771/* Stream type-dependent parameters
1640 */ 1772 */
1641struct v4l2_streamparm { 1773struct v4l2_streamparm {
@@ -1808,16 +1940,6 @@ struct v4l2_dbg_chip_ident {
1808/* Reminder: when adding new ioctls please add support for them to 1940/* Reminder: when adding new ioctls please add support for them to
1809 drivers/media/video/v4l2-compat-ioctl32.c as well! */ 1941 drivers/media/video/v4l2-compat-ioctl32.c as well! */
1810 1942
1811#ifdef __OLD_VIDIOC_
1812/* for compatibility, will go away some day */
1813#define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
1814#define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm)
1815#define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control)
1816#define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio)
1817#define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout)
1818#define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap)
1819#endif
1820
1821#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ 1943#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
1822 1944
1823#endif /* __LINUX_VIDEODEV2_H */ 1945#endif /* __LINUX_VIDEODEV2_H */
diff --git a/include/media/media-device.h b/include/media/media-device.h
new file mode 100644
index 000000000000..6a27d916c250
--- /dev/null
+++ b/include/media/media-device.h
@@ -0,0 +1,95 @@
1/*
2 * Media device
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _MEDIA_DEVICE_H
24#define _MEDIA_DEVICE_H
25
26#include <linux/device.h>
27#include <linux/list.h>
28#include <linux/mutex.h>
29#include <linux/spinlock.h>
30
31#include <media/media-devnode.h>
32#include <media/media-entity.h>
33
34/**
35 * struct media_device - Media device
36 * @dev: Parent device
37 * @devnode: Media device node
38 * @model: Device model name
39 * @serial: Device serial number (optional)
40 * @bus_info: Unique and stable device location identifier
41 * @hw_revision: Hardware device revision
42 * @driver_version: Device driver version
43 * @entity_id: ID of the next entity to be registered
44 * @entities: List of registered entities
45 * @lock: Entities list lock
46 * @graph_mutex: Entities graph operation lock
47 *
48 * This structure represents an abstract high-level media device. It allows easy
49 * access to entities and provides basic media device-level support. The
50 * structure can be allocated directly or embedded in a larger structure.
51 *
52 * The parent @dev is a physical device. It must be set before registering the
53 * media device.
54 *
55 * @model is a descriptive model name exported through sysfs. It doesn't have to
56 * be unique.
57 */
58struct media_device {
59 /* dev->driver_data points to this struct. */
60 struct device *dev;
61 struct media_devnode devnode;
62
63 char model[32];
64 char serial[40];
65 char bus_info[32];
66 u32 hw_revision;
67 u32 driver_version;
68
69 u32 entity_id;
70 struct list_head entities;
71
72 /* Protects the entities list */
73 spinlock_t lock;
74 /* Serializes graph operations. */
75 struct mutex graph_mutex;
76
77 int (*link_notify)(struct media_pad *source,
78 struct media_pad *sink, u32 flags);
79};
80
81/* media_devnode to media_device */
82#define to_media_device(node) container_of(node, struct media_device, devnode)
83
84int __must_check media_device_register(struct media_device *mdev);
85void media_device_unregister(struct media_device *mdev);
86
87int __must_check media_device_register_entity(struct media_device *mdev,
88 struct media_entity *entity);
89void media_device_unregister_entity(struct media_entity *entity);
90
91/* Iterate over all entities. */
92#define media_device_for_each_entity(entity, mdev) \
93 list_for_each_entry(entity, &(mdev)->entities, list)
94
95#endif
diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h
new file mode 100644
index 000000000000..f6caafc874cb
--- /dev/null
+++ b/include/media/media-devnode.h
@@ -0,0 +1,97 @@
1/*
2 * Media device node
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * --
23 *
24 * Common functions for media-related drivers to register and unregister media
25 * device nodes.
26 */
27
28#ifndef _MEDIA_DEVNODE_H
29#define _MEDIA_DEVNODE_H
30
31#include <linux/poll.h>
32#include <linux/fs.h>
33#include <linux/device.h>
34#include <linux/cdev.h>
35
36/*
37 * Flag to mark the media_devnode struct as registered. Drivers must not touch
38 * this flag directly, it will be set and cleared by media_devnode_register and
39 * media_devnode_unregister.
40 */
41#define MEDIA_FLAG_REGISTERED 0
42
43struct media_file_operations {
44 struct module *owner;
45 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
46 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
47 unsigned int (*poll) (struct file *, struct poll_table_struct *);
48 long (*ioctl) (struct file *, unsigned int, unsigned long);
49 int (*open) (struct file *);
50 int (*release) (struct file *);
51};
52
53/**
54 * struct media_devnode - Media device node
55 * @parent: parent device
56 * @minor: device node minor number
57 * @flags: flags, combination of the MEDIA_FLAG_* constants
58 *
59 * This structure represents a media-related device node.
60 *
61 * The @parent is a physical device. It must be set by core or device drivers
62 * before registering the node.
63 */
64struct media_devnode {
65 /* device ops */
66 const struct media_file_operations *fops;
67
68 /* sysfs */
69 struct device dev; /* media device */
70 struct cdev cdev; /* character device */
71 struct device *parent; /* device parent */
72
73 /* device info */
74 int minor;
75 unsigned long flags; /* Use bitops to access flags */
76
77 /* callbacks */
78 void (*release)(struct media_devnode *mdev);
79};
80
81/* dev to media_devnode */
82#define to_media_devnode(cd) container_of(cd, struct media_devnode, dev)
83
84int __must_check media_devnode_register(struct media_devnode *mdev);
85void media_devnode_unregister(struct media_devnode *mdev);
86
87static inline struct media_devnode *media_devnode_data(struct file *filp)
88{
89 return filp->private_data;
90}
91
92static inline int media_devnode_is_registered(struct media_devnode *mdev)
93{
94 return test_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
95}
96
97#endif /* _MEDIA_DEVNODE_H */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
new file mode 100644
index 000000000000..cd8bca63a502
--- /dev/null
+++ b/include/media/media-entity.h
@@ -0,0 +1,151 @@
1/*
2 * Media entity
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _MEDIA_ENTITY_H
24#define _MEDIA_ENTITY_H
25
26#include <linux/list.h>
27#include <linux/media.h>
28
29struct media_pipeline {
30};
31
32struct media_link {
33 struct media_pad *source; /* Source pad */
34 struct media_pad *sink; /* Sink pad */
35 struct media_link *reverse; /* Link in the reverse direction */
36 unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */
37};
38
39struct media_pad {
40 struct media_entity *entity; /* Entity this pad belongs to */
41 u16 index; /* Pad index in the entity pads array */
42 unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */
43};
44
45struct media_entity_operations {
46 int (*link_setup)(struct media_entity *entity,
47 const struct media_pad *local,
48 const struct media_pad *remote, u32 flags);
49};
50
51struct media_entity {
52 struct list_head list;
53 struct media_device *parent; /* Media device this entity belongs to*/
54 u32 id; /* Entity ID, unique in the parent media
55 * device context */
56 const char *name; /* Entity name */
57 u32 type; /* Entity type (MEDIA_ENT_T_*) */
58 u32 revision; /* Entity revision, driver specific */
59 unsigned long flags; /* Entity flags (MEDIA_ENT_FL_*) */
60 u32 group_id; /* Entity group ID */
61
62 u16 num_pads; /* Number of sink and source pads */
63 u16 num_links; /* Number of existing links, both
64 * enabled and disabled */
65 u16 num_backlinks; /* Number of backlinks */
66 u16 max_links; /* Maximum number of links */
67
68 struct media_pad *pads; /* Pads array (num_pads elements) */
69 struct media_link *links; /* Links array (max_links elements)*/
70
71 const struct media_entity_operations *ops; /* Entity operations */
72
73 /* Reference counts must never be negative, but are signed integers on
74 * purpose: a simple WARN_ON(<0) check can be used to detect reference
75 * count bugs that would make them negative.
76 */
77 int stream_count; /* Stream count for the entity. */
78 int use_count; /* Use count for the entity. */
79
80 struct media_pipeline *pipe; /* Pipeline this entity belongs to. */
81
82 union {
83 /* Node specifications */
84 struct {
85 u32 major;
86 u32 minor;
87 } v4l;
88 struct {
89 u32 major;
90 u32 minor;
91 } fb;
92 struct {
93 u32 card;
94 u32 device;
95 u32 subdevice;
96 } alsa;
97 int dvb;
98
99 /* Sub-device specifications */
100 /* Nothing needed yet */
101 };
102};
103
104static inline u32 media_entity_type(struct media_entity *entity)
105{
106 return entity->type & MEDIA_ENT_TYPE_MASK;
107}
108
109static inline u32 media_entity_subtype(struct media_entity *entity)
110{
111 return entity->type & MEDIA_ENT_SUBTYPE_MASK;
112}
113
114#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16
115
116struct media_entity_graph {
117 struct {
118 struct media_entity *entity;
119 int link;
120 } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH];
121 int top;
122};
123
124int media_entity_init(struct media_entity *entity, u16 num_pads,
125 struct media_pad *pads, u16 extra_links);
126void media_entity_cleanup(struct media_entity *entity);
127
128int media_entity_create_link(struct media_entity *source, u16 source_pad,
129 struct media_entity *sink, u16 sink_pad, u32 flags);
130int __media_entity_setup_link(struct media_link *link, u32 flags);
131int media_entity_setup_link(struct media_link *link, u32 flags);
132struct media_link *media_entity_find_link(struct media_pad *source,
133 struct media_pad *sink);
134struct media_pad *media_entity_remote_source(struct media_pad *pad);
135
136struct media_entity *media_entity_get(struct media_entity *entity);
137void media_entity_put(struct media_entity *entity);
138
139void media_entity_graph_walk_start(struct media_entity_graph *graph,
140 struct media_entity *entity);
141struct media_entity *
142media_entity_graph_walk_next(struct media_entity_graph *graph);
143void media_entity_pipeline_start(struct media_entity *entity,
144 struct media_pipeline *pipe);
145void media_entity_pipeline_stop(struct media_entity *entity);
146
147#define media_entity_call(entity, operation, args...) \
148 (((entity)->ops && (entity)->ops->operation) ? \
149 (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
150
151#endif
diff --git a/include/media/noon010pc30.h b/include/media/noon010pc30.h
new file mode 100644
index 000000000000..58eafee36b30
--- /dev/null
+++ b/include/media/noon010pc30.h
@@ -0,0 +1,28 @@
1/*
2 * Driver header for NOON010PC30L camera sensor chip.
3 *
4 * Copyright (c) 2010 Samsung Electronics, Co. Ltd
5 * Contact: Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef NOON010PC30_H
14#define NOON010PC30_H
15
16/**
17 * @clk_rate: the clock frequency in Hz
18 * @gpio_nreset: GPIO driving nRESET pin
19 * @gpio_nstby: GPIO driving nSTBY pin
20 */
21
22struct noon010pc30_platform_data {
23 unsigned long clk_rate;
24 int gpio_nreset;
25 int gpio_nstby;
26};
27
28#endif /* NOON010PC30_H */
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index ee9e2f747c76..9184751f19c0 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -94,7 +94,7 @@ void rc_map_init(void);
94#define RC_MAP_GADMEI_RM008Z "rc-gadmei-rm008z" 94#define RC_MAP_GADMEI_RM008Z "rc-gadmei-rm008z"
95#define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce" 95#define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce"
96#define RC_MAP_GOTVIEW7135 "rc-gotview7135" 96#define RC_MAP_GOTVIEW7135 "rc-gotview7135"
97#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge-new" 97#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge"
98#define RC_MAP_IMON_MCE "rc-imon-mce" 98#define RC_MAP_IMON_MCE "rc-imon-mce"
99#define RC_MAP_IMON_PAD "rc-imon-pad" 99#define RC_MAP_IMON_PAD "rc-imon-pad"
100#define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" 100#define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e"
@@ -125,14 +125,16 @@ void rc_map_init(void);
125#define RC_MAP_PROTEUS_2309 "rc-proteus-2309" 125#define RC_MAP_PROTEUS_2309 "rc-proteus-2309"
126#define RC_MAP_PURPLETV "rc-purpletv" 126#define RC_MAP_PURPLETV "rc-purpletv"
127#define RC_MAP_PV951 "rc-pv951" 127#define RC_MAP_PV951 "rc-pv951"
128#define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new" 128#define RC_MAP_HAUPPAUGE "rc-hauppauge"
129#define RC_MAP_RC5_TV "rc-rc5-tv" 129#define RC_MAP_RC5_TV "rc-rc5-tv"
130#define RC_MAP_RC6_MCE "rc-rc6-mce" 130#define RC_MAP_RC6_MCE "rc-rc6-mce"
131#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys" 131#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
132#define RC_MAP_STREAMZAP "rc-streamzap" 132#define RC_MAP_STREAMZAP "rc-streamzap"
133#define RC_MAP_TBS_NEC "rc-tbs-nec" 133#define RC_MAP_TBS_NEC "rc-tbs-nec"
134#define RC_MAP_TECHNISAT_USB2 "rc-technisat-usb2"
134#define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" 135#define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs"
135#define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" 136#define RC_MAP_TERRATEC_SLIM "rc-terratec-slim"
137#define RC_MAP_TERRATEC_SLIM_2 "rc-terratec-slim-2"
136#define RC_MAP_TEVII_NEC "rc-tevii-nec" 138#define RC_MAP_TEVII_NEC "rc-tevii-nec"
137#define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand" 139#define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand"
138#define RC_MAP_TREKSTOR "rc-trekstor" 140#define RC_MAP_TREKSTOR "rc-trekstor"
diff --git a/include/media/s3c_fimc.h b/include/media/s5p_fimc.h
index ca1b6738e4a4..9fdff8a4ed26 100644
--- a/include/media/s3c_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -9,8 +9,8 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#ifndef S3C_FIMC_H_ 12#ifndef S5P_FIMC_H_
13#define S3C_FIMC_H_ 13#define S5P_FIMC_H_
14 14
15enum cam_bus_type { 15enum cam_bus_type {
16 FIMC_ITU_601 = 1, 16 FIMC_ITU_601 = 1,
@@ -27,34 +27,35 @@ enum cam_bus_type {
27struct i2c_board_info; 27struct i2c_board_info;
28 28
29/** 29/**
30 * struct s3c_fimc_isp_info - image sensor information required for host 30 * struct s5p_fimc_isp_info - image sensor information required for host
31 * interace configuration. 31 * interace configuration.
32 * 32 *
33 * @board_info: pointer to I2C subdevice's board info 33 * @board_info: pointer to I2C subdevice's board info
34 * @clk_frequency: frequency of the clock the host interface provides to sensor
34 * @bus_type: determines bus type, MIPI, ITU-R BT.601 etc. 35 * @bus_type: determines bus type, MIPI, ITU-R BT.601 etc.
36 * @csi_data_align: MIPI-CSI interface data alignment in bits
35 * @i2c_bus_num: i2c control bus id the sensor is attached to 37 * @i2c_bus_num: i2c control bus id the sensor is attached to
36 * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) 38 * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU)
37 * @bus_width: camera data bus width in bits
38 * @flags: flags defining bus signals polarity inversion (High by default) 39 * @flags: flags defining bus signals polarity inversion (High by default)
39 */ 40 */
40struct s3c_fimc_isp_info { 41struct s5p_fimc_isp_info {
41 struct i2c_board_info *board_info; 42 struct i2c_board_info *board_info;
43 unsigned long clk_frequency;
42 enum cam_bus_type bus_type; 44 enum cam_bus_type bus_type;
45 u16 csi_data_align;
43 u16 i2c_bus_num; 46 u16 i2c_bus_num;
44 u16 mux_id; 47 u16 mux_id;
45 u16 bus_width;
46 u16 flags; 48 u16 flags;
47}; 49};
48 50
49
50#define FIMC_MAX_CAMIF_CLIENTS 2
51
52/** 51/**
53 * struct s3c_platform_fimc - camera host interface platform data 52 * struct s5p_platform_fimc - camera host interface platform data
54 * 53 *
55 * @isp_info: properties of camera sensor required for host interface setup 54 * @isp_info: properties of camera sensor required for host interface setup
55 * @num_clients: the number of attached image sensors
56 */ 56 */
57struct s3c_platform_fimc { 57struct s5p_platform_fimc {
58 struct s3c_fimc_isp_info *isp_info[FIMC_MAX_CAMIF_CLIENTS]; 58 struct s5p_fimc_isp_info *isp_info;
59 int num_clients;
59}; 60};
60#endif /* S3C_FIMC_H_ */ 61#endif /* S5P_FIMC_H_ */
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 9386db829fb7..f80b5372baf3 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -17,6 +17,7 @@
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/videodev2.h> 18#include <linux/videodev2.h>
19#include <media/videobuf-core.h> 19#include <media/videobuf-core.h>
20#include <media/videobuf2-core.h>
20#include <media/v4l2-device.h> 21#include <media/v4l2-device.h>
21 22
22extern struct bus_type soc_camera_bus_type; 23extern struct bus_type soc_camera_bus_type;
@@ -29,6 +30,8 @@ struct soc_camera_device {
29 struct device *pdev; /* Platform device */ 30 struct device *pdev; /* Platform device */
30 s32 user_width; 31 s32 user_width;
31 s32 user_height; 32 s32 user_height;
33 u32 bytesperline; /* for padding, zero if unused */
34 u32 sizeimage;
32 enum v4l2_colorspace colorspace; 35 enum v4l2_colorspace colorspace;
33 unsigned char iface; /* Host number */ 36 unsigned char iface; /* Host number */
34 unsigned char devnum; /* Device number per host */ 37 unsigned char devnum; /* Device number per host */
@@ -44,7 +47,10 @@ struct soc_camera_device {
44 int use_count; 47 int use_count;
45 struct mutex video_lock; /* Protects device data */ 48 struct mutex video_lock; /* Protects device data */
46 struct file *streamer; /* stream owner */ 49 struct file *streamer; /* stream owner */
47 struct videobuf_queue vb_vidq; 50 union {
51 struct videobuf_queue vb_vidq;
52 struct vb2_queue vb2_vidq;
53 };
48}; 54};
49 55
50struct soc_camera_host { 56struct soc_camera_host {
@@ -78,6 +84,8 @@ struct soc_camera_host_ops {
78 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); 84 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
79 void (*init_videobuf)(struct videobuf_queue *, 85 void (*init_videobuf)(struct videobuf_queue *,
80 struct soc_camera_device *); 86 struct soc_camera_device *);
87 int (*init_videobuf2)(struct vb2_queue *,
88 struct soc_camera_device *);
81 int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *); 89 int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *);
82 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); 90 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
83 int (*set_bus_param)(struct soc_camera_device *, __u32); 91 int (*set_bus_param)(struct soc_camera_device *, __u32);
@@ -85,6 +93,7 @@ struct soc_camera_host_ops {
85 int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *); 93 int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *);
86 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 94 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
87 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 95 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
96 int (*enum_fsizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
88 unsigned int (*poll)(struct file *, poll_table *); 97 unsigned int (*poll)(struct file *, poll_table *);
89 const struct v4l2_queryctrl *controls; 98 const struct v4l2_queryctrl *controls;
90 int num_controls; 99 int num_controls;
@@ -299,4 +308,17 @@ static inline struct video_device *soc_camera_i2c_to_vdev(struct i2c_client *cli
299 return icd->vdev; 308 return icd->vdev;
300} 309}
301 310
311static inline struct soc_camera_device *soc_camera_from_vb2q(struct vb2_queue *vq)
312{
313 return container_of(vq, struct soc_camera_device, vb2_vidq);
314}
315
316static inline struct soc_camera_device *soc_camera_from_vbq(struct videobuf_queue *vq)
317{
318 return container_of(vq, struct soc_camera_device, vb_vidq);
319}
320
321void soc_camera_lock(struct vb2_queue *vq);
322void soc_camera_unlock(struct vb2_queue *vq);
323
302#endif 324#endif
diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h
index 037cd7be001e..b338108ec305 100644
--- a/include/media/soc_mediabus.h
+++ b/include/media/soc_mediabus.h
@@ -12,8 +12,7 @@
12#define SOC_MEDIABUS_H 12#define SOC_MEDIABUS_H
13 13
14#include <linux/videodev2.h> 14#include <linux/videodev2.h>
15 15#include <linux/v4l2-mediabus.h>
16#include <media/v4l2-mediabus.h>
17 16
18/** 17/**
19 * enum soc_mbus_packing - data packing types on the media-bus 18 * enum soc_mbus_packing - data packing types on the media-bus
@@ -61,5 +60,6 @@ struct soc_mbus_pixelfmt {
61const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( 60const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
62 enum v4l2_mbus_pixelcode code); 61 enum v4l2_mbus_pixelcode code);
63s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); 62s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf);
63int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf);
64 64
65#endif 65#endif
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 51811eac46f1..963e33471835 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -21,6 +21,7 @@
21 21
22#ifndef _TUNER_H 22#ifndef _TUNER_H
23#define _TUNER_H 23#define _TUNER_H
24#ifdef __KERNEL__
24 25
25#include <linux/videodev2.h> 26#include <linux/videodev2.h>
26 27
@@ -131,6 +132,7 @@
131#define TUNER_NXP_TDA18271 83 132#define TUNER_NXP_TDA18271 83
132#define TUNER_SONY_BTF_PXN01Z 84 133#define TUNER_SONY_BTF_PXN01Z 84
133#define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */ 134#define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */
135#define TUNER_TENA_TNF_5337 86
134 136
135/* tv card specific */ 137/* tv card specific */
136#define TDA9887_PRESENT (1<<0) 138#define TDA9887_PRESENT (1<<0)
@@ -156,14 +158,10 @@
156#define TDA9887_GAIN_NORMAL (1<<20) 158#define TDA9887_GAIN_NORMAL (1<<20)
157#define TDA9887_RIF_41_3 (1<<21) /* radio IF1 41.3 vs 33.3 */ 159#define TDA9887_RIF_41_3 (1<<21) /* radio IF1 41.3 vs 33.3 */
158 160
159#ifdef __KERNEL__
160
161enum tuner_mode { 161enum tuner_mode {
162 T_UNINITIALIZED = 0,
163 T_RADIO = 1 << V4L2_TUNER_RADIO, 162 T_RADIO = 1 << V4L2_TUNER_RADIO,
164 T_ANALOG_TV = 1 << V4L2_TUNER_ANALOG_TV, 163 T_ANALOG_TV = 1 << V4L2_TUNER_ANALOG_TV,
165 T_DIGITAL_TV = 1 << V4L2_TUNER_DIGITAL_TV, 164 /* Don't need to map V4L2_TUNER_DIGITAL_TV, as tuner-core won't use it */
166 T_STANDBY = 1 << 31
167}; 165};
168 166
169/* Older boards only had a single tuner device. Nowadays multiple tuner 167/* Older boards only had a single tuner device. Nowadays multiple tuner
@@ -193,11 +191,3 @@ struct tuner_setup {
193#endif /* __KERNEL__ */ 191#endif /* __KERNEL__ */
194 192
195#endif /* _TUNER_H */ 193#endif /* _TUNER_H */
196
197/*
198 * Overrides for Emacs so that we follow Linus's tabbing style.
199 * ---------------------------------------------------------------------------
200 * Local variables:
201 * c-basic-offset: 8
202 * End:
203 */
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 44fe44ec9ea7..b3edb67a8311 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -75,6 +75,7 @@ enum {
75 V4L2_IDENT_OV9640 = 257, 75 V4L2_IDENT_OV9640 = 257,
76 V4L2_IDENT_OV6650 = 258, 76 V4L2_IDENT_OV6650 = 258,
77 V4L2_IDENT_OV2640 = 259, 77 V4L2_IDENT_OV2640 = 259,
78 V4L2_IDENT_OV9740 = 260,
78 79
79 /* module saa7146: reserved range 300-309 */ 80 /* module saa7146: reserved range 300-309 */
80 V4L2_IDENT_SAA7146 = 300, 81 V4L2_IDENT_SAA7146 = 300,
@@ -209,6 +210,9 @@ enum {
209 /* module sn9c20x: just ident 10000 */ 210 /* module sn9c20x: just ident 10000 */
210 V4L2_IDENT_SN9C20X = 10000, 211 V4L2_IDENT_SN9C20X = 10000,
211 212
213 /* Siliconfile sensors: reserved range 10100 - 10199 */
214 V4L2_IDENT_NOON010PC30 = 10100,
215
212 /* module cx231xx and cx25840 */ 216 /* module cx231xx and cx25840 */
213 V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */ 217 V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
214 V4L2_IDENT_CX23100 = 23100, 218 V4L2_IDENT_CX23100 = 23100,
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index a659319e8582..a298ec49ddc4 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -80,21 +80,6 @@
80 80
81/* ------------------------------------------------------------------------- */ 81/* ------------------------------------------------------------------------- */
82 82
83/* Priority helper functions */
84
85struct v4l2_prio_state {
86 atomic_t prios[4];
87};
88void v4l2_prio_init(struct v4l2_prio_state *global);
89int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
90 enum v4l2_priority new);
91void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
92void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local);
93enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
94int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
95
96/* ------------------------------------------------------------------------- */
97
98/* Control helper functions */ 83/* Control helper functions */
99 84
100int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, 85int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 15802a067a12..8266d5ade2ff 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -16,12 +16,15 @@
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/videodev2.h> 17#include <linux/videodev2.h>
18 18
19#include <media/media-entity.h>
20
19#define VIDEO_MAJOR 81 21#define VIDEO_MAJOR 81
20 22
21#define VFL_TYPE_GRABBER 0 23#define VFL_TYPE_GRABBER 0
22#define VFL_TYPE_VBI 1 24#define VFL_TYPE_VBI 1
23#define VFL_TYPE_RADIO 2 25#define VFL_TYPE_RADIO 2
24#define VFL_TYPE_MAX 3 26#define VFL_TYPE_SUBDEV 3
27#define VFL_TYPE_MAX 4
25 28
26struct v4l2_ioctl_callbacks; 29struct v4l2_ioctl_callbacks;
27struct video_device; 30struct video_device;
@@ -32,7 +35,25 @@ struct v4l2_ctrl_handler;
32 Drivers can clear this flag if they want to block all future 35 Drivers can clear this flag if they want to block all future
33 device access. It is cleared by video_unregister_device. */ 36 device access. It is cleared by video_unregister_device. */
34#define V4L2_FL_REGISTERED (0) 37#define V4L2_FL_REGISTERED (0)
38/* file->private_data points to struct v4l2_fh */
35#define V4L2_FL_USES_V4L2_FH (1) 39#define V4L2_FL_USES_V4L2_FH (1)
40/* Use the prio field of v4l2_fh for core priority checking */
41#define V4L2_FL_USE_FH_PRIO (2)
42
43/* Priority helper functions */
44
45struct v4l2_prio_state {
46 atomic_t prios[4];
47};
48
49void v4l2_prio_init(struct v4l2_prio_state *global);
50int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
51 enum v4l2_priority new);
52void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
53void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local);
54enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
55int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
56
36 57
37struct v4l2_file_operations { 58struct v4l2_file_operations {
38 struct module *owner; 59 struct module *owner;
@@ -54,6 +75,9 @@ struct v4l2_file_operations {
54 75
55struct video_device 76struct video_device
56{ 77{
78#if defined(CONFIG_MEDIA_CONTROLLER)
79 struct media_entity entity;
80#endif
57 /* device ops */ 81 /* device ops */
58 const struct v4l2_file_operations *fops; 82 const struct v4l2_file_operations *fops;
59 83
@@ -68,6 +92,9 @@ struct video_device
68 /* Control handler associated with this device node. May be NULL. */ 92 /* Control handler associated with this device node. May be NULL. */
69 struct v4l2_ctrl_handler *ctrl_handler; 93 struct v4l2_ctrl_handler *ctrl_handler;
70 94
95 /* Priority state. If NULL, then v4l2_dev->prio will be used. */
96 struct v4l2_prio_state *prio;
97
71 /* device info */ 98 /* device info */
72 char name[32]; 99 char name[32];
73 int vfl_type; 100 int vfl_type;
@@ -99,18 +126,31 @@ struct video_device
99 struct mutex *lock; 126 struct mutex *lock;
100}; 127};
101 128
129#define media_entity_to_video_device(entity) \
130 container_of(entity, struct video_device, entity)
102/* dev to video-device */ 131/* dev to video-device */
103#define to_video_device(cd) container_of(cd, struct video_device, dev) 132#define to_video_device(cd) container_of(cd, struct video_device, dev)
104 133
134int __must_check __video_register_device(struct video_device *vdev, int type,
135 int nr, int warn_if_nr_in_use, struct module *owner);
136
105/* Register video devices. Note that if video_register_device fails, 137/* Register video devices. Note that if video_register_device fails,
106 the release() callback of the video_device structure is *not* called, so 138 the release() callback of the video_device structure is *not* called, so
107 the caller is responsible for freeing any data. Usually that means that 139 the caller is responsible for freeing any data. Usually that means that
108 you call video_device_release() on failure. */ 140 you call video_device_release() on failure. */
109int __must_check video_register_device(struct video_device *vdev, int type, int nr); 141static inline int __must_check video_register_device(struct video_device *vdev,
142 int type, int nr)
143{
144 return __video_register_device(vdev, type, nr, 1, vdev->fops->owner);
145}
110 146
111/* Same as video_register_device, but no warning is issued if the desired 147/* Same as video_register_device, but no warning is issued if the desired
112 device node number was already in use. */ 148 device node number was already in use. */
113int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr); 149static inline int __must_check video_register_device_no_warn(
150 struct video_device *vdev, int type, int nr)
151{
152 return __video_register_device(vdev, type, nr, 0, vdev->fops->owner);
153}
114 154
115/* Unregister video devices. Will do nothing if vdev == NULL or 155/* Unregister video devices. Will do nothing if vdev == NULL or
116 video_is_registered() returns false. */ 156 video_is_registered() returns false. */
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index b16f307d471a..bd102cf509ac 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -21,7 +21,9 @@
21#ifndef _V4L2_DEVICE_H 21#ifndef _V4L2_DEVICE_H
22#define _V4L2_DEVICE_H 22#define _V4L2_DEVICE_H
23 23
24#include <media/media-device.h>
24#include <media/v4l2-subdev.h> 25#include <media/v4l2-subdev.h>
26#include <media/v4l2-dev.h>
25 27
26/* Each instance of a V4L2 device should create the v4l2_device struct, 28/* Each instance of a V4L2 device should create the v4l2_device struct,
27 either stand-alone or embedded in a larger struct. 29 either stand-alone or embedded in a larger struct.
@@ -39,6 +41,9 @@ struct v4l2_device {
39 Note: dev might be NULL if there is no parent device 41 Note: dev might be NULL if there is no parent device
40 as is the case with e.g. ISA devices. */ 42 as is the case with e.g. ISA devices. */
41 struct device *dev; 43 struct device *dev;
44#if defined(CONFIG_MEDIA_CONTROLLER)
45 struct media_device *mdev;
46#endif
42 /* used to keep track of the registered subdevs */ 47 /* used to keep track of the registered subdevs */
43 struct list_head subdevs; 48 struct list_head subdevs;
44 /* lock this struct; can be used by the driver as well if this 49 /* lock this struct; can be used by the driver as well if this
@@ -51,10 +56,23 @@ struct v4l2_device {
51 unsigned int notification, void *arg); 56 unsigned int notification, void *arg);
52 /* The control handler. May be NULL. */ 57 /* The control handler. May be NULL. */
53 struct v4l2_ctrl_handler *ctrl_handler; 58 struct v4l2_ctrl_handler *ctrl_handler;
59 /* Device's priority state */
60 struct v4l2_prio_state prio;
54 /* BKL replacement mutex. Temporary solution only. */ 61 /* BKL replacement mutex. Temporary solution only. */
55 struct mutex ioctl_lock; 62 struct mutex ioctl_lock;
63 /* Keep track of the references to this struct. */
64 struct kref ref;
65 /* Release function that is called when the ref count goes to 0. */
66 void (*release)(struct v4l2_device *v4l2_dev);
56}; 67};
57 68
69static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
70{
71 kref_get(&v4l2_dev->ref);
72}
73
74int v4l2_device_put(struct v4l2_device *v4l2_dev);
75
58/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. 76/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
59 dev may be NULL in rare cases (ISA devices). In that case you 77 dev may be NULL in rare cases (ISA devices). In that case you
60 must fill in the v4l2_dev->name field before calling this function. */ 78 must fill in the v4l2_dev->name field before calling this function. */
@@ -96,6 +114,12 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
96 wasn't registered. In that case it will do nothing. */ 114 wasn't registered. In that case it will do nothing. */
97void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); 115void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
98 116
117/* Register device nodes for all subdev of the v4l2 device that are marked with
118 * the V4L2_SUBDEV_FL_HAS_DEVNODE flag.
119 */
120int __must_check
121v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
122
99/* Iterate over all subdevs. */ 123/* Iterate over all subdevs. */
100#define v4l2_device_for_each_subdev(sd, v4l2_dev) \ 124#define v4l2_device_for_each_subdev(sd, v4l2_dev) \
101 list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) 125 list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index 1d72dde320bf..0206aa55be24 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -35,6 +35,7 @@ struct v4l2_fh {
35 struct list_head list; 35 struct list_head list;
36 struct video_device *vdev; 36 struct video_device *vdev;
37 struct v4l2_events *events; /* events, pending and subscribed */ 37 struct v4l2_events *events; /* events, pending and subscribed */
38 enum v4l2_priority prio;
38}; 39};
39 40
40/* 41/*
@@ -50,8 +51,16 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev);
50 */ 51 */
51void v4l2_fh_add(struct v4l2_fh *fh); 52void v4l2_fh_add(struct v4l2_fh *fh);
52/* 53/*
54 * Can be used as the open() op of v4l2_file_operations.
55 * It allocates a v4l2_fh and inits and adds it to the video_device associated
56 * with the file pointer.
57 */
58int v4l2_fh_open(struct file *filp);
59/*
53 * Remove file handle from the list of file handles. Must be called in 60 * Remove file handle from the list of file handles. Must be called in
54 * v4l2_file_operations->release() handler if the driver uses v4l2_fh. 61 * v4l2_file_operations->release() handler if the driver uses v4l2_fh.
62 * On error filp->private_data will be NULL, otherwise it will point to
63 * the v4l2_fh struct.
55 */ 64 */
56void v4l2_fh_del(struct v4l2_fh *fh); 65void v4l2_fh_del(struct v4l2_fh *fh);
57/* 66/*
@@ -61,5 +70,25 @@ void v4l2_fh_del(struct v4l2_fh *fh);
61 * driver uses v4l2_fh. 70 * driver uses v4l2_fh.
62 */ 71 */
63void v4l2_fh_exit(struct v4l2_fh *fh); 72void v4l2_fh_exit(struct v4l2_fh *fh);
73/*
74 * Can be used as the release() op of v4l2_file_operations.
75 * It deletes and exits the v4l2_fh associated with the file pointer and
76 * frees it. It will do nothing if filp->private_data (the pointer to the
77 * v4l2_fh struct) is NULL. This function always returns 0.
78 */
79int v4l2_fh_release(struct file *filp);
80/*
81 * Returns 1 if this filehandle is the only filehandle opened for the
82 * associated video_device. If fh is NULL, then it returns 0.
83 */
84int v4l2_fh_is_singular(struct v4l2_fh *fh);
85/*
86 * Helper function with struct file as argument. If filp->private_data is
87 * NULL, then it will return 0.
88 */
89static inline int v4l2_fh_is_singular_file(struct file *filp)
90{
91 return v4l2_fh_is_singular(filp->private_data);
92}
64 93
65#endif /* V4L2_EVENT_H */ 94#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 67df37542c68..dd9f1e7b8ff7 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -37,6 +37,10 @@ struct v4l2_ioctl_ops {
37 struct v4l2_fmtdesc *f); 37 struct v4l2_fmtdesc *f);
38 int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh, 38 int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh,
39 struct v4l2_fmtdesc *f); 39 struct v4l2_fmtdesc *f);
40 int (*vidioc_enum_fmt_vid_cap_mplane)(struct file *file, void *fh,
41 struct v4l2_fmtdesc *f);
42 int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh,
43 struct v4l2_fmtdesc *f);
40 int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh, 44 int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh,
41 struct v4l2_fmtdesc *f); 45 struct v4l2_fmtdesc *f);
42 46
@@ -57,6 +61,10 @@ struct v4l2_ioctl_ops {
57 struct v4l2_format *f); 61 struct v4l2_format *f);
58 int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh, 62 int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh,
59 struct v4l2_format *f); 63 struct v4l2_format *f);
64 int (*vidioc_g_fmt_vid_cap_mplane)(struct file *file, void *fh,
65 struct v4l2_format *f);
66 int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh,
67 struct v4l2_format *f);
60 int (*vidioc_g_fmt_type_private)(struct file *file, void *fh, 68 int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
61 struct v4l2_format *f); 69 struct v4l2_format *f);
62 70
@@ -77,6 +85,10 @@ struct v4l2_ioctl_ops {
77 struct v4l2_format *f); 85 struct v4l2_format *f);
78 int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh, 86 int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh,
79 struct v4l2_format *f); 87 struct v4l2_format *f);
88 int (*vidioc_s_fmt_vid_cap_mplane)(struct file *file, void *fh,
89 struct v4l2_format *f);
90 int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh,
91 struct v4l2_format *f);
80 int (*vidioc_s_fmt_type_private)(struct file *file, void *fh, 92 int (*vidioc_s_fmt_type_private)(struct file *file, void *fh,
81 struct v4l2_format *f); 93 struct v4l2_format *f);
82 94
@@ -97,6 +109,10 @@ struct v4l2_ioctl_ops {
97 struct v4l2_format *f); 109 struct v4l2_format *f);
98 int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh, 110 int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh,
99 struct v4l2_format *f); 111 struct v4l2_format *f);
112 int (*vidioc_try_fmt_vid_cap_mplane)(struct file *file, void *fh,
113 struct v4l2_format *f);
114 int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh,
115 struct v4l2_format *f);
100 int (*vidioc_try_fmt_type_private)(struct file *file, void *fh, 116 int (*vidioc_try_fmt_type_private)(struct file *file, void *fh,
101 struct v4l2_format *f); 117 struct v4l2_format *f);
102 118
@@ -254,7 +270,7 @@ struct v4l2_ioctl_ops {
254 270
255 /* For other private ioctls */ 271 /* For other private ioctls */
256 long (*vidioc_default) (struct file *file, void *fh, 272 long (*vidioc_default) (struct file *file, void *fh,
257 int cmd, void *arg); 273 bool valid_prio, int cmd, void *arg);
258}; 274};
259 275
260 276
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
index 8e6559838ae3..971c7fa29614 100644
--- a/include/media/v4l2-mediabus.h
+++ b/include/media/v4l2-mediabus.h
@@ -11,66 +11,7 @@
11#ifndef V4L2_MEDIABUS_H 11#ifndef V4L2_MEDIABUS_H
12#define V4L2_MEDIABUS_H 12#define V4L2_MEDIABUS_H
13 13
14/* 14#include <linux/v4l2-mediabus.h>
15 * These pixel codes uniquely identify data formats on the media bus. Mostly
16 * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is
17 * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the
18 * data format is fixed. Additionally, "2X8" means that one pixel is transferred
19 * in two 8-bit samples, "BE" or "LE" specify in which order those samples are
20 * transferred over the bus: "LE" means that the least significant bits are
21 * transferred first, "BE" means that the most significant bits are transferred
22 * first, and "PADHI" and "PADLO" define which bits - low or high, in the
23 * incomplete high byte, are filled with padding bits.
24 */
25enum v4l2_mbus_pixelcode {
26 V4L2_MBUS_FMT_FIXED = 1,
27 V4L2_MBUS_FMT_YUYV8_2X8,
28 V4L2_MBUS_FMT_YVYU8_2X8,
29 V4L2_MBUS_FMT_UYVY8_2X8,
30 V4L2_MBUS_FMT_VYUY8_2X8,
31 V4L2_MBUS_FMT_YVYU10_2X10,
32 V4L2_MBUS_FMT_YUYV10_2X10,
33 V4L2_MBUS_FMT_YVYU10_1X20,
34 V4L2_MBUS_FMT_YUYV10_1X20,
35 V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
36 V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
37 V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
38 V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
39 V4L2_MBUS_FMT_RGB565_2X8_LE,
40 V4L2_MBUS_FMT_RGB565_2X8_BE,
41 V4L2_MBUS_FMT_BGR565_2X8_LE,
42 V4L2_MBUS_FMT_BGR565_2X8_BE,
43 V4L2_MBUS_FMT_SBGGR8_1X8,
44 V4L2_MBUS_FMT_SBGGR10_1X10,
45 V4L2_MBUS_FMT_GREY8_1X8,
46 V4L2_MBUS_FMT_Y10_1X10,
47 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
48 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
49 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
50 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
51 V4L2_MBUS_FMT_SGRBG8_1X8,
52 V4L2_MBUS_FMT_SBGGR12_1X12,
53 V4L2_MBUS_FMT_YUYV8_1_5X8,
54 V4L2_MBUS_FMT_YVYU8_1_5X8,
55 V4L2_MBUS_FMT_UYVY8_1_5X8,
56 V4L2_MBUS_FMT_VYUY8_1_5X8,
57};
58
59/**
60 * struct v4l2_mbus_framefmt - frame format on the media bus
61 * @width: frame width
62 * @height: frame height
63 * @code: data format code
64 * @field: used interlacing type
65 * @colorspace: colorspace of the data
66 */
67struct v4l2_mbus_framefmt {
68 __u32 width;
69 __u32 height;
70 enum v4l2_mbus_pixelcode code;
71 enum v4l2_field field;
72 enum v4l2_colorspace colorspace;
73};
74 15
75static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, 16static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
76 const struct v4l2_mbus_framefmt *mbus_fmt) 17 const struct v4l2_mbus_framefmt *mbus_fmt)
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 8d149f1c58d0..16ac4733e80d 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -5,7 +5,7 @@
5 * and destination. 5 * and destination.
6 * 6 *
7 * Copyright (c) 2009 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
8 * Pawel Osciak, <p.osciak@samsung.com> 8 * Pawel Osciak, <pawel@osciak.com>
9 * Marek Szyprowski, <m.szyprowski@samsung.com> 9 * Marek Szyprowski, <m.szyprowski@samsung.com>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
17#ifndef _MEDIA_V4L2_MEM2MEM_H 17#ifndef _MEDIA_V4L2_MEM2MEM_H
18#define _MEDIA_V4L2_MEM2MEM_H 18#define _MEDIA_V4L2_MEM2MEM_H
19 19
20#include <media/videobuf-core.h> 20#include <media/videobuf2-core.h>
21 21
22/** 22/**
23 * struct v4l2_m2m_ops - mem-to-mem device driver callbacks 23 * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
@@ -45,17 +45,20 @@ struct v4l2_m2m_ops {
45 void (*device_run)(void *priv); 45 void (*device_run)(void *priv);
46 int (*job_ready)(void *priv); 46 int (*job_ready)(void *priv);
47 void (*job_abort)(void *priv); 47 void (*job_abort)(void *priv);
48 void (*lock)(void *priv);
49 void (*unlock)(void *priv);
48}; 50};
49 51
50struct v4l2_m2m_dev; 52struct v4l2_m2m_dev;
51 53
52struct v4l2_m2m_queue_ctx { 54struct v4l2_m2m_queue_ctx {
53/* private: internal use only */ 55/* private: internal use only */
54 struct videobuf_queue q; 56 struct vb2_queue q;
55 57
56 /* Queue for buffers ready to be processed as soon as this 58 /* Queue for buffers ready to be processed as soon as this
57 * instance receives access to the device */ 59 * instance receives access to the device */
58 struct list_head rdy_queue; 60 struct list_head rdy_queue;
61 spinlock_t rdy_spinlock;
59 u8 num_rdy; 62 u8 num_rdy;
60}; 63};
61 64
@@ -72,19 +75,31 @@ struct v4l2_m2m_ctx {
72 /* For device job queue */ 75 /* For device job queue */
73 struct list_head queue; 76 struct list_head queue;
74 unsigned long job_flags; 77 unsigned long job_flags;
78 wait_queue_head_t finished;
75 79
76 /* Instance private data */ 80 /* Instance private data */
77 void *priv; 81 void *priv;
78}; 82};
79 83
84struct v4l2_m2m_buffer {
85 struct vb2_buffer vb;
86 struct list_head list;
87};
88
80void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); 89void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev);
81 90
82struct videobuf_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, 91struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
83 enum v4l2_buf_type type); 92 enum v4l2_buf_type type);
84 93
85void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, 94void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
86 struct v4l2_m2m_ctx *m2m_ctx); 95 struct v4l2_m2m_ctx *m2m_ctx);
87 96
97static inline void
98v4l2_m2m_buf_done(struct vb2_buffer *buf, enum vb2_buffer_state state)
99{
100 vb2_buffer_done(buf, state);
101}
102
88int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 103int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
89 struct v4l2_requestbuffers *reqbufs); 104 struct v4l2_requestbuffers *reqbufs);
90 105
@@ -110,13 +125,13 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
110struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops); 125struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops);
111void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); 126void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev);
112 127
113struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(void *priv, struct v4l2_m2m_dev *m2m_dev, 128struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
114 void (*vq_init)(void *priv, struct videobuf_queue *, 129 void *drv_priv,
115 enum v4l2_buf_type)); 130 int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq));
131
116void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); 132void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx);
117 133
118void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct videobuf_queue *vq, 134void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb);
119 struct videobuf_buffer *vb);
120 135
121/** 136/**
122 * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for 137 * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for
@@ -138,7 +153,7 @@ unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
138 return m2m_ctx->out_q_ctx.num_rdy; 153 return m2m_ctx->out_q_ctx.num_rdy;
139} 154}
140 155
141void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); 156void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx);
142 157
143/** 158/**
144 * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready 159 * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready
@@ -146,7 +161,7 @@ void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type);
146 */ 161 */
147static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) 162static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
148{ 163{
149 return v4l2_m2m_next_buf(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 164 return v4l2_m2m_next_buf(&m2m_ctx->out_q_ctx);
150} 165}
151 166
152/** 167/**
@@ -155,29 +170,28 @@ static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
155 */ 170 */
156static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) 171static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
157{ 172{
158 return v4l2_m2m_next_buf(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 173 return v4l2_m2m_next_buf(&m2m_ctx->cap_q_ctx);
159} 174}
160 175
161/** 176/**
162 * v4l2_m2m_get_src_vq() - return videobuf_queue for source buffers 177 * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
163 */ 178 */
164static inline 179static inline
165struct videobuf_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx) 180struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
166{ 181{
167 return v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 182 return &m2m_ctx->out_q_ctx.q;
168} 183}
169 184
170/** 185/**
171 * v4l2_m2m_get_dst_vq() - return videobuf_queue for destination buffers 186 * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers
172 */ 187 */
173static inline 188static inline
174struct videobuf_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) 189struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
175{ 190{
176 return v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 191 return &m2m_ctx->cap_q_ctx.q;
177} 192}
178 193
179void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx, 194void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx);
180 enum v4l2_buf_type type);
181 195
182/** 196/**
183 * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready 197 * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
@@ -185,7 +199,7 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx,
185 */ 199 */
186static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) 200static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
187{ 201{
188 return v4l2_m2m_buf_remove(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 202 return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx);
189} 203}
190 204
191/** 205/**
@@ -194,7 +208,7 @@ static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
194 */ 208 */
195static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) 209static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
196{ 210{
197 return v4l2_m2m_buf_remove(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 211 return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
198} 212}
199 213
200#endif /* _MEDIA_V4L2_MEM2MEM_H */ 214#endif /* _MEDIA_V4L2_MEM2MEM_H */
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index daf1e57d9b26..1562c4ff3a65 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -21,7 +21,11 @@
21#ifndef _V4L2_SUBDEV_H 21#ifndef _V4L2_SUBDEV_H
22#define _V4L2_SUBDEV_H 22#define _V4L2_SUBDEV_H
23 23
24#include <linux/v4l2-subdev.h>
25#include <media/media-entity.h>
24#include <media/v4l2-common.h> 26#include <media/v4l2-common.h>
27#include <media/v4l2-dev.h>
28#include <media/v4l2-fh.h>
25#include <media/v4l2-mediabus.h> 29#include <media/v4l2-mediabus.h>
26 30
27/* generic v4l2_device notify callback notification values */ 31/* generic v4l2_device notify callback notification values */
@@ -36,7 +40,10 @@
36 40
37struct v4l2_device; 41struct v4l2_device;
38struct v4l2_ctrl_handler; 42struct v4l2_ctrl_handler;
43struct v4l2_event_subscription;
44struct v4l2_fh;
39struct v4l2_subdev; 45struct v4l2_subdev;
46struct v4l2_subdev_fh;
40struct tuner_setup; 47struct tuner_setup;
41 48
42/* decode_vbi_line */ 49/* decode_vbi_line */
@@ -160,6 +167,10 @@ struct v4l2_subdev_core_ops {
160 int (*s_power)(struct v4l2_subdev *sd, int on); 167 int (*s_power)(struct v4l2_subdev *sd, int on);
161 int (*interrupt_service_routine)(struct v4l2_subdev *sd, 168 int (*interrupt_service_routine)(struct v4l2_subdev *sd,
162 u32 status, bool *handled); 169 u32 status, bool *handled);
170 int (*subscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
171 struct v4l2_event_subscription *sub);
172 int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
173 struct v4l2_event_subscription *sub);
163}; 174};
164 175
165/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio. 176/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio.
@@ -257,6 +268,10 @@ struct v4l2_subdev_video_ops {
257 int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); 268 int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop);
258 int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); 269 int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
259 int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); 270 int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
271 int (*g_frame_interval)(struct v4l2_subdev *sd,
272 struct v4l2_subdev_frame_interval *interval);
273 int (*s_frame_interval)(struct v4l2_subdev *sd,
274 struct v4l2_subdev_frame_interval *interval);
260 int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); 275 int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);
261 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); 276 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival);
262 int (*enum_dv_presets) (struct v4l2_subdev *sd, 277 int (*enum_dv_presets) (struct v4l2_subdev *sd,
@@ -271,6 +286,8 @@ struct v4l2_subdev_video_ops {
271 struct v4l2_dv_timings *timings); 286 struct v4l2_dv_timings *timings);
272 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, 287 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index,
273 enum v4l2_mbus_pixelcode *code); 288 enum v4l2_mbus_pixelcode *code);
289 int (*enum_mbus_fsizes)(struct v4l2_subdev *sd,
290 struct v4l2_frmsizeenum *fsize);
274 int (*g_mbus_fmt)(struct v4l2_subdev *sd, 291 int (*g_mbus_fmt)(struct v4l2_subdev *sd,
275 struct v4l2_mbus_framefmt *fmt); 292 struct v4l2_mbus_framefmt *fmt);
276 int (*try_mbus_fmt)(struct v4l2_subdev *sd, 293 int (*try_mbus_fmt)(struct v4l2_subdev *sd,
@@ -324,9 +341,13 @@ struct v4l2_subdev_vbi_ops {
324 * This is needed for some sensors, which always corrupt 341 * This is needed for some sensors, which always corrupt
325 * several top lines of the output image, or which send their 342 * several top lines of the output image, or which send their
326 * metadata in them. 343 * metadata in them.
344 * @g_skip_frames: number of frames to skip at stream start. This is needed for
345 * buggy sensors that generate faulty frames when they are
346 * turned on.
327 */ 347 */
328struct v4l2_subdev_sensor_ops { 348struct v4l2_subdev_sensor_ops {
329 int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines); 349 int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines);
350 int (*g_skip_frames)(struct v4l2_subdev *sd, u32 *frames);
330}; 351};
331 352
332/* 353/*
@@ -401,6 +422,25 @@ struct v4l2_subdev_ir_ops {
401 struct v4l2_subdev_ir_parameters *params); 422 struct v4l2_subdev_ir_parameters *params);
402}; 423};
403 424
425struct v4l2_subdev_pad_ops {
426 int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
427 struct v4l2_subdev_mbus_code_enum *code);
428 int (*enum_frame_size)(struct v4l2_subdev *sd,
429 struct v4l2_subdev_fh *fh,
430 struct v4l2_subdev_frame_size_enum *fse);
431 int (*enum_frame_interval)(struct v4l2_subdev *sd,
432 struct v4l2_subdev_fh *fh,
433 struct v4l2_subdev_frame_interval_enum *fie);
434 int (*get_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
435 struct v4l2_subdev_format *format);
436 int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
437 struct v4l2_subdev_format *format);
438 int (*set_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
439 struct v4l2_subdev_crop *crop);
440 int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
441 struct v4l2_subdev_crop *crop);
442};
443
404struct v4l2_subdev_ops { 444struct v4l2_subdev_ops {
405 const struct v4l2_subdev_core_ops *core; 445 const struct v4l2_subdev_core_ops *core;
406 const struct v4l2_subdev_tuner_ops *tuner; 446 const struct v4l2_subdev_tuner_ops *tuner;
@@ -409,6 +449,7 @@ struct v4l2_subdev_ops {
409 const struct v4l2_subdev_vbi_ops *vbi; 449 const struct v4l2_subdev_vbi_ops *vbi;
410 const struct v4l2_subdev_ir_ops *ir; 450 const struct v4l2_subdev_ir_ops *ir;
411 const struct v4l2_subdev_sensor_ops *sensor; 451 const struct v4l2_subdev_sensor_ops *sensor;
452 const struct v4l2_subdev_pad_ops *pad;
412}; 453};
413 454
414/* 455/*
@@ -420,23 +461,36 @@ struct v4l2_subdev_ops {
420 * 461 *
421 * unregistered: called when this subdev is unregistered. When called the 462 * unregistered: called when this subdev is unregistered. When called the
422 * v4l2_dev field is still set to the correct v4l2_device. 463 * v4l2_dev field is still set to the correct v4l2_device.
464 *
465 * open: called when the subdev device node is opened by an application.
466 *
467 * close: called when the subdev device node is closed.
423 */ 468 */
424struct v4l2_subdev_internal_ops { 469struct v4l2_subdev_internal_ops {
425 int (*registered)(struct v4l2_subdev *sd); 470 int (*registered)(struct v4l2_subdev *sd);
426 void (*unregistered)(struct v4l2_subdev *sd); 471 void (*unregistered)(struct v4l2_subdev *sd);
472 int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
473 int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
427}; 474};
428 475
429#define V4L2_SUBDEV_NAME_SIZE 32 476#define V4L2_SUBDEV_NAME_SIZE 32
430 477
431/* Set this flag if this subdev is a i2c device. */ 478/* Set this flag if this subdev is a i2c device. */
432#define V4L2_SUBDEV_FL_IS_I2C (1U << 0) 479#define V4L2_SUBDEV_FL_IS_I2C (1U << 0)
433/* Set this flag if this subdev is a spi device. */ 480/* Set this flag if this subdev is a spi device. */
434#define V4L2_SUBDEV_FL_IS_SPI (1U << 1) 481#define V4L2_SUBDEV_FL_IS_SPI (1U << 1)
482/* Set this flag if this subdev needs a device node. */
483#define V4L2_SUBDEV_FL_HAS_DEVNODE (1U << 2)
484/* Set this flag if this subdev generates events. */
485#define V4L2_SUBDEV_FL_HAS_EVENTS (1U << 3)
435 486
436/* Each instance of a subdev driver should create this struct, either 487/* Each instance of a subdev driver should create this struct, either
437 stand-alone or embedded in a larger struct. 488 stand-alone or embedded in a larger struct.
438 */ 489 */
439struct v4l2_subdev { 490struct v4l2_subdev {
491#if defined(CONFIG_MEDIA_CONTROLLER)
492 struct media_entity entity;
493#endif
440 struct list_head list; 494 struct list_head list;
441 struct module *owner; 495 struct module *owner;
442 u32 flags; 496 u32 flags;
@@ -453,8 +507,47 @@ struct v4l2_subdev {
453 /* pointer to private data */ 507 /* pointer to private data */
454 void *dev_priv; 508 void *dev_priv;
455 void *host_priv; 509 void *host_priv;
510 /* subdev device node */
511 struct video_device devnode;
512 /* number of events to be allocated on open */
513 unsigned int nevents;
514};
515
516#define media_entity_to_v4l2_subdev(ent) \
517 container_of(ent, struct v4l2_subdev, entity)
518#define vdev_to_v4l2_subdev(vdev) \
519 container_of(vdev, struct v4l2_subdev, devnode)
520
521/*
522 * Used for storing subdev information per file handle
523 */
524struct v4l2_subdev_fh {
525 struct v4l2_fh vfh;
526#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
527 struct v4l2_mbus_framefmt *try_fmt;
528 struct v4l2_rect *try_crop;
529#endif
456}; 530};
457 531
532#define to_v4l2_subdev_fh(fh) \
533 container_of(fh, struct v4l2_subdev_fh, vfh)
534
535#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
536static inline struct v4l2_mbus_framefmt *
537v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad)
538{
539 return &fh->try_fmt[pad];
540}
541
542static inline struct v4l2_rect *
543v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad)
544{
545 return &fh->try_crop[pad];
546}
547#endif
548
549extern const struct v4l2_file_operations v4l2_subdev_fops;
550
458static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) 551static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)
459{ 552{
460 sd->dev_priv = p; 553 sd->dev_priv = p;
@@ -475,20 +568,8 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
475 return sd->host_priv; 568 return sd->host_priv;
476} 569}
477 570
478static inline void v4l2_subdev_init(struct v4l2_subdev *sd, 571void v4l2_subdev_init(struct v4l2_subdev *sd,
479 const struct v4l2_subdev_ops *ops) 572 const struct v4l2_subdev_ops *ops);
480{
481 INIT_LIST_HEAD(&sd->list);
482 /* ops->core MUST be set */
483 BUG_ON(!ops || !ops->core);
484 sd->ops = ops;
485 sd->v4l2_dev = NULL;
486 sd->flags = 0;
487 sd->name[0] = '\0';
488 sd->grp_id = 0;
489 sd->dev_priv = NULL;
490 sd->host_priv = NULL;
491}
492 573
493/* Call an ops of a v4l2_subdev, doing the right checks against 574/* Call an ops of a v4l2_subdev, doing the right checks against
494 NULL pointers. 575 NULL pointers.
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
new file mode 100644
index 000000000000..f87472acbc51
--- /dev/null
+++ b/include/media/videobuf2-core.h
@@ -0,0 +1,380 @@
1/*
2 * videobuf2-core.h - V4L2 driver helper framework
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12#ifndef _MEDIA_VIDEOBUF2_CORE_H
13#define _MEDIA_VIDEOBUF2_CORE_H
14
15#include <linux/mm_types.h>
16#include <linux/mutex.h>
17#include <linux/poll.h>
18#include <linux/videodev2.h>
19
20struct vb2_alloc_ctx;
21struct vb2_fileio_data;
22
23/**
24 * struct vb2_mem_ops - memory handling/memory allocator operations
25 * @alloc: allocate video memory and, optionally, allocator private data,
26 * return NULL on failure or a pointer to allocator private,
27 * per-buffer data on success; the returned private structure
28 * will then be passed as buf_priv argument to other ops in this
29 * structure
30 * @put: inform the allocator that the buffer will no longer be used;
31 * usually will result in the allocator freeing the buffer (if
32 * no other users of this buffer are present); the buf_priv
33 * argument is the allocator private per-buffer structure
34 * previously returned from the alloc callback
35 * @get_userptr: acquire userspace memory for a hardware operation; used for
36 * USERPTR memory types; vaddr is the address passed to the
37 * videobuf layer when queuing a video buffer of USERPTR type;
38 * should return an allocator private per-buffer structure
39 * associated with the buffer on success, NULL on failure;
40 * the returned private structure will then be passed as buf_priv
41 * argument to other ops in this structure
42 * @put_userptr: inform the allocator that a USERPTR buffer will no longer
43 * be used
44 * @vaddr: return a kernel virtual address to a given memory buffer
45 * associated with the passed private structure or NULL if no
46 * such mapping exists
47 * @cookie: return allocator specific cookie for a given memory buffer
48 * associated with the passed private structure or NULL if not
49 * available
50 * @num_users: return the current number of users of a memory buffer;
51 * return 1 if the videobuf layer (or actually the driver using
52 * it) is the only user
53 * @mmap: setup a userspace mapping for a given memory buffer under
54 * the provided virtual memory region
55 *
56 * Required ops for USERPTR types: get_userptr, put_userptr.
57 * Required ops for MMAP types: alloc, put, num_users, mmap.
58 * Required ops for read/write access types: alloc, put, num_users, vaddr
59 */
60struct vb2_mem_ops {
61 void *(*alloc)(void *alloc_ctx, unsigned long size);
62 void (*put)(void *buf_priv);
63
64 void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
65 unsigned long size, int write);
66 void (*put_userptr)(void *buf_priv);
67
68 void *(*vaddr)(void *buf_priv);
69 void *(*cookie)(void *buf_priv);
70
71 unsigned int (*num_users)(void *buf_priv);
72
73 int (*mmap)(void *buf_priv, struct vm_area_struct *vma);
74};
75
76struct vb2_plane {
77 void *mem_priv;
78 int mapped:1;
79};
80
81/**
82 * enum vb2_io_modes - queue access methods
83 * @VB2_MMAP: driver supports MMAP with streaming API
84 * @VB2_USERPTR: driver supports USERPTR with streaming API
85 * @VB2_READ: driver supports read() style access
86 * @VB2_WRITE: driver supports write() style access
87 */
88enum vb2_io_modes {
89 VB2_MMAP = (1 << 0),
90 VB2_USERPTR = (1 << 1),
91 VB2_READ = (1 << 2),
92 VB2_WRITE = (1 << 3),
93};
94
95/**
96 * enum vb2_fileio_flags - flags for selecting a mode of the file io emulator,
97 * by default the 'streaming' style is used by the file io emulator
98 * @VB2_FILEIO_READ_ONCE: report EOF after reading the first buffer
99 * @VB2_FILEIO_WRITE_IMMEDIATELY: queue buffer after each write() call
100 */
101enum vb2_fileio_flags {
102 VB2_FILEIO_READ_ONCE = (1 << 0),
103 VB2_FILEIO_WRITE_IMMEDIATELY = (1 << 1),
104};
105
106/**
107 * enum vb2_buffer_state - current video buffer state
108 * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control
109 * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver
110 * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used
111 * in a hardware operation
112 * @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but
113 * not yet dequeued to userspace
114 * @VB2_BUF_STATE_ERROR: same as above, but the operation on the buffer
115 * has ended with an error, which will be reported
116 * to the userspace when it is dequeued
117 */
118enum vb2_buffer_state {
119 VB2_BUF_STATE_DEQUEUED,
120 VB2_BUF_STATE_QUEUED,
121 VB2_BUF_STATE_ACTIVE,
122 VB2_BUF_STATE_DONE,
123 VB2_BUF_STATE_ERROR,
124};
125
126struct vb2_queue;
127
128/**
129 * struct vb2_buffer - represents a video buffer
130 * @v4l2_buf: struct v4l2_buffer associated with this buffer; can
131 * be read by the driver and relevant entries can be
132 * changed by the driver in case of CAPTURE types
133 * (such as timestamp)
134 * @v4l2_planes: struct v4l2_planes associated with this buffer; can
135 * be read by the driver and relevant entries can be
136 * changed by the driver in case of CAPTURE types
137 * (such as bytesused); NOTE that even for single-planar
138 * types, the v4l2_planes[0] struct should be used
139 * instead of v4l2_buf for filling bytesused - drivers
140 * should use the vb2_set_plane_payload() function for that
141 * @vb2_queue: the queue to which this driver belongs
142 * @num_planes: number of planes in the buffer
143 * on an internal driver queue
144 * @state: current buffer state; do not change
145 * @queued_entry: entry on the queued buffers list, which holds all
146 * buffers queued from userspace
147 * @done_entry: entry on the list that stores all buffers ready to
148 * be dequeued to userspace
149 * @planes: private per-plane information; do not change
150 * @num_planes_mapped: number of mapped planes; do not change
151 */
152struct vb2_buffer {
153 struct v4l2_buffer v4l2_buf;
154 struct v4l2_plane v4l2_planes[VIDEO_MAX_PLANES];
155
156 struct vb2_queue *vb2_queue;
157
158 unsigned int num_planes;
159
160/* Private: internal use only */
161 enum vb2_buffer_state state;
162
163 struct list_head queued_entry;
164 struct list_head done_entry;
165
166 struct vb2_plane planes[VIDEO_MAX_PLANES];
167 unsigned int num_planes_mapped;
168};
169
170/**
171 * struct vb2_ops - driver-specific callbacks
172 *
173 * @queue_setup: called from a VIDIOC_REQBUFS handler, before
174 * memory allocation; driver should return the required
175 * number of buffers in num_buffers, the required number
176 * of planes per buffer in num_planes; the size of each
177 * plane should be set in the sizes[] array and optional
178 * per-plane allocator specific context in alloc_ctxs[]
179 * array
180 * @wait_prepare: release any locks taken while calling vb2 functions;
181 * it is called before an ioctl needs to wait for a new
182 * buffer to arrive; required to avoid a deadlock in
183 * blocking access type
184 * @wait_finish: reacquire all locks released in the previous callback;
185 * required to continue operation after sleeping while
186 * waiting for a new buffer to arrive
187 * @buf_init: called once after allocating a buffer (in MMAP case)
188 * or after acquiring a new USERPTR buffer; drivers may
189 * perform additional buffer-related initialization;
190 * initialization failure (return != 0) will prevent
191 * queue setup from completing successfully; optional
192 * @buf_prepare: called every time the buffer is queued from userspace;
193 * drivers may perform any initialization required before
194 * each hardware operation in this callback;
195 * if an error is returned, the buffer will not be queued
196 * in driver; optional
197 * @buf_finish: called before every dequeue of the buffer back to
198 * userspace; drivers may perform any operations required
199 * before userspace accesses the buffer; optional
200 * @buf_cleanup: called once before the buffer is freed; drivers may
201 * perform any additional cleanup; optional
202 * @start_streaming: called once before entering 'streaming' state; enables
203 * driver to receive buffers over buf_queue() callback
204 * @stop_streaming: called when 'streaming' state must be disabled; driver
205 * should stop any DMA transactions or wait until they
206 * finish and give back all buffers it got from buf_queue()
207 * callback; may use vb2_wait_for_all_buffers() function
208 * @buf_queue: passes buffer vb to the driver; driver may start
209 * hardware operation on this buffer; driver should give
210 * the buffer back by calling vb2_buffer_done() function
211 */
212struct vb2_ops {
213 int (*queue_setup)(struct vb2_queue *q, unsigned int *num_buffers,
214 unsigned int *num_planes, unsigned long sizes[],
215 void *alloc_ctxs[]);
216
217 void (*wait_prepare)(struct vb2_queue *q);
218 void (*wait_finish)(struct vb2_queue *q);
219
220 int (*buf_init)(struct vb2_buffer *vb);
221 int (*buf_prepare)(struct vb2_buffer *vb);
222 int (*buf_finish)(struct vb2_buffer *vb);
223 void (*buf_cleanup)(struct vb2_buffer *vb);
224
225 int (*start_streaming)(struct vb2_queue *q);
226 int (*stop_streaming)(struct vb2_queue *q);
227
228 void (*buf_queue)(struct vb2_buffer *vb);
229};
230
231/**
232 * struct vb2_queue - a videobuf queue
233 *
234 * @type: queue type (see V4L2_BUF_TYPE_* in linux/videodev2.h
235 * @io_modes: supported io methods (see vb2_io_modes enum)
236 * @io_flags: additional io flags (see vb2_fileio_flags enum)
237 * @ops: driver-specific callbacks
238 * @mem_ops: memory allocator specific callbacks
239 * @drv_priv: driver private data
240 * @buf_struct_size: size of the driver-specific buffer structure;
241 * "0" indicates the driver doesn't want to use a custom buffer
242 * structure type, so sizeof(struct vb2_buffer) will is used
243 *
244 * @memory: current memory type used
245 * @bufs: videobuf buffer structures
246 * @num_buffers: number of allocated/used buffers
247 * @queued_list: list of buffers currently queued from userspace
248 * @queued_count: number of buffers owned by the driver
249 * @done_list: list of buffers ready to be dequeued to userspace
250 * @done_lock: lock to protect done_list list
251 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued
252 * @alloc_ctx: memory type/allocator-specific contexts for each plane
253 * @streaming: current streaming state
254 * @fileio: file io emulator internal data, used only if emulator is active
255 */
256struct vb2_queue {
257 enum v4l2_buf_type type;
258 unsigned int io_modes;
259 unsigned int io_flags;
260
261 const struct vb2_ops *ops;
262 const struct vb2_mem_ops *mem_ops;
263 void *drv_priv;
264 unsigned int buf_struct_size;
265
266/* private: internal use only */
267 enum v4l2_memory memory;
268 struct vb2_buffer *bufs[VIDEO_MAX_FRAME];
269 unsigned int num_buffers;
270
271 struct list_head queued_list;
272
273 atomic_t queued_count;
274 struct list_head done_list;
275 spinlock_t done_lock;
276 wait_queue_head_t done_wq;
277
278 void *alloc_ctx[VIDEO_MAX_PLANES];
279
280 unsigned int streaming:1;
281
282 struct vb2_fileio_data *fileio;
283};
284
285void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
286void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
287
288void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
289int vb2_wait_for_all_buffers(struct vb2_queue *q);
290
291int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
292int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
293
294int vb2_queue_init(struct vb2_queue *q);
295
296void vb2_queue_release(struct vb2_queue *q);
297
298int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
299int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
300
301int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
302int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
303
304int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
305unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait);
306size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
307 loff_t *ppos, int nonblock);
308size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
309 loff_t *ppos, int nonblock);
310
311/**
312 * vb2_is_streaming() - return streaming status of the queue
313 * @q: videobuf queue
314 */
315static inline bool vb2_is_streaming(struct vb2_queue *q)
316{
317 return q->streaming;
318}
319
320/**
321 * vb2_is_busy() - return busy status of the queue
322 * @q: videobuf queue
323 *
324 * This function checks if queue has any buffers allocated.
325 */
326static inline bool vb2_is_busy(struct vb2_queue *q)
327{
328 return (q->num_buffers > 0);
329}
330
331/**
332 * vb2_get_drv_priv() - return driver private data associated with the queue
333 * @q: videobuf queue
334 */
335static inline void *vb2_get_drv_priv(struct vb2_queue *q)
336{
337 return q->drv_priv;
338}
339
340/**
341 * vb2_set_plane_payload() - set bytesused for the plane plane_no
342 * @vb: buffer for which plane payload should be set
343 * @plane_no: plane number for which payload should be set
344 * @size: payload in bytes
345 */
346static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
347 unsigned int plane_no, unsigned long size)
348{
349 if (plane_no < vb->num_planes)
350 vb->v4l2_planes[plane_no].bytesused = size;
351}
352
353/**
354 * vb2_get_plane_payload() - get bytesused for the plane plane_no
355 * @vb: buffer for which plane payload should be set
356 * @plane_no: plane number for which payload should be set
357 * @size: payload in bytes
358 */
359static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb,
360 unsigned int plane_no)
361{
362 if (plane_no < vb->num_planes)
363 return vb->v4l2_planes[plane_no].bytesused;
364 return 0;
365}
366
367/**
368 * vb2_plane_size() - return plane size in bytes
369 * @vb: buffer for which plane size should be returned
370 * @plane_no: plane number for which size should be returned
371 */
372static inline unsigned long
373vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
374{
375 if (plane_no < vb->num_planes)
376 return vb->v4l2_planes[plane_no].length;
377 return 0;
378}
379
380#endif /* _MEDIA_VIDEOBUF2_CORE_H */
diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h
new file mode 100644
index 000000000000..7e6c68b23773
--- /dev/null
+++ b/include/media/videobuf2-dma-contig.h
@@ -0,0 +1,32 @@
1/*
2 * videobuf2-dma-coherent.h - DMA coherent memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12
13#ifndef _MEDIA_VIDEOBUF2_DMA_COHERENT_H
14#define _MEDIA_VIDEOBUF2_DMA_COHERENT_H
15
16#include <media/videobuf2-core.h>
17#include <linux/dma-mapping.h>
18
19static inline dma_addr_t
20vb2_dma_contig_plane_paddr(struct vb2_buffer *vb, unsigned int plane_no)
21{
22 dma_addr_t *paddr = vb2_plane_cookie(vb, plane_no);
23
24 return *paddr;
25}
26
27void *vb2_dma_contig_init_ctx(struct device *dev);
28void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
29
30extern const struct vb2_mem_ops vb2_dma_contig_memops;
31
32#endif
diff --git a/include/media/videobuf2-dma-sg.h b/include/media/videobuf2-dma-sg.h
new file mode 100644
index 000000000000..0038526b8ef7
--- /dev/null
+++ b/include/media/videobuf2-dma-sg.h
@@ -0,0 +1,32 @@
1/*
2 * videobuf2-dma-sg.h - DMA scatter/gather memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12
13#ifndef _MEDIA_VIDEOBUF2_DMA_SG_H
14#define _MEDIA_VIDEOBUF2_DMA_SG_H
15
16#include <media/videobuf2-core.h>
17
18struct vb2_dma_sg_desc {
19 unsigned long size;
20 unsigned int num_pages;
21 struct scatterlist *sglist;
22};
23
24static inline struct vb2_dma_sg_desc *vb2_dma_sg_plane_desc(
25 struct vb2_buffer *vb, unsigned int plane_no)
26{
27 return (struct vb2_dma_sg_desc *)vb2_plane_cookie(vb, plane_no);
28}
29
30extern const struct vb2_mem_ops vb2_dma_sg_memops;
31
32#endif
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
new file mode 100644
index 000000000000..84e1f6c031c5
--- /dev/null
+++ b/include/media/videobuf2-memops.h
@@ -0,0 +1,45 @@
1/*
2 * videobuf2-memops.h - generic memory handling routines for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 * Marek Szyprowski <m.szyprowski@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation.
12 */
13
14#ifndef _MEDIA_VIDEOBUF2_MEMOPS_H
15#define _MEDIA_VIDEOBUF2_MEMOPS_H
16
17#include <media/videobuf2-core.h>
18
19/**
20 * vb2_vmarea_handler - common vma refcount tracking handler
21 * @refcount: pointer to refcount entry in the buffer
22 * @put: callback to function that decreases buffer refcount
23 * @arg: argument for @put callback
24 */
25struct vb2_vmarea_handler {
26 atomic_t *refcount;
27 void (*put)(void *arg);
28 void *arg;
29};
30
31extern const struct vm_operations_struct vb2_common_vm_ops;
32
33int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
34 struct vm_area_struct **res_vma, dma_addr_t *res_pa);
35
36int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
37 unsigned long size,
38 const struct vm_operations_struct *vm_ops,
39 void *priv);
40
41struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
42void vb2_put_vma(struct vm_area_struct *vma);
43
44
45#endif
diff --git a/include/media/videobuf2-vmalloc.h b/include/media/videobuf2-vmalloc.h
new file mode 100644
index 000000000000..93a76b43038d
--- /dev/null
+++ b/include/media/videobuf2-vmalloc.h
@@ -0,0 +1,20 @@
1/*
2 * videobuf2-vmalloc.h - vmalloc memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12
13#ifndef _MEDIA_VIDEOBUF2_VMALLOC_H
14#define _MEDIA_VIDEOBUF2_VMALLOC_H
15
16#include <media/videobuf2-core.h>
17
18extern const struct vb2_mem_ops vb2_vmalloc_memops;
19
20#endif
diff --git a/include/media/wm8775.h b/include/media/wm8775.h
index 60739c5a23ae..d0e801a9935c 100644
--- a/include/media/wm8775.h
+++ b/include/media/wm8775.h
@@ -32,4 +32,13 @@
32#define WM8775_AIN3 4 32#define WM8775_AIN3 4
33#define WM8775_AIN4 8 33#define WM8775_AIN4 8
34 34
35
36struct wm8775_platform_data {
37 /*
38 * FIXME: Instead, we should parametrize the params
39 * that need different settings between ivtv, pvrusb2, and Nova-S
40 */
41 bool is_nova_s;
42};
43
35#endif 44#endif
diff --git a/include/staging/altera.h b/include/staging/altera.h
new file mode 100644
index 000000000000..94c0c6181daf
--- /dev/null
+++ b/include/staging/altera.h
@@ -0,0 +1,49 @@
1/*
2 * altera.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef _ALTERA_H_
27#define _ALTERA_H_
28
29struct altera_config {
30 void *dev;
31 u8 *action;
32 int (*jtag_io) (void *dev, int tms, int tdi, int tdo);
33};
34
35#if defined(CONFIG_ALTERA_STAPL) || \
36 (defined(CONFIG_ALTERA_STAPL_MODULE) && defined(MODULE))
37
38extern int altera_init(struct altera_config *config, const struct firmware *fw);
39#else
40
41static inline int altera_init(struct altera_config *config,
42 const struct firmware *fw)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return 0;
46}
47#endif /* CONFIG_ALTERA_STAPL */
48
49#endif /* _ALTERA_H_ */
diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h
index 0c864db1a466..28447f1594fa 100644
--- a/include/video/atmel_lcdc.h
+++ b/include/video/atmel_lcdc.h
@@ -52,6 +52,7 @@ struct atmel_lcdfb_info {
52 u8 bl_power; 52 u8 bl_power;
53#endif 53#endif
54 bool lcdcon_is_backlight; 54 bool lcdcon_is_backlight;
55 bool lcdcon_pol_negative;
55 u8 saved_lcdcon; 56 u8 saved_lcdcon;
56 57
57 u8 default_bpp; 58 u8 default_bpp;
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c
index 481a7bd2dfe7..a11db956dd62 100644
--- a/kernel/debug/gdbstub.c
+++ b/kernel/debug/gdbstub.c
@@ -1093,3 +1093,33 @@ int gdbstub_state(struct kgdb_state *ks, char *cmd)
1093 put_packet(remcom_out_buffer); 1093 put_packet(remcom_out_buffer);
1094 return 0; 1094 return 0;
1095} 1095}
1096
1097/**
1098 * gdbstub_exit - Send an exit message to GDB
1099 * @status: The exit code to report.
1100 */
1101void gdbstub_exit(int status)
1102{
1103 unsigned char checksum, ch, buffer[3];
1104 int loop;
1105
1106 buffer[0] = 'W';
1107 buffer[1] = hex_asc_hi(status);
1108 buffer[2] = hex_asc_lo(status);
1109
1110 dbg_io_ops->write_char('$');
1111 checksum = 0;
1112
1113 for (loop = 0; loop < 3; loop++) {
1114 ch = buffer[loop];
1115 checksum += ch;
1116 dbg_io_ops->write_char(ch);
1117 }
1118
1119 dbg_io_ops->write_char('#');
1120 dbg_io_ops->write_char(hex_asc_hi(checksum));
1121 dbg_io_ops->write_char(hex_asc_lo(checksum));
1122
1123 /* make sure the output is flushed, lest the bootloader clobber it */
1124 dbg_io_ops->flush();
1125}
diff --git a/kernel/exit.c b/kernel/exit.c
index f9a45ebcc7b1..6a488ad2dce5 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -908,6 +908,7 @@ NORET_TYPE void do_exit(long code)
908 profile_task_exit(tsk); 908 profile_task_exit(tsk);
909 909
910 WARN_ON(atomic_read(&tsk->fs_excl)); 910 WARN_ON(atomic_read(&tsk->fs_excl));
911 WARN_ON(blk_needs_flush_plug(tsk));
911 912
912 if (unlikely(in_interrupt())) 913 if (unlikely(in_interrupt()))
913 panic("Aiee, killing interrupt handler!"); 914 panic("Aiee, killing interrupt handler!");
diff --git a/kernel/fork.c b/kernel/fork.c
index 457fff2e17e0..e7548dee636b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1205,6 +1205,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1205 * Clear TID on mm_release()? 1205 * Clear TID on mm_release()?
1206 */ 1206 */
1207 p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; 1207 p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
1208#ifdef CONFIG_BLOCK
1209 p->plug = NULL;
1210#endif
1208#ifdef CONFIG_FUTEX 1211#ifdef CONFIG_FUTEX
1209 p->robust_list = NULL; 1212 p->robust_list = NULL;
1210#ifdef CONFIG_COMPAT 1213#ifdef CONFIG_COMPAT
diff --git a/kernel/power/block_io.c b/kernel/power/block_io.c
index 83bbc7c02df9..d09dd10c5a5e 100644
--- a/kernel/power/block_io.c
+++ b/kernel/power/block_io.c
@@ -28,7 +28,7 @@
28static int submit(int rw, struct block_device *bdev, sector_t sector, 28static int submit(int rw, struct block_device *bdev, sector_t sector,
29 struct page *page, struct bio **bio_chain) 29 struct page *page, struct bio **bio_chain)
30{ 30{
31 const int bio_rw = rw | REQ_SYNC | REQ_UNPLUG; 31 const int bio_rw = rw | REQ_SYNC;
32 struct bio *bio; 32 struct bio *bio;
33 33
34 bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); 34 bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1);
diff --git a/kernel/sched.c b/kernel/sched.c
index 480adeb63f8f..ae659b99ce73 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4115,6 +4115,16 @@ need_resched:
4115 switch_count = &prev->nvcsw; 4115 switch_count = &prev->nvcsw;
4116 } 4116 }
4117 4117
4118 /*
4119 * If we are going to sleep and we have plugged IO queued, make
4120 * sure to submit it to avoid deadlocks.
4121 */
4122 if (prev->state != TASK_RUNNING && blk_needs_flush_plug(prev)) {
4123 raw_spin_unlock(&rq->lock);
4124 blk_flush_plug(prev);
4125 raw_spin_lock(&rq->lock);
4126 }
4127
4118 pre_schedule(rq, prev); 4128 pre_schedule(rq, prev);
4119 4129
4120 if (unlikely(!rq->nr_running)) 4130 if (unlikely(!rq->nr_running))
@@ -5528,6 +5538,7 @@ void __sched io_schedule(void)
5528 5538
5529 delayacct_blkio_start(); 5539 delayacct_blkio_start();
5530 atomic_inc(&rq->nr_iowait); 5540 atomic_inc(&rq->nr_iowait);
5541 blk_flush_plug(current);
5531 current->in_iowait = 1; 5542 current->in_iowait = 1;
5532 schedule(); 5543 schedule();
5533 current->in_iowait = 0; 5544 current->in_iowait = 0;
@@ -5543,6 +5554,7 @@ long __sched io_schedule_timeout(long timeout)
5543 5554
5544 delayacct_blkio_start(); 5555 delayacct_blkio_start();
5545 atomic_inc(&rq->nr_iowait); 5556 atomic_inc(&rq->nr_iowait);
5557 blk_flush_plug(current);
5546 current->in_iowait = 1; 5558 current->in_iowait = 1;
5547 ret = schedule_timeout(timeout); 5559 ret = schedule_timeout(timeout);
5548 current->in_iowait = 0; 5560 current->in_iowait = 0;
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index cbafed7d4f38..7aa40f8e182d 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -703,28 +703,21 @@ void blk_trace_shutdown(struct request_queue *q)
703 * 703 *
704 **/ 704 **/
705static void blk_add_trace_rq(struct request_queue *q, struct request *rq, 705static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
706 u32 what) 706 u32 what)
707{ 707{
708 struct blk_trace *bt = q->blk_trace; 708 struct blk_trace *bt = q->blk_trace;
709 int rw = rq->cmd_flags & 0x03;
710 709
711 if (likely(!bt)) 710 if (likely(!bt))
712 return; 711 return;
713 712
714 if (rq->cmd_flags & REQ_DISCARD)
715 rw |= REQ_DISCARD;
716
717 if (rq->cmd_flags & REQ_SECURE)
718 rw |= REQ_SECURE;
719
720 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { 713 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
721 what |= BLK_TC_ACT(BLK_TC_PC); 714 what |= BLK_TC_ACT(BLK_TC_PC);
722 __blk_add_trace(bt, 0, blk_rq_bytes(rq), rw, 715 __blk_add_trace(bt, 0, blk_rq_bytes(rq), rq->cmd_flags,
723 what, rq->errors, rq->cmd_len, rq->cmd); 716 what, rq->errors, rq->cmd_len, rq->cmd);
724 } else { 717 } else {
725 what |= BLK_TC_ACT(BLK_TC_FS); 718 what |= BLK_TC_ACT(BLK_TC_FS);
726 __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), rw, 719 __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
727 what, rq->errors, 0, NULL); 720 rq->cmd_flags, what, rq->errors, 0, NULL);
728 } 721 }
729} 722}
730 723
diff --git a/lib/show_mem.c b/lib/show_mem.c
index d8d602b58c31..90cbe4bb5960 100644
--- a/lib/show_mem.c
+++ b/lib/show_mem.c
@@ -9,7 +9,7 @@
9#include <linux/nmi.h> 9#include <linux/nmi.h>
10#include <linux/quicklist.h> 10#include <linux/quicklist.h>
11 11
12void __show_mem(unsigned int filter) 12void show_mem(unsigned int filter)
13{ 13{
14 pg_data_t *pgdat; 14 pg_data_t *pgdat;
15 unsigned long total = 0, reserved = 0, shared = 0, 15 unsigned long total = 0, reserved = 0, shared = 0,
@@ -61,8 +61,3 @@ void __show_mem(unsigned int filter)
61 quicklist_total_size()); 61 quicklist_total_size());
62#endif 62#endif
63} 63}
64
65void show_mem(void)
66{
67 __show_mem(0);
68}
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 4b3e9f17ee21..0d9a036ada66 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -14,17 +14,11 @@
14 14
15static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); 15static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
16 16
17void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
18{
19}
20EXPORT_SYMBOL(default_unplug_io_fn);
21
22struct backing_dev_info default_backing_dev_info = { 17struct backing_dev_info default_backing_dev_info = {
23 .name = "default", 18 .name = "default",
24 .ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE, 19 .ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE,
25 .state = 0, 20 .state = 0,
26 .capabilities = BDI_CAP_MAP_COPY, 21 .capabilities = BDI_CAP_MAP_COPY,
27 .unplug_io_fn = default_unplug_io_fn,
28}; 22};
29EXPORT_SYMBOL_GPL(default_backing_dev_info); 23EXPORT_SYMBOL_GPL(default_backing_dev_info);
30 24
@@ -604,7 +598,7 @@ static void bdi_prune_sb(struct backing_dev_info *bdi)
604 spin_lock(&sb_lock); 598 spin_lock(&sb_lock);
605 list_for_each_entry(sb, &super_blocks, s_list) { 599 list_for_each_entry(sb, &super_blocks, s_list) {
606 if (sb->s_bdi == bdi) 600 if (sb->s_bdi == bdi)
607 sb->s_bdi = NULL; 601 sb->s_bdi = &default_backing_dev_info;
608 } 602 }
609 spin_unlock(&sb_lock); 603 spin_unlock(&sb_lock);
610} 604}
diff --git a/mm/filemap.c b/mm/filemap.c
index d8b34d1a1071..c641edf553a9 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -166,45 +166,15 @@ void delete_from_page_cache(struct page *page)
166} 166}
167EXPORT_SYMBOL(delete_from_page_cache); 167EXPORT_SYMBOL(delete_from_page_cache);
168 168
169static int sync_page(void *word) 169static int sleep_on_page(void *word)
170{ 170{
171 struct address_space *mapping;
172 struct page *page;
173
174 page = container_of((unsigned long *)word, struct page, flags);
175
176 /*
177 * page_mapping() is being called without PG_locked held.
178 * Some knowledge of the state and use of the page is used to
179 * reduce the requirements down to a memory barrier.
180 * The danger here is of a stale page_mapping() return value
181 * indicating a struct address_space different from the one it's
182 * associated with when it is associated with one.
183 * After smp_mb(), it's either the correct page_mapping() for
184 * the page, or an old page_mapping() and the page's own
185 * page_mapping() has gone NULL.
186 * The ->sync_page() address_space operation must tolerate
187 * page_mapping() going NULL. By an amazing coincidence,
188 * this comes about because none of the users of the page
189 * in the ->sync_page() methods make essential use of the
190 * page_mapping(), merely passing the page down to the backing
191 * device's unplug functions when it's non-NULL, which in turn
192 * ignore it for all cases but swap, where only page_private(page) is
193 * of interest. When page_mapping() does go NULL, the entire
194 * call stack gracefully ignores the page and returns.
195 * -- wli
196 */
197 smp_mb();
198 mapping = page_mapping(page);
199 if (mapping && mapping->a_ops && mapping->a_ops->sync_page)
200 mapping->a_ops->sync_page(page);
201 io_schedule(); 171 io_schedule();
202 return 0; 172 return 0;
203} 173}
204 174
205static int sync_page_killable(void *word) 175static int sleep_on_page_killable(void *word)
206{ 176{
207 sync_page(word); 177 sleep_on_page(word);
208 return fatal_signal_pending(current) ? -EINTR : 0; 178 return fatal_signal_pending(current) ? -EINTR : 0;
209} 179}
210 180
@@ -560,12 +530,6 @@ struct page *__page_cache_alloc(gfp_t gfp)
560EXPORT_SYMBOL(__page_cache_alloc); 530EXPORT_SYMBOL(__page_cache_alloc);
561#endif 531#endif
562 532
563static int __sleep_on_page_lock(void *word)
564{
565 io_schedule();
566 return 0;
567}
568
569/* 533/*
570 * In order to wait for pages to become available there must be 534 * In order to wait for pages to become available there must be
571 * waitqueues associated with pages. By using a hash table of 535 * waitqueues associated with pages. By using a hash table of
@@ -593,7 +557,7 @@ void wait_on_page_bit(struct page *page, int bit_nr)
593 DEFINE_WAIT_BIT(wait, &page->flags, bit_nr); 557 DEFINE_WAIT_BIT(wait, &page->flags, bit_nr);
594 558
595 if (test_bit(bit_nr, &page->flags)) 559 if (test_bit(bit_nr, &page->flags))
596 __wait_on_bit(page_waitqueue(page), &wait, sync_page, 560 __wait_on_bit(page_waitqueue(page), &wait, sleep_on_page,
597 TASK_UNINTERRUPTIBLE); 561 TASK_UNINTERRUPTIBLE);
598} 562}
599EXPORT_SYMBOL(wait_on_page_bit); 563EXPORT_SYMBOL(wait_on_page_bit);
@@ -657,17 +621,12 @@ EXPORT_SYMBOL(end_page_writeback);
657/** 621/**
658 * __lock_page - get a lock on the page, assuming we need to sleep to get it 622 * __lock_page - get a lock on the page, assuming we need to sleep to get it
659 * @page: the page to lock 623 * @page: the page to lock
660 *
661 * Ugly. Running sync_page() in state TASK_UNINTERRUPTIBLE is scary. If some
662 * random driver's requestfn sets TASK_RUNNING, we could busywait. However
663 * chances are that on the second loop, the block layer's plug list is empty,
664 * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
665 */ 624 */
666void __lock_page(struct page *page) 625void __lock_page(struct page *page)
667{ 626{
668 DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); 627 DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
669 628
670 __wait_on_bit_lock(page_waitqueue(page), &wait, sync_page, 629 __wait_on_bit_lock(page_waitqueue(page), &wait, sleep_on_page,
671 TASK_UNINTERRUPTIBLE); 630 TASK_UNINTERRUPTIBLE);
672} 631}
673EXPORT_SYMBOL(__lock_page); 632EXPORT_SYMBOL(__lock_page);
@@ -677,24 +636,10 @@ int __lock_page_killable(struct page *page)
677 DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); 636 DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
678 637
679 return __wait_on_bit_lock(page_waitqueue(page), &wait, 638 return __wait_on_bit_lock(page_waitqueue(page), &wait,
680 sync_page_killable, TASK_KILLABLE); 639 sleep_on_page_killable, TASK_KILLABLE);
681} 640}
682EXPORT_SYMBOL_GPL(__lock_page_killable); 641EXPORT_SYMBOL_GPL(__lock_page_killable);
683 642
684/**
685 * __lock_page_nosync - get a lock on the page, without calling sync_page()
686 * @page: the page to lock
687 *
688 * Variant of lock_page that does not require the caller to hold a reference
689 * on the page's mapping.
690 */
691void __lock_page_nosync(struct page *page)
692{
693 DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
694 __wait_on_bit_lock(page_waitqueue(page), &wait, __sleep_on_page_lock,
695 TASK_UNINTERRUPTIBLE);
696}
697
698int __lock_page_or_retry(struct page *page, struct mm_struct *mm, 643int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
699 unsigned int flags) 644 unsigned int flags)
700{ 645{
@@ -1409,12 +1354,15 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
1409 unsigned long seg = 0; 1354 unsigned long seg = 0;
1410 size_t count; 1355 size_t count;
1411 loff_t *ppos = &iocb->ki_pos; 1356 loff_t *ppos = &iocb->ki_pos;
1357 struct blk_plug plug;
1412 1358
1413 count = 0; 1359 count = 0;
1414 retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); 1360 retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
1415 if (retval) 1361 if (retval)
1416 return retval; 1362 return retval;
1417 1363
1364 blk_start_plug(&plug);
1365
1418 /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ 1366 /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
1419 if (filp->f_flags & O_DIRECT) { 1367 if (filp->f_flags & O_DIRECT) {
1420 loff_t size; 1368 loff_t size;
@@ -1487,6 +1435,7 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
1487 break; 1435 break;
1488 } 1436 }
1489out: 1437out:
1438 blk_finish_plug(&plug);
1490 return retval; 1439 return retval;
1491} 1440}
1492EXPORT_SYMBOL(generic_file_aio_read); 1441EXPORT_SYMBOL(generic_file_aio_read);
@@ -2598,11 +2547,13 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2598{ 2547{
2599 struct file *file = iocb->ki_filp; 2548 struct file *file = iocb->ki_filp;
2600 struct inode *inode = file->f_mapping->host; 2549 struct inode *inode = file->f_mapping->host;
2550 struct blk_plug plug;
2601 ssize_t ret; 2551 ssize_t ret;
2602 2552
2603 BUG_ON(iocb->ki_pos != pos); 2553 BUG_ON(iocb->ki_pos != pos);
2604 2554
2605 mutex_lock(&inode->i_mutex); 2555 mutex_lock(&inode->i_mutex);
2556 blk_start_plug(&plug);
2606 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); 2557 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
2607 mutex_unlock(&inode->i_mutex); 2558 mutex_unlock(&inode->i_mutex);
2608 2559
@@ -2613,6 +2564,7 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2613 if (err < 0 && ret > 0) 2564 if (err < 0 && ret > 0)
2614 ret = err; 2565 ret = err;
2615 } 2566 }
2567 blk_finish_plug(&plug);
2616 return ret; 2568 return ret;
2617} 2569}
2618EXPORT_SYMBOL(generic_file_aio_write); 2570EXPORT_SYMBOL(generic_file_aio_write);
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index e0af336530c6..37feb9fec228 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -945,7 +945,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
945 collect_procs(ppage, &tokill); 945 collect_procs(ppage, &tokill);
946 946
947 if (hpage != ppage) 947 if (hpage != ppage)
948 lock_page_nosync(ppage); 948 lock_page(ppage);
949 949
950 ret = try_to_unmap(ppage, ttu); 950 ret = try_to_unmap(ppage, ttu);
951 if (ret != SWAP_SUCCESS) 951 if (ret != SWAP_SUCCESS)
@@ -1038,7 +1038,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
1038 * Check "just unpoisoned", "filter hit", and 1038 * Check "just unpoisoned", "filter hit", and
1039 * "race with other subpage." 1039 * "race with other subpage."
1040 */ 1040 */
1041 lock_page_nosync(hpage); 1041 lock_page(hpage);
1042 if (!PageHWPoison(hpage) 1042 if (!PageHWPoison(hpage)
1043 || (hwpoison_filter(p) && TestClearPageHWPoison(p)) 1043 || (hwpoison_filter(p) && TestClearPageHWPoison(p))
1044 || (p != hpage && TestSetPageHWPoison(hpage))) { 1044 || (p != hpage && TestSetPageHWPoison(hpage))) {
@@ -1088,7 +1088,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
1088 * It's very difficult to mess with pages currently under IO 1088 * It's very difficult to mess with pages currently under IO
1089 * and in many cases impossible, so we just avoid it here. 1089 * and in many cases impossible, so we just avoid it here.
1090 */ 1090 */
1091 lock_page_nosync(hpage); 1091 lock_page(hpage);
1092 1092
1093 /* 1093 /*
1094 * unpoison always clear PG_hwpoison inside page lock 1094 * unpoison always clear PG_hwpoison inside page lock
@@ -1231,7 +1231,7 @@ int unpoison_memory(unsigned long pfn)
1231 return 0; 1231 return 0;
1232 } 1232 }
1233 1233
1234 lock_page_nosync(page); 1234 lock_page(page);
1235 /* 1235 /*
1236 * This test is racy because PG_hwpoison is set outside of page lock. 1236 * This test is racy because PG_hwpoison is set outside of page lock.
1237 * That's acceptable because that won't trigger kernel panic. Instead, 1237 * That's acceptable because that won't trigger kernel panic. Instead,
diff --git a/mm/nommu.c b/mm/nommu.c
index e629143f9440..cb86e7d5e7f5 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1842,10 +1842,6 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
1842} 1842}
1843EXPORT_SYMBOL(remap_vmalloc_range); 1843EXPORT_SYMBOL(remap_vmalloc_range);
1844 1844
1845void swap_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
1846{
1847}
1848
1849unsigned long arch_get_unmapped_area(struct file *file, unsigned long addr, 1845unsigned long arch_get_unmapped_area(struct file *file, unsigned long addr,
1850 unsigned long len, unsigned long pgoff, unsigned long flags) 1846 unsigned long len, unsigned long pgoff, unsigned long flags)
1851{ 1847{
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 62a5cec08a17..6a819d1b2c7d 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -406,7 +406,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
406 task_unlock(current); 406 task_unlock(current);
407 dump_stack(); 407 dump_stack();
408 mem_cgroup_print_oom_info(mem, p); 408 mem_cgroup_print_oom_info(mem, p);
409 __show_mem(SHOW_MEM_FILTER_NODES); 409 show_mem(SHOW_MEM_FILTER_NODES);
410 if (sysctl_oom_dump_tasks) 410 if (sysctl_oom_dump_tasks)
411 dump_tasks(mem, nodemask); 411 dump_tasks(mem, nodemask);
412} 412}
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 632b46479c94..31f698862420 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1040,11 +1040,17 @@ static int __writepage(struct page *page, struct writeback_control *wbc,
1040int generic_writepages(struct address_space *mapping, 1040int generic_writepages(struct address_space *mapping,
1041 struct writeback_control *wbc) 1041 struct writeback_control *wbc)
1042{ 1042{
1043 struct blk_plug plug;
1044 int ret;
1045
1043 /* deal with chardevs and other special file */ 1046 /* deal with chardevs and other special file */
1044 if (!mapping->a_ops->writepage) 1047 if (!mapping->a_ops->writepage)
1045 return 0; 1048 return 0;
1046 1049
1047 return write_cache_pages(mapping, wbc, __writepage, mapping); 1050 blk_start_plug(&plug);
1051 ret = write_cache_pages(mapping, wbc, __writepage, mapping);
1052 blk_finish_plug(&plug);
1053 return ret;
1048} 1054}
1049 1055
1050EXPORT_SYMBOL(generic_writepages); 1056EXPORT_SYMBOL(generic_writepages);
@@ -1251,7 +1257,7 @@ int set_page_dirty_lock(struct page *page)
1251{ 1257{
1252 int ret; 1258 int ret;
1253 1259
1254 lock_page_nosync(page); 1260 lock_page(page);
1255 ret = set_page_dirty(page); 1261 ret = set_page_dirty(page);
1256 unlock_page(page); 1262 unlock_page(page);
1257 return ret; 1263 return ret;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8e5726ab0d85..d6e7ba7373be 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2195,7 +2195,7 @@ nopage:
2195 current->comm, order, gfp_mask); 2195 current->comm, order, gfp_mask);
2196 dump_stack(); 2196 dump_stack();
2197 if (!should_suppress_show_mem()) 2197 if (!should_suppress_show_mem())
2198 __show_mem(filter); 2198 show_mem(filter);
2199 } 2199 }
2200 return page; 2200 return page;
2201got_pg: 2201got_pg:
diff --git a/mm/page_io.c b/mm/page_io.c
index 2dee975bf469..dc76b4d0611e 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -106,7 +106,7 @@ int swap_writepage(struct page *page, struct writeback_control *wbc)
106 goto out; 106 goto out;
107 } 107 }
108 if (wbc->sync_mode == WB_SYNC_ALL) 108 if (wbc->sync_mode == WB_SYNC_ALL)
109 rw |= REQ_SYNC | REQ_UNPLUG; 109 rw |= REQ_SYNC;
110 count_vm_event(PSWPOUT); 110 count_vm_event(PSWPOUT);
111 set_page_writeback(page); 111 set_page_writeback(page);
112 unlock_page(page); 112 unlock_page(page);
diff --git a/mm/readahead.c b/mm/readahead.c
index 77506a291a2d..2c0cc489e288 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -109,9 +109,12 @@ EXPORT_SYMBOL(read_cache_pages);
109static int read_pages(struct address_space *mapping, struct file *filp, 109static int read_pages(struct address_space *mapping, struct file *filp,
110 struct list_head *pages, unsigned nr_pages) 110 struct list_head *pages, unsigned nr_pages)
111{ 111{
112 struct blk_plug plug;
112 unsigned page_idx; 113 unsigned page_idx;
113 int ret; 114 int ret;
114 115
116 blk_start_plug(&plug);
117
115 if (mapping->a_ops->readpages) { 118 if (mapping->a_ops->readpages) {
116 ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages); 119 ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages);
117 /* Clean up the remaining pages */ 120 /* Clean up the remaining pages */
@@ -129,7 +132,10 @@ static int read_pages(struct address_space *mapping, struct file *filp,
129 page_cache_release(page); 132 page_cache_release(page);
130 } 133 }
131 ret = 0; 134 ret = 0;
135
132out: 136out:
137 blk_finish_plug(&plug);
138
133 return ret; 139 return ret;
134} 140}
135 141
@@ -554,17 +560,5 @@ page_cache_async_readahead(struct address_space *mapping,
554 560
555 /* do read-ahead */ 561 /* do read-ahead */
556 ondemand_readahead(mapping, ra, filp, true, offset, req_size); 562 ondemand_readahead(mapping, ra, filp, true, offset, req_size);
557
558#ifdef CONFIG_BLOCK
559 /*
560 * Normally the current page is !uptodate and lock_page() will be
561 * immediately called to implicitly unplug the device. However this
562 * is not always true for RAID conifgurations, where data arrives
563 * not strictly in their submission order. In this case we need to
564 * explicitly kick off the IO.
565 */
566 if (PageUptodate(page))
567 blk_run_backing_dev(mapping->backing_dev_info, NULL);
568#endif
569} 563}
570EXPORT_SYMBOL_GPL(page_cache_async_readahead); 564EXPORT_SYMBOL_GPL(page_cache_async_readahead);
diff --git a/mm/shmem.c b/mm/shmem.c
index 91ce9a1024d7..58da7c150ba6 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -224,7 +224,6 @@ static const struct vm_operations_struct shmem_vm_ops;
224static struct backing_dev_info shmem_backing_dev_info __read_mostly = { 224static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
225 .ra_pages = 0, /* No readahead */ 225 .ra_pages = 0, /* No readahead */
226 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED, 226 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED,
227 .unplug_io_fn = default_unplug_io_fn,
228}; 227};
229 228
230static LIST_HEAD(shmem_swaplist); 229static LIST_HEAD(shmem_swaplist);
diff --git a/mm/slub.c b/mm/slub.c
index 93de30db95f5..f881874843a5 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -849,11 +849,11 @@ static inline void slab_free_hook(struct kmem_cache *s, void *x)
849 local_irq_save(flags); 849 local_irq_save(flags);
850 kmemcheck_slab_free(s, x, s->objsize); 850 kmemcheck_slab_free(s, x, s->objsize);
851 debug_check_no_locks_freed(x, s->objsize); 851 debug_check_no_locks_freed(x, s->objsize);
852 if (!(s->flags & SLAB_DEBUG_OBJECTS))
853 debug_check_no_obj_freed(x, s->objsize);
854 local_irq_restore(flags); 852 local_irq_restore(flags);
855 } 853 }
856#endif 854#endif
855 if (!(s->flags & SLAB_DEBUG_OBJECTS))
856 debug_check_no_obj_freed(x, s->objsize);
857} 857}
858 858
859/* 859/*
@@ -1604,7 +1604,7 @@ static inline void note_cmpxchg_failure(const char *n,
1604 1604
1605void init_kmem_cache_cpus(struct kmem_cache *s) 1605void init_kmem_cache_cpus(struct kmem_cache *s)
1606{ 1606{
1607#if defined(CONFIG_CMPXCHG_LOCAL) && defined(CONFIG_PREEMPT) 1607#ifdef CONFIG_CMPXCHG_LOCAL
1608 int cpu; 1608 int cpu;
1609 1609
1610 for_each_possible_cpu(cpu) 1610 for_each_possible_cpu(cpu)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 5c8cfabbc9bc..46680461785b 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -24,12 +24,10 @@
24 24
25/* 25/*
26 * swapper_space is a fiction, retained to simplify the path through 26 * swapper_space is a fiction, retained to simplify the path through
27 * vmscan's shrink_page_list, to make sync_page look nicer, and to allow 27 * vmscan's shrink_page_list.
28 * future use of radix_tree tags in the swap cache.
29 */ 28 */
30static const struct address_space_operations swap_aops = { 29static const struct address_space_operations swap_aops = {
31 .writepage = swap_writepage, 30 .writepage = swap_writepage,
32 .sync_page = block_sync_page,
33 .set_page_dirty = __set_page_dirty_nobuffers, 31 .set_page_dirty = __set_page_dirty_nobuffers,
34 .migratepage = migrate_page, 32 .migratepage = migrate_page,
35}; 33};
@@ -37,7 +35,6 @@ static const struct address_space_operations swap_aops = {
37static struct backing_dev_info swap_backing_dev_info = { 35static struct backing_dev_info swap_backing_dev_info = {
38 .name = "swap", 36 .name = "swap",
39 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED, 37 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED,
40 .unplug_io_fn = swap_unplug_io_fn,
41}; 38};
42 39
43struct address_space swapper_space = { 40struct address_space swapper_space = {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 039e61677635..8c6b3ce38f09 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -95,39 +95,6 @@ __try_to_reclaim_swap(struct swap_info_struct *si, unsigned long offset)
95} 95}
96 96
97/* 97/*
98 * We need this because the bdev->unplug_fn can sleep and we cannot
99 * hold swap_lock while calling the unplug_fn. And swap_lock
100 * cannot be turned into a mutex.
101 */
102static DECLARE_RWSEM(swap_unplug_sem);
103
104void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
105{
106 swp_entry_t entry;
107
108 down_read(&swap_unplug_sem);
109 entry.val = page_private(page);
110 if (PageSwapCache(page)) {
111 struct block_device *bdev = swap_info[swp_type(entry)]->bdev;
112 struct backing_dev_info *bdi;
113
114 /*
115 * If the page is removed from swapcache from under us (with a
116 * racy try_to_unuse/swapoff) we need an additional reference
117 * count to avoid reading garbage from page_private(page) above.
118 * If the WARN_ON triggers during a swapoff it maybe the race
119 * condition and it's harmless. However if it triggers without
120 * swapoff it signals a problem.
121 */
122 WARN_ON(page_count(page) <= 1);
123
124 bdi = bdev->bd_inode->i_mapping->backing_dev_info;
125 blk_run_backing_dev(bdi, page);
126 }
127 up_read(&swap_unplug_sem);
128}
129
130/*
131 * swapon tell device that all the old swap contents can be discarded, 98 * swapon tell device that all the old swap contents can be discarded,
132 * to allow the swap device to optimize its wear-levelling. 99 * to allow the swap device to optimize its wear-levelling.
133 */ 100 */
@@ -1662,10 +1629,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1662 goto out_dput; 1629 goto out_dput;
1663 } 1630 }
1664 1631
1665 /* wait for any unplug function to finish */
1666 down_write(&swap_unplug_sem);
1667 up_write(&swap_unplug_sem);
1668
1669 destroy_swap_extents(p); 1632 destroy_swap_extents(p);
1670 if (p->flags & SWP_CONTINUED) 1633 if (p->flags & SWP_CONTINUED)
1671 free_swap_count_continuations(p); 1634 free_swap_count_continuations(p);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 060e4c191403..f73b8657c2d0 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -358,7 +358,7 @@ static int may_write_to_queue(struct backing_dev_info *bdi,
358static void handle_write_error(struct address_space *mapping, 358static void handle_write_error(struct address_space *mapping,
359 struct page *page, int error) 359 struct page *page, int error)
360{ 360{
361 lock_page_nosync(page); 361 lock_page(page);
362 if (page_mapping(page) == mapping) 362 if (page_mapping(page) == mapping)
363 mapping_set_error(mapping, error); 363 mapping_set_error(mapping, error);
364 unlock_page(page); 364 unlock_page(page);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 30916b06c12b..c8e10216c113 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -38,6 +38,14 @@ struct unix_domain {
38 38
39extern struct auth_ops svcauth_unix; 39extern struct auth_ops svcauth_unix;
40 40
41static void svcauth_unix_domain_release(struct auth_domain *dom)
42{
43 struct unix_domain *ud = container_of(dom, struct unix_domain, h);
44
45 kfree(dom->name);
46 kfree(ud);
47}
48
41struct auth_domain *unix_domain_find(char *name) 49struct auth_domain *unix_domain_find(char *name)
42{ 50{
43 struct auth_domain *rv; 51 struct auth_domain *rv;
@@ -47,7 +55,7 @@ struct auth_domain *unix_domain_find(char *name)
47 while(1) { 55 while(1) {
48 if (rv) { 56 if (rv) {
49 if (new && rv != &new->h) 57 if (new && rv != &new->h)
50 auth_domain_put(&new->h); 58 svcauth_unix_domain_release(&new->h);
51 59
52 if (rv->flavour != &svcauth_unix) { 60 if (rv->flavour != &svcauth_unix) {
53 auth_domain_put(rv); 61 auth_domain_put(rv);
@@ -74,14 +82,6 @@ struct auth_domain *unix_domain_find(char *name)
74} 82}
75EXPORT_SYMBOL_GPL(unix_domain_find); 83EXPORT_SYMBOL_GPL(unix_domain_find);
76 84
77static void svcauth_unix_domain_release(struct auth_domain *dom)
78{
79 struct unix_domain *ud = container_of(dom, struct unix_domain, h);
80
81 kfree(dom->name);
82 kfree(ud);
83}
84
85 85
86/************************************************** 86/**************************************************
87 * cache for IP address to unix_domain 87 * cache for IP address to unix_domain
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index d63c1754e05f..6943e24a74a1 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -51,7 +51,7 @@ config SND_SOC_ALL_CODECS
51 select SND_SOC_TWL6040 if TWL4030_CORE 51 select SND_SOC_TWL6040 if TWL4030_CORE
52 select SND_SOC_UDA134X 52 select SND_SOC_UDA134X
53 select SND_SOC_UDA1380 if I2C 53 select SND_SOC_UDA1380 if I2C
54 select SND_SOC_WL1273 if RADIO_WL1273 54 select SND_SOC_WL1273 if MFD_WL1273_CORE
55 select SND_SOC_WM2000 if I2C 55 select SND_SOC_WM2000 if I2C
56 select SND_SOC_WM8350 if MFD_WM8350 56 select SND_SOC_WM8350 if MFD_WM8350
57 select SND_SOC_WM8400 if MFD_WM8400 57 select SND_SOC_WM8400 if MFD_WM8400
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 347a567b01e1..b8066ef10bb0 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -153,7 +153,8 @@ static int cq93vc_resume(struct snd_soc_codec *codec)
153 153
154static int cq93vc_probe(struct snd_soc_codec *codec) 154static int cq93vc_probe(struct snd_soc_codec *codec)
155{ 155{
156 struct davinci_vc *davinci_vc = snd_soc_codec_get_drvdata(codec); 156 struct davinci_vc *davinci_vc =
157 mfd_get_data(to_platform_device(codec->dev));
157 158
158 davinci_vc->cq93vc.codec = codec; 159 davinci_vc->cq93vc.codec = codec;
159 codec->control_data = davinci_vc; 160 codec->control_data = davinci_vc;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index e4d464b937d6..8512800f6326 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -26,6 +26,7 @@
26#include <linux/pm.h> 26#include <linux/pm.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/mfd/core.h>
29#include <linux/i2c/twl.h> 30#include <linux/i2c/twl.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <sound/core.h> 32#include <sound/core.h>
@@ -732,7 +733,8 @@ static int aif_event(struct snd_soc_dapm_widget *w,
732 733
733static void headset_ramp(struct snd_soc_codec *codec, int ramp) 734static void headset_ramp(struct snd_soc_codec *codec, int ramp)
734{ 735{
735 struct twl4030_codec_audio_data *pdata = codec->dev->platform_data; 736 struct twl4030_codec_audio_data *pdata =
737 mfd_get_data(to_platform_device(codec->dev));
736 unsigned char hs_gain, hs_pop; 738 unsigned char hs_gain, hs_pop;
737 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 739 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
738 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 740 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -2297,7 +2299,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2297 2299
2298static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2300static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2299{ 2301{
2300 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; 2302 struct twl4030_codec_audio_data *pdata = mfd_get_data(pdev);
2301 2303
2302 if (!pdata) { 2304 if (!pdata) {
2303 dev_err(&pdev->dev, "platform_data is missing\n"); 2305 dev_err(&pdev->dev, "platform_data is missing\n");
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 861b28f543d2..c8a874d0d4ca 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com> 4 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com>
5 * 5 *
6 * Copyright: (C) 2010 Nokia Corporation 6 * Copyright: (C) 2010, 2011 Nokia Corporation
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -179,7 +179,12 @@ static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
179 return 0; 179 return 0;
180} 180}
181 181
182static const char *wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" }; 182/*
183 * TODO: Implement the audio routing in the driver. Now this control
184 * only indicates the setting that has been done elsewhere (in the user
185 * space).
186 */
187static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
183 188
184static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, 189static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
185 struct snd_ctl_elem_value *ucontrol) 190 struct snd_ctl_elem_value *ucontrol)
@@ -239,7 +244,7 @@ static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
239 return 1; 244 return 1;
240} 245}
241 246
242static const char *wl1273_audio_strings[] = { "Digital", "Analog" }; 247static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };
243 248
244static const struct soc_enum wl1273_audio_enum = 249static const struct soc_enum wl1273_audio_enum =
245 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings), 250 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings),
@@ -436,7 +441,8 @@ EXPORT_SYMBOL_GPL(wl1273_get_format);
436 441
437static int wl1273_probe(struct snd_soc_codec *codec) 442static int wl1273_probe(struct snd_soc_codec *codec)
438{ 443{
439 struct wl1273_core **core = codec->dev->platform_data; 444 struct wl1273_core **core =
445 mfd_get_data(to_platform_device(codec->dev));
440 struct wl1273_priv *wl1273; 446 struct wl1273_priv *wl1273;
441 int r; 447 int r;
442 448
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 3c3bc079167e..736b785e3756 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -22,6 +22,7 @@
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/mfd/wm8400-audio.h> 23#include <linux/mfd/wm8400-audio.h>
24#include <linux/mfd/wm8400-private.h> 24#include <linux/mfd/wm8400-private.h>
25#include <linux/mfd/core.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
@@ -1377,7 +1378,7 @@ static void wm8400_probe_deferred(struct work_struct *work)
1377 1378
1378static int wm8400_codec_probe(struct snd_soc_codec *codec) 1379static int wm8400_codec_probe(struct snd_soc_codec *codec)
1379{ 1380{
1380 struct wm8400 *wm8400 = dev_get_platdata(codec->dev); 1381 struct wm8400 *wm8400 = mfd_get_data(to_platform_device(codec->dev));
1381 struct wm8400_priv *priv; 1382 struct wm8400_priv *priv;
1382 int ret; 1383 int ret;
1383 u16 reg; 1384 u16 reg;
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 9d2afccc3a2d..13e05a302a92 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -205,7 +205,7 @@ static struct snd_soc_dai_driver davinci_vcif_dai = {
205 205
206static int davinci_vcif_probe(struct platform_device *pdev) 206static int davinci_vcif_probe(struct platform_device *pdev)
207{ 207{
208 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); 208 struct davinci_vc *davinci_vc = mfd_get_data(pdev);
209 struct davinci_vcif_dev *davinci_vcif_dev; 209 struct davinci_vcif_dev *davinci_vcif_dev;
210 int ret; 210 int ret;
211 211